Homemade WireGuard VPN on a VPS server

Je poste ça ici, car je penses que cela peut être utile à d’autres membres de la communauté. I’m posting this here because I think it may be useful to other members of the community.

Mes objectifs - My goals :

  • Je souhaitais pouvoir disposer d’une adresse IPV4 et IPV6 fixe.

  • Je souhaitais pouvoir personnaliser le reverse DNS en IPV4 et en IPV6

  • Je souhaitais une vitesse de connexion rapide digne de la fibre

  • Je souhaitais une solution à moins de 15/20 € par an

  • I wanted to have a fixed IPV4 and IPV6 address.

  • I wanted to be able to customize the reverse DNS in IPV4 and IPV6

  • I wanted a fast connection speed worthy of the fiber

  • I wanted a solution for less than 15/20 € per year

Ma solution - My solution:

  • Louer un VPS entrée de gamme qui donne accès à une IPV4 et une IPV6 fixe, permette de personnaliser les reverse DNS et y mettre en place un serveur VPN pour router le trafic de mon serveur à la maison.

  • Mon choix : un VPS S chez IONOS à 1€ HT par mois.

  • Ce tuto est néanmoins adaptable pour n’importe quel fournisseur de VPS

  • Rent an entry-level VPS that gives access to a fixed IPV4 and IPV6, allows to customize reverse DNS and set up a VPN server on it to route traffic to my server at home.

  • My choice: a VPS S from IONOS at 1€ excl. tax per month.

  • This tutorial is however adaptable for any VPS provider

Remarques concernant les choix techniques - Notes about technical choices :

  • J’ai choisis d’utiliser Wireguard plutôt qu’OpenVPN pour sa simplicité de mise en place et sa légèreté

  • J’utilise du NAT en IPV6 et non un proxy NDP car IONOS me permet seulement de personnaliser le reverse DNS de l’IPV6 du VPS.

  • J’utilise le port TCP 140 pour me connecter en SSH à mon serveur Yunohost.

  • L’interface réseau de mon VPS s’appelle ens192. Modifier son nom en fonction de votre configuration dans la suite du tuto (par exemple enp3s0, eth0, …)

  • I chose to use Wireguard rather than OpenVPN for its simplicity of implementation and its lightness

  • I use NAT in IPV6 and not a NDP proxy because IONOS only allows me to customize the reverse DNS of the VPS IPV6 address.

  • I use TCP port 140 to connect to my Yunohost server via SSH.

  • The network interface of my VPS is called ens192. Change its name according to your configuration in the following tutorial (for example enp3s0, eth0, …)

Améliorations possible - Possible improvements :

  • Automatiser tous le processus côté VPS

  • Packager le client VPN au format Yunohost côté client

  • Automate all the process on VPS side

  • Pack the VPN client in Yunohost format on client side

Mise en place - Set Up:

Commander un VPS - Order a VPS :

  • Commander un VPS

  • Demander une attribution d’une IPV6 si nécessaire

  • Ouvrir les ports TCP et UDP requis sur le site du fournisseur de VPS

  • Installer une distribution basée sur Debian sur le VPS (ici Debian 10)

  • Facultatif : configurer SSH (clé SSH + changement de ports, port différent de celui du serveur YunoHost)

  • Order a VPS

  • Request an IPV6 address if necessary

  • Open the required TCP and UDP ports on the VPS provider’s website

  • Install a Debian-based distribution on the VPS (here Debian 10)

  • Optional: configure SSH (SSH key + port change, different port from YunoHost server)

Configurer le VPS - configure the VPS :

Fixer les adresses ip publiques dans le fichier interfaces Set public ip addresses in the interfaces file

sudo nano /etc/network/interfaces

Le fichier doit ressembler à ça The file should look like this :

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback
iface lo inet6 loopback

allow-hotplug ens192

# IPV4 Setup
iface ens192 inet static
        address [insert public IPV4 address]
        netmask [insert IPV4 netmask]
        gateway [insert IPV4 gateway]

