chschroe
asked on
NAT problem with OpenVPN on a multi-homed client
I use a linux box (kernel 2.6.27.42-0.1-xen) as a router. The router has multiple outgoing network (dsl) connections. It should also build up a vpn connection to a server using OpenVPN.
The OpenVPN client is bound to a dummy interface (as described in http://vigor.co.za/linux/multihome/openvpn). I try to nat all packets from this interface so that they appear to come from one of the external interfaces. This seems to work, i.e. the packets reach the vpn server with the correct source ip and the response packets reach the router on the external interface; however, the response packets are not forwarded to the local dummy interface and thus never reach the OpenVPN client. Can anybody explain why this happens?
My configuration is as follows (I have omitted some rules that should not matter; VPN_SERVER is the ip address of the vpn server):
> iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 1935K packets, 121M bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE udp -- * dsl1 192.168.147.0/24 VPN_SERVER udp dpt:1194
0 0 MASQUERADE udp -- * dsl2 192.168.147.0/24 VPN_SERVER udp dpt:1194
> iptables -t mangle -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 79M packets, 106G bytes)
pkts bytes target prot opt in out source destination
0 0 MARK udp -- * * 0.0.0.0/0 VPN_SERVER udp dpt:1194 MARK xset 0x1/0xffffffff
> ip rule show
500: from all fwmark 0x1 lookup dsl1
> ip route show table dsl1
217.0.116.165 dev dsl1 scope link src 80.128.79.220
default via 217.0.116.165 dev dsl1 src 80.128.79.220
> ip addr show dev int
2: int: <BROADCAST,MULTICAST,UP,LO WER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:16:3e:30:98:32 brd ff:ff:ff:ff:ff:ff
inet 192.168.146.90/24 brd 192.168.146.255 scope global int
inet 192.168.147.1/32 scope global int
When I add logging to all chains (including chains in the RAW table) I get the following output for the first outgoing packet:
raw.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
mangle.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
nat.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
filter.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
mangle.POSTROUTING IN= OUT=dsl1 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
nat.POSTROUTING IN= OUT=dsl1 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
This is exactly what I expected. Subsequent outgoing packets are identical, but do not pass the NAT table (which is the regular behavior).
Incoming packets generate this ourput:
raw.PREROUTING IN=dsl1 OUT= MAC= SRC=VPN_SERVER DST=80.128.79.220 LEN=42 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
mangle.PREROUTING IN=dsl1 OUT= MAC= SRC=VPN_SERVER DST=80.128.79.220 LEN=42 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
martian source 192.168.147.1 from VPN_SERVER, on dev dsl1
ll header: 45:00:00:2a:00:00:40:00:39 :11:3b:6b: 3e:92:74:1 c:c0:a8:93 :01:04:aa
The OpenVPN client is bound to a dummy interface (as described in http://vigor.co.za/linux/multihome/openvpn). I try to nat all packets from this interface so that they appear to come from one of the external interfaces. This seems to work, i.e. the packets reach the vpn server with the correct source ip and the response packets reach the router on the external interface; however, the response packets are not forwarded to the local dummy interface and thus never reach the OpenVPN client. Can anybody explain why this happens?
My configuration is as follows (I have omitted some rules that should not matter; VPN_SERVER is the ip address of the vpn server):
> iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 1935K packets, 121M bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE udp -- * dsl1 192.168.147.0/24 VPN_SERVER udp dpt:1194
0 0 MASQUERADE udp -- * dsl2 192.168.147.0/24 VPN_SERVER udp dpt:1194
> iptables -t mangle -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 79M packets, 106G bytes)
pkts bytes target prot opt in out source destination
0 0 MARK udp -- * * 0.0.0.0/0 VPN_SERVER udp dpt:1194 MARK xset 0x1/0xffffffff
> ip rule show
500: from all fwmark 0x1 lookup dsl1
> ip route show table dsl1
217.0.116.165 dev dsl1 scope link src 80.128.79.220
default via 217.0.116.165 dev dsl1 src 80.128.79.220
> ip addr show dev int
2: int: <BROADCAST,MULTICAST,UP,LO
link/ether 00:16:3e:30:98:32 brd ff:ff:ff:ff:ff:ff
inet 192.168.146.90/24 brd 192.168.146.255 scope global int
inet 192.168.147.1/32 scope global int
When I add logging to all chains (including chains in the RAW table) I get the following output for the first outgoing packet:
raw.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
mangle.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
nat.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
filter.OUTPUT IN= OUT=dsl2 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
mangle.POSTROUTING IN= OUT=dsl1 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
nat.POSTROUTING IN= OUT=dsl1 SRC=192.168.147.1 DST=VPN_SERVER LEN=42 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22 MARK=0x1
This is exactly what I expected. Subsequent outgoing packets are identical, but do not pass the NAT table (which is the regular behavior).
Incoming packets generate this ourput:
raw.PREROUTING IN=dsl1 OUT= MAC= SRC=VPN_SERVER DST=80.128.79.220 LEN=42 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
mangle.PREROUTING IN=dsl1 OUT= MAC= SRC=VPN_SERVER DST=80.128.79.220 LEN=42 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=UDP SPT=1194 DPT=1194 LEN=22
martian source 192.168.147.1 from VPN_SERVER, on dev dsl1
ll header: 45:00:00:2a:00:00:40:00:39
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.