Here I explain how I had specfic app(s) be in network namespace in linux and have a proxy (cloudflare-warp) route the traffic to act like a vpn
Skip steps and run script setup-namespace.sh then edit the service using sudo systemctl edit warp-svc.service by adding
[Service]
NetworkNamespacePath=/var/run/netns/discordns
PrivateNetwork=true
Run sudo systemctl restart warp-svc.service
Run discord in the namespace (or any app) via run-discord
To remove all setup run cleanup.sh
Had to do because discord got banned in jordan and can only access it via a vpn but since I am running arch linux with sway not all vpns with split tunneling always work and rialiable.
variables:
NAMESPACE="discordns"
VETH_HOST="veth-discord"
VETH_NS="veth-discord-ns"
HOST_IP="10.200.1.1"
NS_IP="10.200.1.2"Run warp service
sudo systemctl start warp-svc.serviceCreate directory for the namespace
sudo mkdir -p /etc/netns/discordnsCopy your DNS config
sudo cp /etc/resolv.conf /etc/netns/discordns/resolv.confCreate namespace
sudo ip netns add $NAMESPACECreate veth pair
sudo ip link add $VETH_HOST type veth peer name $VETH_NSMove interface to the namespace
sudo ip link set $VETH_NS netns $NAMESPACEAssigns IP address HOST_IP to VETH_HOST interface on the host
sudo ip addr add ${HOST_IP}/24 dev $VETH_HOSTBrings up the interface VETH_HOST
sudo ip link set $VETH_HOST upits like the host virtual cable end now has the address HOST_IP
Configure namespace side, setting IP and bring up on the namespace side (other end of the cable)
sudo ip netns exec $NAMESPACE ip addr add ${NS_IP}/24 dev $VETH_NS
sudo ip netns exec $NAMESPACE ip link set $VETH_NS upits like the namespace virtual cable end now has the address NS_IP
bring up the lo interface
sudo ip netns exec $NAMESPACE ip link set lo upAdd default route in namespace
sudo ip netns exec $NAMESPACE ip route add default via $HOST_IPEnable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1get internet interface from routing table br0 my case
INET_IFACE=$(ip route | grep default | awk '{print $5}' | head -n1)the MASQUERADE Rule
sudo iptables -t nat -A POSTROUTING -s ${NS_IP}/24 -o $INET_IFACE -j MASQUERADEWhy ? because:
Before NAT:
┌─────────────┐
│ Packet from │
│ 10.200.1.2 │ ──► To: google.com
└─────────────┘
After MASQUERADE:
┌─────────────┐
│ Packet from │
│ YOUR_HOST_IP│ ──► To: google.com
└─────────────┘
forward rules:
Allow packets coming FROM the internet TO the namespace
sudo iptables -A FORWARD -i $INET_IFACE -o $VETH_HOST -j ACCEPTAllow packets coming FROM the internet TO the namespace
sudo iptables -A FORWARD -o $INET_IFACE -i $VETH_HOST -j ACCEPTfull flow
┌─────────────────────────────────────────────────────-─────────┐
│ HOST SYSTEM │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ NAMESPACE "discordns" │ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ │ │ Discord │ │ │
│ │ │ App │ │ │
│ │ └────┬─────┘ │ │
│ │ │ Unencrypted traffic │ │
│ │ │ (thinks it's going to discord.com) │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Warp Client │ ← Running in namespace │ │
│ │ │ (encrypts & │ │ │
│ │ │ tunnels) │ │ │
│ │ └──────┬───────┘ │ │
│ │ │ Encrypted traffic │ │
│ │ │ (wrapped for Cloudflare) │ │
│ │ ▼ │ │
│ │ ┌────────────────┐ │ │
│ │ │ veth-discord-ns│ │ │
│ │ │ 10.200.1.2 │◄────────────────────────────────┐ │ │
│ │ └────────┬───────┘ │ │ │
│ │ │ │ │ │
│ └───────────┼─────────────────────────────────────────┼───┘ │
│ │ │ │
│ │ Virtual ethernet "cable" │ │
│ │ │ │
│ ┌──────▼───────┐ │ │
│ │ veth-discord │ │ │
│ │ 10.200.1.1 │ │ │
│ └──────┬───────┘ │ │
│ │ │ │
│ │ NAT/MASQUERADE │ │
│ │ (10.200.1.2 → YOUR_PUBLIC_IP) │ │
│ ▼ │ │
│ ┌─────────────┐ │ │
│ │ wlan0/eth0 │ │ │
│ │ (Internet) │ │ │
│ └──────┬──────┘ │ │
│ │ │ │
└──────────────┼─────────────────────────────────────────┼──────┘
│ │
│ Encrypted traffic to Cloudflare │
▼ │
┌──────────┐ │
│ Internet │ │
│ Router │ │
└─────┬────┘ │
│ │
▼ │
┌────────────────┐ │
│ Cloudflare │ │
│ Network │ │
│ (Warp Edge) │ │
└────────┬───────┘ │
│ Decrypts & forwards │
▼ │
┌──────────┐ │
│discord.com│ │
└───────────┘ │
│
Reply path ───────────────────────────────┘
Modify the warp service to run only in the namespace
[Service]
NetworkNamespacePath=/var/run/netns/discordns
PrivateNetwork=true
Restart the servcie
sudo systemctl restart warp-svc.serviceFinally run your app mine is discord
sudo ip netns exec discordns sudo -u $USER \
XDG_RUNTIME_DIR=/run/user/$(id -u) \
WAYLAND_DISPLAY=$WAYLAND_DISPLAY \
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus \
discordfor cleanup check cleanup.md