PHP kann keine Verbindung zu PostgreSQL mit "Erlaubnis verweigert" -Fehler mit SELinux herstellen

3385
Chloe

Meine PHP-App kann eine Verbindung herstellen, wenn ich SELinux ausschalte, aber nicht bei eingeschaltetem Gerät.

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

Ergibt keine Fehler in /var/log/httpd/error_log. Wenn ich es jedoch habe, erhalte ich diesen Fehler:

PHP Warnung: pg_connect (): Verbindung zum PostgreSQL-Server kann nicht hergestellt werden: Verbindung zum Server konnte nicht hergestellt werden: Berechtigung verweigert. Läuft der Server lokal und akzeptiert Verbindungen auf dem Unix-Domänensocket "/tmp/.s.PGSQL.5432"?

ich habe es versucht

# 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 

Mit SELinux kann ich immer noch Folgendes tun:

# 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 

Hier ist der Fehler von /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 weist darauf hin, dass die relevantesten Informationen fehlen: die Art des SELinux-Fehlers. Wenn Sie es manuell von einer Shell aus ausführen können, hat dies wahrscheinlich mit der Domäne oder Rolle zu tun, die auf Ihren Webserver angewendet wird, je nachdem, wie es gestartet wird. vor 10 Jahren 0

3 Antworten auf die Frage

1
Oneiroi

Weitere Informationen werden benötigt:

Sie müssen unter /var/log/audit/audit.log nach den Avc-Ablehnungen suchen.

Stellen Sie alternativ sicher, dass Sie Folgendes installiert haben

  1. setroubleshoot-server
  2. auditd
  3. Messagebus

Die Nachrichten werden in / var / log / messages angezeigt

weitere Referenz: http://danwalsh.livejournal.com/7995.html

Der Grund, warum Ihre PHP-Shell funktioniert, ist, dass sie in Ihrem Benutzerkontext ausgeführt wird, während Ihre Anwendung mit dem Apache-Kontext ausgeführt wird.

Ich vermute, das Problem liegt im Zusammenhang mit dem HTTPD-Benutzer / -Prozess, der Probleme mit der Verbindung zu Postgres hat (dh es ist kein Problem mit den HTML-Dateien, eher weil PHP die Datenbank nicht aufrufen kann). Es sieht so aus, als sei @Chloe auf dem richtigen Weg, wenn man sich die SELinux-Regeln ansieht, aber der falsche "Zweig", in dem der Fehler bei der Verbindung zum Postfix-Dienst auftritt, nicht beim Apache-Dienst. davidgo vor 10 Jahren 0
Ich habe die Fehler von "audit.log" hinzugefügt. Über den Link habe ich `setroubleshoot` installiert, aber es wird nicht als Dienst gestartet:` setroubleshoot: nicht erkannter Dienst`. `setroubleshoot-server: nicht erkannter Dienst`. "Kein Paket-Audit verfügbar." Chloe vor 10 Jahren 0
@chloe du musst zuerst 'yum install setroubleshoot-server' installieren ;-) und dann messagebus neu starten, falls schon vorhanden Oneiroi vor 10 Jahren 0
1
Chloe

Ich habe es repariert! Ich habe hier eine Lösung gefunden: https://bugzilla.redhat.com/show_bug.cgi?id=772084#c8

Was ich tat, war, die 2 Zeilen, die in audit.log geschrieben wurden, zu nehmen und sie weiterzuleiten audit2allow, wodurch 2 Dateien, eine Binärdatei und ein Text erzeugt werden. Dann habe ich diese Datei importiert semodule. Ich verstehe die Datei jedoch nicht. Stellen Sie sicher, dass Sie die httpd-Fehler erfassen.

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

Die eigentliche Textdatei war 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; 
OK, Sie haben hier lediglich eine neue Richtlinie erstellt, damit die Aktion ausgeführt werden kann. Ich sage nicht, dass das falsch ist. Seien Sie jedoch sehr vorsichtig, was Sie in einer Richtlinie zulassen, und verstehen Sie, was Sie zulassen, bitte Oneiroi vor 10 Jahren 0
@Oneiroi Kannst du erklären, was es macht? Chloe vor 10 Jahren 0
@Chole SELinux verhindert das Auftreten von "Out-of-Context" -Aktionen. Manchmal kann es erforderlich sein, ein neues Modul zu schreiben, um Kontexte zu definieren, in denen das Programm arbeiten kann. Dies sollte verstanden werden. Zum Beispiel wäre es eine sehr schlechte Idee, httpd_t Zugriff auf die Passwd_file_t und shadow_t zu gewähren. Das Piping von audit.log in audit2allow hat das Potenzial, Sie zu beißen. Oneiroi vor 10 Jahren 1
0
JJC

Haben Sie versucht, einfach die boolesche SELinux-Richtlinie festzulegen, die es httpd ermöglicht, DB-Verbindungen herzustellen:

setsebool -P httpd_can_network_connect_db 1 

Das hat bei mir funktioniert. Sie können überprüfen / überprüfen, ob die Einstellung festgelegt ist:

getsebool httpd_can_network_connect_db 

die sollte '... => on' zurückgeben

Wenn Sie danach -f /var/log/audit/audit.log abschließen und den Vorgang erneut versuchen, sollte dies funktionieren.