strongswan IPSec, bhyve nat-traffic

Hi,

I was able to set up an IPSec/strongswan VPN tunnel and it works great so far (Forum: 67850).
Now, I'd like to forward traffic from my bhyve VM's through the tunnel but I am having problems with it. The picture looks like that: (all done on FreeBSD 11.2p4)

Code:
(*) normal DSL Router with 192.168.2.1
     ___ dynamic (wlan0: x.x.x.x)
    /    tun0: 172.16.55.200 (autogenerated by ipsec up home)
    |
    |
   [VPN Client]---*---------[VPN Server]
     |                                \_ ext: y.y.y.y
     |                                \_ lo1: 172.16.55.1
     |tun0: 172.16.55.200   
     |
     |
     |
    bridge0  192.168.4/24
       tap0: vm1
       tap1: vm2

I can successfully connect (from VPN Client) with strongswan and reach 172.16.55.1, and i can also route all traffic through the VPN Server by using strongswan and pf (the vpn server is using NAT). This works fine.

When bringing up the ipsec tunnel, strongswan creates a tun0 device with the 172.16.55.200 ipaddr.

But when i am trying to NAT the 192.168.4 network to the tun0 interface, I can't ping other hosts (i.e. inside a VM, i cant ping any hosts). I do see the ping request on the bridge0 (with tcpdump) device but nothing comes back.

I also noticed that I do not see a ping request on the tun0 device when using the "VPN Client" itself (and not a VM). Does anyone know why?

I also can't add the tun0 device to the bridge0 since it either would need a gre or gif interface.

Is it possible to set up strongswan in a way it is using gif(4) or are there any alternatives? Perhaps I have to setup a second subnet within the strongswan config?


VPN Server:
Code:
config setup
        # strictcrlpolicy=yes
         uniqueids = no

conn %default
        keyexchange=ikev2
        ikelifetime=60m
        keylife=20m
        rekeymargin=3m
        keyingtries=1
        keyexchange=ikev2
        authby=secret   
conn rw
        left=y.y.y.y.y
        leftsubnet=0.0.0.0/0 
        right=%any
        rightsourceip=172.16.55.200
        auto=add

VPN Client:

Code:
config setup
conn %default
        ikelifetime=60m
        keylife=20m
        rekeymargin=3m
        keyingtries=1
        keyexchange=ikev2
        authby=secret              # psk or secret
conn home      # name used in ipsec(1) commands
        leftfirewall=yes
        right=y.y.y.y
        rightsubnet=0.0.0.0/0
        auto=add
        leftsourceip=%config

The pf.conf on the client:

Code:
# VPN Client
ext_if="wlan0"
set skip on lo0

virt_net="192.168.4.1/24"


scrub all
#Works: nat on $ext_if from $virt_net to any -> (wlan0)

#not working: nat on $ext_if from $virt_net to any -> 172.16.55.1
nat from 192.168.4.1/24 to any -> (tun0)  # not working

pass log all

Code:
# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
0.0.0.0/1          192.168.2.1        US         tun0
default            172.16.55.1        UGS        tun0
127.0.0.1          link#2             UH          lo0
128.0.0.0/1        192.168.2.1        US         tun0
172.16.55.200      link#5             UH         tun0


Thanks!
 
To be a bit more precise what I am trying to achieve: I'd like to NAT the bhyve VM connections over an IPSec tunnel (tun0) and NAT it on the VPN Sever to the internet.
I am not quite sure if a GRE tunnel would solve my problem because this is a mobile client - so not sure if this would be the solution.

Furthermore, it is strnage that i don't see any decrypted traffic flowing through the enc0 interface.
 
Than ks for your reply, sure yes. Attached is ifconfig and netstat output without ipsec connection. (The lo1 and 172.16.60.x addresses are jail tests and should not conflict with the bhyve stuff that is on 192.168.4.x)
 

Attachments

As all IP addresses are private why do you need NAT as you can just route the networks?

You will only need to change your VPN configuration and add gateway_enable="YES" in rc.conf on your laptop.

