FreeBSD IPsec enc0 NAT not works this is the problem

Hi, i have trouble with Ipsec & pf enc0 nat problem . I show you my problematic scenerio below any help would be appreciated at this point


1636533550073.png


STRONGSWAN CONFIGURATION


Code:
 alfa7000 {
        fragmentation = yes
        unique = replace
        version = 1
        aggressive = no
        proposals = 3des-sha1-modp1024
        dpd_delay = 10s
        dpd_timeout = 60s
        reauth_time = 3240s
        over_time = 360s
        rand_time = 360s
        encap = no
        mobike = no
        remote_addrs = 78.48.48.48
        local {
        id =
          auth = psk
        }
        remote {
          id = 78.48.48.48
          auth = psk
        }
        
children {
                alfa7001 {
                        dpd_action = trap
                        mode = tunnel
                        policies = yes
                        life_time = 3600s
                        rekey_time = 3240s
                        rand_time = 360s
                        start_action = trap
                        local_ts = 212.154.31.32/32
                        remote_ts = 88.75.75.75/32
                        esp_proposals = 3des-sha1-modp1024
                }
        }
   }
}
secrets {
        ike-0 {
                secret = 0sMTIzNDU2WHg=
                id-0 = %any
                id-1 = 78.48.48.48
        }
}
 
Because ESP packets are unidirectional, NAT devices can't map them like they do with e.g. TCP/UDP packets by using the source and destination ports in those headers. Some NAT devices have a feature, often called something like "IPsec passthrough", that detects IKE traffic from a single host behind the NAT and will forward incoming plain ESP packets to that host. But that won't work with multiple clients behind the same NAT that use the same server. To allow multiple clients UDP encapsulation is used. Adding a UDP header to the ESP packets allows NAT devices to treat them like the IKE packets (or any other UDP packets) and to maintain port mappings to forward the packets from/to the correct hosts behind the NAT.

I don't have to traverse a NAT but you do need to allow ESP, AH and IPENCAP protocols through the firewall.

This is for a one-to-one IPSec connection from my home router to my VPS:
Code:
pass in quick on $ext_if proto esp from $home to ($ext_if)
pass in quick on $ext_if proto ah from $home to ($ext_if)
pass in quick on $ext_if proto ipencap from $home to ($ext_if)
pass in quick on $ext_if proto udp from $home port = 500 to ($ext_if) port = 500
 

I don't have to traverse a NAT but you do need to allow ESP, AH and IPENCAP protocols through the firewall.

This is for a one-to-one IPSec connection from my home router to my VPS:
Code:
pass in quick on $ext_if proto esp from $home to ($ext_if)
pass in quick on $ext_if proto ah from $home to ($ext_if)
pass in quick on $ext_if proto ipencap from $home to ($ext_if)
pass in quick on $ext_if proto udp from $home port = 500 to ($ext_if) port = 500
i already allowed IPSEc protocols at first, i have not problem with them.
i also tried pass in all and pass out all for testing.

i tried this on a linux firewall and it able to do this nat scenerio successfully . I am asking to help FreeBSD masters ..
 
I show you my problematic scenerio below
[UPDATE]

Code:
/sys/amd64/conf/GENERIC

nooptions     IPSEC            # IP (v4/v6) security
options     IPSEC_SUPPORT

Hi again, now after hours of my researches i have found that removing IPSEC kernel implementation and loading as a kernel module and changed this sysctl tunable as
Code:
sysctl net.inet.ipsec.filtertunnel=1
WORKED above the scenario BUT!!! only one time?‍♂️

I don't know what the problem is this i am gonna crazy about that . Thanks for any help ...
 
I establish IKEv2-IPsec tunnels between AWS-EC2 instances and some clients, all running FreeBSD 13.0-RELEASE using security/strongswan. I use ipfw(8) as the NAT’ting stateful firewall on both sides, and in addition my strongSwan setup is far less sophisticated than yours. Therefore, not everything of the following might be useful in your case:
  1. strongSwan detects whether the endpoints are separated by NAT and switches automatically to NAT-T on UDP port 4500 - so you need to open this port in your firewall as well

  2. for ipfw, I need to add the following to /etc/sysctl.conf: net.inet.ip.fw.one_pass=0, otherwise NAT does not work correctly. However, I can’t tell whether this does apply to pf as well.

  3. for other systems in the same network of the strongSwan client having access to the remote IPsec endpoint, I need to manually set up the route on these not directly connected machines.

  4. all involved systems got the directive gateway_enable="YES" in /etc/rc.conf
That said, I never had any problems coming close to your one. Perhaps you want to start over again with a more simple setup, and do the sophistication later on.
 
