Skip to main content
stinky.blog

OpenVPN inside LXC container

Why not Wireguard #

My little qbittorrent container has been chugging along for a couple years now, happily connected to its VPN over wireguard. It has worked great! ...Until now.

Recently I noticed that it was suddenly struggling to maintain connections. Even extremely active torrents were stalling out completely -- 0 peers connected, 0 seeds connected. Not sure what exactly has changed with how the VPN routes traffic to cause this, but I needed to correct it. No more passive peering for me, time to set up port forwarding the right way.

My VPN provider does offer port forwarding for Wireguard, but only within their little app. I'm not using the app. I have purchased a static IP from them and I connect directly. They only support OpenVPN for port forwarding in this situation.

Why it doesn't work #

Just like with samba/nfs and gpu transcoding, LXC containers need to be privileged in order to access certain kernel modules. OpenVPN creates a new device in /dev/net/tun using kernel module "tun" -- that ain't gonna work in a LXC.

Googling it brings up various methods involving adding lines to your LXC config file in /etc/pve on the Proxmox host and then doing some user masking similar to samba/nfs. I didn't have to do any of that. All I had to do was add /dev/net/tun as a passthrough device in the "Resources" section of the LXC options.

The steps #

Install openvpn in the container

apt install openvpn

Generate config file or download from VPN provider, place file in:

/etc/openvpn/[yourfile].conf

Make a credentials file

nano /etc/openvpn/creds

Use this format:

username
password

Save the file and secure it:

chmod 600 /etc/openvpn/creds

Add the location of your credentials file to your OpenVPN config:

nano /etc/openvpn/[yourfile].conf

Look for "auth-user-pass" and add the path to the creds file:

auth-user-pass /etc/openvpn/creds

Navigate to the container settings in Proxmox.

Select the "Options" tab.

Click Features --> Enable Nesting and Create Device Nodes

Select the "Resources" tab.

Click Add --> Device Passthrough

Device path: /dev/net/tun --> Click Add

Reboot the container. Test the connection:

openvpn --config /etc/openvpn/[yourfile].conf
2024-05-27 23:48:24 TUN/TAP device tun0 opened

Tadaaaaaaa!


Connect automatically #

Make a systemd timer:

nano /etc/systemd/system/openvpn@yourname.service

With these contents (edit the filename):

[Unit]
Description=OpenVPN connection
After=network.target

[Service]
Type=simple
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/[yourname].conf
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start it:

systemctl daemon-reload
systemctl enable openvpn@yourname
systemctl start openvpn@yourname

Enjoy!