Comment puis-je remplacer lsof dans un Docker (natif, pas basé sur LXC)

16

Je suis un peu déconcerté que l'intérieur d'un conteneur Docker lsof -ine donne aucune sortie.

Exemple (toutes les commandes / sorties de l'intérieur du conteneur):

[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      -

Veuillez également noter qu'aucun PID ou nom de programme n'est affiché par netstat. fuserdonne également une sortie quelque peu confuse et est incapable de localiser également les PID.

Quelqu'un peut-il nous éclairer à ce sujet?

  • Comment puis-je remplacer lsof -i(pour voir le nom du processus aussi!)
  • Pourquoi la sortie de est-elle également netstatparalysée?

NB: Le conteneur s'exécute avec "ExecDriver": "native-0.1", c'est la propre couche d'exécution de Docker, pas 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:

(Je ne suis pas obsédé par le Permission denied, car cela donne des chiffres. Ce qui m'embrouille, c'est la liste vide de PID après 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)

Il y a un peu plus de sortie pour l'utilisateur connecté, qui est également correctement identifié, mais c'est tout. Il est apparemment impossible de discerner de quel type ( lsof -ilimites aux prises Internet) se trouve un certain "objet".

0xC0000022L
la source
Qu'est-ce qu'un lsofrapport? Le même?
slm
@slm: une brillante enquête! Il ne le garde pas vide. Au lieu de cela, il montre toute une série de sshdlignes (également liées), dont certaines pourraient être des sockets TCP, comme TYPE unknown. Particulier. Ajout de la sortie à ma question.
0xC0000022L
Si vous l'exécutez, strace -s 2000 -o lsof.log lsof -icela vous donnera probablement des informations supplémentaires sur ce qui est bloqué.
slm
1
@slm: bon point. Merci de me le rappeler. Je le ferai demain, cependant. Il est également possible que stracelui - même soit limité dans le conteneur. De nouvelles choses passionnantes à apprendre. Merci d'avoir rebondi. Doit frapper le lit, cependant.
0xC0000022L
FYI: Cela casse également netstat -lp. Il est définitivement causé par l'apparmeur.
Alan Robertson

Réponses:

7

(REMARQUE: la question de savoir comment le demandeur entre dans le conteneur Docker n'est pas claire. Je suppose qu'il a docker exec -it CONTAINER bash été utilisé.)

J'ai eu ce problème lors de l'utilisation d'une image Docker basée sur une centos:7version Docker 1.9.0et pour surmonter cela, j'ai simplement exécuté:

docker exec --privileged -it CONTAINER bash

Notez l'inclusion de --privileged.

Ma compréhension naïve de la raison pour laquelle cela est nécessaire: il semble que Docker fasse un effort pour que le conteneur soit plus "sécurisé", comme indiqué ici .

erik.weathers
la source
4

Hah, l'intrigue s'épaissit. Si quelqu'un a une meilleure réponse, veuillez l'écrire et je l'accepterai, si elle est acceptable. Mais voici la raison apparente. Quelle négligence de ma part d'ignorer les fichiers journaux sur l' hôte :

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"

L'apparmeur semble donc être le coupable, bien que je doive trouver un moyen de le convaincre de permettre cela sans compromettre la sécurité de l'hôte / conteneur ou de voir si c'est possible sans compromettre la sécurité.

0xC0000022L
la source
2
Décrit dans le numéro 7276 de Docker
Anthony O.
3

Autre possibilité, cette fois avec un paramètre de sécurité plus précis: donnez le privilège SYS_PTRACE au conteneur Docker:

docker run --cap-add=SYS_PTRACE ...
peterh - Réintégrer Monica
la source
1
Au cas où quelqu'un se demanderait pourquoi a lsofbesoin CAP_SYS_PTRACE: Il faut lire /proc/*/stat. Voir ptrace (2)
David Röthlisberger
2

J'ai aussi trouvé ce problème. Le problème est allé après avoir désactivé apparmorsur docker:

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

URL de référence: https://help.ubuntu.com/community/AppArmor

menghan
la source
3
Vous voudrez peut-être envisager d'ajouter plus d'explications à cette réponse (par exemple, qu'est aa-complain- ce qui fait, ou une documentation qui prend en charge cette solution).
HalosGhost
@HalosGhost Désolé, je ne suis pas très familier avec apparmor, je viens de le googler et j'ai trouvé un moyen de le désactiver. En d'autres termes, je ne sais pas pourquoi cela fonctionne ou pourquoi cela n'a pas fonctionné. Mon système d'exploitation hôte est Ubuntu 14.04, j'ai donc recherché «ubuntu apparmor» et trouvé help.ubuntu.com/community/AppArmor . J'espère que cela vous sera utile.
menghan
2
Je n'ai pas ce problème; ma préoccupation portait sur la qualité de votre réponse et sur l'utilité (et l'information) qu'elle apporterait au PO.
HalosGhost
@HalosGhost Merci pour votre aide, je réédite ma réponse.
menghan
Sur Ubuntu 14.04, la commande était sudo aa-complain /etc/apparmor.d/docker. Fondamentalement, il désactive l'armure d'application pour le processus Docker, ce qui signifie que Docker peut lire n'importe quel fichier sur le système. Auparavant, il ne pouvait fonctionner qu'avec des fichiers autorisés dans le profil. Une meilleure solution pourrait être de modifier les règles d'armure d'application qui autoriseraient l'accès aux fichiers / proc / pid / fd.
Martins Balodis