4

I want to cheat a program to use a special /etc/resolv.conf file, that in turn will force it to use a nonstandard nameserver.

The obvious solution is to recreate the whole filesystem except one file and use a chroot. But may be there is a simpler hack for doing this.

how to change a file's content for a specific process only? gives solutions that work in many cases, but not for /etc/resolv.conf: LD_PRELOAD doesn't catch when the resolver inside libc opens /etc/resolv.conf, and a bind mount doesn't work to override a symbolic link (if the link target is missing or when the link is changed afterwards).

EDIT: A relevant question is How do I mount a file on top of a broken symbolic link? and there is no universal solution found

5
  • 1
    Yes. You can run it in a different mount namespace. Commented Jul 21, 2019 at 17:34
  • @ctrl-alt-delor how to overwrite a single file afterwards? If I just run mount --bind newresolv /tmp/mnt/etc/resolv.conf it will follow the link path or, in my case where the link path is nonexistent, it fails with an error mount point is a symbolic link to nowhere Commented Jul 21, 2019 at 19:03
  • 1
    One way is with unshare, see duplicate. There is probably a way to do it without root privileges (maybe fuse). Commented Jul 21, 2019 at 22:24
  • 1
    @gilles I don't think that either answer to the purported dupe applies. Overriding fopen() with a LD_PRELOAD hack will not work when /etc/resolv.conf is opened by the resolver (ie via getaddrinfo()), and the way to reliably use unshare + bind mount with a "dynamic" symlink like /etc/resolv.conf needs to be explained more (at least for me, it's not at all obvious how that could be done; assuming that this Q is linux-only, despite no [linux] tag). Commented Jul 22, 2019 at 3:11
  • @mosvy You're right, this is a special case where the usual methods don't necessarily work. I've edited and reopened the question. Commented Jul 23, 2019 at 18:33

2 Answers 2

1

You can use bubblewrap to create a mount namespace. It is included in most distributions, since flatpak needs it.

bwrap \ --bind / / \ --bind /home/user/resolv.conf /etc/resolv.conf \ binary parameter1 parameter2d 
2
  • It looks a little bit like bubblewrap and overlayfs are superficially similar.  Can you briefly discuss the similarities and/or differences?  Why would a user choose bubblewrap over overlayfs? Commented Apr 4, 2022 at 10:26
  • @G-ManSays'ReinstateMonica' bubblewrap in OP's case will mount over /run/NetworkManager/resolv.conf (or /run/systemd...) rather than /etc/resolv.conf (which is still a symlink). Commented Apr 4, 2022 at 10:28
0

One can use overlayfs to avoid duplication. If it's temporary, everything can be done using /tmp. Combined with a mount namespace, this can then be made to affect a single application. To be prepared from root (it does work with an user+mount namespace where a normal user is mapped as root, but without privileged assistance and/or recent kernel for pid translation, user mappings wouldn't help to do something useful).

  • create a new mount namespace
  • create an overlayfs in this mount namespace
  • bind mount this overlayfs back over /etc
  • change contents (eg delete the /etc/resolv.conf symlink then create the regular file /etc/resolv.conf with custom content)
  • run application, still from this mount namespace

Example:

mkdir /tmp/upper /tmp/work /tmp/fake_etc unshare -m 

next commands are run in the new mount namespace:

mount -t overlay -olowerdir=/etc,upperdir=/tmp/upper,workdir=/tmp/work overlay_etc /tmp/fake_etc 

then just cover /etc with the one used to fake its contents:

mount --bind /tmp/fake_etc /etc 

and do changes (affecting only the overlayfs in the mount namespace):

rm /etc/resolv.conf echo nameserver 192.0.2.2 > /etc/resolv.conf 

AFAIK can't mount a mount namespace to keep a reference. If needed one can use instead a PID reference from the mount namespace:

# echo $$ 325304 

Either in the same shell or in a separate (root) shell by running this:

nsenter -t 325304 --mount 

then following the previous example (with a nameserver 192.0.2.2 that isn't reachable):

# su - -c 'ping stackexchange.com' someuser ping: stackexchange.com: Name or service not known 

While anywhere else ping will work as usual.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.