24

I want to run a program without any internet access, e.g.

unshare -n ping 127.0.0.1.

As an unprivileged user, it returns Operation not permitted, as a privileged user, it returns the desired Network is unreachable.

Is there any way to make it work for the unprivileged user, as well?

clinei
  • 343
  • 1
  • 2
  • 6

3 Answers3

18

In later versions of util-linux, unshare gained the --map-root-user option. Quoting from unshare(1) version 2.26.2:

-r, --map-root-user

Run the program only after the current effective user and group IDs have been mapped to the superuser UID and GID in the newly created user namespace. This makes it possible to conveniently gain capabilities needed to manage various aspects of the newly created namespaces (such as configuring interfaces in the network namespace or mounting filesystems in the mount namespace) even when run unprivileged. As a mere convenience feature, it does not support more sophisticated use cases, such as mapping multiple ranges of UIDs and GIDs. This option implies --setgroups=deny.

So, on newer systems, you can run:

unshare -n -r ping 127.0.0.1

And this will yield the expected Network is unreachable.

On Debian systems you might still get an Operation not permitted error, then you have to enable unprivileged user namespaces first by running:

sudo sysctl -w kernel.unprivileged_userns_clone=1

Note: for a wider range of use cases, the more sophisticated bwrap --unshare-net may be considered, as described briefly in a different answer.

Amir
  • 1,531
  • 1
  • 14
  • 18
  • I'm still getting `Operation not permitted` with `~$ unshare -n -r ping 127.0.0.1` – Arctic Kona Feb 22 '20 at 21:11
  • 2
    @ArcticKona your system may be configured differently from ours, sorry I can’t help. For some use cases, it may also be worth trying my other answer with `bwrap --unshare-net`, but keep in mind that ICMP (ping) is specifically not supported in that solution. – Amir Feb 23 '20 at 11:05
4

Another way to enter a new network namespace, besides unshare -n, is using the higher-level Bubblewrap (bwrap --unshare-net):

bwrap --bind / / --dev /dev --unshare-net -- your-program args …

Note: if your-program args … is ping 127.0.0.1, you will notice that ICMP is not supported under Bubblewrap, so the OP example will not show “Network is unreachable”.

Also interesting to note is that programs in --unshare-net do get a loopback interface, but it’s a network namespace-isolated one.

Amir
  • 1,531
  • 1
  • 14
  • 18
3

You could use the setcap utility to setup unshare.

sudo setcap cap_sys_admin+ep /usr/bin/unshare

After this you can use unshare -n ping 127.0.0.1 I can't explain it any further and I do not know if this is a good idea, but it works and whoami does not show root as user name.

jue
  • 131
  • 2
  • 1
    This is similar to the setuid approach, but instead of always running `unshare` as root, it always runs it with the CAP_SYS_ADMIN capability, regardless of whether the user has it. This is better than setuid, but still could, in the case of a vuln. in `unshare`, lead to some privilege escalation. – Andrew Marshall Nov 14 '20 at 23:37