SELinux'a audit2allow olmadan bir unix soketine nginx erişimine izin vermesini nasıl söyleyebilirim?


10

Bir unix soketi ile gunicorn nginx yönlendirme istekleri var /run/gunicorn/socket. Varsayılan olarak, bu davranışa SELinux tarafından izin verilmez:

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)

Baktığım her yerde (örneğin, burada ve burada ), nginx'e bir talepte bulunmalarını sağlamak için bu talimatın SELinux tarafından reddedilmesi, sonra audit2allowgelecekteki taleplere izin vermek için çalıştırılması talimatı . Bu davranışa açıkça izin veren herhangi bir komut chconveya semanagekomut bulamıyorum.

Tek yolu bu mu? Nginx'in bir sokete yazma girişimine izin vermeden ve sonra reddedilen şeyleri mümkün kılan bir araç çalıştırmadan bir sokete yazmasına izin veren bir politika ayarlayamamanız saçma görünüyor. Neyin etkinleştirildiğini tam olarak nasıl biliyorsunuz? Makinelerinizi otomasyon altında kurarsanız bunun nasıl çalışması gerekiyor?

CentOS 7 kullanıyorum.


Bize AVC reddedilen mesajları göstermeniz gerekir ve hangi işletim sistemini ve sürümünü çalıştırdığınızı bilmek iyi olur.
user9517 13:16

@lain iyi bir nokta.
drs

Yanıtlar:


23

Nginx'in bir sokete yazma girişimine izin vermeden ve sonra reddedilen şeyleri mümkün kılan bir araç çalıştırmadan bir sokete yazmasına izin veren bir politika ayarlayamamanız saçma görünüyor.

Peki hayır, SELinux Zorunlu Erişim Kontrolüdür, varsayılan olarak işler reddedilir ve bir şeye açıkça izin vermeniz gerekir. Politika yazarları belirli bir (franken) yığını düşünmediyse veya bir daemon yazarları bunu SELinux için bilinçli ve yazılı bir politika haline getirmediyse, kendi başınızasınız. Hizmetlerinizin neler yaptığını ve SELinux ile nasıl etkileşime girdiklerini analiz etmeli ve buna izin vermek için kendi politikanızı oluşturmalısınız. Size yardım etmek için araçlar bulunmaktadır audit2why , audit2allow vs.

... Tek yolu bu mu?

Hayır, ama ne yapmaya çalıştığınıza ve çözümün ne olduğuna göre nasıl yapmaya çalıştığınıza bağlıdır. Örneğin, nginx'i (httpd_t) 8010 numaralı bağlantı noktasına (unreserved_port_t) bağlamak isteyebilirsiniz. Nginx'i başlattığınızda başarısız olur

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8010 failed (13: Permission denied)

ve (sonunda) denetim günlüğüne bakıp

type=AVC msg=audit(1457904756.503:41673): avc:  denied  { name_bind } for
pid=30483 comm="nginx" src=8010 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

Bunu audit2alllow aracılığıyla çalıştırabilir ve bulgularını saf bir şekilde kabul edebilirsiniz.

allow httpd_t port_t:tcp_socket name_bind;

bu da httpd_t'nin herhangi bir tcp portuna bağlanmasına izin verir. İstediğiniz bu olmayabilir.

Sen kullanabilirsiniz sesearch politikasını araştırmak ve liman tipleri httpd_t için name_bind neler yapabileceğini görmek için

sesearch --allow -s httpd_t | grep name_bind
...
allow httpd_t http_port_t : tcp_socket name_bind ;
allow httpd_t http_port_t : udp_socket name_bind ;
...

Diğer türler arasında http_t http_port_t dosyasına bağlanabilir. Şimdi biraz daha derin kazmak için semanage kullanabilirsiniz .

semanage port -l | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
...

Bağlantı noktası 8010 listelenmiyor. Nginx'in 8010 numaralı bağlantı noktasına bağlanmasını istediğimizden, http_port_t listesine eklemek mantıksız değil

semanage port -a -t http_port_t -p tcp 8010

Şimdi nginx'in yukarıdaki 8010 numaralı bağlantı noktasına adını vermesine izin verilecek ve yukarıdaki her tcp bağlantı noktasına değil.

Neyin etkinleştirildiğini tam olarak nasıl biliyorsunuz?

