laravel / reverb

Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.
https://reverb.laravel.com
MIT License
1.02k stars 71 forks source link

Starting in secure mode even if certificate is not specified #155

Closed vatsake closed 4 months ago

vatsake commented 4 months ago

Reverb Version

1.0.0-beta6

Laravel Version

11

PHP Version

8.2

Description

Am I understanding correctly, that if the certificate is not specified then it tries to grab it itself from "hostname"?

My app is behind a reverse proxy, that means the connection between proxy and app is not encrypted. The websocket server is started in secure mode with wrong certificate.

    location /websocket {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http:/app:8080/;
    }

src/Servers/Reverb/Factory.php 114

    protected static function configureTls(array $context, ?string $hostname): array
    {
        $context = array_filter($context, fn ($value) => $value !== null);

        $usesTls = ($context['local_cert'] ?? false) || ($context['local_pk'] ?? false);

        if (! $usesTls && $hostname && Certificate::exists($hostname)) {
            [$certificate, $key] = Certificate::resolve($hostname);

            $context['local_cert'] = $certificate;
            $context['local_pk'] = $key;
        }

        return $context;
    }

You can close this issue if the first question is false.

Steps To Reproduce

.

joedixon commented 4 months ago

Reverb will try to grab the certificate from the Valet or Herd paths using the REVERB_HOST value, but only if you are not manually specifying your own certifcate.

vatsake commented 4 months ago

Okay, the problem isn't because of that, but it is because of #105.

I have these tls options in reverb config file. Currently reverb will run in secure mode if the tls option is not empty (even if 'local_cert' is null). Or was it intended this way?

'tls' => [
    'local_cert' => env('REVERB_CERT'),
    'verify_peer' => env('APP_ENV') === 'production',
    'allow_self_signed' => env('APP_ENV') !== 'production',
],
joedixon commented 4 months ago

That was fixed here: https://github.com/laravel/reverb/pull/85

Are you on the latest version?

vatsake commented 4 months ago

Yeah, v1.0.0-beta7. Just tried it like this: image And the websocket server started in secure mode.

joedixon commented 4 months ago

Can you do some logging in here and see where the certificate is being found?

https://github.com/laravel/reverb/blob/bf6b6f85cdc3fff360761dac9f854c27ffc792fe/src/Servers/Reverb/Factory.php#L114-L128

vatsake commented 4 months ago

Certainly.

No certificate is found. Method configureTls returns

array:1 [
  "verify_peer" => false
]

And because it is not empty: https://github.com/laravel/reverb/blob/bf6b6f85cdc3fff360761dac9f854c27ffc792fe/src/Servers/Reverb/Factory.php#L54-L56

joedixon commented 4 months ago

Thanks @vatsake

Can you give this PR a try? https://github.com/laravel/reverb/pull/158

vatsake commented 4 months ago

@joedixon https://github.com/laravel/reverb/blob/9c12e2d8a650237525cfb0abbc36b1530a721804/src/Servers/Reverb/Factory.php#L56 Currently it starts in secure mode if usesTls is false, I think these need to be switched up.

joedixon commented 4 months ago

Great minds think alike! Just pushed a fix

vatsake commented 4 months ago

I can confirm that now it works perfectly.