# IPV6 Setup
iface ens192 inet6 static
        accept_ra 0
        address [insert public IPV6 address]
        netmask [insert IPV6 netmask]
        gateway [insert IPV6 gateway]
        
# Save and quit (CTRL+O, CTRL+X)

Redémarrer le réseau restart the network

/etc/init.d/networking restart

Autoriser la redirections des paquets IPV4 et IPV6 Allow forwarding of IPV4 and IPV6 packets

sudo nano /etc/sysctl.conf
# Uncomment the following lines:
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
# Save and quit (CTRL+O, CTRL+X)
sudo sysctl -p

Installation et configuration de Wireguard - installation and configuration of Wireguard :

Installer Wireguard sur le VPS et sur le serveur YunoHost (Les utilisateurs ayant des versions de Debian plus anciennes que Bullseye doivent d’abord activer les rétroportages) Install Wireguard on the VPS and on the YunoHost server (Users with Debian releases older than Bullseye should first enable backports)

sudo apt install wireguard

WireGuard nécessite des clés publiques et privées codées en base64. Celles-ci peuvent être générées en utilisant l’utilitaire wg. Des deux côtés, faites WireGuard requires base64-encoded public and private keys. These can be generated using the wg utility. On both side do :

cd /etc/wireguard
sudo wg genkey | tee privatekey | wg pubkey > publickey

Configurer Wireguard sur le VPS - Configure Wireguard on the VPS :

sudo nano /etc/wireguard/wg0.conf

Remplir le fichier wg0.conf comme ceci Fill in the wg0.conf file like this

[Interface]
PrivateKey = [insert private key of the VPS]
Address = 10.6.0.1/24,fd42:42:42::1/64
ListenPort = 51820
SaveConfig = true

PostUp = bash /etc/wireguard/PostUp.sh
PostDown = bash /etc/wireguard/PostDown.sh

### begin yunohost ###
[Peer]
PublicKey = [insert public key of the YunoHost Server]
AllowedIPs = 10.6.0.2/32,fd42:42:42::2/128
### end yunohost ###

# Save and quit (CTRL+O, CTRL+X)

Puis créer et remplir les fichiers PostUp.sh et PostDown.sh comme suit Then create and fill the PostUp.sh and PostDown.sh files as follows :

sudo nano /etc/wireguard/PostUp.sh

Remplir le fichier PostUp.sh comme ceci Fill in the PostUp.sh file like this

iptables -A FORWARD -i wg0 -j ACCEPT; 
iptables -t nat -A POSTROUTING -o ens192 -j MASQUERADE; 
ip6tables -A FORWARD -i wg0 -j ACCEPT; 
ip6tables -t nat -A POSTROUTING -o ens192 -j MASQUERADE; 

# icmp
iptables -A INPUT -p icmp -j ACCEPT;
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT; 
 
# Routing TCP port 25 and 587 from Yunohost Server to internet 
for j in 25 587
do
	iptables -t nat -A POSTROUTING -s 10.6.0.2 -p tcp --dport $j -j SNAT --to [insert public IPV4 of the VPS]; 
	iptables -A FORWARD -s 10.6.0.2 -p tcp --dport $j -j ACCEPT; 
	ip6tables -t nat -A POSTROUTING -s fd42:42:42::2 -p tcp --dport $j -j SNAT --to [insert public IPV6 of the VPS]; 
	ip6tables -A FORWARD -s fd42:42:42::2 -p tcp --dport $j -j ACCEPT; 
done

# Routing TCP port required from VPN server to Yunohost server
for i in 25 80 140 443 587 993 5222 5269 
do 
	iptables -t nat -A PREROUTING -i ens192 -p tcp --dport $i -j DNAT --to-destination 10.6.0.2; 
	iptables -A FORWARD -d 10.6.0.2 -p tcp --dport $i -j ACCEPT; 
	ip6tables -t nat -A PREROUTING -i ens192 -p tcp --dport $i -j DNAT --to-destination fd42:42:42::2; 
	ip6tables -A FORWARD -d fd42:42:42::2 -p tcp --dport $i -j ACCEPT; 