Politikadaki değişikliklerin okunması oldukça kolaydır, yukarıdaki mesajlarınızı denetim yoluyla çalıştırırız

allow httpd_t httpd_sys_content_t:sock_file write;
allow httpd_t initrc_t:unix_stream_socket connectto;

ki bu oldukça açıklayıcı görünüyor.

Bunlardan ilki, inum 76151 ile dosyaya atıfta bulunur. Dosya adını (find / -inum 76151) almak için find komutunu kullanabilir ve daha sonra semanage fcontext -a -t ...bağlamı düzeltmek için ilkeyi değiştirmek ve restorecon komutunu kullanabilirsiniz.

İkincisi /run/gunicorn/socket, yine yanlış bağlama sahip olan ile ilgilidir . Sesearch'ü kullanarak http_t türünün (diğerleri arasında) http_t türündeki unix_stream_sockets'e bağlanabildiğini görebiliriz. Böylece bağlamı buna göre değiştirebiliriz, örneğin

semanage fcontext -a -t httpd_t "/run/gunicorn(/.*)?"
restorecon -r /run

Bu, / run / gunicorn ve ağacın içeriğini belirler | altındaki dosyaları httpd_t.

Makinelerinizi otomasyon altında kurarsanız bunun nasıl çalışması gerekiyor?

Sistemi analiz etmeniz ve testte uygun değişiklikleri yapmanız gerekir. Daha sonra değişiklikleri dağıtmak için otomasyon araçlarınızı kullanırsınız, kukla ve ansible bunun için destek alır.

Elbette her şeyi SElinux'un izin verecek şekilde hazırladığı üretimde yapabilirsiniz. Tüm iletileri toplayın, değişikliklerinize karar vererek bunları analiz edin ve dağıtın.

SELinux hakkında bilinmesi gereken çok şey var, ancak bu becerilerimin sınırı, Michael Hampton daha iyi ve Mathew Ife yine çok daha iyi, eklemek için daha fazla şeyleri olabilir.


1
Tavsiyeniz kapsamlı ve bu sorunları kendim çözmem için beni biraz daha yaklaştırıyor. allow httpd_t httpd_sys_content_t:sock_file write;umduğun gibi kendimi açıklayıcı değil. Ya bu o dosya ihtiyaçlarına politikasını söylediğini şekilde değiştirilmesi (yani sonra ne gider -tde semanagekomuta?
DRS

Ayrıca, semanagekomutlarınızı doğrudan kullanırken kullanım talimatları alıyorum . Bir --addargüman eklemem gerekiyor .
drs

Aslında, soket dosyasının türünü httpd_var_run_tMichael Hampton'un aşağıda belirtildiği gibi değiştirdikten sonra , audit2allowmesajın şöyle olduğunu da söylemeliyim :allow httpd_t var_run_t:sock_file write;
drs

Eğer ayarlı gibi görünüyor var_run_tdeğil httpd_var_run_t.
user9517

@lain, hmm .. zar yok. Şimdi audit2allowdiyorallow httpd_t var_run_t:sock_file write;
drs

3

Kullanmak istediğiniz tür değil httpd_sys_content_t. Bu, web sunucusunun kullanıcı aracılarına sunması gereken statik dosyalar içindir.

İşlemler arası iletişim için kullanılan bir soket için aradığınız türdür httpd_var_run_t.

Yine de, silahsız bir şekilde koştuğunuz için, bununla iletişimde ek sorunlar olabileceğini lütfen unutmayın.


3
Teşekkürler! Bu SELinux sorunlarından biriyle ilgilenmiş gibi görünüyor. Silahın (veya başka bir hizmetin) nasıl ayarlanacağına dair herhangi bir işaretçi var mı?
drs

1

Önceki cevapları başarılı olmadan denedim, benim durumumda, bir uwsgi uygulaması için unix soketlerini kullanarak iletişim kurmak için bir nginx sunucusu kullanıyorum, işletim sistemim Bu bir Fedora sunucusu 26.

Unix yuvaları dizinde oluşturulur /var/local/myapp:

/var/local/myapp/server.sock    
/var/local/myapp/stats.sock

SELinux'u yapılandırmak için bağlam türünü eklemek zorunda kaldım: httpd_sys_rw_content_t

semanage fcontext -at httpd_sys_rw_content_t "/var/local/myapp(/.*)?"
restorecon -R -v '/var/local/myapp' 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.