Setup nextcloud like a static ip without a static ip
Your ISP probably offers no static ip in your typical consumer plan, but with wireguard we can solve this problem.
We can buy a cheap virtual server online. I found one for 2,89 € at hetzner.de with 20 TB traffic included per month. It is there CX11 cloud offering. This is plenty for basicly everything a private person wants to do online. You could even stream movies from home with that kind of traffic. I just want to host a nextcloud and maybe this blog at home.
What we need:
-
online server with static ip, root access and ssh (most servers have that)
-
wireguard (easiest to choose something with a modern kernel e.g. ubuntu 20.04)
Setup a connection between the home server and the online server
we use an ubuntu 20.04 server in this example
First we install wireguard on a fresh server
apt udpate
apt upgrade
apt install wireguard wireguard-tools
We need to generate key pairs for the server and our home server. The following need to be executed one both machines.
cd /etc/wireguard/
wg genkey | tee privatekey | wg pubkey > publickey
We need to add a file /etc/wireguard/wg0.conf with the following content. The privatekey needs to be filled in.
Server
[Interface]
PrivateKey = <insert-server-private-key-here>
ListenPort = 55107
Address = 192.168.4.1
[Peer]
PublicKey = <insert-public-key-for-client-here>
AllowedIPs = 192.168.4.2/32
Client
[Interface]
PrivateKey = <insert-client-private-key-here>
Address = 192.168.4.2/32
[Peer]
PublicKey = <insert-public-key-for-server-here>
AllowedIPs = 192.168.4.1/32
Endpoint = <ip-of-the-server>:55107
PersistentKeepalive = 25
Now we want to start and autostart on reboots the wireguard connection
systemctl start wg-quick@wg0
systemctl enable wg-quick@wg0
To verify if the connection works as expected you can try to ping the server from the client.
ping 192.168.4.1
Setup routing so the server moves traffic to the home server
Lets assume we want to route traffic for http (port 80) from the server to our home server.
We need to modifiy the routing table with iptables
.
iptables -P FORWARD DROP
iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
First we disable any forwarding that might exist.
Second we set incoming packages on eth0 to be forwarded to wg0 for port 80 for any package that tries to make a new connection
Third with the last two lines we allow any traffic from wg0 and eth0 to pass through that is related to a connection
We still have one problem. The actually network package contains faulty ip address since the internet does not know that we have a home server behind the server. So we need to adjust the ip addresses.
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.3.4
This will transform the ip for any incoming package to the online server. Note that we set the destination ip to the ip we gave it in the wireguard setup.
iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport 80 -d 192.168.3.4 -j SNAT --to-source 192.168.3.1
Now any package from our homeserver will get sent back to our online server which handles the rest.
Persist rules during reboot
Iptables forgets during a shutdown any custom rules. There is a package netfilter-persistent
which solves this problem
apt install iptables-persistent netfilter-persistent
systemctl enable netfilter-persistent
netfilter-persistent save
If there are any changes to the routing we need to call netfilter-persistent save
again to store the new rules on disk.