Как я могу заменить lsof внутри Docker (нативный, не на основе LXC)

16

Я несколько озадачен тем, что внутри контейнера Docker lsof -iничего не получается.

Пример (все команды / вывод изнутри контейнера):

[1] root@ec016481cf5f:/# lsof -i
[1] root@ec016481cf5f:/# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -

Также обратите внимание, что PID или название программы не отображаются netstat. fuserтакже дает несколько запутанный вывод и не может точно определить PID.

Кто-нибудь может пролить свет на это?

  • Как я могу заменить lsof -i(чтобы увидеть название процесса !)
  • Почему вывод netstatкалекой так же?

NB . Контейнер работает с "ExecDriver": "native-0.1"собственным уровнем выполнения Докера, а не с LXC.


[1] root@ec016481cf5f:/# fuser -a4n tcp 22
Cannot stat file /proc/1/fd/0: Permission denied
Cannot stat file /proc/1/fd/1: Permission denied
Cannot stat file /proc/1/fd/2: Permission denied
Cannot stat file /proc/1/fd/3: Permission denied
Cannot stat file /proc/1/fd/255: Permission denied
Cannot stat file /proc/6377/fd/0: Permission denied
Cannot stat file /proc/6377/fd/1: Permission denied
Cannot stat file /proc/6377/fd/2: Permission denied
Cannot stat file /proc/6377/fd/3: Permission denied
Cannot stat file /proc/6377/fd/4: Permission denied
22/tcp:

(Я не одержим Permission denied, потому что эти цифры. Меня смущает пустой список PID после 22/tcp.)


# lsof|awk '$1 ~ /^sshd/ && $3 ~ /root/ {print}'
sshd    6377      root  cwd   unknown                        /proc/6377/cwd (readlink: Permission denied)
sshd    6377      root  rtd   unknown                        /proc/6377/root (readlink: Permission denied)
sshd    6377      root  txt   unknown                        /proc/6377/exe (readlink: Permission denied)
sshd    6377      root    0   unknown                        /proc/6377/fd/0 (readlink: Permission denied)
sshd    6377      root    1   unknown                        /proc/6377/fd/1 (readlink: Permission denied)
sshd    6377      root    2   unknown                        /proc/6377/fd/2 (readlink: Permission denied)
sshd    6377      root    3   unknown                        /proc/6377/fd/3 (readlink: Permission denied)
sshd    6377      root    4   unknown                        /proc/6377/fd/4 (readlink: Permission denied)
sshd    6442      root  cwd   unknown                        /proc/6442/cwd (readlink: Permission denied)
sshd    6442      root  rtd   unknown                        /proc/6442/root (readlink: Permission denied)
sshd    6442      root  txt   unknown                        /proc/6442/exe (readlink: Permission denied)
sshd    6442      root    0   unknown                        /proc/6442/fd/0 (readlink: Permission denied)
sshd    6442      root    1   unknown                        /proc/6442/fd/1 (readlink: Permission denied)
sshd    6442      root    2   unknown                        /proc/6442/fd/2 (readlink: Permission denied)
sshd    6442      root    3   unknown                        /proc/6442/fd/3 (readlink: Permission denied)
sshd    6442      root    4   unknown                        /proc/6442/fd/4 (readlink: Permission denied)
sshd    6442      root    5   unknown                        /proc/6442/fd/5 (readlink: Permission denied)

Еще есть вывод для подключенного пользователя, который также правильно идентифицирован, но это все. По-видимому, невозможно определить, к какому типу ( lsof -iограничениям интернет-сокетов) относится определенный «объект».

0xC0000022L
источник
Что делает lsofотчет? Такой же?
SLM
@Slm: блестящий запрос! Это не держит это пустым. Вместо этого он показывает целый ряд (также sshdсвязанных) строк, некоторые из которых могут быть сокетами TCP, как TYPE unknown. Свой. Добавление вывода к моему вопросу.
0xC0000022L
Если вы запустите strace -s 2000 -o lsof.log lsof -iего, скорее всего, вы получите дополнительную информацию о том, что блокируется.
SLM
1
@Slm: хорошая мысль. Спасибо за напоминание. Я сделаю это завтра, хотя. Также вполне возможно, что straceсам ограничен в контейнере. Захватывающие новые вещи, чтобы учиться. Спасибо за прыгающую идею. Должен врезаться в кровать, хотя.
0xC0000022L
К вашему сведению: это также нарушает netstat -lp. Это определенно вызвано apparmor.
Алан Робертсон

