Skip to content

Instantly share code, notes, and snippets.

@brauliobo
Created September 4, 2024 00:30
Show Gist options
  • Save brauliobo/94ac38fe2695f405df2cbd8d0a1da207 to your computer and use it in GitHub Desktop.
Save brauliobo/94ac38fe2695f405df2cbd8d0a1da207 to your computer and use it in GitHub Desktop.
OpenVPN network namespace service and sample unit returning its public IP address
[Unit]
Description=Test NetworkNamespacePath with DynamicUser
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Use DynamicUser to create a temporary user for the service
DynamicUser=true
# Specify the custom network namespace
NetworkNamespacePath=/var/run/netns/vpnspace
# Command to test curl inside the namespace
ExecStart=/usr/bin/curl ifconfig.co
# Set a shorter time for testing purposes
TimeoutSec=30
[Install]
WantedBy=multi-user.target
[Unit]
Description=Setup vpnspace namespace and run OpenVPN client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Pre-cleanup to remove any leftover namespace, interfaces, and routes
ExecStartPre=/bin/bash -c 'ip netns delete vpnspace 2>/dev/null || true'
ExecStartPre=/bin/bash -c 'ip link delete veth0 2>/dev/null || true'
# Create the network namespace and setup veth pair
ExecStartPre=/usr/sbin/ip netns add vpnspace
ExecStartPre=/usr/sbin/ip link add veth0 type veth peer name veth1
ExecStartPre=/usr/sbin/ip link set veth0 up
ExecStartPre=/usr/sbin/ip link set veth1 netns vpnspace
ExecStartPre=/usr/sbin/ip netns exec vpnspace ip link set veth1 up
ExecStartPre=/usr/sbin/ip addr add 10.200.1.1/24 dev veth0
ExecStartPre=/usr/sbin/ip netns exec vpnspace ip addr add 10.200.1.2/24 dev veth1
ExecStartPre=/usr/sbin/ip netns exec vpnspace ip route add default via 10.200.1.1
# Automatically detect the primary network interface for outbound traffic
ExecStartPre=/bin/bash -c 'export OUT_IF=$(ip route | grep "^default" | awk "{print \$5}") && sysctl -w net.ipv4.ip_forward=1 && iptables -t nat -A POSTROUTING -s 10.200.1.0/24 -o $OUT_IF -j MASQUERADE'
# Run OpenVPN inside the vpnspace namespace
ExecStart=/usr/sbin/ip netns exec vpnspace /usr/sbin/openvpn --config /home/braulio/openvpn/9876718C749F90DB_us-mia_openvpn.ovpn
# Clean up the namespace and the veth pair on stop
ExecStop=/usr/sbin/ip netns delete vpnspace || /bin/true
ExecStopPost=/usr/sbin/ip link delete veth0 || /bin/true
# Use 'ExecStopPost' to remove the iptables rules tied to the specific interface
ExecStopPost=/bin/bash -c 'export OUT_IF=$(ip route | grep "^default" | awk "{print \$5}") && iptables -t nat -D POSTROUTING -s 10.200.1.0/24 -o $OUT_IF -j MASQUERADE'
ExecStopPost=/bin/bash -c 'while [ -e /var/run/netns/vpnspace ]; do sleep 0.1; done'
RemainAfterExit=yes
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment