I have a problem with iptables POSTROUTING rule, it seems that SNAT rule doesn't change source IP address. I would like set up the following system to route all traffic from LAN 2 through a VPN tunnel. System has two routing tables configured.

System configuration

              +-----------------+
  LAN 2 ----> |eth1       eth0  +-----> LAN 1 ---> Gateway ---> Internet
              |           tun1  |
              +-------------|---+
                            `--------------- VPN tunnel ------>

iptables / routing configuration

  • iptables

    root@misio:~# iptables -n -L --line-numbers -v -t nat
    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
    
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
    
    Chain OUTPUT (policy ACCEPT 1 packets, 122 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
    
    Chain POSTROUTING (policy ACCEPT 1 packets, 122 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
    1        0     0 SNAT       all  --  *      *       192.168.124.0/24     0.0.0.0/0            to:192.168.124.1
    
  • routing (two routing tables)

    root@misio:~# ip route list
    default via 192.168.123.1 dev eth0 
    192.168.123.0/24 dev eth0  proto kernel  scope link  src 192.168.123.3 
    
    root@misio:~# ip route list table frankenjura
    default via 10.10.11.4 dev tun1 
    10.10.11.0/24 dev tun1  scope link 
    192.168.124.0/24 dev eth1  scope link 
    
    root@misio:~# ip rule
    0:      from all lookup local 
    32761:  from 192.168.124.0/24 lookup frankenjura 
    32762:  from all to 192.168.124.0/24 lookup frankenjura 
    32766:  from all lookup main 
    32767:  from all lookup default 
    

Investigation

  • Input (eth1) - system is receiving packets from the hosts in LAN 2 (192.168.124.17):

    root@misio:~# tcpdump -n -i eth1 icmp and host 8.8.8.8
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes 
    12:39:25.134315 IP 192.168.124.17 > 8.8.8.8: ICMP echo request, id 1, seq 1181, length 40
    12:39:30.142011 IP 192.168.124.17 > 8.8.8.8: ICMP echo request, id 1, seq 1182, length 40
    
  • Output (tun1) - packets are routed to the correct interface (tun1), but the source IP address is not changed:

    root@misio:~# tcpdump -n -i tun1 icmp and host 8.8.8.8 
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on tun1, link-type RAW (Raw IP), capture size 262144 bytes
    12:40:20.140953 IP 192.168.124.17 > 8.8.8.8: ICMP echo request, id 1, seq 1192, length 40
    12:40:25.148605 IP 192.168.124.17 > 8.8.8.8: ICMP echo request, id 1, seq 1193, length 40
    
  • ...but number of packets/bytes for the following rule doesn't increment!

    Chain POSTROUTING (policy ACCEPT 1 packets, 122 bytes)
    num   pkts bytes target     prot opt in     out     source               destination         
    1        0     0 SNAT       all  --  *      *       192.168.124.0/24     0.0.0.0/0            to:192.168.124.1
    

IP tables version: 1.4.21

Would you be so kind to help, please?

EDIT 2016-07-15

I set up iptables logging in all chains and learned that packets don't go through NAT table at all!

packets go through: - raw (PREROUTING) - mangle (PREROUTING) - filter (FORWARD) - mangle (POSTROUTING)

Jul 15 12:36:04 misio kernel: [ 7913.969872] raw-PRE IN=eth1 OUT= MAC=00:1e:2a:49:9d:ad:00:17:a4:da:13:09:08:00 SRC=192.168.124.17 DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=128 ID=7668 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1022
Jul 15 12:36:04 misio kernel: [ 7913.969894] mangle-PRE IN=eth1 OUT= MAC=00:1e:2a:49:9d:ad:00:17:a4:da:13:09:08:00 SRC=192.168.124.17 DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=128 ID=7668 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1022 
Jul 15 12:36:04 misio kernel: [ 7913.969908] filter-FW IN=eth1 OUT=tun1 MAC=00:1e:2a:49:9d:ad:00:17:a4:da:13:09:08:00 SRC=192.168.124.17 DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=7668 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1022 
Jul 15 12:36:04 misio kernel: [ 7913.969914] mangle-POST IN= OUT=tun1 SRC=192.168.124.17 DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=127 ID=7668 PROTO=ICMP TYPE=8 CODE=0 ID=1 SEQ=1022 

Kind regards, Grzegorz

  • I don't get what's the point doing what you're trying to do: your VPN network is 10.10.11.0/24 so I'd expect you to have iptables -t nat -A POSTROUTING -o tun1 -j SNAT --to-source 10.10.11.N where , 10.10.11.N is what ip addr show tun1 displays; otherwise these packets will be "martian" to the other end of the tunnel. – kostix Jul 13 '16 at 16:41
  • 2
    One more thing: I have OpenVPN deployed on several servers (to connect branch offices with the main one and between each other) and never had the need to SNAT/MASQUERADE the IPs of the servers: OpenVPN just forwards traffic between the connected networks, so you merely need to have correct ip route (and possible OpenVPN's own iroute) rules in place. What real (original) problem are you trying to solve? – kostix Jul 13 '16 at 16:45
  • Thanks for your response. Unfortunately it hasn't solved a problem. I added rule suggested by you, but it's also not increment for the traffic from incoming to eth1. So iptables don't apply it to them. I am trying to achieve the following solution: (1) all packets from LAN1 (eth0) should go through default route in LAN1 (2) all packets from LAN2 (eth1) should go through a OpenVPN tunnel (tun1). – gbajson Jul 14 '16 at 14:55

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.