Contents⌗
- Beginning
- IPIP
- Wireguard
- OpenVPN
- OpenVPN - Certificates
- OpenVPN - Server
- OpenVPN - Client
- OpenVPN - DCO
Beginning⌗
We need to enable IP forwarding on our router.
# Enable Forwarding
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
IPIP⌗
No install here. Just copy the commands and change the IPs as necessary. lient is given 2001:db8:7:a::/64 in this example with the router taking the first address for itself, Enterprise subnet is 2001:db8:7::/48 in this example, Public IPs must be hardcoded for IPIP (cannot be dynamic).
# IPIP Setup (on Client)
ip link add name ipip6 type ip6tnl local <client IP>> remote <server IP>> mode any
ip link set up ipip6
ip addr add 2001:db8:7:a::2/64 dev ipip6
ip -6 route add 2001:db8:7::/48 dev ipip6
# IPIP Setup (on Server)
ip link add name ipip6 type ip6tnl local <server IP> remote <client IP> mode any
ip link set up ipip6
ip addr add 2001:db8:7:a::/64 dev ipip6
#addr add implicitly adds a /64 route to that interface, so no other routes required
Wireguard⌗
First we install it (apt install wireguard
)
Next, we need to create keys on each nodes, so run this command on both sides:
#Gen private key
wg genkey | tee /etc/wireguard/server.key
#Gen public key from private key
cat /etc/wireguard/server.key | wg pubkey | tee /etc/wireguard/server.pub
# You will need these two keys later, so be ready to copy and paste them
Next, we need a /etc/wireguard/wg0.conf
on both nodes:
# Conf for SERVER side
[Interface]
PrivateKey = oBic4cnZOBjmucL10dtiB5QZpUkqPPjEm9rA6E90iUg=
Address = 2001:db8:7:b::/128
ListenPort = 51820
# Peer (CLIENT's public key here)
[Peer]
PublicKey = 1b0J0WcCObEOq0R9zIQoitRa6I4YqLDDL7evmNwN3Go=
AllowedIPs = 2001:db8:7:b::/64
Endpoint = testsrc2.palnet.net:51820
# Conf for CLIENT side
[Interface]
PrivateKey = qKUMygkE+YPWE2MmdCOi5j6Sno78/w9FvXHGTIVpoVU=
Address = 2001:db8:7:b::4/64
ListenPort = 51820
# Peer (SERVER's public key here)
[Peer]
PublicKey = 2VIGy0JS27RjGI9VDug2iNK4dd/Ned9dNDnlCOP1DTQ=
AllowedIPs = 2001:db8:7::/48
Endpoint = wgmetal.palnet.net:51820
Then bring up the interfaces (wg-quick up wg0
on both sides)
OpenVPN⌗
First we install it (apt install openvpn
).
Certificates⌗
We will be using cert auth here, so we need an x.509 cert for both sides. For simplicity, I’m using self-signed ECDSA certs using prime256v1 for leafs and scep384 for the CA
#Generate private key using scep384:
openssl ecparam -name secp384r1 -genkey -out root.key
#Sign the root certificate
#Pathlen:0 means there can be only one more cert below this CA (no more CAs)
#Make sure you update the subj name with your own names
#C=US is also the country, it's optional
#O= is the organization, also optional
#CN= is the Common Name and it's required
#I also set validity to 69 years, make sure you watch for expiration (manually)
openssl req -new -key root.key -x509 -nodes -days 25202 -out root.pem -subj "/C=US/O=apalrd.net/CN=openvpn" -addext "basicConstraints=critical,CA:TRUE,pathlen:0"
#Now you can view it (for fun)
openssl x509 -in root.pem -text -noout
Next, generate the serve’s cert + key
#Change this to the name of your server
export sv=wgmetal.palnet.net
#Generate scep256 key for this client
#If you want 192-bit security, use scep384r1 instead of prime256v1
openssl ecparam -name prime256v1 -genkey -out $sv.key
#Generate a CSR (certificate signing request) for my new key
#again, C and O are optional, CN is the Common Name of the cert
#Allowed only for server auth
openssl req -new -key $sv.key -out $sv.csr -subj "/C=US/O=apalrd.net/CN=$sv" -addext "extendedKeyUsage = serverAuth" --addext "keyUsage = digitalSignature,keyAgreement"
#Sign the CSR using the root
#Shorter lived at only 365 days
openssl x509 -req -in $sv.csr -CA root.pem -CAkey root.key -CAcreateserial -out $sv.crt -days 365 -sha256 -copy_extensions=copyall
#Now you can view it (for fun)
openssl x509 -in $sv.crt -text -noout
And finally, generate the client cert:
#Change this to the name of your client
export cl=testsrc2.palnet.net
#Generate scep256 key for this client
#If you want 192-bit security, use scep384r1 instead of prime256v1
openssl ecparam -name prime256v1 -genkey -out $cl.key
#Generate a CSR (certificate signing request) for my new key
#again, C and O are optional, CN is the Common Name of the cert
openssl req -new -key $cl.key -out $cl.csr -subj "/C=US/O=apalrd.net/CN=$cl" -addext "extendedKeyUsage = clientAuth" --addext "keyUsage = digitalSignature,keyAgreement"
#Sign the CSR using the root
#Sign it allowing for server and client auth as the key usage
openssl x509 -req -in $cl.csr -CA root.pem -CAkey root.key -CAcreateserial -out $cl.crt -days 365 -sha256 -copy_extensions=copyall
#Now you can view it (for fun)
openssl x509 -in $cl.crt -text -noout
Transfer your .key and .crt files to the server and client respectively. The server will need its client .key and .crt, and the server will need its server .key and .crt, and they both need root.pem
Server⌗
The server setup is quite complex. Here’s my final /etc/openvpn/server.conf
:
server
#UDP over IPV6 outside of tunnel
port 1194
proto udp6
dev tun
user nobody
group nogroup
persist-key
persist-tun
keepalive 10 120
topology subnet
#IPv6 inside of tunnel
server-ipv6 2001:db8:7:c::/64
ifconfig-ipv6-pool 2001:db8:7:c::/64
push "route-ipv6 2001:db8:7::/48"
ifconfig-pool-persist ipp.txt
#Crypto parameters
dh none
ecdh-curve prime256v1
tls-crypt tls-crypt.key
#Client verification
ca root.pem
cert server.crt
key server.key
remote-cert-tls client
# no CRL in my setup
#crl-verify root.pem
auth SHA256
cipher AES-128-GCM
data-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
client-config-dir /etc/openvpn/ccd
status /var/log/openvpn/status.log
verb 3
Also, a few commands to get it started:
openvpn --genkey secret /etc/openvpn/tls-crypt.key
mkdir -p /etc/openvpn/ccd
mkdir -p /var/log/openvpn
systemctl enable --now openvpn@server
Once we’ve generated tls-crypt.key we need to copy that file to the client (it’s our Shared Secret)
Client⌗
For the client we need a /etc/openvpn/client.conf
file:
client
remote wgmetal.palnet.net 1194
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name wgmetal.palnet.net name
auth SHA256
cipher AES-128-GCM
data-ciphers AES-128-GCM
auth-nocache
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
verb 3
#Client certs
cert client.crt
key client.key
#Server's CA
ca root.pem
tls-crypt tls-crypt.key
remote-cert-tls server
And a few commands too:
systemctl enable --now openvpn@client
DCO⌗
The whole reason for this test is to see if DCO is as performant! And we aren’t using DCO just yet. So, here’s how to enable it:
#Make sure you have rebooted since any kernel upgrades!
apt update
apt install -y linux-headers-$(uname -r)
apt install -y openvpn-dco-dkms
modprobe ovpn-dco-v2
At this point, restarting the server (or client, it works both ways) should enable DCO. Check the logs (journalctl -xeu openvpn@server
) to make sure.
IPSec⌗
Oh boy you are in for a fun ride here, we’re gonna install Strongswan (apt install -y strongswan
).
You will also need the same certificates we created earlier for OpenVPN.