3.0.1 - openvpn server in unprivilged container

TL;DR some pointers for those interested to deploy an openvpn server in an unprivilged container


  • host ubuntu bionic 4.15.0-23
    lxc 3.0.1
    dnsmasq 2.79
  • container gentoo
    netifrc
    nftables 0.8.3
    openvpn 2.4.6

as baseline it assumed that host’s and container’s network are working.

  • this example is set with TUN UDP4 only. TCP4/6 | UDPv6 may require additional steps but certainly some alterations
  • TAP been tried but did not work out (something about gateway information going wrong)
  • any IP addresses/ranges, bridge names, mac addresses stated below are specifics of this setup and may require tailoring to other particular network environments

  1. dnsmasq on host - assign static ip to the container’s veth iface (alternative to the mac address can be the container’s name space)

    dhcp-range=br3,172.25.120.0,static
    dhcp-host=00:16:3e:88:b0:c5,172.25.120.2

  2. enable container access to kernel’s netdev tun (which though weakens the security of the unpriviliged environment!)

  • in the container mkdir -p /dev/net/tun

  • shut down the container

  • add to the container’s conf

    lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file 0 0

  1. in the host add nf rule to open (accept) openvpn udp port on the wan

  2. in the host add nf rule (nat prerouting dnat) to foward opvpn udp port from the wan ip to the container lan ip (172.25.120.1)

  3. in the container add nf rule to NAT (postrouting masquerade) for the container’s ethernet iface

  4. add TUN ifcae in the container’s network (/etc/conf.d/net)

    tuntap_tun0="tun"
    config_tun0="null"

    and then from cli

    ln -s /etc/init.d/net.lo /etc/init.d/net.tun0
    rc-update add net.tun0 default

  5. ensure forwarding is enabled in the container

    net.ipv4.ip_forward=1

  6. openvpn server conf (important that the openvpn server’s subnet is different from the container’s)

    dev tun0
    proto udp4
    local 172.25.120.2
    server 172.25.121.0 255.255.255.0
    topology subnet
    push "route 172.25.0.0 255.255.0.0"


In case the keys/certs pertinent to openvpn server conf are lcated on the host and not the container than the respective lxc.mount.entry have to be added to the container conf and mirroring directories created on the container and access to be granted to the keys/certs to the user of the unprivilged container user (setfacl -m u:100000:r )