I have set up an OpenVPN server on CentOS 6.7
I copied the configuration from a known working server so I was pretty sure the server was configured correctly.
The problem I'm having is that a VPN client will connect fine, but can't reach anything on the internet.
- The clients are using certificates for authentication.
- I'm pushing Google's public DNS server (8.8.8.8)
I've enabled packet forwarding in sysctl.conf
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.all.mc_forwarding = 0
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.mc_forwarding = 0
net.ipv4.conf.lo.forwarding = 1
net.ipv4.conf.lo.mc_forwarding = 0
net.ipv4.conf.eth0.forwarding = 1
net.ipv4.conf.eth0.mc_forwarding = 0
net.ipv4.conf.tun0.forwarding = 1
net.ipv4.conf.tun0.mc_forwarding = 0
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_use_pmtu = 0
I've added these iptables rules:
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE -m comment --comment "Masquerade OpenVPN traffic"
iptables -A INPUT -i tun0 -j ACCEPT -m comment --comment "Allow all incoming OpenVPN"
iptables -A FORWARD -i tun0 -j ACCEPT
tun0 is configured as follows:
$ ip address show tun0
6: tun0: mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 100
link/[65534]
inet 172.16.1.1 peer 172.16.1.2/32 scope global tun0
In my openvpn.log I can see the client connects ok:
Thu Aug 20 06:54:59 2015 us=94453 31.108.32.42:55065 [David] Peer Connection Initiated with [AF_INET]31.108.32.42:55065
Thu Aug 20 06:54:59 2015 us=94789 MULTI: new connection by client 'David' will cause previous active sessions by this client to be dropped. Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
Thu Aug 20 06:54:59 2015 us=94913 MULTI_sva: pool returned IPv4=172.16.1.6, IPv6=(Not enabled)
Thu Aug 20 06:54:59 2015 us=94991 MULTI: Learn: 172.16.1.6 -> David/31.108.32.42:55065
Thu Aug 20 06:54:59 2015 us=95013 MULTI: primary virtual IP for David/31.108.32.42:55065: 172.16.1.6
Thu Aug 20 06:55:00 2015 us=350681 David/31.108.32.42:55065 UDPv4 READ [56] from [AF_INET]31.108.32.42:55065: P_CONTROL_V1 kid=0 [ ] pid=6 DATA len=42
Thu Aug 20 06:55:00 2015 us=351165 David/31.108.32.42:55065 PUSH: Received control message: 'PUSH_REQUEST'
Thu Aug 20 06:55:00 2015 us=351212 David/31.108.32.42:55065 send_push_reply(): safe_cap=940
Thu Aug 20 06:55:00 2015 us=351282 David/31.108.32.42:55065 SENT CONTROL [David]: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 8.8.8.8,route 172.16.1.1,topology net30,ping 10,ping-restart 120,ifconfig 172.16.1.6 172.16.1.5' (status=1)
If I use tshark to watch tun0 I can see DNS queries being performed, but there doesn't appear to be any response:
1.935018671 172.16.1.6 -> 8.8.8.8 DNS 74 Standard query 0xe4a3 A external-lhr3-1.xx.fbcdn.net
1.937067717 172.16.1.6 -> 8.8.8.8 DNS 68 Standard query 0xdbc8 A edge-chat.facebook.com
2.324716221 172.16.1.6 -> 8.8.8.8 DNS 65 Standard query 0xc98b A clients4.google.com
2.331865976 172.16.1.6 -> 8.8.8.8 DNS 65 Standard query 0x5acb AAAA clients4.google.com
2.335206663 172.16.1.6 -> 8.8.8.8 DNS 65 Standard query 0x6ba8 A clients4.google.com
2.610867667 172.16.1.6 -> 8.8.8.8 DNS 62 Standard query 0xfb5e A www.google.co.uk
2.612555200 172.16.1.6 -> 8.8.8.8 DNS 62 Standard query 0xcaf7 A www.google.co.uk
2.628983231 172.16.1.6 -> 8.8.8.8 DNS 75 Standard query 0x803d A fbcdn-photos-a-a.akamaihd.net
I can see packets on eth0 too, which has a public internet IP.
$ tshark -i eth0 -f "host 172.16.1.6"
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0
0.000000000 172.16.1.6 -> 8.8.8.8 DNS 79 Standard query 0x7afb A clients4.google.com
0.002199239 172.16.1.6 -> 8.8.8.8 DNS 74 Standard query 0x4f3c A m.facebook.com
0.003786487 172.16.1.6 -> 8.8.8.8 DNS 74 Standard query 0x7033 A m.facebook.com
0.005484385 172.16.1.6 -> 8.8.8.8 DNS 70 Standard query 0x86a1 A google.com
0.008791391 172.16.1.6 -> 8.8.8.8 DNS 74 Standard query 0x031d AAAA api.amazon.com
Again – nothing the other way
The client can ping the vpn server (172.16.1.1) but nothing outside of it.
I'm not sure what else I can check.
Best Answer
Just did a quick test to see whether tcpdump (I̶ ̶a̶s̶s̶u̶m̶e̶ ̶T̶S̶H̶A̶R̶K̶ ̶b̶e̶h̶a̶v̶e̶s̶ ̶t̶h̶e̶ ̶s̶a̶m̶e̶) shows the NAT'd or original source IP address on the egress interface, when NAT is configured using iptables, even without OpenVPN configured.
Setup : Ubuntu eth1 <-> eth1 CentOS eth0 <-> "Internet"
Ubuntu config :
CentOS config :
(Just ask if you need any of the above config explained.)
Now we ping from Ubuntu (172.16.1.2) to 8.8.8.8 (Google DNS) ...
Internal :
External :
Success !
More importantly, we see that tcpdump shows the NAT'd address !
In your output, the captured IP is "172.16.1.6" - a clear indication of why no traffic is being returned.
Your ISP (or some Internet router) is dropping the traffic as soon as it sees a private address.
As another comment mentioned, check your NAT configuration - or try to get NAT working as I did above before you even touch OpenVPN.
Cheers !
EDIT : Just tested with tshark and it does behave the same as tcpdump, in that it shows the source IP address post-NAT :
Looking at your iptables config more closely ...
The first line specifies the "external networking device" on which to perform NAT as tun0.
The second line isn't really relevant to forwarding, since the INPUT chain concerns traffic destined for the local server itself, not traffic passing through, iinm.
The third line specifies that tun0 is the "internal / inside" interface.
Seems to me that
1) your NAT'd interface should be eth0, not the tunnel interface, and
2) that you need to specify the outside interface (eth0) with an option like "-o eth0 -j ACCEPT" on the same line you specify your inside interface (tun0), and
3) don't forget a separate iptables statement for return traffic, as in my example above !