8

I have a docker container running Debian jessie on Ubuntu yakkety.

When within the docker (connected via ssh for instance) I am isolated from the host (which is expected). I however realized that dmesg shows me the messages for the host and not for the container. How can it have access to information of its host?

The configuration of the docker container is not special (except that it uses a specific bridge, different from docker0), in particular it does not run in any privileged mode ("Privileged": false below):

root@srv ~# docker inspect minecraft-1-8
[
    {
        "Id": "748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e",
        "Created": "2016-12-01T15:35:05.287672787Z",
        "Path": "/usr/bin/supervisord",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 28650,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2016-12-15T18:37:08.409564695Z",
            "FinishedAt": "2016-12-15T18:37:07.457274028Z"
        },
        "Image": "sha256:78a2f88d47e29523503c2196ed2faaa3d1039d948d73987edc03b2abd338595d",
        "ResolvConfPath": "/var/lib/docker/containers/748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e/hostname",
        "HostsPath": "/var/lib/docker/containers/748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e/hosts",
        "LogPath": "/var/lib/docker/containers/748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e/748cfdfbf3fb5526cb7151cbc0857117af3c7bd8ab9e086c4f2efb897290d66e-json.log",
        "Name": "/minecraft-1-8",
        "RestartCount": 0,
        "Driver": "overlay",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "docker",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": -1,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0
        },
        "GraphDriver": {
            "Name": "overlay",
            "Data": {
                "LowerDir": "/var/lib/docker/overlay/e78ce9dbcedd6974429a4aada8f38913b7d35da41f586f203dd99a568f38b6c3/root",
                "MergedDir": "/var/lib/docker/overlay/e8422e4707d95db8ea747af2367626cc8bf16e95f8eb05dfad9a63461c9ade86/merged",
                "UpperDir": "/var/lib/docker/overlay/e8422e4707d95db8ea747af2367626cc8bf16e95f8eb05dfad9a63461c9ade86/upper",
                "WorkDir": "/var/lib/docker/overlay/e8422e4707d95db8ea747af2367626cc8bf16e95f8eb05dfad9a63461c9ade86/work"
            }
        },
        "Mounts": [],
        "Config": {
            "Hostname": "minecraft-1-8",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/usr/bin/supervisord"
            ],
            "Image": "minecraft",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "cf411634babad31138ab4572b9cd7306f74a54dd1baf4cd8d7706d7e7020c594",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/cf411634baba",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "docker": {
                    "IPAMConfig": {
                        "IPv4Address": "10.200.0.100"
                    },
                    "Links": null,
                    "Aliases": [
                        "748cfdfbf3fb"
                    ],
                    "NetworkID": "7b20560b36032d36ffe6c0ebece6b4408355d207f4e203a2957b0434ee0afdc1",
                    "EndpointID": "9fa4fc914dfe76022ce0db02e48a7e7c85c57bc2a15b0b3e5d81b1f24d95f376",
                    "Gateway": "10.200.0.1",
                    "IPAddress": "10.200.0.100",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:c8:00:64"
                }
            }
        }
    }
]
WoJ
  • 27,165
  • 48
  • 180
  • 345
  • Show your `docker run` command – user2915097 Dec 15 '16 at 18:58
  • @user2915097: I `start` an existing container created with `docker create --network docker --ip 10.200.0.100 --name=minecraft-1-8 -h minecraft-1-8 base`, where `base` is a debian yakkety image. – WoJ Dec 15 '16 at 19:11
  • 2
    This was [raised as security concern](https://github.com/moby/moby/issues/37897), and [fixed in latest version](https://github.com/moby/moby/pull/37929). – Franklin Yu Mar 25 '19 at 21:57

1 Answers1

8

In most distro's dmesg is not a privileged command. Any user can use the klogctl interface to read the kernel ring buffer.

$ id
uid=1001(matt) gid=1001(matt) groups=1001(matt)
$ dmesg | head -1
[    0.000000] Initializing cgroup subsys cpuset

But can't do anything beyond read

$ dmesg -C
dmesg: klogctl failed: Operation not permitted

Which extends to Docker

$ sudo docker run debian dmesg | head -1
[    0.000000] Initializing cgroup subsys cpuset
$ sudo docker run debian dmesg -C
dmesg: klogctl failed: Operation not permitted

Restricting access

You can restrict read access down to root users and those with the CAP_SYSLOG or CAP_SYS_ADMIN capabilities via /proc/sys/kernel/dmesg_restrict.

$ echo 1 > /proc/sys/kernel/dmesg_restrict

Then you should be getting a permission denied message:

$ docker run ubuntu:yakkety dmesg
dmesg: read kernel buffer failed: Operation not permitted

Running a container in privileged mode will then regain access to the hosts kernel ring buffer

$ docker run --privileged ubuntu:yakkety dmesg
[146902.131915] br-fa26f1dc96a1: port 3(veth80d3d5d) entered disabled state
...

Use sysctl to configure kernel.dmesg_restrict=1 if you need it permanently.

Namespacing

As to why the kernel log doesn't have name spacing like other kernel areas, I think the answer is "it's difficult". There's more detail than you'd care to know in this 2012 Stepping closer to practical containers: "syslog" namespaces LWN post. I can't see any reference's to it getting any further than proposed patches: https://lwn.net/Articles/562389/ https://lwn.net/Articles/561271/. As you can see in this recent netfilter patch, they have a work around to allow rules in a container name space to use the global log.

Matt
  • 68,711
  • 7
  • 155
  • 158
  • Thank you Matt. My concern was about the third point of your answer - I do not care about who can see (and do what) within the container **for the container data**. The ability to see the host logs is very annoying as these logs may hold information not intended for the (segregated and unprivileged) docker instance. – WoJ Dec 16 '16 at 07:30
  • @WoJ yeah probably best to just disable non privileged access. – Matt Dec 17 '16 at 08:24
  • I was under the impression that this was already the case? (looking at the `inspect` output) – WoJ Dec 17 '16 at 08:25
  • ...to the klogctl read functions via `kernel.dmesg_restrict=1` – Matt Dec 17 '16 at 08:26
  • Wondering why `dmesg_restrict` is set to 0 by default? People don't think it sensitive? – Franklin Yu Mar 25 '19 at 21:55
  • @FranklinYu it's a point of contention. See https://lists.ubuntu.com/archives/ubuntu-devel/2020-June/041063.html for a proposal to change it in Ubuntu 20.10 and https://lists.ubuntu.com/archives/ubuntu-devel/2011-May/033240.html for historical context from 2011. – Anon Jul 19 '20 at 16:20