audit2allow없이 nLinux에 nginx 액세스를 허용하도록 SELinux에 지시하려면 어떻게해야합니까?


10

에서 유닉스 소켓을 통해 gginx에 nginx 전달 요청을했습니다 /run/gunicorn/socket. 기본적으로이 동작은 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)

어디서나 (예를 들어 herehere ), nginx에 요청을하고 SELinux에서 요청을 거부 한 다음 audit2allow향후 요청을 허용하도록 실행하라는 지시를 내릴 수있는 지침 . 이 동작을 명시 적으로 허용하는 명령 chcon이나 semanage명령을 알아낼 수 없습니다 .

이것이 유일한 방법입니까? 먼저 시도를 거부하지 않고 거부 된 것을 가능하게하는 도구를 실행하지 않고 nginx가 소켓에 쓸 수있는 정책을 설정할 수 없다는 것은 우스운 것 같습니다. 무엇이 활성화되어 있는지 정확히 어떻게 알 수 있습니까? 자동화 환경에서 기계를 설정하는 경우 어떻게 작동합니까?

CentOS 7을 사용하고 있습니다.


AVC 거부 메시지를 표시해야하며 실행중인 OS 및 버전을 아는 것이 좋습니다.
user9517

@ 좋은 지적.
drs

답변:


23

먼저 시도를 거부하지 않고 거부 된 것을 가능하게하는 도구를 실행하지 않고 nginx가 소켓에 쓸 수있는 정책을 설정할 수 없다는 것은 우스운 것 같습니다.

SELinux는 필수 액세스 제어입니다. 기본적으로 사물이 거부되며 명시 적으로 무언가를 허용해야합니다. 정책 작성자가 특정 (프 랭켄) 스택으로 간주하지 않거나 데몬의 작성자가 SELinux에서이를 인식하고 정책을 작성하지 않은 경우 귀하는 본인의 책임입니다. 서비스가 수행하는 작업과 서비스가 SELinux와 상호 작용하는 방식을 분석하고이를 허용하기위한 고유 한 정책을 마련해야합니다. audit2why , audit2allow 등 을 도와주는 도구가 있습니다 .

... 이것이 유일한 방법입니까?

아니요, 그러나 그것은 당신이하려는 일과 솔루션이 무엇인지에 대한 방법에 달려 있습니다. 예를 들어 nginx (httpd_t)를 포트 8010 (unreserved_port_t)에 바인딩 할 수 있습니다. nginx를 시작하면 실패합니다

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

그리고 당신은 (결국) 감사 로그를보고 찾아

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

audit2alllow를 통해 이것을 실행하고 그 결과를 순진하게 받아 들일 수 있습니다.

allow httpd_t port_t:tcp_socket name_bind;

그러면 httpd_t가 모든 tcp 포트에 연결할 수 있습니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다.

sesearch 를 사용 하여 정책을 조사하고 httpd_t가 name_bind 할 수있는 포트 유형을 확인할 수 있습니다.

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 ;
...

다른 유형 중에서 http_t는 http_port_t에 바인딩 할 수 있습니다. 이제 semanage 를 사용 하여 좀 더 깊이 파고들 수 있습니다 .

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

포트 8010이 표시되지 않습니다. nginx가 포트 8010에 바인딩되기를 원하므로 http_port_t 목록에 추가하는 것은 무리가 없습니다.

semanage port -a -t http_port_t -p tcp 8010

이제 nginx는 위의 모든 tcp 포트가 아니라 포트 8010에 name_bind 할 수 있습니다.

무엇이 활성화되어 있는지 정확히 어떻게 알 수 있습니까?

정책 변경은 읽기 쉬우므로 감사를 통해 위의 메시지를 실행하십시오.

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

상당히 설명이 필요합니다.

이들 중 첫 번째는 inum 76151이있는 파일을 참조합니다. find를 사용하여 이름 (find / -inum 76151)을 얻은 다음 semanage fcontext -a -t ...정책을 변경하고 컨텍스트를 수정하기 위해 restorecon을 사용할 수 있습니다.

두 번째는 /run/gunicorn/socket다시 잘못된 컨텍스트를 갖는 것과 관련이 있습니다. sesearch를 사용하면 http_t가 http_t 유형의 unix_stream_sockets에 연결할 수 있음을 알 수 있습니다. 예를 들어 컨텍스트를 변경할 수 있습니다

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

이것은 / run / gunicorn과 tree |의 컨텍스트를 설정합니다 그 아래의 파일은 httpd_t에 있습니다.

자동화 환경에서 기계를 설정하는 경우 어떻게 작동합니까?

시스템을 분석하고 테스트를 적절히 변경해야합니다. 그런 다음 자동화 도구를 사용하여 변경 사항을 배포하고 꼭두각시 및 ansible에서이를 지원합니다.

물론 SElinux를 허용으로 설정하여 프로덕션 환경에서 모든 작업을 수행 할 수 있습니다. 모든 메시지를 수집하고 변경 사항을 결정한 후 배포하십시오.

SELinux에 대해 더 많은 정보가 있지만 그것은 나의 기술의 한계입니다. Michael Hampton이 더 좋고 Mathew Ife가 더 나아질 것입니다.


1
귀하의 조언은 철저하고 이러한 문제를 직접 해결하는 데 훨씬 더 가까이 가지만 여전히 조금 짧습니다. allow httpd_t httpd_sys_content_t:sock_file write;당신이 원하는 것만 큼 나 자신을 설명하지 않습니다. 이 파일에 대한 정책을 다음과 같이 변경해야한다고 말하는 것은 무엇입니까 (즉, 명령 -t에서 수행 할 내용)semanage
drs

또한 semanage명령을 직접 사용할 때 사용 지침을 얻습니다 . --add인수 를 추가해야합니다 .
drs

실제로 소켓 파일의 유형을 httpd_var_run_tMichael Hampton이 아래와 같이 변경 한 후 audit2allow메시지는 다음과 같습니다.allow httpd_t var_run_t:sock_file write;
drs

설정 var_run_t하지 않은 것 같습니다 httpd_var_run_t.
user9517

@lain, 흠 .. 주사위가 없습니다. 이제 audit2allow말한다allow httpd_t var_run_t:sock_file write;
drs

2

사용하려는 유형이 아닙니다 httpd_sys_content_t. 웹 서버가 사용자 에이전트에 제공하는 정적 파일 용입니다.

프로세스 간 통신에 사용되는 소켓의 경우 찾고있는 유형은 httpd_var_run_t입니다.

gunicorn을 무제한으로 실행했기 때문에 추가 문제가있을 수 있습니다.


3
감사! 이것이 SELinux 문제 중 하나를 처리 한 것으로 보입니다. gunicorn 또는 다른 서비스를 설정하는 방법에 대한 조언이 있습니까?
drs

1

나는 이전의 답변을 성공없이 시도했지만, 내 경우에는 유닉스 소켓을 사용하여 uwsgi 응용 프로그램의 프론트 엔드로 nginx 서버를 사용하고 있으며 내 OS는 Fedora 서버입니다.

유닉스 소켓은 다음 디렉토리에 생성됩니다 /var/local/myapp:

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

SELinux를 구성하려면 컨텍스트 유형을 추가해야했습니다. httpd_sys_rw_content_t

semanage fcontext -at httpd_sys_rw_content_t "/var/local/myapp(/.*)?"
restorecon -R -v '/var/local/myapp' 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.