hishamhm / htop

htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'.
GNU General Public License v2.0
5.84k stars 581 forks source link

Find correct username for processes running in jail #501

Open huschu opened 8 years ago

huschu commented 8 years ago

On FreeBSD htop 2.0.1 shows the username of a jailed process apparently by looking up the id in the host system. Since htop knows in which jail the process is running (which is awesome, thanks!), could it somehow look up the correct username?

etosan commented 8 years ago

First htop maintains it's own username<->UID hashmap.

When simple jail name/JID started working, I was just happy that it works. As htop core provides username/UID mapper internally, it meshed nicely together on it's own.

But it turned out, if jail has custom users, UIDs will show only numerically, as you observe.

This is caused by a fact, that htop username/uid mapping is completely unaware of in-jail users.

Unfortunately "solution" is not so simple.

Problem with jails is, that they are really isolated from the rest of the system, and that you would need to either:

  1. simplistically read /$somedir/$jail_name/etc/passwd database which is problematic:
    • because admin is free to construct any jail anywhere (I believe this is good thing), eg change $somedir, and you won't know where to look for db files,
      • theoretically you could extract jail root path from jail table and hope jail has /etc or /usr/local/etc (it is in no way required for it to have /etc at all)
    • because jail can have special nss setup (LDAP, DB, whatever integration) you cannot reasonably guess and parse all possible setups
      • I believe there is no standardized way to parse such configs and handle that "manually"
      • keep in mind from "host" view, those configs are "just" passwd (etc) formatted files as well
      • I am not sure if it would be possible to load LDAP nss plugin for example, and query it in "host's" environment same way like it is being done from inside of jail.
    • because of these complications, combinatorial explosion of possibilities, this design direction is IMHO probably complete dead-end.
  2. much more correct way, IMHO would be to devise some tiny IPC protocol, fork htop into parent-child connected (through socket) "htop-uid-probe" process pair, attach probe into given JID and collect given jail users in-jail:
    • Once process enters jail, it cannot ever leave and that's why you need to hold socket open to tether in-jail data from probe back into actual htop instance.
    • I am not sure atm, but I think jail_attach function requires root privs, and that would mean making htop capable to drop and elevate it's privs and to be run as suid program in general.
      • Not sure if htop was written with such design in mind (problematic from security standpoint as well)
    • As probe would run in-jail, holding socket to host, jail's nss setup would become non issue and probe would just use same functions as any other in-jail process, and no matter how complex nss setup is, it would see same "image".
    • However this could end up problematic with htop's internal username/UID hashmap instead, in situations, where there are multiple jails and where two UIDs can map to same "virtual" username and vice versa on host (eg htop hashmap would need to be hashed by jid:uid pairs and not just uid).
    • if this is implemented this way, it ends up extremely FreeBSD specific. Only other major jail tech user is DragonflyBSD and there are some important differences (split occured long ago). OpenBSD frowns on jails completely (eg. jails are bad design).

Even reuse of this functionality could be problematic. Solaris and SmartOS have Zones support, which should be similar to jails, but I don't know if you can "inject" probes into them from "host". Linux has much lower level, separate UID namespace "sub-component", for building up containers, and whether process probe design would mesh with that design even is questionable. I personally have no clue how Linux containers really work, but from what I read, they are very complex compared to jails and others. Maybe it' easy there though.

As you see this "simple" thing turns out not so simple to do correctly. Because of complexity, if I remember correctly, even native FreeBSD top doesn't show in-jail user names either.

Maybe somebody more experienced or hishamhm would be able to abstract all this machinery needed?

However with this two more interesting things surface:

Thus easiest solution, if you want to see usernames and which works right now, is administrative one. Just keep your UIDs and usernames synced between host and "jails", and make sure all jails have same UID:username pairs between them as well and you will get correct output.