Score:2

Use netns to bind programs to specific IP addresses

ph flag

I have an IP address on my server, say, 192.168.0.3, I want to share in a net namespace, so to run apps there which will only be able to communicate to the internet using that 192.168.0.3.

I can "kind" of get it working with the macvlan device type... except, for having two mac addresses, the gateway will often favor my root or my namespace-bound interface.

Is there a way I could just mirror that IP inside a netns without affecting the external IP?

Here's what I've been trying:

ip netns add myns
ip link add link eth0 name en0 netns myns type macvlan
ip netns exec myns ip link set en0 up
ip netns exec myns ip addr add 192.168.0.3/24 dev en0
ip netns exec myns ip route add default via 192.168.0.1

And then I test with variations of netcat; either listening in a remote host and connecting from inside and outside the namespace, or listening inside and outside the namespace and connecting from the remote host.

With macvlan it is unreliable just because the immediate router will send packets to a mac address or the other, I need to reset the cached mac in the router (by sending a packet) before I can switch between the physical or macvlan interface. While this is understandable, I am missing a way to let the IPs be "shared" instead of "fought over".

My motivation for that is that I have just a few IPs in my server, and each already listen to services (that properly allows you to bind to specific IP/ports). And then I'm trying to create a chroot jail which would expose only one of these few IPs to apps running therein. So these jailed apps could bind to any (free) port of these IPs, but won't stand a chance of taking over any other IP addresses in the same server.

(I can think of other options like using LD_PRELOAD, or iptables NAT, but I really think I'm missing just a little to have it working with net namespaces)

A.B avatar
cl flag
A.B
If by "share" you mean the host has the same IP address as the network namespace, then you're just causing a collision by using the same IP address on two systems (consider the network namespace as an other system). Looks like an XY problem with a wrong Y part. You'll have to explain better X: the need to have applications use a specific IP address and why their configuration isn't enough.
ph flag
Yes, I understand this is making a collision, and that's exactly why sometimes it works within the netns and then outside it. What I needed was a means to literally expose the outside .3 IP in the netns, such that apps within it could only bind to it.
Score:1
de flag

You have two options:

  • Give the IP address 192.168.0.3 to an interface in that namespace, and don't use it outside of that namespace. This will allow that namespace to use the full range of ports without fear of collisions. For this, macvlan is a good option.
  • Share the IP address 192.168.0.3 between the host and the namespace. In this case, it has to be the same interface, you can't have separate interfaces using the same IP address on the same network. A solution for this would be to use a veth pair and set up forwarding on the host (making sure to use the correct interface/source address). This is similar to what containers do. That would NOT allow you to run a webserver on port 80 on both the host and the container though.

You can set up the veth pair like this:

# Create namespace
ip netns add myns
ip -n myns link set lo up
# Create devices
ip link add myveth0 type veth peer name myveth1
ip link set myveth0 netns myns
# Set addresses
ip -n myns addr add 10.64.0.1/24 dev myveth0
ip -n myns link set myveth0 up
ip addr add 10.64.0.2/24 dev myveth1
ip link set myveth1 up
# Enable forwarding between netns and outside network (customize the rules as needed)
sysctl -w net.ipv4.ip_forward=1
iptables -t filter -A FORWARD -i myveth1 -j ACCEPT
iptables -t filter -A FORWARD -o myveth1 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.64.0.0/24 -j MASQUERADE
ph flag
Your second option is exactly what I wanted to do but couldn't find a way to. The first option you mentioned is what I am able to do but can't, because I already use the IP outside the netns. I just wanted to use the netns like a "mask" to expose only a range (or a single) IP address I have outside. I don't understand what you mean with _"use a veth pair and set up forwarding"_, at first it sounds exactly what I want to avoid (different IPs within the netns).
de flag
Sure, I added instructions for that. This will create a private interface with a private IP address in the namespace. Then you can forward packets on the host between the namespace and the outside network, using whatever routing and filtering rules you need. The problem w.r.t your initial request is that the namespace sees that private IP address, not `192.168.0.3`.
ph flag
Thanks for sharing the alternative. This is exactly what I meant with _iptables NAT_ and _conceptually_ what Docker containers do to make services accessible from outside. I'm actually using the `LD_PRELOAD` alternative but still looking forward to a possibility to just use the same IP through different namespaces, if that's possible somehow.
de flag
Same address in different namespaces... why not just use a single namespace for all your jails? What are you namespacing? They have to share a single namespace of UDP and TCP ports if they use the same IP address, because of how those protocols work.
ph flag
Because I need 192.168.0.3 also to programs outside the netns, that could bind to that IP and (hypotetically) another 192.168.0.2 address -- that I don't want jailed apps to be able to see or bind to. And I'll still want to get "address already in use" in case, from either netns, I try to bind to an already used port. That's a problem the iptables solution can't solve (yet the `LD_PRELOAD` one does).
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.