11

In FreeBSD 4.9 it was very easy to accomplish with just a single command like

jail [-u username]  path hostname ip-number command

if path was / you had running just the same program as usual but all its network communication was restricted to use only given IP-address as the source. Sometimes it's very handy.

Now in Linux there's LXC, which does look very similar to FreeBSD's jail (or Solaris' zones) — can you think of similar way to execute a program?

  • What program are you trying to do this with? Many programs are configurable enough that they can be told which IP to bind to. – Warren Young Sep 13 '14 at 22:54
  • @WarrenYoung, Thanks K. O., but "many" != "all" – poige Sep 14 '14 at 4:36
  • A good use case for "jailing" an executable to use a specific IP is running multiple game servers on one machine on a LAN party. E.g. Valve games are only broadcasting on ports 27015-27020 so per IP you can only have 6 servers. So you add virtual IP's on a NIC but then you need to specify "+ip <address>" on the game server's command line which stops broadcasting its presence to clients => no servers visible in LAN browser. So "+ip" won't work. Therefore we need to jail each server in an environment where it can only find 1 IP address. Result: no limit in #servers + clients see all servers. – Timmos Jan 17 '17 at 9:15
12

Starting the process inside a network namespace that can only see the desired IP address can accomplish something similar. For instance, supposed I only wanted localhost available to a particular program.

First, I create the network namespace:

ip netns add limitednet

Namespaces have a loopback interface by default, so next I just need to bring it up:

sudo ip netns exec limitednet ip link set lo up

Now, I can run a program using ip netns exec limitednet and it will only be able to see the loopback interface:

sudo ip netns exec limitednet ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

If I wanted to limit it to an address other than localhost, I could add other interfaces into the namespace using:

ip link set DEVICE_NAME netns NAMESPACE

I'd have to experiment a bit more to figure out how to add a single IP address into a namespace in the case where an interface might have more than one IP address

The LWN article on namespaces is also helpful.

  • But it's worth mentioning it would require much more preparations since network namespace has its own routing table and so on. If somebody comes with simpler way to mimic jail, I'm gonna use it. ;) – poige Sep 13 '14 at 20:47

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.