Tomasz Zdybel
Tomasz Zdybel

Reputation: 33

who and w commands in CentOS 8 Docker container

While playing with CentOs 8 on Docker container I found out, that outputs of who and w commands are always empty.

[root@9e24376316f1 ~]# who
[root@9e24376316f1 ~]# w
 01:01:50 up  7:38,  0 users,  load average: 0.00, 0.04, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT

Even when I'm logged in as a different user in second terminal. When I want to write to this user it shows

[root@9e24376316f1 ~]# write test
write: test is not logged in

Is this because of Docker? Maybe it works in some way that disallow sessions to see each other? Or maybe that's some other issue. I would really appreciate some explanation.

Upvotes: 3

Views: 241

Answers (1)

Danila Kiver
Danila Kiver

Reputation: 3758

These utilities obtain the information about current logins from the utmp file (/var/run/utmp). You can easily check that in ordinary circumstances (e.g. on the desktop system) this file contains something like the following string (here qazer is my login and tty7 is a TTY where my desktop environment runs):

$ cat /var/run/utmp
tty7:0qazer:0�o^�

while in the container this file is (usually) empty:

$ docker run -it centos
[root@5e91e9e1a28e /]# cat /var/run/utmp
[root@5e91e9e1a28e /]#

Why?

The utmp file is usually modified by programs which authenticate the user and start the session: login(1), sshd(8), lightdm(1). However, the container engine cannot rely on them, as they may be absent in the container file system, so "logging in" and "executing on behalf of" is implemented in the most primitive and straightforward manner, avoiding relying on anything inside the container.

When any container is started or any command is execd inside it, the container engine just spawns the new process, arranges some security settings, calls setgid(2)/setuid(2) to forcibly (without any authentication) alter the process' UID/GID and then executes the required binary (the entry point, the command, and so on) within this process.

Say, I start the CentOS container running its main process on behalf of UID 42:

docker run -it --user 42 centos

and then try to execute sleep 1000 inside it:

docker exec -it $CONTAINER_ID sleep 1000

The container engine will perform something like this:

[pid 10170] setgid(0)                   = 0
[pid 10170] setuid(42)                  = 0
...
[pid 10170] execve("/usr/bin/sleep", ["sleep", "1000"], 0xc000159740 /* 4 vars */) = 0

There will be no writes to /var/run/utmp, thus it will remain empty, and who(1)/w(1) will not find any logins inside the container.

Upvotes: 2

Related Questions