On 25.07.2017 10:36, Muenz, Michael wrote: > Am 24.07.2017 um 19:01 schrieb Andrey V. Elsukov: >> >> .1.1: ICMP echo reply, id 33347, seq 28416, length 8 >> This does not match with what I expected to see. The reply here should >> be something like "10.24.66.25 > 10.26.2.N: ICMP echo reply". >> >> It seems the problem is with ipfw_nat, that for both directions thinks >> that packets are inbound and this leads to incorrect translation. >> >> Can you modify your IPsec security policies, so outgoing packets from >> 10.26.2.0/24 will go through the same tunnel? Then you need to modify >> nat rule: >> >> ipfw nat 1 config ip 10.26.1.1 >> ipfw add 179 nat 1 log ip from 10.26.2.0/24 to 10.24.66.0/24 out xmit >> enc0 >> ipfw add 179 nat 1 log ip from 10.24.66.0/24 to 10.26.1.1 in recv enc0 >> > > Hi, > > when I change it to > > out xmit enc0 > > nothing happens because the packets have to math the IPSEC SA before > entering the tunnel (and enc0 I guess). > So it has to be > > in recv vtnet1
ICMP request should be matched by outbound IPsec policy. Looking to your tcpdump, you use tunnel IPsec mode. So, how this should work: * 10.26.2.N sends ICMP request to 10.24.66.25 * 10.26.1.1 handles it by tunnel mode IPsec security policy, something like: spdadd -4 10.26.2.0/24 10.24.66.0/24 any -P out ipsec \ esp/tunnel/213.244.192.191-81.24.74.3/require; * IPsec code does lookup for IPsec SA and uses something like: add 213.244.192.191 81.24.74.3 esp 0x2478d746 -m tunnel -E ...; * Then if_enc(4) pfil handler is called and now you need to do address translation (with net.enc.out.ipsec_filter_mask=1), and in tcpdump you should see not yet translated packet: 10.26.2.N > 10.24.66.25: ICMP echo request .... * Then IPsec code does IP encapsulation and you will see: 213.244.192.191 > 81.24.74.3: IPIP ... 10.26.1.1 > 10.24.66.25: ICMP echo request (in my previous patch was a bug, and you did not see outbound packet two times in tcpdump, I attached new patch where it is fixed) * Then IPsec sends encrypted packet to 81.24.74.3. * The second host sends ICMP reply to 10.26.1.1. * 213.244.192.191 recieves encrypted packet and does IPsec SA lookup, it should have something like: add 81.24.74.3 213.244.192.191 esp 0xce702ac1 -m tunnel -E ...; * IPsec code does decryption and if_enc(4) hook is called, and you will see in the tcpdump: 81.24.74.3 > 213.244.192.191: IPIP ... 10.24.66.25 > 10.26.1.1: ICMP echo reply * Since we use net.enc.out.ipsec_filter_mask=2, this packet will not be handled by firewall and IPsec will do IP decapsultion, and then will pass decapsulated packet to the pfil where it will be translated: 10.24.66.25 > 10.26.2.N: ICMP echo reply .... * Then this packet goes to ip_input() -> ip_forward() processing. To avoid extra IPsec processing you should have no security policy that matches "10.24.66.25 > 10.26.2.N" packet, or this should be policy that requires "none" IPsec processing. * Then ip_forward() sends this packet to 10.26.2.N. -- WBR, Andrey V. Elsukov
Index: sys/net/if_enc.c =================================================================== --- sys/net/if_enc.c (revision 321414) +++ sys/net/if_enc.c (working copy) @@ -223,10 +223,11 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, vo if (ctx->af != hhook_id) return (EPFNOSUPPORT); - if (((hhook_type == HHOOK_TYPE_IPSEC_IN && - (ctx->enc & V_bpf_mask_in) != 0) || + if ((ctx->enc & IPSEC_ENC_BEFORE) != 0 && ( + (hhook_type == HHOOK_TYPE_IPSEC_IN && + (V_bpf_mask_in & IPSEC_ENC_BEFORE) != 0) || (hhook_type == HHOOK_TYPE_IPSEC_OUT && - (ctx->enc & V_bpf_mask_out) != 0)) && + (V_bpf_mask_out & IPSEC_ENC_BEFORE) != 0)) && bpf_peers_present(ifp->if_bpf) != 0) { hdr.af = ctx->af; hdr.spi = ctx->sav->spi; @@ -247,7 +248,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, vo (*ctx->mp)->m_pkthdr.len); } if ((ctx->enc & V_filter_mask_in) == 0) - return (0); /* skip pfil processing */ + goto handle_bpf; /* skip pfil processing */ pdir = PFIL_IN; break; case HHOOK_TYPE_IPSEC_OUT: @@ -258,7 +259,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, vo (*ctx->mp)->m_pkthdr.len); } if ((ctx->enc & V_filter_mask_out) == 0) - return (0); /* skip pfil processing */ + goto handle_bpf; /* skip pfil processing */ pdir = PFIL_OUT; break; default: @@ -280,7 +281,7 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, vo ph = NULL; } if (ph == NULL || !PFIL_HOOKED(ph)) - return (0); + goto handle_bpf; /* Make a packet looks like it was received on enc(4) */ rcvif = (*ctx->mp)->m_pkthdr.rcvif; (*ctx->mp)->m_pkthdr.rcvif = ifp; @@ -290,6 +291,24 @@ enc_hhook(int32_t hhook_type, int32_t hhook_id, vo return (EACCES); } (*ctx->mp)->m_pkthdr.rcvif = rcvif; + +handle_bpf: + if ((ctx->enc & IPSEC_ENC_AFTER) != 0 && ( + (hhook_type == HHOOK_TYPE_IPSEC_IN && + (V_bpf_mask_in & IPSEC_ENC_AFTER) != 0) || + (hhook_type == HHOOK_TYPE_IPSEC_OUT && + (V_bpf_mask_out & IPSEC_ENC_AFTER) != 0)) && + bpf_peers_present(ifp->if_bpf) != 0) { + hdr.af = ctx->af; + hdr.spi = ctx->sav->spi; + hdr.flags = 0; + if (ctx->sav->alg_enc != SADB_EALG_NONE) + hdr.flags |= M_CONF; + if (ctx->sav->alg_auth != SADB_AALG_NONE) + hdr.flags |= M_AUTH; + bpf_mtap2(ifp->if_bpf, &hdr, sizeof(hdr), *ctx->mp); + } + return (0); }
signature.asc
Description: OpenPGP digital signature