Sign inSign up

yusiwen/openvpn-cli

By yusiwen

•Updated 10 days ago

Alpine OpenVPN client with NAT masquerading — use it as a VPN gateway for your LAN.

Image
Networking
Security
0

67

yusiwen/openvpn-cli repository overview

⁠OpenVPN client container

A small Alpine-based OpenVPN client image. It connects the container to an OpenVPN server using an .ovpn profile and a credentials file, and it also enables NAT masquerading on the tunnel interface, so the container can act as a VPN gateway for other hosts on your LAN — not just for itself.

⁠Features

  • Reads the OpenVPN profile and credentials from a mounted /config directory.
  • Adds iptables NAT masquerading for outbound tun0 traffic, so forwarded packets are rewritten to the VPN-assigned source address.
  • Ships tcpdump and iptables for packet-level troubleshooting inside the container.
  • tini as PID 1, so signals and restarts behave correctly.
  • Credentials are passed with --auth-nocache and are not retained in memory after authentication.

⁠Image

  • yusiwen/openvpn-cli:2.5.8 (platform linux/amd64)
  • Based on ccmpbll/openvpn-client⁠ (Alpine + OpenVPN + bash, curl, jq, tini, speedtest-cli), with tcpdump and iptables added and a custom entrypoint that installs the NAT rule before starting openvpn.
  • The 2.5.8 tag records the OpenVPN version the image was built against.
docker pull yusiwen/openvpn-cli:2.5.8

⁠Usage

Prepare a directory with two files:

config/
├── client.ovpn    # OpenVPN client profile
└── auth.txt       # username and password, one per line

auth.txt must contain exactly two lines:

myCoolUsername
mySuperSecretPassword

Start the container:

docker run -d --name openvpn_client \
  --restart unless-stopped \
  --cap-add=NET_ADMIN \
  --cap-add=NET_RAW \
  --device /dev/net/tun \
  -v /path/to/config:/config:rw \
  -e OPENVPN_CONF=client.ovpn \
  -e OPENVPN_AUTH=auth.txt \
  yusiwen/openvpn-cli:2.5.8

Follow the connection log:

docker logs -f openvpn_client
⁠Environment variables
VariableDefaultDescription
OPENVPN_CONFNONEName of the .ovpn profile inside /config. The container exits if the file is missing.
OPENVPN_AUTHNONEName of the credentials file inside /config. The container exits if the file is missing.
OPENVPN_OPTSemptyExtra arguments appended to the openvpn command line, e.g. --verb 4.
CONFIG_PATH/configDirectory the profile and auth file are read from.

⁠Using the container as a LAN gateway

Because the tunnel is on tun0 and outbound traffic is masqueraded, other machines can route through the container. A common setup is a macvlan network that gives the container a real address on the physical segment:

services:
  vpn:
    image: yusiwen/openvpn-cli:2.5.8
    container_name: openvpn_client
    restart: unless-stopped
    privileged: true
    devices:
      - /dev/net/tun:/dev/net/tun
    volumes:
      - ./config:/config:rw
    environment:
      - OPENVPN_CONF=client.ovpn
      - OPENVPN_AUTH=auth.txt
    sysctls:
      - net.ipv4.ip_forward=1
    networks:
      macvlan:
        ipv4_address: "192.168.1.50"

networks:
  macvlan:
    name: macvlan
    driver: macvlan
    driver_opts:
      parent: eth0
    ipam:
      config:
        - subnet: "192.168.1.0/24"
          ip_range: "192.168.1.0/25"
          gateway: "192.168.1.1"

Then set the default gateway of the client machines to the container address (192.168.1.50 in the example).

Notes:

  • Reserve that address in your router's DHCP pool, or a lease and the container can collide.
  • net.ipv4.ip_forward=1 is required for forwarding; the masquerade rule alone is not enough.
  • Docker hosts generally cannot reach a macvlan container address directly — test from another host on the LAN.
  • Without NAT, --cap-add=NET_ADMIN --cap-add=NET_RAW and /dev/net/tun are sufficient; use privileged: true when you also want the container to route and rewrite traffic on behalf of others.

⁠Troubleshooting

  • Container exits with "config could not be found" — OPENVPN_CONF / OPENVPN_AUTH must match the real file names in /config.
  • Cannot reach anything behind the gateway — check docker exec openvpn_client sysctl net.ipv4.ip_forward and docker exec openvpn_client ip route.
  • Inspect packets — docker exec openvpn_client tcpdump -ni tun0.
  • Inspect the NAT rule — docker exec openvpn_client iptables -t nat -L POSTROUTING -n -v.

⁠Security

  • The container needs /dev/net/tun, and elevated network capabilities for iptables. It can rewrite firewall state; run it only on hosts you control.
  • The credentials file is stored in plain text on the host. Restrict it (chmod 600) and keep it out of version control and out of images.
  • A macvlan address exposes the tunnel to the whole LAN segment. If that is not intended, keep the container on a private bridge network instead.

⁠Credits

Tag summary

Content type

Image

Digest

sha256:31e56f50d…

Size

24.3 MB

Last updated

10 days ago

docker pull yusiwen/openvpn-cli:2.5.8