Allow client to client communication in OpenVPN for certain IP range

The Goal

We've got one OpenVPN Server that's up and running (10.8.0.0/16). And some clients. Clients can be separated into two specific groups: humans and non-humans. The non-humans shall only have access to the VPN server and a couple of external IP addresses through the VPN. The humans on the other hand shall have access to everything - especially to the non-humans (non-human clients have a web interface the humans shall reach).

What works

Humans and non-humans can connect to the VPN. Non-human access is successfully restricted.

The Problem

When connected with a human client, I cannot ping the non-human client nor can I reach the web interface of the non-human client.

~ ping 10.8.0.2 PING 10.8.0.2 (10.8.0.2) 56(84) bytes of data. From 10.8.0.1 icmp_seq=2 Redirect Host(New nexthop: 2.0.8.10) From 10.8.0.1 icmp_seq=3 Redirect Host(New nexthop: 2.0.8.10) From 10.8.0.1 icmp_seq=4 Redirect Host(New nexthop: 2.0.8.10) 

Configs

server.conf

local 192.168.12.152 port 1194 proto udp dev tun0 ca ca.crt cert server.crt key server.key dh dh.pem auth SHA512 tls-crypt tc.key topology subnet server 10.8.0.0 255.255.0.0 client-config-dir /etc/openvpn/ccd push "redirect-gateway def1 bypass-dhcp" ifconfig-pool-persist ipp.txt push "dhcp-option DNS 1.1.1.1" push "dhcp-option DNS 8.8.8.8" keepalive 10 120 cipher AES-256-CBC user nobody group nogroup persist-key persist-tun status openvpn-status.log verb 3 crl-verify crl.pem explicit-exit-notify management 127.0.0.1 5555 

sample_client.ovpn (The Difference between humans and non-humans is made by ccd where clients get a static IP-address. Humans get a IP address from 10.8.255.0/24 and non-humans from 10.8.x.y [x != 255] - so in the ccd there is just 'ifconfig-push 10.8.y.y 255.255.0.0').

client dev tun proto udp remote some-vpn-dyndns.net 1194 resolv-retry infinite nobind persist-key persist-tun remote-cert-tls server auth SHA512 cipher AES-256-CBC ignore-unknown-option block-outside-dns block-outside-dns verb 3 <ca>[...]</ca> <cert>[...]</cert> <key>[...]</key> <tls-crypt>[...]</tls-crypt> 

Iptable changes:

iptables -t nat -A POSTROUTING -s 10.8.0.0/16 ! -d 10.8.0.0/16 -j SNAT --to 192.168.12.152 iptables -I INPUT -p udp --dport 1194 -j ACCEPT iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -I FORWARD -s 10.8.0.0/16 -j DROP iptables -I FORWARD -s 10.8.0.0/16 -d 1.1.1.1 -j ACCEPT <---for DNS iptables -I FORWARD -s 10.8.0.0/16 -d 8.8.8.8 -j ACCEPT <---for DNS iptables -I FORWARD -s 10.8.0.0/16 -d 213.187.93.146 -j ACCEPT <--- special (dummy) server that non-humans have to reach iptables -I FORWARD -s 10.8.255.0/24 -j ACCEPT 

This adds to this iptables -L:

Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:1194 Chain FORWARD (policy ACCEPT) target prot opt source destination ACCEPT all -- 10.8.255.0/24 0.0.0.0/0 ACCEPT all -- 10.8.0.0/16 213.187.93.146 ACCEPT all -- 10.8.0.0/16 8.8.8.8 ACCEPT all -- 10.8.0.0/16 1.1.1.1 DROP all -- 10.8.0.0/16 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 

tl;dr If somebody could tell me why I'm not able to ping from a human client (10.8.255.1) a non-human client (10.8.0.2) - that would be really nice. (Everything else is working as it should)

Thanks in advance!

1 Answer

So I found a solution that kinda works.

What did I do? I changed some FORWARD rules.

Chain FORWARD (policy DROP) target prot opt source destination ACCEPT all -- 10.8.255.0/24 anywhere ACCEPT all -- 10.8.0.0/16 some-dummy-server ACCEPT all -- 10.8.0.0/16 dns.google ACCEPT all -- 10.8.0.0/16 one.one.one.one ACCEPT all -- one.one.one.one 10.8.0.0/16 ACCEPT all -- dns.google 10.8.0.0/16 ACCEPT all -- some-dummy-server 10.8.0.0/16 ACCEPT all -- anywhere 10.8.255.0/24 

First: the default policy for FORWARD is set to DROP. Second: allowed communication to default DNS-Servers for all of my VPN-Range, allowed communication to my special dummy server. Third: I allowed communication with everything and from everything with the IP range of my human clients.

Why do I say it kinda works? Because if I ping from a human client a non human client I still get this:

~ ping 10.8.0.2 PING 10.8.0.2 (10.8.0.2) 56(84) bytes of data. 64 bytes from 10.8.0.2: icmp_seq=1 ttl=63 time=120 ms From 10.8.0.1 icmp_seq=2 Redirect Host(New nexthop: 2.0.8.10) 64 bytes from 10.8.0.2: icmp_seq=2 ttl=63 time=132 ms From 10.8.0.1 icmp_seq=3 Redirect Host(New nexthop: 2.0.8.10) 64 bytes from 10.8.0.2: icmp_seq=3 ttl=63 time=108 ms From 10.8.0.1 icmp_seq=4 Redirect Host(New nexthop: 2.0.8.10) 64 bytes from 10.8.0.2: icmp_seq=4 ttl=63 time=102 ms 

I would guess that is because of the routing table on my (human) client side:

~ sudo route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default _gateway 0.0.0.0 UG 50 0 0 tun0 default _gateway 0.0.0.0 UG 600 0 0 wlp0s20f3 10.8.0.0 0.0.0.0 255.255.0.0 U 50 0 0 tun0 ip5b426419.dyna _gateway 255.255.255.255 UGH 600 0 0 wlp0s20f3 link-local 0.0.0.0 255.255.0.0 U 1000 0 0 wlp0s20f3 192.168.42.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp0s20f3 _gateway 0.0.0.0 255.255.255.255 UH 600 0 0 wlp0s20f3 

So if someone got a better idea, I'm happy to mark their answer as correct.

Ty for reading.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like