Ответы:

7

(ПРИМЕЧАНИЕ: неясно в вопросе, как запрашивающая сторона входит в контейнер докера. Я предполагаю, что docker exec -it CONTAINER bash она использовалась.)

У меня была эта проблема при использовании образа докера, основанного на centos:7версии докера, 1.9.0и чтобы преодолеть это, я просто запустил:

docker exec --privileged -it CONTAINER bash

Обратите внимание на включение --privileged.

Мое наивное понимание причины, по которой это необходимо: кажется, что докер прилагает усилия, чтобы сделать контейнер более «безопасным», как описано здесь .

erik.weathers
источник
4

Ха, сюжет утолщается. Если у кого-то есть лучший ответ, пожалуйста, напишите его, и я приму его, если это приемлемо. Но тут очевидная причина. Как небрежно с моей стороны игнорировать файлы журналов на хосте :

Jun 12 01:29:46 hostmachine kernel: [140235.718807] audit_printk_skb: 183 callbacks suppressed
Jun 12 01:29:46 hostmachine kernel: [140235.718810] type=1400 audit(1402536586.521:477): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="trace" denied_mask="trace" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718860] type=1400 audit(1402536586.521:478): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718886] type=1400 audit(1402536586.521:479): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718899] type=1400 audit(1402536586.521:480): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718921] type=1400 audit(1402536586.521:481): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.718954] type=1400 audit(1402536586.521:482): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719001] type=1400 audit(1402536586.521:483): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719043] type=1400 audit(1402536586.521:484): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719086] type=1400 audit(1402536586.521:485): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"
Jun 12 01:29:46 hostmachine kernel: [140235.719126] type=1400 audit(1402536586.521:486): apparmor="DENIED" operation="ptrace" profile="docker-default" pid=3782 comm="lsof" requested_mask="read" denied_mask="read" peer="docker-default"

Таким образом, apparmor, по-видимому, является виновником, хотя мне придется выяснить, как убедить его в том, что это разрешается без ущерба для безопасности хоста / контейнера или чтобы увидеть, возможно ли это вообще без ущерба для безопасности.

0xC0000022L
источник
2
Описано в выпуске Docker № 7276
Энтони О.
3

Еще одна возможность, на этот раз с более тонкой настройкой безопасности: дать привилегию SYS_PTRACE контейнеру Docker:

docker run --cap-add=SYS_PTRACE ...
Петер - Восстановить Монику
источник
1
На случай, если кому-то интересно, зачем это lsofнужно CAP_SYS_PTRACE: обязательно читать /proc/*/stat. См. Ptrace (2)
Дэвид Ротлисбергер
2

Я тоже нашел эту проблему. Проблема ушла после того, как я отключил apparmorна docker:

$ sudo aa-complain <docker apparmor profile name, "docker-default" on ubuntu>

URL ссылки: https://help.ubuntu.com/community/AppArmor

menghan
источник
3
Возможно, вы захотите добавить дополнительные пояснения к этому ответу (например, что aa-complainделает, или некоторую документацию, которая поддерживает это решение).
HalosGhost
@HalosGhost Извините, я не совсем знаком apparmor, я просто погуглил и нашел способ отключить его. Другими словами, я не знаю, почему это работает или почему это не работает. Мой хост OS Ubuntu 14.04, поэтому я искал "ubuntu apparmor" и нашел help.ubuntu.com/community/AppArmor . Я надеюсь, что это будет полезно для вас.
Менган
2
У меня нет этой проблемы; я беспокоился о качестве вашего ответа и о том, насколько полезным (и информативным) он будет для ФП.
HalosGhost
@HalosGhost Спасибо за вашу помощь, я переосмыслил свой ответ.
Менган
На убунту 14.04 команда была sudo aa-complain /etc/apparmor.d/docker. В основном это отключает броню приложения для процесса докера, что означает, что докер может читать любой файл в системе. Ранее он мог работать только с файлами, которые были разрешены в профиле. Лучшим решением может быть изменение правил брони приложения, которые позволят доступ к файлам / proc / pid / fd.
Мартинс Балодис