VPN#
A Virtual Private Network is a technology that creates a secure, encrypted connection over the internet, allowing a device to appear as if it is part of a private network. It enables users to securely access network resources and protect their online activity from eavesdropping, even when using public networks.
Minimal setup#
This section shows the simplest example of a VPN, it shows the ideas behind the definition of a Virtual Private Network. It is based on the Static Key Mini-HOWTO tutorial.
We will set up VPN server in a Docker container, connect to it from the host, and show what has happened to the host’s network configuration as a result.
The following cell starts the Docker container and installs the necessarry compoments.
docker run --name server -itd --name vpn_server --privileged --rm ubuntu:24.04
docker exec vpn_server bash -c "apt update && apt install -y openvpn" &> /dev/null
b12ef9318d36d1d29206d323c18d7dad21b83f36676c5f09edab733463687dc3
To start the openvpn
server you need to create a config in the /usr/share/doc/openvpn/server.conf
path and generate a key, in this case it would be static.key
.
Note the ifconfig
directive in the configuraion, it sets up the ip to the computers in the virtual network.
docker exec -i vpn_server tee /usr/share/doc/openvpn/server.conf > /dev/null << EOF
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
cipher AES-256-CBC
EOF
docker exec vpn_server openvpn --genkey --secret static.key &> /dev/null
docker exec -d vpn_server openvpn /usr/share/doc/openvpn/server.conf &> /dev/null
Host is almost the same, but we’ll load a key generated in the sever.
container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' vpn_server)
cat << EOF > /tmp/client.conf
remote ${container_ip}
dev tun
ifconfig 10.8.0.2 10.8.0.1
secret /tmp/static.key
cipher AES-256-CBC
EOF
docker cp vpn_server:/static.key /tmp/static.key
openvpn /tmp/client.conf &> /dev/null &
process_id=$!
Successfully copied 2.56kB to /tmp/static.key
[1] 20276
Finally, you can ping the address of the vpn server, in the virtual network, and it would work.
ping -c 5 10.8.0.1
PING 10.8.0.1 (10.8.0.1): 56 data bytes
64 bytes from 10.8.0.1: seq=0 ttl=64 time=0.386 ms
64 bytes from 10.8.0.1: seq=1 ttl=64 time=0.921 ms
64 bytes from 10.8.0.1: seq=2 ttl=64 time=0.898 ms
64 bytes from 10.8.0.1: seq=3 ttl=64 time=0.912 ms
64 bytes from 10.8.0.1: seq=4 ttl=64 time=1.024 ms
--- 10.8.0.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.386/0.828/1.024 ms
Note that a new network interface has appeared in the client configuration - it organises interaction with the virtual network.
ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 1e:9d:ec:67:b4:c4 brd ff:ff:ff:ff:ff:ff link-netnsid 0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:af:62:f0:42 brd ff:ff:ff:ff:ff:ff
19: vethac27a55@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether 5a:81:82:16:7c:f9 brd ff:ff:ff:ff:ff:ff link-netnsid 1
20: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 500
link/none
kill $process_id
docker stop vpn_server
vpn_server
[1]+ Done openvpn /tmp/client.conf &> /dev/null