Mam prośby o przesłanie przez Nginx do gunicorn przez gniazdo unix w /run/gunicorn/socket
. Domyślnie takie zachowanie nie jest dozwolone przez 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)
Gdziekolwiek spojrzę (np. Tutaj i tutaj ), instrukcje pozwalające temu powiedzieć na wysłanie żądania do nginx, mają zostać odrzucone przez SELinux, a następnie uruchomione, audit2allow
aby zezwolić na przyszłe żądania. Nie mogę znaleźć żadnego polecenia chcon
ani semanage
polecenia, które zezwalałoby na to zachowanie.
Czy to jedyny sposób? To absurdalne, że nie można skonfigurować polityki, która pozwala nginx pisać do gniazda bez uprzedniej próby odmowy, a następnie uruchomienia narzędzia, które umożliwia odmowę. Skąd dokładnie wiesz, co jest włączone? Jak to ma działać, jeśli konfigurujesz maszyny w trybie automatyzacji?
Używam CentOS 7.
Odpowiedzi:
Cóż, nie, SELinux jest obowiązkową kontrolą dostępu, domyślnie odmawia się i trzeba na coś wyraźnie zezwolić. Jeśli autorzy zasad nie brali pod uwagę konkretnego stosu (franken) lub autorzy demona nie sprawili, że SELinux jest świadomy i napisał dla niego zasady, to jesteś sam. Musisz przeanalizować, co robią twoje usługi i ich interakcje z SELinux, i opracować własną politykę, która na to pozwala. Dostępne są narzędzia, które pomogą Ci audit2why , audit2allow itp.
Nie, ale zależy to od tego, co próbujesz zrobić i jak próbujesz to zrobić, jakie jest rozwiązanie. Na przykład możesz powiązać nginx (httpd_t) z portem 8010 (unreserved_port_t). Po uruchomieniu nginx nie działa
a ty (ewentualnie) przeglądasz dziennik kontroli i znajdujesz
Możesz uruchomić to przez audit2alllow i naiwnie zaakceptować jego ustalenia
co następnie pozwala httpd_t połączyć się z dowolnym portem TCP. To może nie być to, czego chcesz.
Możesz użyć wyszukiwarki, aby sprawdzić zasady i zobaczyć, do jakich typów portów httpd_t może przypisać nazwę
Wśród innych typów http_t może wiązać się z http_port_t. Teraz możesz użyć semanage, aby kopać nieco głębiej.
Port 8010 nie znajduje się na liście. Ponieważ chcemy, aby nginx powiązał się z portem 8010, dodanie go do listy http_port_t nie jest nierozsądne.
Teraz nginx będzie mógł przypisać nazwę do portu 8010 i nie do każdego portu TCP jak wyżej.
Zmiany w polityce są dość łatwe do odczytania, uruchamiamy twoje wiadomości powyżej za pośrednictwem audit2allow, które otrzymujemy
które wydają się dość oczywiste.
Pierwszy z nich odnosi się do pliku z inum 76151. Możesz użyć find, aby uzyskać jego nazwę (find / -inum 76151), a następnie użyć
semanage fcontext -a -t ...
do zmiany polityki i przywracania, aby naprawić kontekst.Drugi odnosi się do
/run/gunicorn/socket
którego ponownie ma niewłaściwy kontekst. Za pomocą sesearch możemy zobaczyć, że http_t może łączyć się z uniksowymi_stream_sockets typu (między innymi) http_t. Możemy na przykład odpowiednio zmienić kontekstTo ustawia kontekst / run / gunicorn i drzewa | pliki poniżej to httpd_t.
Musisz przeanalizować system i wprowadzić odpowiednie zmiany w teście. Następnie używasz narzędzi automatyzacji do wdrożenia zmian, kukiełka i ansible mają na to wsparcie.
Oczywiście możesz to wszystko zrobić w produkcji z SElinux ustawionym na permisywny. Zbierz wszystkie wiadomości, przeanalizuj je, zdecyduj o zmianach i wdróż je.
O SELinuksie można dowiedzieć się o wiele więcej, ale to jest granica moich umiejętności, Michael Hampton jest lepszy, a Mathew Ife jest znowu lepszy, mogą mieć więcej do dodania.
źródło
allow httpd_t httpd_sys_content_t:sock_file write;
nie jest dla mnie tak oczywiste, jak się spodziewałeś. Co to jest powiedzenie politykę na który potrzebuje plików ma być zmieniony na (czyli po co idzie-t
wsemanage
komendzie?semanage
poleceń bezpośrednio. Muszę dodać--add
argument.httpd_var_run_t
jak zauważył poniżej Michael Hampton,audit2allow
komunikat brzmi:allow httpd_t var_run_t:sock_file write;
var_run_t
nie ustawiłeśhttpd_var_run_t
.audit2allow
mówiallow httpd_t var_run_t:sock_file write;
Typ, którego chcesz użyć, nie jest
httpd_sys_content_t
. Dotyczy to plików statycznych, które serwer WWW ma udostępniać agentom użytkownika.W przypadku gniazda używanego do komunikacji międzyprocesowej poszukiwany jest typ
httpd_var_run_t
.Pamiętaj jednak, że ponieważ uruchomiłeś gunicorn bez ograniczeń, mogą wystąpić dodatkowe problemy z komunikacją z nim.
źródło
Próbowałem wcześniejszych odpowiedzi bez powodzenia, w moim przypadku używam serwera nginx jako nakładki dla aplikacji uwsgi używającej gniazd unix do komunikacji, mój system operacyjny To serwer Fedora 26.
Gniazda unixowe są tworzone w katalogu
/var/local/myapp
:Aby skonfigurować SELinux, musiałem dodać typ kontekstu:
httpd_sys_rw_content_t
źródło