Bagaimana saya bisa mengganti lsof di dalam Docker (asli, bukan berbasis LXC)

16

Saya agak bingung bahwa di dalam wadah Docker lsof -itidak menghasilkan output apa pun.

Contoh (semua perintah / output dari dalam wadah):

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

Harap perhatikan juga bagaimana tidak ada PID atau nama program yang ditunjukkan oleh netstat. fuserjuga memberikan hasil yang agak membingungkan dan tidak dapat menentukan PID juga.

Adakah yang bisa menjelaskan hal ini?

  • Bagaimana saya bisa mengganti lsof -i(untuk melihat nama proses juga!)
  • Mengapa output dari netstatpincang juga?

NB: Kontainer berjalan dengan "ExecDriver": "native-0.1", itu adalah layer eksekusi Docker sendiri, bukan 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:

(Saya tidak terobsesi dengan Permission denied, karena angka-angka itu. Yang membingungkan saya adalah daftar PID kosong setelahnya 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)

Ada beberapa output lagi untuk pengguna yang terhubung, yang diidentifikasi dengan benar juga, tetapi hanya itu. Tampaknya tidak mungkin untuk membedakan jenis ( lsof -ibatasan untuk soket internet) "objek" tertentu.

0xC0000022L
sumber
Apa yang lsofdilaporkan? Sama?
slm
@slm: pertanyaan brilian! Itu tidak menyimpannya kosong. Sebaliknya itu menunjukkan seluruh host (juga sshdterkait) baris, beberapa di antaranya bisa menjadi soket TCP, sebagai TYPE unknown. Aneh. Menambahkan output ke pertanyaan saya.
0xC0000022L
Jika Anda menjalankannya strace -s 2000 -o lsof.log lsof -ikemungkinan akan memberi Anda wawasan tambahan tentang apa yang diblokir.
slm
1
@slm: poin bagus. Terima kasih sudah mengingatkan saya. Saya akan melakukan ini besok. Juga dimungkinkan bahwa straceitu sendiri terbatas dalam wadah. Hal-hal baru yang menarik untuk dipelajari. Terima kasih telah memunculkan ide. Tapi harus tidur.
0xC0000022L
FYI: Ini juga memecah netstat -lp. Ini pasti disebabkan oleh apparmor.
Alan Robertson

Jawaban:

7

(CATATAN: tidak jelas dalam pertanyaan bagaimana penanya memasuki wadah buruh pelabuhan. Saya berasumsi docker exec -it CONTAINER bash telah digunakan.)

Saya mengalami masalah ini ketika menggunakan gambar buruh pelabuhan yang didasarkan pada centos:7versi buruh pelabuhan 1.9.0dan untuk mengatasinya, saya hanya menjalankan:

docker exec --privileged -it CONTAINER bash

Perhatikan penyertaan --privileged.

Pemahaman saya yang naif tentang alasan ini diperlukan: tampaknya buruh pelabuhan berupaya agar wadah itu lebih "aman", seperti yang didokumentasikan di sini .

erik
sumber
4

Hah, plotnya menebal. Jika seseorang memiliki jawaban yang lebih baik tolong tulis dan saya akan menerimanya, jika dapat diterima. Tapi di sini alasan yang jelas. Betapa saya lalai mengabaikan file-file log pada host :

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"

Jadi apparmor tampaknya menjadi biang keladinya, walaupun saya harus mencari cara meyakinkannya untuk membiarkan ini tanpa mengorbankan keamanan host / kontainer atau untuk melihat apakah itu mungkin terjadi tanpa mengorbankan keamanan.

0xC0000022L
sumber
2
Dijelaskan dalam edisi Docker # 7276
Anthony O.
3

Kemungkinan lain, kali ini dengan pengaturan keamanan yang lebih terbatas: beri hak istimewa SYS_PTRACE ke wadah buruh pelabuhan:

docker run --cap-add=SYS_PTRACE ...
peterh - Pasang kembali Monica
sumber
1
Seandainya ada yang bertanya-tanya mengapa lsofperlu CAP_SYS_PTRACE: Dibutuhkan membaca /proc/*/stat. Lihat ptrace (2)
David Röthlisberger
2

Saya juga menemukan masalah ini. Masalahnya telah pergi setelah saya dinonaktifkan apparmorpada docker:

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

url referensi: https://help.ubuntu.com/community/AppArmor

menghan
sumber
3
Anda mungkin ingin mempertimbangkan untuk menambahkan lebih banyak penjelasan untuk jawaban ini (mis. Apa aa-complain, atau beberapa dokumentasi yang mendukung solusi ini).
HalosGhost
@HalosGhost Maaf, saya tidak terlalu mengenal apparmor, saya hanya mencari di Google dan menemukan cara untuk menonaktifkannya. Dengan kata lain, saya tidak tahu mengapa itu bekerja atau mengapa itu tidak berhasil. Os host saya adalah Ubuntu 14.04, jadi saya mencari "ubuntu apparmor" dan menemukan help.ubuntu.com/community/AppArmor . Saya harap ini akan membantu Anda.
menghan
2
Saya tidak memiliki masalah ini; kekhawatiran saya adalah kualitas jawaban Anda dan bagaimana membantu (dan informatif) itu untuk OP.
HalosGhost
@HalosGhost Terima kasih atas bantuan Anda, saya edit ulang jawaban saya.
menghan
Di ubuntu 14.04 perintahnya adalah sudo aa-complain /etc/apparmor.d/docker. Pada dasarnya ia menonaktifkan pelindung aplikasi untuk proses buruh pelabuhan yang berarti buruh pelabuhan dapat membaca file apa pun di sistem. Sebelumnya hanya bisa bekerja dengan file yang diizinkan di profil. Solusi yang lebih baik mungkin dengan mengubah aturan aplikasi armor yang akan memungkinkan akses ke file / proc / pid / fd.
Martins Balodis