Saya memiliki permintaan penerusan nginx ke gunicorn melalui soket unix di /run/gunicorn/socket
. Secara default, perilaku ini tidak diizinkan oleh SELinux:
grep nginx /var/log/audit/audit.log
type=SERVICE_START msg=audit(1454358912.455:5390): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=AVC msg=audit(1454360194.623:7324): avc: denied { write } for pid=9128 comm="nginx" name="socket" dev="tmpfs" ino=76151 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=SYSCALL msg=audit(1454360194.623:7324): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5710 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1454361591.701:13343): avc: denied { connectto } for pid=9128 comm="nginx" path="/run/gunicorn/socket" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket
type=SYSCALL msg=audit(1454361591.701:13343): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5950 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
Di mana-mana saya melihat (misalnya, di sini dan di sini ), instruksi untuk mengaktifkan ini mengatakan untuk membuat permintaan ke nginx, minta permintaan ditolak oleh SELinux, kemudian jalankan audit2allow
untuk mengizinkan permintaan di masa depan. Saya tidak tahu chcon
atau semanage
perintah apa pun yang memungkinkan perilaku ini secara eksplisit.
Apakah ini satu-satunya jalan? Tampaknya konyol bahwa Anda tidak dapat mengatur kebijakan yang memungkinkan nginx untuk menulis ke soket tanpa terlebih dahulu upaya ditolak dan kemudian menjalankan alat yang memungkinkan hal-hal yang ditolak. Bagaimana Anda tahu persis apa yang sedang diaktifkan? Bagaimana ini bisa berfungsi jika Anda mengatur mesin di bawah otomatisasi?
Saya menggunakan CentOS 7.
Jawaban:
Yah tidak, SELinux adalah Kontrol Akses Wajib, semuanya ditolak secara default dan Anda harus secara eksplisit mengizinkan sesuatu. Jika pembuat kebijakan belum mempertimbangkan tumpukan tertentu (franken) atau penulis daemon belum membuatnya SELinux mengetahui dan menulis kebijakan untuk itu maka Anda sendiri. Anda harus menganalisis apa yang dilakukan layanan Anda dan bagaimana mereka berinteraksi dengan SELinux dan membuat kebijakan Anda sendiri untuk mengizinkannya. Ada alat yang tersedia untuk membantu Anda audit2why , audit2allow dll
Tidak, tetapi itu tergantung pada apa yang Anda coba lakukan dan bagaimana Anda mencoba melakukannya untuk apa solusinya. Misalnya Anda mungkin ingin mengikat nginx (httpd_t) ke port 8010 (unreserved_port_t). Ketika Anda mulai nginx gagal
dan Anda (akhirnya) melihat log audit dan menemukan
Anda dapat menjalankan ini melalui audit2alllow dan secara naif menerima temuan itu
yang kemudian memungkinkan httpd_t untuk terhubung ke port tcp. Ini mungkin bukan yang Anda inginkan.
Anda dapat menggunakan sesearch untuk menyelidiki kebijakan dan melihat jenis port apa yang bisa dinamai httpd_t
Di antara jenis-jenis lain http_t dapat diikat ke http_port_t. Sekarang Anda dapat menggunakan semanage untuk menggali lebih dalam.
Port 8010 tidak terdaftar. Karena kami ingin nginx mengikat ke port 8010, tidak masuk akal untuk menambahkannya ke daftar http_port_t
Sekarang nginx akan diizinkan untuk name_bind ke port 8010 dan tidak semua port tcp seperti di atas.
Perubahan kebijakan cukup mudah dibaca, menjalankan pesan Anda di atas melalui audit2, mari kita dapatkan
yang tampaknya cukup jelas.
Yang pertama merujuk ke file dengan inum 76151. Anda dapat menggunakan find untuk mendapatkan namanya (find / -inum 76151) dan kemudian gunakan
semanage fcontext -a -t ...
untuk mengubah kebijakan dan restorecon untuk memperbaiki konteks.Yang kedua berhubungan dengan
/run/gunicorn/socket
yang lagi-lagi memiliki konteks yang salah. Menggunakan sesearch kita dapat melihat bahwa http_t dapat terhubung ke unix_stream_sockets jenis (antara lain) http_t. Jadi kita bisa mengubah konteksnya misalnyaIni mengatur konteks / run / gunicorn dan pohon | file di bawahnya ke httpd_t.
Anda perlu menganalisis sistem dan membuat perubahan yang sesuai dalam pengujian. Anda kemudian menggunakan alat otomasi Anda untuk menyebarkan perubahan, boneka dan mungkin memiliki dukungan untuk ini.
Tentu saja Anda dapat melakukan semuanya dalam produksi dengan SElinux diatur ke permisif. Kumpulkan semua pesan, menganalisisnya memutuskan perubahan Anda dan menyebarkannya.
Ada banyak lagi yang perlu diketahui tentang SELinux, tetapi itulah batas kemampuan saya, Michael Hampton lebih baik dan Mathew Ife jauh lebih baik lagi, mereka mungkin harus menambahkan lebih banyak.
sumber
allow httpd_t httpd_sys_content_t:sock_file write;
tidak cukup jelas bagi saya seperti yang Anda harapkan. Apa maksudnya kebijakan pada file itu perlu diubah (yaitu, apa yang terjadi setelahnya-t
dalamsemanage
perintah?semanage
perintah Anda secara langsung. Saya perlu menambahkan--add
argumen.httpd_var_run_t
seperti Michael Hampton dicatat di bawah ini,audit2allow
pesannya adalah:allow httpd_t var_run_t:sock_file write;
var_run_t
tidakhttpd_var_run_t
.audit2allow
berkataallow httpd_t var_run_t:sock_file write;
Jenis yang ingin Anda gunakan tidak
httpd_sys_content_t
. Ini untuk file statis yang dimaksudkan untuk melayani server web kepada agen pengguna.Untuk soket yang digunakan untuk komunikasi antarproses, tipe yang Anda cari adalah
httpd_var_run_t
.Meskipun, harap dicatat bahwa karena Anda menjalankan gunicorn tanpa batasan, mungkin ada masalah tambahan berkomunikasi dengannya.
sumber
Saya mencoba jawaban sebelumnya tanpa hasil, dalam kasus saya saya menggunakan server nginx sebagai antarmuka untuk aplikasi uwsgi menggunakan soket unix untuk mengkomunikasikannya, OS saya Ini adalah server Fedora 26.
Soket unix dibuat di direktori
/var/local/myapp
:Untuk mengkonfigurasi SELinux saya harus menambahkan tipe konteks:
httpd_sys_rw_content_t
sumber