This is an old revision of the document!
WireGuard
WireGuard is a modern VPN tunnel solution…
Concepts
network
tunnel
keys
Installation
You will also need nftables if you plan to do port-forwarding
emerge -v net-vpn/wireguard-tools net-firewall/nftables
Create local host private and public keys:
wg genkey > /etc/wireguard/privatekey wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey
Configuration
Each WireGuard tunnel requires it's own configuration, usually called wg0, wg1…
So, create one file for each tunnel at /etc/wireguard/wg0.conf:
- wg0.conf
[Interface] PrivateKey = << local private key >> Address = 10.100.0.1/24 ListenPort = << my port >> [Peer] PublicKey = << remote end public key >> Endpoint = << peer public IP >>:<< peer port >> AllowedIPs = 10.100.0.2/24 # PersistentKeepAlive = 25
Where:
- You can have as many peers as you need to connect to the local host
- The PrivateKey is the local host private key
- The Address is the local host address on the tunnel subnetwork
- The ListenPort is the port on which the local host can be reached from the peers. This can be omitted if the local host is not reacheable from the peers, in this case the local hosts will connect to the peers.
- The PublicKey is the remote host public key
- The Endpoint is the peer public IP, omit if the peer cannot be reached from the local host, in this case the peers will connect to the localhost.
- The peer port is the ListenPort of the peer
- The AllowedIPs limits which hosts can send data to the local host, in case you have more than one machine connecting trough the peer
- The PersistentKeepAlive is usefull to help keep the tunnel connected by sending a keekalive e forcing a reconnection.
Each peer (host) connecting to the WireGuard tunnel will need one of these files. If you have two hosts (tipycal setup), assume that you need two wgX.conf files, one located on each host. These pair of configuration files will need to symmetrical to each other.
Link the startup scripts and set it to start on boot:
ln -s /etc/init.d/wg-quick /etc/init.d/wg-quick.wg0 rc-update add wg-quick.wg0 default
Port Forwarding
For more details in NFTables, see here.
I will assume that you have one internal host and one external host connected trough WireGuard tunnel, already setup like described above.
The goal is having port 2022 of the external server redirect to port 22 of the internal server torugh the WireGuard tunnel so that you can SSH inside your internal server from outside, seamlessly.
I assume your external server has an interface called enp1s0, it's WireGuard interface is wg0 and the WireGuard subnet mask is 10.100.0.0/24, with 10.100.0.2 being the external server and 10.100.0.1 the internal server.
What we need:
- A dedicated table called wg
- A prerouting chain to apply DNAT to incoming packes on port 2022 to the wg tunnel port 22
- A postrouting chain to ensure that all reply packets are properly SNAT back to outside
Create the wg table:
nft add table ip wg
Create the base chains:
nft 'add chain ip wg ssh-in { type nat hook prerouting priority -100 ; }' nft 'add chain ip wg ssh-out { type nat hook postrouting priority 100 ; }'
Create the SNAT return rule: <code bash>
nft add rule ip wg prerouting tcp dport 2022 dnat to 10.70.0.1 dport 22 nft add rule ip wg prerouting tcp dport 22 dnat to 10.70.0.1
nft add rule ip wg postrouting ip daddr 10.70.0.1 masquerade
nft add ip wg prerouting 'dnat to tcp dport map { 2022 : 10.70.0.1 . 22 }'