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?

poige
  • 6,195
  • 2
  • 30
  • 57
  • 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 04: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
    " 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 09:15

1 Answers1

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.

Steven D
  • 45,310
  • 13
  • 119
  • 114
  • 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