PHP не может подключиться к PostgreSQL с ошибкой «Отказано в доступе» в SELinux

3225
Chloe

Мое приложение PHP может подключаться, когда я выключаю SELinux, но не с ним.

setenforce 0; curl -I http://domain.com; setenforce 1 

Не дает ошибок в /var/log/httpd/error_log. Однако, если он у меня включен, я получаю эту ошибку:

Предупреждение PHP: pg_connect (): невозможно подключиться к серверу PostgreSQL: не удалось подключиться к серверу: разрешение запрещено. Работает ли сервер локально и принимает подключения через сокет домена Unix "/tmp/.s.PGSQL.5432"?

я пробовал

# restorecon -R -v /home/domain/public_html # chcon -R -t httpd_sys_rw_content_t /home/domain/public_html/ # chcon -v --type=httpd_sys_content_t /home/domain/public_html # semanage fcontext -a -t httpd_sys_content_t "/home/domain/public_html(/.*)?" # service httpd restart 

С SELinux я все еще могу сделать это:

# php -a Interactive shell  php > $connection = pg_connect ("dbname=domain user=domain password=xxxxxx") or die(pg_last_error()); php > echo $connection; Resource id #1 

Вот ошибка из /var/log/audit/audit.log:

type=AVC msg=audit(1404684735.513:97245): avc: denied { write } for pid=3594 comm="httpd" name=".s.PGSQL.5432" dev=xvde ino=2552 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:tmp_t:s0 tclass=sock_file type=SYSCALL msg=audit(1404684735.513:97245): arch=c000003e syscall=42 success=no exit=-13 a0=b a1=7f40ae4fd640 a2=6e a3=0 items=0 ppid=26231 pid=3594 auid=0 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=2700 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null) 

CentOS 6.5

1
Как отметил @oneiroi, отсутствует самая важная информация: тип ошибки SELinux. Если вы можете запустить его вручную из оболочки, хотя это, вероятно, связано с доменом или ролью, применяемой к вашему веб-серверу, в зависимости от того, как он запущен. 9 лет назад 0

3 ответа на вопрос

1
Oneiroi

Требуется больше информации:

Вам нужно посмотреть /var/log/audit/audit.log для отказов AVC.

в качестве альтернативы убедитесь, что у вас установлено следующее

  1. setroubleshoot-сервер
  2. auditd
  3. messagebus

Сообщения появятся в / var / log / messages

дополнительная ссылка: http://danwalsh.livejournal.com/7995.html

Причина, по которой ваша интерактивная оболочка php работает, заключается в том, что она работает в вашем пользовательском контексте, где ваше приложение работает в контексте apache.

Я подозреваю, что проблема будет связана с тем, что у пользователя / процесса HTTPD возникают проблемы с подключением к Postgres (т. Е. Проблема не в html-файлах, а в невозможности PHP вызвать базу данных). Похоже, @Chloe идет по правильному пути, рассматривая правила SELinux, но неправильная «ветвь» в том, что сбой происходит при подключении к службе Postfix, а не к службе Apache. davidgo 9 лет назад 0
Я добавил ошибки из `audit.log`. По ссылке я установил `setroubleshoot`, но он не запустится как сервис:` setroubleshoot: неопознанный сервис`. `setroubleshoot-server: нераспознанный сервис`. «Нет доступных пакетов аудита» Chloe 9 лет назад 0
@chloe сначала нужно `yum установить setroubleshoot-server` ;-), а затем перезапустить шину сообщений, если она уже есть. Oneiroi 9 лет назад 0
1
Chloe

I fixed it! I found a solution here: https://bugzilla.redhat.com/show_bug.cgi?id=772084#c8

What I did was take the 2 lines that were written to audit.log, and piped them into audit2allow, which generates 2 files, a binary and a text. Then I imported that file into semodule. I don't understand the file however. Make sure you capture the httpd errors.

tail -2 /var/log/audit/audit.log | audit2allow -M mypol semodule -i mypol.pp # takes a while 

The actual text file it generated was mypol.te

module mypol 1.0; require { type httpd_t; type initrc_t; class unix_stream_socket connectto; } #============= httpd_t ============== allow httpd_t initrc_t:unix_stream_socket connectto; 
Хорошо, все, что вы сделали здесь, - это создайте новую политику, чтобы позволить действию выполнить; Я не говорю, что это неправильно. Однако БУДЬТЕ ОЧЕНЬ ОСТОРОЖНЫ в том, что вы разрешаете в политике, и понимайте, что именно вы разрешаете принимать, пожалуйста Oneiroi 9 лет назад 0
@Oneiroi Можете ли вы объяснить, что он делает? Chloe 9 лет назад 0
@Chole SELinux предназначен для предотвращения действий «вне контекста»; иногда может потребоваться написать новый модуль, чтобы определить контексты, в которых может работать программа; это следует понимать, например, разрешить httpd_t доступ к passwd_file_t и shadow_t было бы очень плохой идеей, так как передача из Audit.log в Audit2allow может «укусить вас» - вот и все, что я здесь говорю. Oneiroi 9 лет назад 1
0
JJC

Did you try simply setting the SELinux policy boolean that allows httpd to make DB connections via:

setsebool -P httpd_can_network_connect_db 1 

This worked for me. You can check/verify that the setting is set by:

getsebool httpd_can_network_connect_db 

which should return '... => on'

After that, if you tail -f /var/log/audit/audit.log and re-attempt your operation, it should work.