Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP-FPM mode can't suppose unix socket connect ? #277

Closed
iyaozhen opened this issue Aug 27, 2015 · 7 comments

Comments

@iyaozhen
Copy link

commented Aug 27, 2015

Predis is very good, I already use it in my project. But I have a problem.

This is a demo:

require "frame/predis/Autoloader.php";
Predis\Autoloader::register();
$redis = new Predis\Client([
    'scheme' => 'unix',
    'path' => "/home/work/local/monitor/redis/redis.sock",
]);

$redis->set('test', '123');
echo $redis->get('test')."###\n";

cli:

php test.php
123###

well done.

But, when I access http://xxx/test.php:
image

It connect redis use TCP socket, but I set my redis "port 0", so failure.

I use nginx/1.4.4, php/5.4, redis/3.02, predis/1.0.3 and my system is Red Hat 4.4.4.

@iyaozhen

This comment has been minimized.

Copy link
Author

commented Aug 27, 2015

I modify redis.conf and listen on a TCP socket again, It is work well.

@nrk

This comment has been minimized.

Copy link
Owner

commented Aug 27, 2015

Hardly related to Predis. Check the permissions of your UNIX domain socket file to make sure that the user of your PHP-FPM or PHP-FCGI process can properly access it.

@nrk nrk closed this Aug 27, 2015

@iyaozhen

This comment has been minimized.

Copy link
Author

commented Aug 27, 2015

Thx, I forget check this point.

@iyaozhen

This comment has been minimized.

Copy link
Author

commented Aug 28, 2015

@nrk Maybe not UNIX socket permissions's reason. I chmod 777 redis.socket file, but It is not work.

srwxrwxrwx  work work   redis.sock
@nrk

This comment has been minimized.

Copy link
Owner

commented Aug 28, 2015

@iyaozhen it's not an issue related to Predis anyway or you wouldn't be able to use UNIX sockets via CLI. The exception says your script is trying to connect using TCP sockets which means it's a most likely a misconfiguration of your script.

@iyaozhen

This comment has been minimized.

Copy link
Author

commented Aug 28, 2015

@nrk I understand. I just worry it's Predis's bug. I'll check my environment again, It is must be my bug.

@allella

This comment has been minimized.

Copy link

commented Dec 20, 2016

There is another explanation for CentOS / RHEL 7 and related operating systems using SELinux.

SELinux blocks the connection between PHP-FPM and the unix sockets, even when permissions are 777. TCP connections are also blocked.

This SELinux block is evident in /var/log/audit/audit.log, where you'd see something like this for a UNIX socket connection

type=AVC msg=audit(1482196842.870:11582): avc: denied { write } for pid=27282 comm="php-fpm" name="redis.sock" dev="tmpfs" ino=149160 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:redis_var_run_t:s0 tclass=sock_file

or, like the following for a TCP connection

type=AVC msg=audit(1482376534.431:2829): avc: denied { name_connect } for pid=846 comm="php-fpm" dest=6379 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:redis_port_t:s0 tclass=tcp_socket

IF you're running Redis as a UNIX socket (i.e. using Port 0 and you set unixsocket and unixsocketperm in /etc/redis.conf) then try the following on the Linux command line to generate a permissive SELinux policy that allows Apache or Nginx to read and write to the Redis unix socket.

This assumes your socket is named /var/run/redis/redis.sock. If you're using something other than redis.sock then change the redis.sock in the grep command to match your socket file name.

setsebool -P daemons_enable_cluster_mode 1

grep 'redis.sock' /var/log/audit/audit.log | audit2allow -M httpd-to-redis-socket

semodule -i httpd-to-redis-socket.pp

To verify the custom httpd-to-redis-socket policy was applied run the command below:

semodule -l | grep httpd-to-redis-socket

Restart your web server and PHP-FPM for good measure

systemctl restart httpd.service && systemctl restart php-fpm.service

Kudos and more details on the Nginx blog under Example 2.

ELSE IF, you're running Redis as a TCP socket (i.e. how Redis works out of the box, like Port 6379 in /etc/redis.conf) then run

/usr/sbin/setsebool -P httpd_can_network_connect=1

Versions probably don't matter, since the issue is if SELinux is installed and enabled, but I was running CentOS 7, Apache 2.4.23, Redis 3.25, Predis 1.1, PHP and PHP-FPM 7.1. Both Apache and Nginx would seem to experience these problems and have the same solutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.