Skip to content

Instantly share code, notes, and snippets.

@dpino
Last active April 19, 2024 18:12
Show Gist options
  • Save dpino/6c0dca1742093346461e11aa8f608a99 to your computer and use it in GitHub Desktop.
Save dpino/6c0dca1742093346461e11aa8f608a99 to your computer and use it in GitHub Desktop.
Setup a network namespace with Internet access
#!/usr/bin/env bash
# set -x
if [[ $EUID -ne 0 ]]; then
echo "You must be root to run this script"
exit 1
fi
# Returns all available interfaces, except "lo" and "veth*".
available_interfaces()
{
local ret=()
local ifaces=$(ip li sh | cut -d " " -f 2 | tr "\n" " ")
read -a arr <<< "$ifaces"
for each in "${arr[@]}"; do
each=${each::-1}
if [[ ${each} != "lo" && ${each} != veth* ]]; then
ret+=( "$each" )
fi
done
echo ${ret[@]}
}
IFACE="$1"
if [[ -z "$IFACE" ]]; then
ifaces=($(available_interfaces))
if [[ ${#ifaces[@]} -gt 0 ]]; then
IFACE=${ifaces[0]}
echo "Using interface $IFACE"
else
echo "Usage: ./ns-inet <IFACE>"
exit 1
fi
fi
NS="ns1"
VETH="veth1"
VPEER="vpeer1"
VETH_ADDR="10.200.1.1"
VPEER_ADDR="10.200.1.2"
trap cleanup EXIT
cleanup()
{
ip li delete ${VETH} 2>/dev/null
}
# Remove namespace if it exists.
ip netns del $NS &>/dev/null
# Create namespace
ip netns add $NS
# Create veth link.
ip link add ${VETH} type veth peer name ${VPEER}
# Add peer-1 to NS.
ip link set ${VPEER} netns $NS
# Setup IP address of ${VETH}.
ip addr add ${VETH_ADDR}/24 dev ${VETH}
ip link set ${VETH} up
# Setup IP ${VPEER}.
ip netns exec $NS ip addr add ${VPEER_ADDR}/24 dev ${VPEER}
ip netns exec $NS ip link set ${VPEER} up
ip netns exec $NS ip link set lo up
ip netns exec $NS ip route add default via ${VETH_ADDR}
# Enable IP-forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward
# Flush forward rules.
iptables -P FORWARD DROP
iptables -F FORWARD
# Flush nat rules.
iptables -t nat -F
# Enable masquerading of 10.200.1.0.
iptables -t nat -A POSTROUTING -s ${VPEER_ADDR}/24 -o ${IFACE} -j MASQUERADE
iptables -A FORWARD -i ${IFACE} -o ${VETH} -j ACCEPT
iptables -A FORWARD -o ${IFACE} -i ${VETH} -j ACCEPT
# Get into namespace
ip netns exec ${NS} /bin/bash --rcfile <(echo "PS1=\"${NS}> \"")
@Magicrafter13
Copy link

I tried this script, though I set VETH_ADDR to 192.168.0.1 and VPEER_ADDR to 192.168.0.2.

inside the namespace, I can ping 192.168.0.1, and I can ping my computer's actual ipv4: 10.0.0.199, but I can't ping the gateway 10.0.0.1 from inside the namespace. And it goes without saying, but I also can't ping any internet addresses like 1.1.1.1 for example.

Maybe I have the issue that @oleshii mentioned, though I'm not sure. I have Xfinity, and we currently have their XB6 modem. If their default settings do allow this however, then I'm still not sure what the issue is.

I'm on Manjaro. I don't believe there was any firewall preinstalled.

It's weird too, because, I had it working last night. Not this script specifically, but I followed this guide:
https://blog.laxu.de/2020/04/02/how-use-zoom-sandbox/
Yet after restarting my computer (and running the commands again once I realized my changes hadn't been saved), it doesn't work, which is the main reason I tried this script.

@dpino
Copy link
Author

dpino commented Jan 11, 2021

Considering the feedback from the last comments, I run the script again on my laptop and I can tell it works for me.

$ sudo ./ns-inet.sh 
Using interface wlp59s0
ns1> ping -c 1 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=61 time=2.04 ms

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.044/2.044/2.044/0.000 ms
ns1> ping -c 1 www.google.com
PING www.google.com (172.217.24.36) 56(84) bytes of data.
64 bytes from hkg07s23-in-f36.1e100.net (172.217.24.36): icmp_seq=1 ttl=116 time=6.18 ms

--- www.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.181/6.181/6.181/0.000 ms

@Magicrafter13 the script also works for me using VETH_ADDR and VPEER_ADDR as 192.168.0.1 and 192.168.0.2. Would you mind sharing your routing table (route -n) in the network namespace as well as in the host?

@yangtzeriverli
Copy link

I don't think using different private IP prefix block would cause trouble. @dpino

@tariromukute
Copy link

if the system uses a local dns server (like dnsmasqd on ubuntu ), a resolv.conf needs to be setup for the namespace, for example mkdir -p /etc/netns/ns1/ echo 'nameserver 8.8.8.8' > /etc/netns/ns1/resolv.conf

For anyone else, this resolved my name resolution issue on Ubuntu 22.04. Thanks @markododa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment