---
title: "Network configuration with OpenVPN"
date: 2020-07-27T18:00:00+02:00
---

Networking is hard. Dealing with ISP modem settings is even harder. Mine doesn't have a static public IP address by
default. If the modem reboots, it is likely that it will be assigned a new one. For regular people, it is not a problem
for browsing the Internet. But for hackers like us, that means we cannot use the IP address itself to reach the private
network from the outside world. It becomes a problem when we try to join hosts in different networks.

For your information, this is the price my ISP would like me to pay for this "option":

![Fixed IP option](/fixed-ip-option.png)

This is insane!

The first idea was to deploy a script on each host that discover the public IP address and register an A record on a
given subdomain name. This job could have been run by a cron daemon. It would transform a dynamic IP address into a
predictable name. It was like the [no-ip](https://www.noip.com/) service. It worked. I was able to know the home public
IP address.

Then, I started to use [port
mapping](https://www.proximus.be/support/en/id_sfaqr_ports_mapping/personal/support/internet/internet-at-home/advanced-settings/internet-port-mapping-on-your-modem.html#/bbox3)
to redirect a given port on my router to a host in the private network. By default, some protocols like SSH, HTTP and
HTTPS are [not
open](https://www.proximus.be/support/en/id_sfaqr_ports_unblock_secu/personal/support/internet/security-and-protection/internet-ports-and-security/open-internet-ports.html),
even if you configure port mapping correctly. You have to go on the ISP website and lower your *security level* from
high to low. At my apartment, I successfully managed to reach some port from the outside, but never on my current house.
The major problem of this procedure is its **complexity** and the fact it **highly depends on your ISP
devices/settings**. I had to find a simpler solution.

Here comes [OpenVPN](https://openvpn.net/). It's an open-source software which creates  private networks on public
networks. It uses encryption to secure connection between each host to keep your transport safe. The initial setup is
quite long and complex but you just have to follow this [great
tutorial](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-debian-10) and it will
work like a charm. The drawback is you'll need a single point to act as a server. I choose to [rent a
VPS](https://www.ovhcloud.com/fr/vps/) for a few euros per month. It has a fixed IP address and a decent bandwidth for
our usage. It runs on Debian but there are plenty of operating systems available.

The OpenVPN certificate management can be a bit disturbing at first. I use my monitoring host as CA[^1] to keep trust at
home and every host has its own client certificate. I've set static IP addressing up to always assign the same address
to clients. I've enabled direct communication between clients because storage servers will send snapshots to each
others. I didn't configure clients to forward all their packets to the VPN server because the goal here is not to hide
behind it for privacy.

I have changed the following settings on the VPN server:

```
topology subnet                                 ; declare a subnet like home
server 10.xx.xx.xx 255.xx.xx.xx                 ; with the range you like
client-to-client                                ; allow clients to talk to each other
client-config-dir /etc/openvpn/ccd              ; static IP configuration per client
ifconfig-pool-persist /var/log/openvpn/ipp.txt  ; IP lease settings
```

Example of *ipp.txt* file:

```
storage1,10.xx.xx.xx
storage2,10.yy.yy.yy
storage3,10.zz.zz.zz
```

Example of */etc/openvpn/ccd/storage1.user* file:

```
ifconfig-push 10.xx.xx.xx 255.xx.xx.xx
```

The network configuration declared in *client-config-dir* must match the one in *ipp.txt*.

The configuration generated by the *make_config.sh* script (see the tutorial mentioned above) can be written to:
* */etc/openvpn/client.conf* (Debian)
* */usr/local/etc/openvpn/openvpn.conf* (FreeBSD)

When the OpenVPN service is started, you should be able to see the tun interface up and running.

```
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
	options=80000<LINKSTATE>
	inet6 fe80::xxxx:xxxx:xxxx:xxxx%tun0 prefixlen 64 scopeid 0x3
	inet 10.xx.xx.xx --> 10.xx.xx.xx netmask 0xffffff00
	groups: tun
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	Opened by PID 962
```
```
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none 
    inet 10.xx.xx.xx/xx brd 10.xx.xx.xx scope global tun0
       valid_lft forever preferred_lft forever
```

Et voilà! Every server is now part of a private network:

```
monitoring ~ # nmap -sn 10.xx.xx.xx/xx
Starting Nmap 7.70 ( https://nmap.org ) at 2020-07-13 17:28 CEST
Nmap scan report for vps (10.xx.xx.xx)
Host is up (0.018s latency).
Nmap scan report for 10.xx.xx.xx
Host is up (0.032s latency).
Nmap scan report for 10.xx.xx.xx
Host is up (0.24s latency).
Nmap scan report for 10.xx.xx.xx
Host is up (0.22s latency).
Nmap scan report for 10.xx.xx.xx
Host is up.
Nmap done: xx IP addresses (5 hosts up) scanned in 13.11 seconds
```

[^1]: [Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)
