This recipe is a continuation of the previous recipe. It will demonstrate how to set up a TAP-based connection in client or server mode using certificates. By using the client-to-client
directive, it will also enable different OpenVPN clients to contact each other. For TAP-based networks, this has some important side-effects.
We use the following network layout:
Set up the client and server certificates using the first recipe from Chapter 2, Client-server IP-only Networks.
For this recipe, the server was running CentOS 5 Linux and OpenVPN 2.1.1; one client was running Windows 2000 SP4 and OpenVPN 2.1.1, the other client was running Windows XP SP3 and OpenVPN 2.1.1. For the server, keep the configuration file example3-1-server.conf
from the previous recipe at hand.
- Create the server configuration file by adding a line to the
example3-1-server.conf
file:client-to-client
Save it as
example-3-2-server.conf
. - Start the server:
[root@server]# openvpn --config example3-2-server.conf
- Set up IP forwarding and an
iptables
masquerading rule:[root@server]# sysctl -w net.ipv4.ip_forward=1 [root@server]# iptables -t nat -I POSTROUTING -i tap+ -o eth0 \ -s 192.168.99.0/24 -j MASQUERADE
- Next, create the client configuration file for the first client:
client proto udp remote openvpnserver.example.com port 1194 dev tap nobind ca "c:/program files/openvpn/config/ca.crt" cert "c:/program files/openvpn/config/client1.crt" key "c:/program files/openvpn/config/client1.key" tls-auth "c:/program files/openvpn/config/ta.key" 1 ns-cert-type server verb 5
Save it as
example-3-2-client1.ovpn
. - Similarly, for the second client create the configuration file:
client proto udp remote openvpnserver.example.com port 1194 dev tap nobind ca "c:/program files/openvpn/config/ca.crt" cert "c:/program files/openvpn/config/client2.crt" key "c:/program files/openvpn/config/client2.key" tls-auth "c:/program files/openvpn/config/ta.key" 1 ns-cert-type server verb 5
And save it as
example-3-2-client2.ovpn
. - Start the Windows clients on the command line or from the OpenVPN GUI:
[WinClient1]C:> cd \program files\openvpn\config [WinClient1]C:> ..\bin\openvpn --config example3-2-client1.ovpn
Client2:
- After the connection is established, we can verify that it is working by pinging the server:
[WinClient1]C:> ping 192.168.99.1 Pinging 192.168.99.1 with 32 bytes of data: Reply from 192.168.99.1: bytes=32 time=24ms TTL=64 Reply from 192.168.99.1: bytes=32 time=25ms TTL=64
And also that we can ping the second client:
[WinClient1]C:> ping 192.168.99.3 Pinging 192.168.99.3 with 32 bytes of data: Reply from 192.168.99.3: bytes=32 time=49ms TTL=128 Reply from 192.168.99.3: bytes=32 time=50ms TTL=128
Notice the higher round-trip time.
- Finally, verify that we can still ping a host on the server-side LAN:
[WinClient1]C:\> ping -c 2 10.198.0.9 Pinging 10.198.0.9 with 32 bytes of data: Reply from 10.198.0.9: bytes=32 time=25ms TTL=63 Reply from 10.198.0.9: bytes=32 time=25ms TTL=63
Both clients connect to the OpenVPN server in the regular manner. The following directive is all that is needed for the clients to "see" each other:
client-to-client
Communication between the clients will still pass through the OpenVPN server, which explains the higher round-trip time for the ICMP packets. The flow of an ICMP (ping
) echo and reply is:
- The OpenVPN client encrypts the packet and forwards it to the server over a secure link.
- The server decrypts the packet and determines that the packet needs to be forwarded to another OpenVPN client. Therefore, the packet is not forwarded to the kernel routing modules but is encrypted again and is forwarded to the second client.
- The second client receives the packet, decrypts it, and sends a reply back to the server over the secure link.
- The server decrypts the reply packet and determines that the packet needs to be forwarded to first client. Therefore, the packet is not forwarded to the kernel routing modules but is encrypted again and is forwarded to the original client.
All machines that are connected to a TAP-style network form a single broadcast domain. When client-to-client
is enabled, this means that all the broadcast traffic from all the clients is forwarded to all other clients. Wireshark running on client2
indeed shows a lot of broadcast packets from client1
, all of which passed through the OpenVPN server. This can lead to a scalability problem when a large number of clients are connected.
In the current version of OpenVPN, it is not possible to filter the traffic between VPN clients when the client-to-client
directive is used. A future version of OpenVPN will have this functionality. It is also possible to enable client-to-client communications without the client-to-client
directive, but this requires some iptables
rules. The advantage is that you can then use the normal iptables
commands to filter the client-to-client traffic. The downside is that it is less efficient.