I've been working on writing my own Linux container from scratch in C. I've borrowed code from several places and put up a basic version with namespaces & cgroups.

Basically, I clone a new process with all the CLONE_NEW* flags to create new namespaces for the clone'ed process.

I also set up UID mapping by inserting 0 0 1000 into the uid_map and gid_map files. I want to ensure that the root inside the container is mapped to the root outside.

For the filesystem, I am using a base image of stretch created with debootstrap.

Now, I am trying to set up the network connectivity from inside the container. I used this script to setup the interface inside the container. This script creates a new network-namespace of its own. I edited it slightly to mount the net-namespace of the created process onto the newly created net-namespace via the script.

mount --bind /proc/$PID/ns/net /var/run/netns/demo

I can just get into the new network namespace as follows:

ip netns exec ${NS} /bin/bash --rcfile <(echo "PS1=\"${NS}> \"")

and successfully ping outside.

But from the bash shell when I get inside the clone'ed process by default I am unable to PING. I get the error:

ping: socket: Operation not permitted

I've tried setting up capabilities: cap_net_raw and cap_net_admin

I would like some guidance.


I would prefer to work from a more complete specification. However from careful reading of the script and your description, I conclude you are entering a network namespace (using the script) first, and entering a user namespace afterwards.

The netns is owned by the initial userns, not your child userns. To do ping, you need cap_net_raw in the userns that owns the netns. I think.

There is a similar answer here, which provides links to reference documentation: Linux Capabilities with User Namespaces

(I think ping can also work without privilege if you have access to ICMP sockets. But at least on my Fedora 29, this does not seem to be used. Unprivileged cp "$(which ping)" && ping localhost shows the same socket: Operation not permitted. Not sure why it has not been adopted).

  • This indeed guided me towards the right answer. So in my code, I had cloned with all the flags and unshare(CLONE_NEWUSER) later since I had to set up things like mount points. When I moved the CLONE_NEWNET also to the unshare call after the clone() it worked as expected. – Shabirmean Jan 22 at 3:19

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.