Cannot get TLS to work on proxied websocket with nginx
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- nginx, php
- Domain
- networking
Research direction
Start by reproducing the failed handshake with the Pawl client using the provided PHP client and nginx configuration, comparing behavior with verify_peer enabled and disabled. Inspect the TLS settings in the client, Ratchet server, and nginx proxy; done means identifying the handshake failure and establishing a verified wss connection through /wss.
Written by the indexing model from the issue text.
Description
I can get it to work with a javascript websocket but it will not work with a Pawl websocket. It seems like the handshake always fails and I'm not too sure how to debug it.
Here's my client code:
$secureContext = array(
'verify_peer' => false,
'verify_peer_name' => true,
'local_cert' => '/redacted/fullchain.pem',
'local_pk' => '/redacted/privkey.pem'
);
$reactConnector = new \React\Socket\Connector([
'dns' => '8.8.8.8',
'timeout' => 10,
'tls' => $secureContext
]);
$loop = \React\EventLoop\Loop::get();
$connector = new \Ratchet\Client\Connector($loop, $reactConnector, $secureContext);
$connector('wss://vps1.mazion.tv/wss')->then(function($conn) {
$conn->send('eyyy!');
$conn->close();
}, function ($e) {
echo "Could not connect: {$e->getMessage()}\n";
});
Here is my server code:
class saveTheBeardWS implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $from, $msg) {
echo $msg;
foreach ($this->clients as $client) {
if ($from != $client) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$conn->close();
}
}
$loop = Factory::create();
$server = new Server('127.0.0.1:8843', $loop);
$secureServer = new SecureServer($server, $loop, [
'local_cert' => '/redacted/fullchain.pem',
'local_pk' => '/redacted/privkey.pem',
'verify_peer' => false,
]);
$httpServer = new HttpServer(
new WsServer(
new saveTheBeardWS()
)
);
$ioServer = new IoServer($httpServer, $secureServer, $loop);
$loop->run();
Here's my nginx configuration with the proxy for the websocket:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream localhost{
server 127.0.0.1:8843;
}
server{
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /redacted/fullchain.pem; # managed by Certbot
ssl_certificate_key /redacted/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name redacted;
error_log /redacted/error_log warn;
root /redacted;
index index.php;
#error_page 404 /404.html;
#error_page 500 502 503 504 /50x.html;
location /wss {
proxy_pass https://localhost;
proxy_ssl_certificate /redacted/fullchain.pem;
proxy_ssl_certificate_key /redacted/privkey.pem;
proxy_ssl_session_reuse on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
keepalive_timeout 86400s;
reset_timedout_connection on;
}
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include /etc/nginx/conf.d/fastcgi.conf;
try_files $uri =404;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
}
location ~ (\.ht|\.json|\.db) {
deny all;
return 404;
}
location ^~ /vendor {
deny all;
return 404;
}
}
server{
listen 80;
listen [::]:80;
server_name redacted;
return 301 https://$host$request_uri;
}
If I enable verify_peer on the client-side. It fails to handshake.
If I understand correctly, with verify_peer disabled I am leaving the door open for MITM attacks. What are the risks associated with keeping verify_peer disabled?
What am I missing to get the TLS handshake to work?
- Dominant language
- PHP
- Stars
- 616
- Forks
- 98
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ratchetphp/Pawl
-
Difficulty 2/5 1-3 hours Newbie friendliness 48/100
ratchetphp/Pawl#166 · 6 comments · 5 reactions ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
ratchetphp/Pawl#165 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 20/100
ratchetphp/Pawl#163 · 1 comment ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
ratchetphp/Pawl#157 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
ratchetphp/Pawl#156 ·
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
getgrav/grav-plugin-api#45 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
RSS-Bridge/rss-bridge#5098 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
phingofficial/phing#2025 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
silverstripe/developer-docs#911 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100