У меня есть веб-сервер под управлением CentOS 6.2 и последней версии Apache из репозиториев. Todey Я столкнулся с проблемой при запуске исполняемой программы через CGI на Apache. Программа должна подключиться к какому-либо сайту, загрузить что-то и затем вернуть это пользователю (обычный запрос порта 80, ничего подозрительного).
Проблема в том, что программы CGI возвращают Permission denied
на socket_open
команда.
Другие более простые программы CGI, которые не требуют подключения к сети, работают нормально, и эта программа работает так же хорошо, когда вызывается из командной строки, поэтому я подозревал, что есть проблемы с разрешениями, и поскольку setuid
на исполняемом файле не решила проблему, я пришел к выводу, что это то, что контролирует SELinux.
Я никогда особо не работал с SELinux, но getsebool -a | grep httpd
возвращается
allow_httpd_anon_write --> off
allow_httpd_mod_auth_ntlm_winbind --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_read_user_content --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_tmp_exec --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
Я подозреваю что httpd_can_network_connect --> off
здесь проблематичный, но это разрешение для httpd
, а не сам исполняемый файл. Унаследованы ли разрешения SELinux от родительского процесса? Как бы включить его только для сценария, а не для всего? httpd
? Или это совсем другая проблема, не связанная с SELinux?
Спасибо за помощь.
Редактировать: Я попытался setenforce 0
и скрипт тогда работает, так что это вещь SELinux.
Редактировать 2: ausearch -ts recent -m avc
возвращается
time->Thu May 3 23:52:29 2012
type=SYSCALL msg=audit(1336081949.221:18563): arch=c000003e syscall=42 success=no exit=-13 a0=8 a1=7fff21161cb0 a2=10 a3=7fff21161a30 items=0 ppid=6813 pid=6814 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=".stutsk" exe="/var/www/html/stutsk-cgi/.stutsk" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null)
type=AVC msg=audit(1336081949.221:18563): avc: denied { name_connect } for pid=6814 comm=".stutsk" dest=80 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket
Унаследованы ли разрешения SELinux от родительского процесса?
Да, если правило не вызывает переход на новый домен.
Как сделать так, чтобы он был включен только для сценария, а не для всего httpd?
Вам потребуется создать новый домен, разрешающий доступ к сети, и написать правило, которое вызывает переход домена при вызове интерпретатора сценария. Обратите внимание, что это приведет к тому, что любой сценарий, вызываемый этим интерпретатором при вызове httpd, будет следовать этому переходу; гораздо менее тривиально вызвать переход домена для конкретного сценария.
Лично у меня были бы оговорки, чтобы разрешить обработке CGI получать данные из сети (просто заставляет меня чувствовать себя некомфортно), но вы можете включить это с помощью следующей политики:
policy_module(localhttpd_script_t, 1.0.0)
gen_require(`
type httpd_sys_script_t;
type http_port_t;
')
gen_tunable(`httpd_script_can_http_connect', `false')
tunable_policy(`httpd_script_can_http_connect', `
allow httpd_sys_script_t self:tcp_socket rw_socket_perms;
corenet_tcp_connect_http_port(httpd_sys_script_t)
corenet_tcp_sendrecv_http_port(httpd_sys_script_t)
')
Вам нужно будет установить policycoreutils-python вещи, если это еще не сделано.
Для этого запустите
make -f /usr/share/selinux/devel/Makefile load
Это скомпилирует и установит модуль. Я скомпилировал Fedora 15, но не думаю, что для этой системы есть какие-то особые правила.
Чтобы включить это (временно), выполните команду setsebool httpd_script_can_http_connect 1 и сделать постоянным setsebool -P httpd_script_can_http_connect 1 .