Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Setup a network namespace with Internet access
#!/usr/bin/env bash
set -x
NS="ns1"
VETH="veth1"
VPEER="vpeer1"
VETH_ADDR="10.200.1.1"
VPEER_ADDR="10.200.1.2"
if [[ $EUID -ne 0 ]]; then
echo "You must be root to run this script"
exit 1
fi
# 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 eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o ${VETH} -j ACCEPT
iptables -A FORWARD -o eth0 -i ${VETH} -j ACCEPT
# Get into namespace
ip netns exec ${NS} /bin/bash --rcfile <(echo "PS1=\"${NS}> \"")
@purpletech77

This comment has been minimized.

Copy link

commented Nov 9, 2016

Hi,
Iam able to ping the host IP with your script from ns1, but Iam not able to ping outside of the host - Any idea ?

Thanks .

@andrew160

This comment has been minimized.

Copy link

commented Nov 25, 2016

@purpletech77 Make sure you got the interface name right. For me it was enp0s3, and not eth0. Now it works perfectly 😄

@markododa

This comment has been minimized.

Copy link

commented Feb 3, 2017

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

@EJohnF

This comment has been minimized.

Copy link

commented Feb 15, 2017

It works fine for me if change row 49:
iptables -t nat -A POSTROUTING -s ${VPEER_ADDR}/24 -o eth0 -j MASQUERADE
to
iptables -t nat -A POSTROUTING -s ${VETH_ADDR}/24 -o eth0 -j MASQUERADE

And it's logically true. In this row you set up the iptable routing. And try to connect eth0 with virtual interface.
But, VPEER_ADDR - locate in the ns1 network namespace while VETH_ADDR in global(default).

Am I right that it's a mistake in that row?

@aneeshdurg

This comment has been minimized.

Copy link

commented Sep 12, 2018

I don't think that row makes a difference, it's only looking at the prefix, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.