done

# Save and quit (CTRL+O, CTRL+X)

Remplir le fichier PostDown.sh comme ceci Fill in the PostDown.sh file like this

sudo nano /etc/wireguard/PostDown.sh

# PostDown.sh 

iptables -D FORWARD -i wg0 -j ACCEPT; 
iptables -t nat -D POSTROUTING -o ens192 -j MASQUERADE; 
ip6tables -D FORWARD -i wg0 -j ACCEPT; 
ip6tables -t nat -D POSTROUTING -o ens192 -j MASQUERADE; 

# icmp
iptables -D INPUT -p icmp -j ACCEPT;
ip6tables -D INPUT -p ipv6-icmp -j ACCEPT; 
 
# Routing TCP port 25 and 587 from Yunohost Server to internet 
for j in 25 587
do
	iptables -t nat -D POSTROUTING -s 10.6.0.2 -p tcp --dport $j -j SNAT --to [insert public IPV4 of the VPS]; 
	iptables -D FORWARD -s 10.6.0.2 -p tcp --dport $j -j ACCEPT; 
	ip6tables -t nat -D POSTROUTING -s fd42:42:42::2 -p tcp --dport $j -j SNAT --to [insert public IPV6 of the VPS]; 
	ip6tables -D FORWARD -s fd42:42:42::2 -p tcp --dport $j -j ACCEPT; 
done

# Routing TCP port required from VPN server to Yunohost server
for i in 25 80 140 443 587 993 5222 5269 
do 
	iptables -t nat -D PREROUTING -i ens192 -p tcp --dport $i -j DNAT --to-destination 10.6.0.2; 
	iptables -D FORWARD -d 10.6.0.2 -p tcp --dport $i -j ACCEPT; 
	ip6tables -t nat -D PREROUTING -i ens192 -p tcp --dport $i -j DNAT --to-destination fd42:42:42::2; 
	ip6tables -D FORWARD -d fd42:42:42::2 -p tcp --dport $i -j ACCEPT; 
done

# Save and quit (CTRL+O, CTRL+X)

Rendre les deux scripts exécutables Make both scripts executable

sudo chmod +x /etc/wireguard/PostUp.sh
sudo chmod +x /etc/wireguard/PostDown.sh

Configurer Wireguard sur le serveur YunoHost - Configure Wireguard on the YunoHost server :

sudo nano /etc/wireguard/wg0.conf

Remplir le fichier wg0.conf comme ceci Fill in the wg0.conf file like this

[Interface]
PrivateKey = [insert private key of the YunoHost server]
Address = 10.6.0.2/24, fd42:42:42::2/64
# choose your DNS - for instance FDN DNS resolver
DNS = 80.67.169.12, 2001:910:800::12

PostUp = bash /etc/wireguard/PostUp.sh
PostDown = bash /etc/wireguard/PostDown.sh 

[Peer]
PublicKey = [insert public key of the VPS]
Endpoint = [insert your domain name (link to the ips of the VPS server)]:51820
AllowedIPs = 0.0.0.0/0, ::0/0
PersistentKeepalive = 25

# Save and quit (CTRL+O, CTRL+X)

Remplir le fichier PostUp.sh comme ceci Fill in the PostUp.sh file like this

sudo nano /etc/wireguard/PostUp.sh

# PostUp.sh 

#Begin IPV4
iptables -w -N vpnclient_in; 
iptables -w -N vpnclient_out; 
iptables -w -N vpnclient_fwd;
 
iptables -w -A vpnclient_in -p icmp -j ACCEPT; 
iptables -w -A vpnclient_in -s 10.6.0.2/24 -j ACCEPT; 

#Allowing required TCP ports
for i in 25 80 140 443 587 993 5222 5269
do
	iptables -w -A vpnclient_in -p tcp --dport $i -j ACCEPT; 
done
iptables -w -A vpnclient_in -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT; 
iptables -w -A vpnclient_in -j DROP; 

iptables -w -A vpnclient_out -j ACCEPT; 

iptables -w -A vpnclient_fwd -j DROP; 

iptables -w -I INPUT 1 -i wg0 -j vpnclient_in; 
iptables -w -I OUTPUT 1 -o wg0 -j vpnclient_out; 
iptables -w -I FORWARD 1 -o  wg0 -j vpnclient_fwd; 
#End IPV4

#Begin IPV6
ip6tables -w -N vpnclient_in; 
ip6tables -w -N vpnclient_out; 
ip6tables -w -N vpnclient_fwd; 

ip6tables -w -A vpnclient_in -p ipv6-icmp -j ACCEPT; 
ip6tables -w -A vpnclient_in -s fd42:42:42::2/64 -j ACCEPT; 

#Allowing required TCP ports
for i in 25 80 140 443 587 993 5222 5269
do
	ip6tables -w -A vpnclient_in -p tcp --dport $i -j ACCEPT; 
done

ip6tables -w -A vpnclient_in -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT; 
ip6tables -w -A vpnclient_in -j DROP;
 
ip6tables -w -A vpnclient_out -j ACCEPT; 

ip6tables -w -A vpnclient_fwd -j DROP; 

ip6tables -w -I INPUT 1 -i wg0 -j vpnclient_in; 
ip6tables -w -I OUTPUT 1 -o wg0 -j vpnclient_out; 
ip6tables -w -I FORWARD 1 -o  wg0 -j vpnclient_fwd;
#End IPV6

# Save and quit (CTRL+O, CTRL+X)

Remplir le fichier PostDown.sh comme ceci Fill in the PostDown.sh file like this

sudo nano /etc/wireguard/PostDown.sh

# PostDown.sh

#Begin IPV4
iptables -w -F vpnclient_in; 
iptables -w -F vpnclient_out; 
iptables -w -F vpnclient_fwd; 

iptables -D INPUT -i wg0 -j vpnclient_in; 
iptables -D FORWARD -o wg0 -j vpnclient_fwd; 
iptables -D OUTPUT -o wg0 -j vpnclient_out; 

iptables -w -X vpnclient_in; 
iptables -w -X vpnclient_out; 
iptables -w -X vpnclient_fwd;
#End IPV4

#Begin IPV6
ip6tables -w -F vpnclient_in; 
ip6tables -w -F vpnclient_out; 
ip6tables -w -F vpnclient_fwd; 

ip6tables -D INPUT -i wg0 -j vpnclient_in; 
ip6tables -D FORWARD -o wg0 -j vpnclient_fwd; 
ip6tables -D OUTPUT -o wg0 -j vpnclient_out;
 
ip6tables -w -X vpnclient_in; 
ip6tables -w -X vpnclient_out; 
ip6tables -w -X vpnclient_fwd;
#End IPV6

# Save and quit (CTRL+O, CTRL+X)

Rendre les deux scripts exécutables Make both scripts executable

sudo chmod +x /etc/wireguard/PostUp.sh
sudo chmod +x /etc/wireguard/PostDown.sh

Activer le VPN sur les deux serveurs Enable VPN on both sides :

Sur le VPS puis sur le serveur YunoHost exécuter les commandes suivantes On the VPS and then on the YunoHost server run the following commands :

sudo systemctl start wg-quick@wg0.service
sudo systemctl enable wg-quick@wg0.service

Afin de permettre la génération automatique des certificats Let’s Encrypt des domaines/sous-domaines associés à votre serveur YunoHost, vous devez ajouter les lignes suivantes à votre fichier Hosts sur le serveur YunoHost (sudo nano /etc/hosts) In order to enable automatic generation of Let’s Encrypt certificates for domains/subdomains associated with your YunoHost server, you must add the following lines to your Hosts file on the YunoHost server (sudo nano /etc/hosts):

::1         domain.tld
127.0.0.1   domain.tld

Test et déploiement Testing and deployment:

  • Assurer vous que votre zone DNS est configurer de sorte que le champs A pointe vers l’IPV4 de votre VPS et le champs AAAA pointe vers l’IPV6 de votre VPS.

  • Une fois la propagation DNS effective, vous pouvez configurer les reverse DNS des IPV4 et IPV6 du VPS vers votre nom de domaine sur le site du fournisseur du VPS.

  • Faite un diagnostique sur l’API d’administration YunoHost, normalement tout est vert !

  • Make sure that your DNS zone is configured so that the A field points to the IPV4 of your VPS and the AAAA field points to the IPV6 of your VPS.

  • Once the DNS propagation is effective, you can configure the reverse DNS of the VPS IPV4 and IPV6 to your domain name on the VPS provider’s website.

  • Do a diagnostic on the YunoHost administration API, normally everything is green!

Conclusion :

J’espère que ce tuto sera utile pour d’autres personnes. Si vous avez des suggestions d’amélioration je suis preneur. I hope this tutorial will be useful for other people. If you have any suggestions for improvement I’d love to hear them.

Augustin Rungeard

EDIT: If you are interested in configuring this setup for the Synapse application, @tomas made a detailed post on the subject here → Tutorial : How to make matrix-synapse's coturn (audio & video calls) work behind a VPN - #3 by tomas

12 Likes

Or if you are lazy like me you use the script here GitHub - Nyr/wireguard-install: WireGuard road warrior installer for Ubuntu, Debian, CentOS and Fedora

wget https://git.io/wireguard -O wireguard-install.sh && bash wireguard-install.sh

1 Like

Sympa comme script @TheNomad11 ! S’occupe-t-il aussi de la redirection des différents ports TCP/UDP requis pour l’utilisation de YunoHost ?

Salut @rungeard, super tuto, très clair.
Je ne suis pas expert en vps, alors je voulais savoir ce qu’on pouvait utiliser comme applications yunohost avec ce type de VPS (512mb ram et ssd 16Go).
Est-ce que c’est suffisant pour héberger un mattermost, WordPress, un site Web institutionnel et quelques fichiers ?

Bonne journée

Salut @binouzzz ! Ce genre de configuration correspond clairement à la configuration minimale requise pour faire tourner YunoHost et tu risque vite de te retrouver à l’étroit. Mon serveur YunoHost dans ce tutoriel n’est pas sur le VPS, il s’agit d’un pc à la maison avec des caractéristiques beaucoup plus généreuses. Le VPS me sert simplement de relai vers internet pour m’affranchir des contraintes de mon FAI à moindre prix. Pour mieux comprendre l’intérêt d’un VPN je t’invites à regarder la page de la documentation Yunohost correspondante. J’espère que cela répondra à ta question.

Merci beaucoup pour ta réponse, ça me va très bien.
J’avais vu cette page, mais sans vraiment la comprendre, c’est plus clair avec ton cas d’usage.

Bonne soirée

Also there is a package for Yunohost now that is really easy to use. I use it and it works great!

1 Like

It is a great package I agree with you @arkadi . However, it allows you to transform your YunoHost server into a WireGuard VPN host server. But I wanted to transform my YunoHost server into a WireGuard VPN client server. Hence this tuto!

1 Like

It’s actually something we could cook up. :slight_smile: Automating your steps is doable, and we could use the “config panel” feature that would come in the future to paste wg0.conf into YunoHost.

Anyhow, great tutorial, thanks!

5 Likes

Thank you very much for your message @tituspijean . Can’t wait for the future. Being able to use the YunoHost WireGuard application as both a client and a host would be awesome!

1 Like

