26

When using a TUN (layer 3) OpenVPN server with client-to-client disabled, my clients can still talk to each other.

The client-to-client config should prevent this according to the documentation:

Uncomment out the client-to-client directive if you would like connecting clients to be able to reach each other over the VPN. By default, clients will only be able to reach the server.

Why can the clients continue to communicate to each other when this option is disabled?

Here is my server conf:

port 443
proto tcp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh4096.pem
topology subnet
server 10.10.201.0 255.255.255.128
ifconfig-pool-persist ipp.txt
crl-verify /etc/openvpn/keys/crl.pem
push "route [omitted]"
push "dhcp-option DNS [omitted]"
keepalive 10 120
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so login
cipher AES-256-CBC
tls-auth /etc/openvpn/keys/pfs.key 0
verb 4
lobi
  • 1,021
  • 2
  • 14
  • 26

3 Answers3

77

If client-to-client is enabled, the VPN server forwards client-to-client packets internally without sending them to the IP layer of the host (i.e. to the kernel). The host networking stack does not see those packets at all.

           .-------------------.
           | IP Layer          |
           '-------------------'


           .-------------------.
           | TUN device (tun0) |
           '-------------------'


           .-------------------.
           | OpenVPN server    |
           '-------------------'
             ^           |
          1  |           |  2   
             |           v
 .----------------.  .----------------.
 | Client a       |  | Client b       |
 '----------------'  '----------------'

If client-to-client is disabled, the packets from a client to another client go through the host IP layer (iptables, routing table, etc.) of the machine hosting the VPN server: if IP forwarding is enabled, the host might forward the packet (using its routing table) again to the TUN interface and the VPN daemon will forward the packet to the correct client inside the tunnel.

           .-------------------.
           | IP Layer          |  (4) routing, firewall, NAT, etc.
           '-------------------'      (iptables, nftables, conntrack, tc, etc.)
              ^          |
          3   |          |  5
              |          v
           .-------------------.
           | TUN device (tun0) |
           '-------------------'
             ^           |
          2  |           |  6  
             |           v
           .-------------------.
           | OpenVPN server    |
           '-------------------'
             ^           |
          1  |           |  7  
             |           v
 .----------------.  .----------------.
 | Client a       |  | Client b       |
 '----------------'  '----------------'

In this case (client-to-client disabled), you can block the client-to-client packets using iptables:

 iptables -A FORWARD -i tun0 -o tun0 -j DROP

where tun0 is your VPN interface.

ysdx
  • 1,623
  • 11
  • 13
  • Marked this as the answer; concise yet very informative and actually provides the iptables firewall rule in the answer. – lobi Nov 24 '15 at 23:26
  • 1
    I have a question about the diagram, do you draw it char by char and space by space? or do you use any app to help you getting that simply and quickly? – Mohammed Noureldin Jul 15 '17 at 17:02
  • 3
    @MohammedNoureldin, I made the original diagram with asciio (http://search.cpan.org/dist/App-Asciio/) which is a WYSWYG point-and-click editor for asciiart diagrams. – ysdx Jul 17 '17 at 07:32
  • Thank you, did you manage to run it on windows? it seems to be an app from the middle ages, and I couldn't run it on windows, I tried to install it with camelbox package, but I get always 404 error. – Mohammed Noureldin Jul 17 '17 at 18:01
  • 2
    @MohammedNoureldin, I'm not using Windows. I'm using Debian and it's direcly installable from the packages. – ysdx Jul 17 '17 at 19:37
  • The **if IP forwarding is enabled** part saved my day. The diagram is great too, thanks! – Yajo May 04 '18 at 13:02
  • note that this applys to 'topology subnet', if the topology is commented, it defaults to net30, which doesn't work this way. – BOYPT Sep 28 '21 at 06:26
  • @BOYPT, could you elaborate on this? I'm not aware of any difference in this regard. – ysdx Sep 28 '21 at 07:17
  • @ysdx ah that was inaccurate. The default topology is net30, each client has a /30 subnet, if the VPN is not configured as a gateway with client-to-client off, ping another client, neither peer client or the server receives the ping packet. I change to --topology subnet (which is recommended now by the official document) everything works as expected as yours post described. – BOYPT Sep 29 '21 at 13:04
8

You need to do more than just commenting the directive as it says here:

Uncomment this directive to allow different clients to be able to "see" each other. By default, clients will only see the server. To force clients to only see the server, you will also need to appropriately firewall the server's TUN/TAP interface.

Therefore you may configure seperate IP address policy for each client. See the section Configuring client-specific rules and access policies here: https://openvpn.net/index.php/open-source/documentation/howto.html. and here: https://www.sbarjatiya.com/notes_wiki/index.php/Configuring_separate_IP_and_firewall_rule_for_each_openvpn_client.

Diamond
  • 8,791
  • 3
  • 22
  • 37
  • Then this means what I thought: the only way to achieve this is to put each client on different subnets. This mostly answers the question, plus you gave some documentation on how to do that. I'll mark this down as the answer. Thanks. – lobi Nov 15 '15 at 03:05
6

The next paragraph of the man page for openvpn answers this question, although it's not necessarily clear at first reading:

Because the OpenVPN server mode handles multiple clients through a single tun or tap interface, it is effectively a router. The --client-to-client flag tells OpenVPN to internally route client-to-client traffic rather than pushing all client-originating traffic to the TUN/TAP interface.

When this option is used, each client will "see" the other clients which are currently connected. Otherwise, each client will only see the server. Don't use this option if you want to firewall tunnel traffic using custom, per-client rules.

The client-to-client option short-circuits the normal routing tables on the server. Removing it does not prevent the clients using the server's routing tables. If those routing tables - and the server's firewall configuration - permit clients to see each other then they will be able to do so.

roaima
  • 1,567
  • 13
  • 26