On the server point the leftsubnet to be the network behind your laptop (192.168.4.0/24) and on the client laptop point what networks are behind the server (if there's any)

server config
conn rw
left=y.y.y.y.y
leftsubnet=192.168.4.0/24
right=%any
rightsourceip=172.16.55.200
auto=add

client config
conn home # name used in ipsec(1) commands
leftfirewall=yes
right=y.y.y.y
rightsubnet=0.0.0.0/0
auto=add
leftsourceip=%config

Or if there's any network behind your server specify them as rightsubnet on your client.

So after your connect to the VPN the routing table on your laptop should include this:

Code:
Destination        Gateway            Flags     Netif Expire
default            192.168.2.1        UGS       wlan0
172.16.55.200      link#5             UH         tun0

And the routing table on the server:

Code:
Destination        Gateway           Flags     Netif Expire
default                   y.y.y.y             UGS       ext
172.16.55.1           link#5             UH         tun0
192.168.4.0/24     172.16.55.200 U         tun0


Edit:
If you need to use NAT on tun0 for some other reasons then you can do it like this:

nat on tun0 from {192.168.4.0/24} to any -> (tun0)
 
  • Thanks
Reactions: bch
I've set gateway_enabled on all hosts, so this should be ok.

The y.y.y.y was meant to be a public ip address.

I've included the 0.0.0.0/0 to use this ipsec tunnel as default route? was this wrong?


(the public ip address has been replaced with XX.YY.XX.YY.) I am now seeing this error and the routes are not set in my table:

Code:
initiating IKE_SA home[3] to XX.YY.XX.YY
generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]                                            
sending packet: from 192.168.2.100[500] to XX.YY.XX.YY[500] (768 bytes)
received packet: from XX.YY.XX.YY[500] to 192.168.2.100[500] (272 bytes)
parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(MULT_AUTH) ]                                              
selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256                                                                          
local host is behind NAT, sending keep alives
no IDi configured, fall back on IP address
authentication of '192.168.2.100' (myself) with pre-shared key
establishing CHILD_SA home{3}
generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH CPRQ(ADDR DNS) N(ESP_TFC_PAD_N) SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
sending packet: from 192.168.2.100[4500] to XX.YY.XX.YY[4500] (368 bytes)
received packet: from XX.YY.XX.YY[4500] to 192.168.2.100[4500] (176 bytes)
parsed IKE_AUTH response 1 [ IDr AUTH CPRP(ADDR) N(AUTH_LFT) N(MOBIKE_SUP) N(ADD_4_ADDR) N(TS_UNACCEPT) ]                                              
authentication of 'XX.YY.XX.YY' with pre-shared key successful
IKE_SA home[3] established between 192.168.2.100[192.168.2.100]...XX.YY.XX.YY[XX.YY.XX.YY]                                                          
scheduling reauthentication in 3354s
maximum IKE_SA lifetime 3534s
installing new virtual IP 172.16.55.200
created TUN device: tun0
received TS_UNACCEPTABLE notify, no CHILD_SA built
failed to establish CHILD_SA, keeping IKE_SA
establishing connection 'home' failed

i've tried your changes but when starting the tunnel with ipsec up, i get the following error:


I tried the nat command but i guess i have an error somewhere - no icmp packet gets replied (despite i'm seeing the traffic on tun0 and bridge0. What makes me a bit unsure is that i don't see "other" traffic that originates from my host system (laptop))
 
I've fooled around a bit and attached debugging output and configuration files from server and client.

This time, i can ping and reach the server within a bhyve VM. But i can't ping the server from my host system (which is very wired).

I can ping my VM's from the server, too.

I've turned off pf on the client machine.

The only thing that is missing is that my client machine/laptop is using the server as default gateway (vpn secured).
 

Attachments

Your VPN subnet overlaps with the server local subnet. Check the link with the example for net2net network.


VladiBG: Thanks a lot for your help.

I tried to remove and clean up the subnet's and I find a configuration that seems to work. I am not quite sure if this is the final result I wanted to have. The network address of the VM's is 192.168.4/24 and my local IP address is 192.168.2/24. So, I configured ipsec.conf with leftsubnet to use 192.168/16 on the local client. The output of the ipsec status command:


Connections:
home: %any...X.X.X.X IKEv2
home: local: uses pre-shared key authentication
home: remote: [X.X.X.X] uses pre-shared key authentication
home: child: 192.168.0.0/16 === 0.0.0.0/0 TUNNEL
Security Associations (1 up, 0 connecting):
home[2]: ESTABLISHED 19 seconds ago, 192.168.2.100[192.168.2.100]...X.X.X.X[X.X.X.X]
home[2]: IKEv2 SPIs: 88ab949de0dabcdd_i* fa4585392ee2506b_r, pre-shared key reauthentication in 51 minutes
home[2]: IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256
home{5}: INSTALLED, TUNNEL, reqid 2, ESP in UDP SPIs: c62c9933_i cb363d0b_o
home{5}: AES_CBC_128/HMAC_SHA2_256_128, 1582 bytes_i (6 pkts, 2s ago), 1624 bytes_o (6 pkts, 1s ago), rekeying in 14 minutes
home{5}: 192.168.0.0/16 === 0.0.0.0/0


With that configuration, bhyve VM's and my host send ESP encrypted packets over to my server which is doing NAT on that address space. (and I guess jails, which are now using 192.168.5/24 addresses may also send data over the encrypted channel)

What doesn't seem to work is specifying different leftsubnets on my client machine, i.e. "192.168.4/24, 172.16.1.1/24, dynamic === 0.0.0.0/0".
The problem with my current solution is that I have to manually change the configuration file when I am on a network that is using 10/8 addresses for example.

And I am still wondering why I don't see any decrypted traffic on enc0. I've loaded the kernel module, changed a few sysctl according to the manual but nothing is seen. Can anyone explain how to see the decrypted traffic?
 
The 192.168.0.0/16 is overlapping your 192.168.4.0/24 and 192.168.2.0/24 networks. You need to use smaller network for your vpn for example 192.168.99.0/24.
 
That was on purpose, yes. But ok, it seems to work when non overlapping nets are specified (not sure why it previously failed, i may have introduced another error). What I now have is:
Code:
leftsubnet = %dynamic,192.168.4.0/24

I would like to exclude the 192.168.4.1 address but haven't found such an option in the strongswan con section. An alternative way would be to specify actual hosts in the leftsubnet section or using another local network on the laptop.
 
If you haven't previously read about routing in packet switching networks do it and you will understand how it's working and why it previously failed.

You can specify only specific hosts that will be protected by ipsec tunnel like this

leftsubnet = %dynamic,192.168.4.1,192.168.4.2,10.0.1.0/24
 
Back
Top