I just tried it again and it worked flawlessly while I never succeeded with the official YH Wireguard app

1 Like

I’m glad it works @TheNomad11 . Concerning the Wireguard YunoHost application I think it’s because as @tituspijean titus said for the moment it is designed to work as a host and not as a client but this will surely evolve in the futur.

1 Like

This guide is pure gold!

Many, many thanks @rungeard !! I’ve been looking for an easy to follow, step by step guide for noobs for a long time!

My ISP is blocking all ports, and having Yunohost accessible from the internet is a nightmare. I will try this to see if it works.

How is the performance so far? Are you getting good speeds?

Also, would it be possible to add a bit more detail as to how to specifically do these two final steps:

  • Make sure that your DNS zone is configured so that the A field points to the IPV4 of your VPS and the AAAA field points to the IPV6 of your VPS.
  • Once the DNS propagation is effective, you can configure the reverse DNS of the VPS IPV4 and IPV6 to your domain name on the VPS provider’s website.

Thanks again!

Thank you @Sindorf for your message. I’m glad you like this tuto.

The performance is comparable to the slowest connection between your ISP and the VPS connection (at ionos 400 Mbits/sec symmetrical). At my ISP it’s the slowest so I get a connection of about 200 Mbits/sec in the end.

Concerning the DNS configuration you just have to follow the YunoHost doc → https://yunohost.org/en/administrate/install/dns

Normally, once the VPN is configured and active on both sides, the configuration automatically proposed in the Webadmin in domain/domain.tld/DNS configuration should be correct.

You can test DNS propagation with sites like https://dnschecker.org/

For the configuration of ReverseDNS, the steps to follow are linked to your VPS provider. With Ionos you can configure it in the server panel in the network section and under public IP.

Then you have to enter manually your domain name for the ipv4 and ipv6 of your VPS

I hope this will answer your questions.

1 Like

Thanks for the prompt and clear reply @rungeard. I ordered a VPS at Ionos and I am waiting for confirmation to start with the setup. Can’t wait to do it and test it!

Just another question I just though about: If I want to set up a second Younohost on another Raspberry Pi at another location, would it be feasible to use the same setup with the same VPS? I guess I would need a second IPv4 from Ionos, but would there be any way to do it just with one IPv4, by playing with the domain, subdomain and DNS?

I don’t think so because you have to use the same ports on the same ipv4…

It would be possible to use ipv6 using an NDP proxy because you have a whole ipv6 subnet on the VPS and you can assign an ipv6 address per client. But in this case Ionos does not allow you to configure reverseDNS for each ipv6.

A new Ipv4 on the same VPS costs 5€ excl. tax per month. A new VPS costs 1€ excl. tax per month. According to me the choice is quickly made…

1 Like

Thanks! Again, very clear and easy choice, indeed.

The main issue I see with IPv6 is that unfortunately and sadly it is not widely spread yet. I can access any IPV6 website from my home, but I can’t access any from my office or from my phone :frowning:

Hopefully some day IPv6 will be the global standard accepted and accessible everywhere!

@rungeard Can I ask a stupid question? Is it possible by doing this to the VPS, route all internet traffic through the VPN, by lets say installing a wireguard client app into a mobile phone ? I mean instead of using a VPN provider, to do this using our VPS…

I’m not sure I understand your question @HoldMyGin . There is no VPN provider. The VPN is home made on your VPS. It replaces a VPN provider.

That’s the concept of a VPN

Yes, it is perfectly possible but it doesn’t have much to do with YunoHost!

route all internet traffic through the VPN

If I may intrude here, that is actually not quite true. Literally VPNs are private networks, made to make computers appear as if they were on the same local network, even if they are accross the Internet from each other. (My main VPN use, for example, is to have SAMBA shares that no one should create over standard Internet connections. Other example is my work VPN which is only used to access the intranet.)

However, the common practice is indeed to designate a main server on this network, through which clients can route their Internet connection.

/useless precision.

1 Like