Network namespaces isolate your network stack
You are testing a new firewall rule and you do not want to lock yourself out of your own machine. Or you are debugging a script that binds to a specific interface and you need a clean slate. Or you just want to see how routing works without touching your production network. Network namespaces give you that isolation. You get a private network stack inside your running Fedora system. The host keeps its connections. The namespace gets its own interfaces, routes, and rules.
What is actually happening
Think of a network namespace as a separate apartment in a shared building. The building is your kernel. The plumbing is duplicated for each apartment. You can have a sink in apartment A and a sink in apartment B. They look the same, but they are independent. Water flowing into apartment A does not flood apartment B.
In Linux terms, the kernel allocates a new set of data structures for interfaces, routing tables, and iptables rules. The ip command from the iproute package is the tool that manipulates these structures. Fedora ships iproute by default, so you have everything you need. No extra packages to install.
Network namespaces are volatile. They live in memory. A reboot destroys them. Use them for testing, development, or temporary isolation. Write automation if you need them to survive a restart.
Create and inspect a namespace
Here is how to create a namespace and check its initial state.
sudo ip netns add testns # Creates a new isolated network stack named testns
ip netns list # Lists all active namespaces; output shows testns
sudo ip netns exec testns ip addr # Runs ip addr inside testns to see interfaces
The output of ip addr inside the namespace shows only one interface: lo. That is the loopback interface. It is down by default. You cannot do anything until you bring it up. Many tools fail silently or crash if the loopback is down.
Here is how to bring the loopback interface up inside the namespace.
sudo ip netns exec testns ip link set lo up # Enables loopback; required for most network tools
The command ip netns exec runs a command in the context of the namespace. It is the standard way to interact with namespaces. You can run bash inside it for an interactive shell, but exec is safer for scripts because it does not leave orphaned shells running in the background.
Run ip netns list to see the namespace name and the PID of the last process that entered it. If the PID is 0, no process is currently inside. The namespace exists, but it is idle.
Connect a namespace to the host
A namespace is useless if it cannot talk to anything. You need a pipe to connect it to the host or another namespace. Virtual Ethernet pairs provide that pipe. A veth pair is a tunnel with two ends. One end stays on the host. The other end moves into the namespace. Traffic sent into one end comes out the other.
Here is how to create a veth pair, move one end into the namespace, and assign IP addresses.
sudo ip link add veth0 type veth peer name veth1 # Creates a pipe; veth0 stays on host, veth1 is the peer
sudo ip link set veth1 netns testns # Moves veth1 into the namespace; the pipe connects host to testns
sudo ip addr add 10.200.0.1/24 dev veth0 # Assigns IP to host side of the pipe
sudo ip link set veth0 up # Brings host interface up; traffic can now flow
sudo ip netns exec testns ip addr add 10.200.0.2/24 dev veth1 # Assigns IP to namespace side
sudo ip netns exec testns ip link set veth1 up # Brings namespace interface up
Use unique names for your veth pairs. If you run this multiple times, veth0 will conflict. Names like veth-testns-0 prevent collisions and make debugging easier.
Here is how to verify the connection works by pinging the host from the namespace.
sudo ip netns exec testns ping -c 3 10.200.0.1 # Pings host IP; expect 3 replies
Ping the host first. If the veth pair is broken, nothing else will work.
Add internet access via NAT
The namespace can talk to the host, but it needs the internet. You need to enable forwarding on the host and masquerade the traffic so the outside world sees the host's IP.
Enable IP forwarding and add a masquerade rule to give the namespace outbound internet access.
sudo sysctl -w net.ipv4.ip_forward=1 # Allows host to route packets between interfaces
sudo firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.200.0.0/24 -j MASQUERADE # Hides namespace IP behind host IP
sudo firewall-cmd --reload # Applies firewall changes; runtime and persistent configs must match
sudo ip netns exec testns ip route add default via 10.200.0.1 # Sets default gateway to host side of veth
The sysctl command changes are runtime only. Fedora uses sysctl.d drop-ins for persistence, but for a quick test, -w is fine. The firewall-cmd --reload step is mandatory. A rule added via --direct does not take effect until the firewall reloads.
Here is how to test external connectivity from the namespace.
sudo ip netns exec testns ping -c 3 8.8.8.8 # Pings external IP; confirms NAT is working
Reload the firewall. A masquerade rule that sits in the config but not in the runtime is a ghost rule.
Fix DNS resolution
The namespace does not inherit the host's DNS configuration. You will get ping: unknown host even if routing works. The kernel does not copy /etc/resolv.conf into the namespace.
Here is how to provide DNS configuration to the namespace using the standard glibc mechanism.
sudo mkdir -p /etc/netns/testns # Creates directory for namespace-specific config
sudo cp /etc/resolv.conf /etc/netns/testns/resolv.conf # Copies DNS config; glibc reads this automatically
sudo ip netns exec testns ping -c 3 fedoraproject.org # Tests DNS resolution inside namespace
This /etc/netns/ trick is a glibc feature, not a kernel feature. It works for C-based tools and anything linked against glibc. Python or Go binaries might need explicit DNS flags if they do not use glibc for name resolution.
Copy resolv.conf to /etc/netns. DNS failures are the most common reason namespaces look broken.
Common pitfalls and errors
If you see Cannot find device "veth1" after moving it, the move failed. Check that the namespace exists with ip netns list. The device might have been created in the wrong namespace if you typed the name incorrectly.
If ping returns Network is unreachable, the default route is missing or the gateway is down. Run ip route inside the namespace to check. The output should show a default route pointing to the host side of the veth pair.
If you get Permission denied on ip netns exec, you are missing sudo. Network namespace operations require root privileges. The ip command needs to modify kernel data structures.
If journalctl -xe shows NF_DROP messages, the firewall is blocking traffic. Check your firewall-cmd rules. SELinux rarely interferes with ip netns commands, but if you see denials in journalctl -t setroubleshoot, read the summary before disabling enforcement.
Run journalctl -xe first. Read the actual error before guessing.
Persistence and cleanup
Commands vanish on reboot. To make a namespace survive a restart, you need a systemd service or a NetworkManager dispatcher script. Fedora does not persist ip netns state by default. Write the automation yourself.
Here is how to remove the namespace when you are done.
sudo ip netns del testns # Deletes namespace and all interfaces inside it
Deleting the namespace also destroys all virtual interfaces that belong to it. The host side of the veth pair (veth0) remains on the host. You must delete it manually if you want a clean state.
Delete the namespace. Orphaned veth pairs on the host can leak resources and confuse routing.
When to use network namespaces
Use network namespaces when you need to isolate network stacks for testing or development without rebooting. Use containers when you need process isolation along with network isolation and a simplified lifecycle. Use virtual machines when you require a full guest kernel and hardware emulation. Use NetworkManager bridges when you need to share a physical interface with multiple services or guests. Stick to the host network when you are running a simple service that only needs to listen on a specific port.