laravel / reverb

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

Reverb + Valet SSL certificate problem: unable to get local issuer certificate #93

Closed ghost closed 5 months ago

ghost commented 6 months ago

Reverb Version

1.0.0-beta3

Laravel Version

4.6.1

PHP Version

8.3.3

Description

I'm running on osx (14.2.1) with valet (4.6.1). I have created a new laravel project (11.0.6) using the laravel new command. I've secured my site using valet secure.

I've ran the artisan install:broadcasting to install reverb. I'm running the server very basic using artisan reverb:start --debug (also tried the command from the docs: php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="project.test") which gives me:

INFO Starting secure server on 0.0.0.0:8080 (project.test).

So far it seems good to me. I've created an event to test with. Because the event is queued, I run artisan queue:listen. Then I use tinker to send the message:

$newMessage = new \App\Events\NewMessage('Hello, world!');broadcast($newMessage)->toOthers();

The message is run in the queue listener, but fails. When I look in the log file, I see this message:

local.ERROR: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for ...

I've checked to see if the certificates exists in the .config/valet directory and they do.

In my .env I've set REVERB_HOST=project.test as well.

Steps To Reproduce

joedixon commented 6 months ago

Hey @thatsalltheyare, are you able to connect to the server from the client over wss?

ghost commented 6 months ago

Hi, @joedixon, yes I am able to do that in Firefox

joedixon commented 6 months ago

Can you share all the environment variables you have set?

ghost commented 6 months ago
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:uCb3nZ7Rf0Y51N3EPW38gx54m5/J4m3QU+rBdUNkPFw=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_DOMAIN=project.test
APP_URL=https://${APP_DOMAIN}

APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

APP_MAINTENANCE_DRIVER=file
APP_MAINTENANCE_STORE=database

BCRYPT_ROUNDS=12

LOG_CHANNEL=daily
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=project
DB_USERNAME=root
DB_PASSWORD=

SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null

BROADCAST_CONNECTION=reverb
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database

CACHE_STORE=database
CACHE_PREFIX=

MEMCACHED_HOST=127.0.0.1

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

VITE_APP_NAME="${APP_NAME}"

REVERB_APP_ID=721616
REVERB_APP_KEY=suntnfxzmcad0t0cxc9w
REVERB_APP_SECRET=9mz8pk8eqw7slt9lz97c
REVERB_HOST=${APP_DOMAIN}
REVERB_PORT=8080
REVERB_SCHEME=https

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
joedixon commented 6 months ago

If you hit project.test:8080 in the browser, do you get a certificate error?

lsdevelop commented 6 months ago

Similarly, with Herd Pro

.env

APP_URL=https://chatbot.test
...
REVERB_APP_ID=1001
REVERB_APP_KEY=laravel-herd
REVERB_APP_SECRET=secret
REVERB_HOST=chatbot.test
REVERB_PORT=8080
REVERB_SCHEME=https

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

reverb.config

'servers' => [

        'reverb' => [
            'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
            'port' => env('REVERB_SERVER_PORT', 8080),
            'hostname' => env('REVERB_HOST'),
            'options' => [
                'tls' => [],
            ],
            'scaling' => [
                'enabled' => env('REVERB_SCALING_ENABLED', false),
                'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
            ],
            'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
        ],

],

Service reverb on Herd.

REVERB_APP_ID=1001
REVERB_APP_KEY=laravel-herd
REVERB_APP_SECRET=secret
REVERB_HOST="0.0.0.0"
REVERB_PORT=8080

echo.ts

window.Pusher = Pusher;
window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
});

browser:

image

request https://chatbot.test:8080

image

request http://chatbot.test:8080

image

Notes: In unsecure settins works fine! In production using real certificate works fine too!

ghost commented 6 months ago

If you hit project.test:8080 in the browser, do you get a certificate error?

https://project.test:8080

An error occurred during a connection to project.test:8080. PR_END_OF_FILE_ERROR

http://project.test:8080

The connection to the server was reset while the page was loading.

joedixon commented 6 months ago

@lsdevelop the service in Herd doesn't support TLS right now.

When you are running Reverb alongside your application, it doesn't look to me like Reverb is able to find a certificate for chatbot.test. When is does find a certifcate, it won't allow you to connect over plaintext. Is that site secured in Herd?

Would you be able to carry out some logging here to see if the certicate is being found? https://github.com/laravel/reverb/blob/7237ff17a249128218c614a6e0f9cf0a8aca91a9/src/Certificate.php#L20-L33

joedixon commented 6 months ago

@thatsalltheyare do you see the same thing in all browsers?

ghost commented 6 months ago

Yes, I've just checked in Safari and chrome (the previous message was in firefox)

joedixon commented 6 months ago

@thatsalltheyare can you try the same as my suggestion able and carry out some logging here to see if the certificate is being found?

https://github.com/laravel/reverb/blob/7237ff17a249128218c614a6e0f9cf0a8aca91a9/src/Certificate.php#L20-L33

ghost commented 6 months ago

I did the logging like this:

   foreach (static::paths() as $path) {
            if (file_exists($path.$certificate) && file_exists($path.$key)) {
                dump($path.$certificate);
                dump($path.$key);
                return [$path.$certificate, $path.$key];
            }
        }

The result:

"/Users/user/.config/valet/Certificates/project.test.crt" // vendor/laravel/reverb/src/Certificate.php:28
"/Users/user/.config/valet/Certificates/project.test.key" // vendor/laravel/reverb/src/Certificate.php:29
"/Users/user/.config/valet/Certificates/project.test.crt" // vendor/laravel/reverb/src/Certificate.php:28
"/Users/user/.config/valet/Certificates/project.test.key" // vendor/laravel/reverb/src/Certificate.php:29

   INFO  Starting secure server on 0.0.0.0:8080 (project.test).

Seems like the certificates can be found.

lsdevelop commented 6 months ago

@lsdevelop the service in Herd doesn't support TLS right now.

When you are running Reverb alongside your application, it doesn't look to me like Reverb is able to find a certificate for chatbot.test. When is does find a certifcate, it won't allow you to connect over plaintext. Is that site secured in Herd?

Would you be able to carry out some logging here to see if the certicate is being found?

https://github.com/laravel/reverb/blob/7237ff17a249128218c614a6e0f9cf0a8aca91a9/src/Certificate.php#L20-L33

image

Yes, i`m trying another possibility

mateusztumatek commented 5 months ago

i have same problem, also using laravel Valet. On MacOs. Only one setup works, when i run everything localhost (using php artisan serve). This is the only way i can connect to websocket from my frontened.

mateusztumatek commented 5 months ago

This PR fixed my issue in local development. The only line is needed is verify_peer option in servers.reverb.options.tls config. And also changes in Server Factory class.

joedixon commented 5 months ago

This will be resolved in the next release: https://github.com/laravel/reverb/pull/85