phpredis / phpredis

A PHP extension for Redis
Other
9.97k stars 2.14k forks source link

Using TLS for Sessions with Heroku Redis 6 #1941

Open outmost opened 3 years ago

outmost commented 3 years ago

Expected behaviour

Persist user sessions to Redis.

Actual behaviour

This is using Redis 6 on StackHero, which works perfectly:

        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', "tls://[HOST].stackhero-network.com:6380?auth=[PASSWORD]");

This is using Redis 6 on Heroku, which causes the error below:

        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', "tls://[HOST].eu-west-1.compute.amazonaws.com:21070?auth=[PASSWORD]");

Error message:

Warning: session_start(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in /var/www/application/core/Session.php on line 19
Warning: session_start(): Failed to read session data: redis (path: tls://[HOST].eu-west-1.compute.amazonaws.com:21070?auth=[PASSWORD]) in /var/www/application/core/Session.php on line 19

I'm pretty certain it's down to Heroku Redis being self-signed certificates, but I'm not sure how to disable certificate verification / whether that's the right approach.

Thanks in advance for any pointers.

I'm seeing this behaviour on

Steps to reproduce, backtrace or example script

I've checked

yariksheptykin commented 3 years ago

Disabling certificate validation shold be the option of last resort as it makes it easy to break tls. Better approach would be to try to add heroku's (root & intermediate) certificates to the list of trusted ones. They should be added to the list of certs that PhpRedis uses for validation. Not sure how to do this practically. Speculation: phpredis uses underlying system for tls, so the certs shuold be places somewhere where system looks for them, like https://wiki.ubuntu.com/CAcert, or some other known location.

eddturtle commented 3 years ago

Hope you don't mind me asking @tomsutton1984 - did you manage this in the end with Heroku? I'm currently hitting the same issue

eddturtle commented 2 years ago

I asked Heroku Support about this issue, thought I'd share their reply here in case anyone's in the same boat

The data team has actually been working to make verifiable SSL certificates available on Heroku Data. However, we still cannot tell whether or when we may be able to do so. If you'd be able to start providing verifiable certificates, we will most likely be announcing it as an entry to Changelog.

Unfortunately, until then, it seems that the best way forward is to follow along with the GitHub issue you are aware of: https://github.com/phpredis/phpredis/issues/1941

I am sorry that we don't have better news here. Please let us know if we may be of further help to you here.

Regards,

shengslogar commented 2 years ago

For anyone using Laravel and upgrading to Redis 6 on Heroku, your config/database.php would need to look something like this (you can pass context to global options or within a named connection):

'redis' => [
    ...
    'options' => [
        'context' => [
            // Disable SSL validation for Heroku
            // @url https://github.com/phpredis/phpredis/issues/1941
            'stream' => [
                'verify_peer' => false,
                'verify_peer_name' => false
            ]
        ]
    ],

    'default' => [
        'url' => env('REDIS_URL'),
         ...
    ]
]
wit3 commented 2 years ago

For anyone using Laravel and upgrading to Redis 6 on Heroku, your config/database.php would need to look something like this (you can pass context to global options or within a named connection):

'redis' => [
    ...
    'options' => [
        'context' => [
            // Disable SSL validation for Heroku
            // @url https://github.com/phpredis/phpredis/issues/1941
            'stream' => [
                'verify_peer' => false,
                'verify_peer_name' => false
            ]
        ]
    ],

    'default' => [
        'url' => env('REDIS_URL'),
         ...
    ]
]

If i try this solution i receive this error

Redis::connect(): Failed to enable crypto

any suggest? @shengslogar