I have a program I would like to test in offline mode without taking down my actual network. This program would still need to connect to local sockets, including unix domain sockets and loopback. It also needs to listen on loopback and be visible to other apps.

But attempts to connect to a remote machine should fail.

I'd like to have a utility that works like strace/unshare/sudo and simply runs a command with the Internet (and LAN) concealed and everything else still working:

$ offline my-program-to-test

This question has hints at the answer: Block network access of a process?

There are a couple of suggestions there, such as run as another user then manipulate iptables, or unshare -n. But in both cases I don't know the incantation to get unix domain sockets and loopback to be shared with the main system - the answers to that question only tell me how to unshare the entire network.

The program I'm testing still needs to connect to my X server and dbus and even be able to listen on loopback for connections from other apps on the system.

Ideally I'd like to avoid creating chroots or users or VMs or the like, since it becomes just as annoying as unplugging the network cable is. i.e. the point of the question is how can I make this as simple as a sudo.

I'd love the process to run 100% normally except that network calls specifying a non-local address would fail. Ideally keeping the same uid, same homedir, same pwd, same everything except ... offline.

I'm using Fedora 18, so unportable Linux answers are just fine (expected, even).

I'm even happy to solve this by writing a C program, if that's what's involved, so answers that involve writing C are fine. I just don't know what syscalls that C program would need to make to revoke the external network access while keeping local network.

Any developer trying to support "offline mode" would probably appreciate this utility!


The traditional answer is to run the program as another user and use iptables -m owner. That way, the network configuration is shared. However, with the advent of namespaces, there is an easier way.

With namespaces, you unshare the network, then create a virtual network link if you need limited network access.

To share unix domain sockets, all you need is to have a recent enough kernel, after this 2010 patch, so 2.6.36 or above (which is the case on all current distributions at the time of writing except RHEL/CentOS).

Run the program in its own IP namespace. Before starting the program, establish a virtual ethernet interface. There doesn't seem to be much documentation; I found the right incantation in a few blogs:

In the snippet below, I use the ns_exec is the this wrapper around setns listed in the man page to bring up the host side of the network link from the process running in the restricted namespace. You don't actually need this: you can set up the host side of the link from outside the restricted namespace. Doing it from inside merely facilitate the flow control, otherwise you need some synchronization to set up the link after it's been established but before starting your program.

unshare -n -- sh -c '
  # Create a virtual ethernet interface called "confined",
  # with the other end called "global" in the namespace of PID 1
  ip link add confined type veth peer name global netns 1

  # Bring up the confined end of the network link
  ip addr add dev confined
  ip link set confined up

  # Bring up the global end of the network link
  ns_exec /proc/1/ns/net ifconfig global netmask up

  # Execute the test program
  exec sudo -E -u "$TARGET_USER" "$0" "$@"
' /path/to/program --argument

You need to do all of this as root. The introduction of user namespaces in kernel 3.8 may make this doable with no special permissions, except setting up the global end of the network link.

I don't know how to share localhost between the two namespaces. Virtual ethernet interfaces create a point-to-point bridge. You can use iptables forwarding rules to redirect traffic from/to lo if desired.

| improve this answer | |
  • Good additional info, thanks. I think veth gives me a link to "outside" the namespace but my new namespace still amounts to a separate network node, rather than the same network node minus the non-local interfaces. Implications are (?): Unix domain / abstract sockets would still fail, and loopback could be forwarded via iptables, but forwarding doesn't achieve sharing - that is, both original and restricted namespace may be listening on loopback and both sets of (dynamically-changing) ports would need to be visible in both namespaces... starting to guess what I want is impossible here :-/ – Havoc P Oct 17 '13 at 14:03

This can be also be achieved with iptables rule matching cgroups. I wrote a tool to abstract the steps. While it requires root-permissions for the initial setup and is otherwise a setuid binary, I think it offers a fairly straightforward way to deal with the problem in the question. It requires an iptables version that's recent enough and that the proper netfilter modules are available.


| improve this answer | |

/!!\ This is probably not a valid answer as this will take all of your traffic down with you, not just a single pid's traffic.

I've not used it, but I think you could potentially use Comcast:


set to 100% packet loss

Again, I've not tested this, but theoretically, modified from their readme you can do:


On Linux, you can use iptables to drop incoming and outgoing packets.

$ iptables -A INPUT -m statistic --mode random --probability 1 -j DROP
$ iptables -A OUTPUT -m statistic --mode random --probability 1 -j DROP

Alternatively, you can use tc which supports some additional options.

$ tc qdisc change dev eth0 root netem reorder 0 duplicate 0 corrupt 1

To reset:

$ tc qdisc del dev eth0 root netem
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.