in my problematic scenario :

these were already done:

Code:
UDP 4500 opened
gateway_enable="YES"
sysctl net.inet.ipsec.filtertunnel=1

Code:
/sys/amd64/conf/MYKERNEL

nooptions     IPSEC            # IP (v4/v6) security
options     IPSEC_SUPPORT
options     IPSEC_DEBUG
...
device    enc
device    crypto


i have also established many site to site simple ipsec vpn tunnels successfully. Only this scenario caused a problem i need DNAT before packet entered ipsec tunnel.

my local pc ip 192.168.0.200 and local_ts is virtual ip like 212.154.31.32 so i am expecting 0.200 natted to 31.32 before enter tunnel but no luck! packet goes to WAN side :(

thanks
 
Last edited:
I have solved and tested nat problem shown below and will try this solution for my old scenario

thanks to this thread https://unix.stackexchange.com/ques...g-pf-on-freebsd-11-and-strongswan-x-fortigate

SOLUTION:

setkey -DP

spdflush;

setkey -v -c
spdadd 192.168.30.232/32[any] 192.168.11.0/24[any] any -P out ipsec esp/tunnel/aa.bb.cc.dd-ee.ff.gg.hh.ll/unique:1;


nat on enc0 from 192.168.30.232/32 to 192.168.11.0/24 -> 22.22.22.22

rdr log (all) on { enc0 } proto { icmp } from { 0.0.0.0/0 } to any -> 192.168.30.232 #forwarding_86


sysctl net.inet.ipsec.filtertunnel=1

sysctl net.enc.out.ipsec_bpf_mask=0x00000001
sysctl net.enc.out.ipsec_filter_mask=0x00000001
sysctl net.enc.in.ipsec_bpf_mask=0x00000002
sysctl net.enc.in.ipsec_filter_mask=0x00000002


Code:
#tcpdump -i enc0
21:36:05.156435 (authentic,confidential): SPI 0xcddccf50: IP 192.168.11.1 > 22.22.22.22: ICMP echo request, id 58720, seq 1594, length 64
21:36:05.162540 (authentic,confidential): SPI 0xc0417bac: IP 192.168.30.232 > 192.168.11.1: ICMP echo reply, id 58720, seq 1594, length 64

#tcpdump -i pflog0 -tttt -n -e | grep 22.22.22.22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
2022-07-29 21:42:52.004705 rule 61/0(match): rdr out on enc0: 22.22.22.22 > 192.168.11.1: ICMP echo reply, id 58720, seq 2000, length 64
2022-07-29 21:42:53.005596 rule 61/0(match): rdr out on enc0: 22.22.22.22 > 192.168.11.1: ICMP echo reply, id 58720, seq 2001, length 64
2022-07-29 21:42:54.006732 rule 61/0(match): rdr out on enc0: 22.22.22.22 > 192.168.11.1: ICMP echo reply, id 58720, seq 2002, length 64



#tcpdump -i pflog0 -tttt -n -e | grep 192.168.11.1

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
2022-07-29 21:44:56.280663 rule 61/0(match): rdr in on enc0: 192.168.11.1 > 192.168.30.232: ICMP echo request, id 58720, seq 2124, length 64
2022-07-29 21:44:56.280699 rule 21/0(match): pass in on pppoe_em1: 192.168.11.1 > 192.168.30.232: ICMP echo request, id 58720, seq 2124, length 64
2022-07-29 21:44:56.283556 rule 61/0(match): rdr out on enc0: 32.32.32.32 > 192.168.10.1: ICMP echo reply, id 58720, seq 2124, length 64
2022-07-29 21:44:57.281283 rule 61/0(match): rdr in on enc0: 192.168.11.1 > 192.168.30.232: ICMP echo request, id 58720, seq 2125, length 64

1659085444230.png
 
Last edited:
When you create site to site IPSec you will not use any NAT, only pure routing because you are defining which traffic of interest will be protected via IPSec (setkey). In strongSwan this is defined as Left Side (local network) and Right Side (remote network).

I think the following two post will help you to understand the difference of Site-to-Site and Site-to-Client. Also you can use draw.io to create a better network topology.


 
When you create site to site IPSec you will not use any NAT, only pure routing because you are defining which traffic of interest will be protected via IPSec (setkey). In strongSwan this is defined as Left Side (local network) and Right Side (remote network).

I think the following two post will help you to understand the difference of Site-to-Site and Site-to-Client. Also you can use draw.io to create a better network topology.


I can use NAT on Site to site IPsec on Fortigate firewall even pfsense but i could'nt perform nat on FreeBSD enc0.
But Eventually i did .

Thanks for your advice
 
Back
Top