Configure linux to route traffic from internal network through ipsec tunnel (policy based)

Solution 1:

Notes:

  • We don't really know nor care what the partner netowrk setup internally looks like in detail. We just know their vpn-endpoint public ip (1.1.1.1), their internal network (10.10.10.0/24) and the ip adress of their server(s) (for example 10.10.10.1)
  • Our vpn-router-server is a IAAS server hosted by a public cloud provider. It has a directly reachable external ip (2.2.2.2). It does use a gatway to reach the internet, however as the IAAS provider handles all of that, we dont include it in our diagram.

In this example we will focus on the following scenario:

  • Our client1 will send a ping to target server1. Other clients and target servers work the exact same way, just their ips are different.

On client1:

# tell the client to send all traffic for the partner network to the vpn-router-server
$ route add -net 10.10.10.0 gw 192.168.1.1

On vpn-router-server: /etc/ipsec.conf-configuration

config setup
  uniqueids = yes

conn con1
  aggressive = no
  fragmentation = yes
  keyexchange = ikev2
  mobike = yes
  reauth = yes
  rekey = yes
  forceencaps = no
  installpolicy = yes

  left = %any
  leftid = 2.2.2.2
  leftsubnet = 192.168.1.0/24
  leftauth = psk

  right = 1.1.1.1
  rightid = 1.1.1.1
  rightsubnet = 10.10.10.0/24
  rightauth = psk

  ikelifetime = 86400s
  lifetime = 3600s
  ike = aes256gcm16-sha512-ecp521!
  reqid = 1000
  esp = aes256-sha512-ecp521,aes256gcm16-sha512-ecp521,3des-sha512-ecp521,cast128-sha512-ecp521!
  auto = start

Set iptable-rules:

$ iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 ! -p esp -j SNAT --to-source 192.168.1.1
  • -s 192.168.1.0/24 apply SNAT only to traffic from our internal network
  • -o eth0 apply SNAT only for traffic going out through the external interface eth0
  • ! -p esp Do not SNAT the DSP / ipsec traffic itself. This is the important part and I was missing this part before.
  • -j SNAT SNAT the traffic
  • --to-source 192.168.1.1 Use the vpn-router-server internal ip as the source ip for the SNATed packets

The client1 should now be able to ping target server1:

$ ping 10.10.10.1

You can analyse whats going on the vpn-router-server using tcpdump:

$ tcpdump -n -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
07:10:37.150680 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 1, length 64
07:10:38.152097 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 2, length 64
07:10:39.153237 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 3, length 64
07:10:40.153997 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 4, length 64
07:10:41.154766 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 5, length 64
07:10:42.155937 IP 10.10.10.1 > 192.168.1.1: ICMP echo reply, id 7642, seq 6, length 64

$ tcpdump -n -i eth1 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
07:10:46.156162 IP 192.168.1.101 > 10.10.10.1: ICMP echo request, id 7642, seq 10, length 64
07:10:46.161079 IP 10.10.10.1 > 192.168.1.101: ICMP echo reply, id 7642, seq 10, length 64
07:10:47.157485 IP 192.168.1.101 > 10.10.10.1: ICMP echo request, id 7642, seq 11, length 64
07:10:47.162435 IP 10.10.10.1 > 192.168.1.101: ICMP echo reply, id 7642, seq 11, length 64
07:10:48.158920 IP 192.168.1.101 > 10.10.10.1: ICMP echo request, id 7642, seq 12, length 64
07:10:48.163772 IP 10.10.10.1 > 192.168.1.101: ICMP echo reply, id 7642, seq 12, length 64
07:10:49.160364 IP 192.168.1.101 > 10.10.10.1: ICMP echo request, id 7642, seq 13, length 64
07:10:49.165322 IP 10.10.10.1 > 192.168.1.101: ICMP echo reply, id 7642, seq 13, length 64