I have an OpenVPN server located on a VPS. It has one network card (eth0), with a public IP address. It runs an openvpn server, giving out addresses in the 192.168.2.x subnet.
I have a client connecting via a home router. The client's local IP address is 192.168.1.100, and it gets the address of 192.168.2.5 from the VPN server.
I can successfully access the VPN server from the client.
I have the following firewall rule(s) on the server:
Code:
mikeage@server ~$ sudo iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 1816 packets, 90836 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 13133 packets, 824K bytes)
pkts bytes target prot opt in out source destination
3 180 MASQUERADE all -- any eth0 192.168.2.0/24 anywhere
Chain OUTPUT (policy ACCEPT 13132 packets, 823K bytes)
pkts bytes target prot opt in out source destination
mikeage@server ~$ sudo iptables -L -v
Chain INPUT (policy DROP 3 packets, 168 bytes)
pkts bytes target prot opt in out source destination
28026 12M ACCEPT all -- lo any anywhere anywhere
45691 43M ACCEPT all -- eth0 any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:ssh state NEW
18 880 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:smtp state NEW
56 3248 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:www state NEW
10 600 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:https state NEW
0 0 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:openvpn state NEW
0 0 ACCEPT icmp -- any any anywhere anywhere
0 0 ACCEPT all -- tap+ any anywhere anywhere
3943 737K ACCEPT all -- tun+ any anywhere anywhere
56 2008 REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable
Chain FORWARD (policy DROP 4 packets, 240 bytes)
pkts bytes target prot opt in out source destination
18 1080 ACCEPT all -- any tun+ anywhere anywhere state RELATED,ESTABLISHED
3 180 ACCEPT all -- tun+ eth0 anywhere anywhere state NEW
Chain OUTPUT (policy ACCEPT 69421 packets, 24M bytes)
pkts bytes target prot opt in out source destination
I want to send web (port 80 and 443) traffic from the client to the internet via the openvpn server, but have all other traffic leave the client via the default route (192.168.1.100 -> 192.168.1.1).
If I set up a fixed route to an internet site, I can get to the internet via the vpn:
Code:
mikeage@client ~% sudo /sbin/route add -host 74.125.45.100 gw 192.168.2.1
[in another window: wget http://74.125.45.100]
mikeage@client ~% sudo /usr/sbin/tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 96 bytes
15:04:12.976945 IP 192.168.2.5.52196 > 74.125.45.100.80: S 422926017:422926017(0) win 5840 <mss 1460,sackOK,timestamp 1632623 0,nop,wscale 6>
15:04:13.169740 IP 74.125.45.100.80 > 192.168.2.5.52196: S 1800842449:1800842449(0) ack 422926018 win 5672 <mss 1366,sackOK,timestamp 564894277 1632623,nop,wscale 6>
15:04:13.169772 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 1 win 92 <nop,nop,timestamp 1632671 564894277>
15:04:18.887565 IP 192.168.2.5.52196 > 74.125.45.100.80: P 1:17(16) ack 1 win 92 <nop,nop,timestamp 1634101 564894277>
15:04:19.075521 IP 74.125.45.100.80 > 192.168.2.5.52196: . ack 17 win 89 <nop,nop,timestamp 564900184 1634101>
15:04:19.657798 IP 74.125.45.100.80 > 192.168.2.5.52196: P 1:163(162) ack 17 win 89 <nop,nop,timestamp 564900189 1634101>
15:04:19.657815 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 163 win 108 <nop,nop,timestamp 1634293 564900189>
15:04:19.657860 IP 74.125.45.100.80 > 192.168.2.5.52196: . 163:1517(1354) ack 17 win 89 <nop,nop,timestamp 564900189 1634101>
15:04:19.657872 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 1517 win 154 <nop,nop,timestamp 1634293 564900189>
15:04:19.657914 IP 74.125.45.100.80 > 192.168.2.5.52196: . 1517:2871(1354) ack 17 win 89 <nop,nop,timestamp 564900189 1634101>
15:04:19.657926 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 2871 win 199 <nop,nop,timestamp 1634293 564900189>
15:04:19.657968 IP 74.125.45.100.80 > 192.168.2.5.52196: . 2871:4225(1354) ack 17 win 89 <nop,nop,timestamp 564900189 1634101>
15:04:19.657982 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 4225 win 244 <nop,nop,timestamp 1634293 564900189>
15:04:19.815271 IP 74.125.45.100.80 > 192.168.2.5.52196: P 1:163(162) ack 17 win 89 <nop,nop,timestamp 564900750 1634101>
15:04:19.815285 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 4225 win 244 <nop,nop,timestamp 1634333 564900189,nop,nop,sack 1 {1:163}>
15:04:20.054009 IP 74.125.45.100.80 > 192.168.2.5.52196: . 4225:5579(1354) ack 17 win 89 <nop,nop,timestamp 564901159 1634293>
15:04:20.054029 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 5579 win 289 <nop,nop,timestamp 1634392 564901159>
15:04:20.214097 IP 74.125.45.100.80 > 192.168.2.5.52196: . 5579:6933(1354) ack 17 win 89 <nop,nop,timestamp 564901159 1634293>
15:04:20.214113 IP 192.168.2.5.52196 > 74.125.45.100.80: . ack 6933 win 335 <nop,nop,timestamp 1634432 564901159>
15:04:20.214135 IP 74.125.45.100.80 > 192.168.2.5.52196: FP 6933:7084(151) ack 17 win 89 <nop,nop,timestamp 564901159 1634293>
15:04:20.214397 IP 192.168.2.5.52196 > 74.125.45.100.80: F 17:17(0) ack 7085 win 377 <nop,nop,timestamp 1634432 564901159>
15:04:20.486693 IP 74.125.45.100.80 > 192.168.2.5.52196: . ack 18 win 89 <nop,nop,timestamp 564901593 1634432>
^C
22 packets captured
22 packets received by filter
0 packets dropped by kernel
However, I'd like to leave the route alone, and just mark the packets intended for port 80, and port 443 (right now I'm just doing 80), and create a route just for them
Code:
mikeage@client ~% sudo /sbin/route del 74.125.45.100 gw 192.168.2.1
mikeage@client ~% sudo iptables -t mangle -A OUTPUT -j MARK -p tcp --dport 80 --set-mark 80
mikeage@client ~% sudo ip route add table 200 default via 192.168.2.1
mikeage@client ~% sudo ip rule add fwmark 0x50 table 200
mikeage@client ~% sudo ip route flush cache
mikeage@client ~% sudo /usr/sbin/tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 96 bytes
15:05:07.470646 IP 192.168.1.100.58073 > 74.125.45.100.80: S 1270174169:1270174169(0) win 5840 <mss 1460,sackOK,timestamp 1646246 0,nop,wscale 6>
15:05:10.467210 IP 192.168.1.100.58073 > 74.125.45.100.80: S 1270174169:1270174169(0) win 5840 <mss 1460,sackOK,timestamp 1646996 0,nop,wscale 6>
15:05:16.467218 IP 192.168.1.100.58073 > 74.125.45.100.80: S 1270174169:1270174169(0) win 5840 <mss 1460,sackOK,timestamp 1648496 0,nop,wscale 6>
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
Note that the source here is 192.168.1.100, which is wrong. tcpdump on the server shows the same thing (the same addresses)
If I enable NAT on the client as well:
Code:
mikeage@client ~% sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
Then I get the following, which looks a little better, but I still get a timeout on the client's wget.
Code:
mikeage@client~% sudo /usr/sbin/tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 96 bytes
15:46:37.169338 IP 192.168.2.5.51810 > 74.125.45.100.80: S 1660332926:1660332926(0) win 5840 <mss 1460,sackOK,timestamp 2268715 0,nop,wscale 6>
15:46:37.364124 IP 74.125.45.100.80 > 192.168.2.5.51810: S 369374977:369374977(0) ack 1660332927 win 5672 <mss 1366,sackOK,timestamp 1451381315 2268715,nop,wscale 9>
15:46:37.708185 IP 74.125.45.100.80 > 192.168.2.5.51810: S 369374977:369374977(0) ack 1660332927 win 5672 <mss 1366,sackOK,timestamp 1451381659 2268715,nop,wscale 9>
15:46:38.307771 IP 74.125.45.100.80 > 192.168.2.5.51810: S 369374977:369374977(0) ack 1660332927 win 5672 <mss 1366,sackOK,timestamp 1451382259 2268715,nop,wscale 9>
15:46:39.507393 IP 74.125.45.100.80 > 192.168.2.5.51810: S 369374977:369374977(0) ack 1660332927 win 5672 <mss 1366,sackOK,timestamp 1451383459 2268715,nop,wscale 9>
15:46:41.908584 IP 74.125.45.100.80 > 192.168.2.5.51810: S 369374977:369374977(0) ack 1660332927 win 5672 <mss 1366,sackOK,timestamp 1451385860 2268715,nop,wscale 9>
I suspect that the return packets are not being accepted for some reason, although there's no firewall or anything on the client machine.