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 example10.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 aping
totarget 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 thevpn-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