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

Using self-signed certs with TLS WebSockets causes "No response from ping frame." error event after a short period connectivity. #18977

Closed
alexnygren opened this issue May 3, 2023 · 7 comments
Assignees
Labels
ext/websocket related to the ext/websocket crate needs investigation requires further investigation before determining if it is an issue or not

Comments

@alexnygren
Copy link

alexnygren commented May 3, 2023

Using self signed certificates with Deno.listenTls() results in an error event being received "No response from ping frame".
This timeout error occurs after a short time (< 1 minute or so), after the initial connection. The problem seems to be in the switch to fastwebsockets crate in Rust as far as I can tell. Prior to 1.31 Deno websockets using self-signed certs seemed to work.

See:
chore(ext/websocket): remove ping frame handling (https://github.com/denoland/deno/pull/18847)

Example using the deno_std websocket chat example converted to using wss and TLS, and some sample self-signed certs.
example_reproduction.zip

@lucacasonato lucacasonato added needs investigation requires further investigation before determining if it is an issue or not ext/websocket related to the ext/websocket crate labels May 3, 2023
@caramboleyo
Copy link

caramboleyo commented May 13, 2023

I just saw this issue with a cloudflare certificate, then switched it off anf again have it with the servers own letsencrypt certificate. Also again the websockets do not work. They make some initial pushes, receive initial data from the server and then the client socket is just dead, still having readyState 1, after some time the “No response from ping frame” occurs. When i reconnect the socket same game: i can make some inital sends, then it goes numb. Went back to 1.32.3 (by cycling back through all latest versions) which seems to be the last version were websockets worked properly.

@jespertheend
Copy link
Contributor

I'm not having any issues with the chat example for some reason. I made another reduced test case where I'm able to reproduce it on both Linux and macOS, though I'm not sure what exactly the difference is between this and the chat example.

Reduced test case

import {Server} from "https://deno.land/[email protected]/http/mod.ts";
import {dirname, fromFileUrl, resolve} from "https://deno.land/[email protected]/path/mod.ts";

const scriptDir = dirname(fromFileUrl(import.meta.url));

const certPath = resolve(scriptDir, "websocket.crt");
Deno.writeTextFileSync(certPath, `
-----BEGIN CERTIFICATE-----
MIIFCzCCAvOgAwIBAgIUExQ4pn1ysAlDThobYR8dPXRkIpowDQYJKoZIhvcNAQEL
BQAwFTETMBEGA1UEAwwKTmFycm93IE9uZTAeFw0yMzA4MDcxMTA3MjRaFw0yNDA4
MDYxMTA3MjRaMBUxEzARBgNVBAMMCk5hcnJvdyBPbmUwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCWLwXynqULPa0XFV/K3tfrLvg8rnaK728//OHgZTJw
vPiTyu0NyIwuCpV4L1VQyte63F+y6kY1skGktdlXGl7fFRwxwBn/UWOFlNdV94yH
W2AZNyA4j4um71kUKWhypYbEPtOu6E4b0jcNVzPDidLHi3iv5HhMRtylBDkQFhYV
wsEvbLBE5PUlMOgz2AhX20/BZkAfp+TREWjDmkk0t/Lw2rCjO3IP+YKPRQLGYUTM
EU5zl3t/chmE9qaaJNv+PmD6Q1by7/R+uZQUkFCIguX7QcjjJgvnM7ZVoxq0I/a7
CAdeMzxtZLsU8oVkmaDeC1q/xeY/CzjJQwlfxHLRQ4PpeDJDqHG5rgtFrEBAZW4K
78wzkCzKP7fvFi2D9DmVWJofd9oRs76uAlFmx1TKKKaEgTuTstcl5JlL9JftCnZB
vMa6SpUpFEEvEuqtK+Iv40VSwdt5RMnUGlSIicAwEXQByDP6JV2di1fOFkPvaRMz
CjhtVtMmrh1G/ac15HRsB9/nUFuQ0sNWGzrIef/XGLEIlewC3dm0bMDE0BW1DAau
GCbbfp7NR8dSCAYwSLgr27e77J8qB+BeFoyb2diCLCESYk6hipWYAook+BQmPZq9
5HlPkHR+exYrJcUs5Qh9Mal36qe2P0AHnsgeEC5DZmvzwvecSVPNsPj2k7suslBD
KwIDAQABo1MwUTAwBgNVHREEKTAnghRsb2NhbGhvc3QubmFycm93Lm9uZYIJbG9j
YWxob3N0hwR/AAABMB0GA1UdDgQWBBTIpZEOxhEt5ycuCmK44XPt0m9L2zANBgkq
hkiG9w0BAQsFAAOCAgEAB3Mrs0jhKE5YyJQ+06nJjgkgr9WmkDPaxn0RfO93iNmn
2O0VCWIh62Deq0Gelik6EQZbq1LXUgb93DZ5heL3HArJUE5L1ApcqIzX0KbDTNwv
FnXAPv1qKeUbeWBQFzEvsQ3Ily1Geykvom/f2/GIdBpH5V8ELt3+tZCL6H3c8SqA
7nBq++ZT/YwD/CS8wpCM0RXhq6SQkjMv7qm4YfCrkY3zyA6LxVTtLYaFGuVmFk4o
p5kDl8TApTGWX3fIWnOxQ/4bOiIL/bNAW38JQL/bSsCz/1Dg7QgXVvILdwsqZoma
2P510HNM53vh3mGLv61n+IBTxRZNs8X4wbx7PYSFfiUrNtiuh10X0R3Z6mBhjjGg
U3Pxyb9tuAtIegyE68hezkKU02+uBQnQMBq6RZplHfVv0nlb4AU3tfc+H5ICFfIz
OJ4ETgwGwGBj0jJMwYwmSkDdhQ4Y8jpn8Ton9pUzG+08JZDPSi688OCT0EZ6jma/
+PUCPTG5qoRW1bpTQwAf2ZEIt2IJxvgCwpiyTURj3tGSkh1X0UU24d29gdY5xVhL
1nHoT5kk8qAzvA7TOKEA4IA6YP1TVftVP31Lgt/eKUrc5wBn/nrKf81oT6wom7xe
1ryjPD9JWed1/+l5YJCu94WDa2cOnZtRhUmsqd5I6Js5e9+wfD93iAODtR4sEok=
-----END CERTIFICATE-----
`);
const keyPath = resolve(scriptDir, "websocket.key");
Deno.writeTextFileSync(keyPath, `
-----BEGIN PRIVATE KEY-----
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
icnDTUnWWa7k7W1qJ4bb4gh3Z5u75A==
-----END PRIVATE KEY-----
`);

const tlsServer = new Server({
	port: 8080,
	handler: async (request, connInfo) => {
		const url = new URL(request.url);
		if (url.pathname == "/") {
			return new Response(`<script>
const ws = new WebSocket("wss://" + location.host + "/ws");
ws.onopen = () => {
	setInterval(() => {
		ws.send("hi");
	}, 1000);
}
			</script>`, {
				headers: {
					"content-type": "text/html; charset=utf-8",
				},
			});
		} else if (url.pathname == "/ws") {
			const {socket, response} = Deno.upgradeWebSocket(request);
			socket.addEventListener("open", e => {
				setInterval(() => {
					// Uncomment this line to make receiving messages work again:
					socket.send("hi");
				}, 1000);
			});
			socket.addEventListener("message", e => {
				console.log("message received");
			});
			return response;
		} else {
			return new Response("404", {status: 404});
		}
	},
});

tlsServer.listenAndServeTls(certPath, keyPath);

Put this in a server.js file and run with deno run -A server.js
Then visit https://localhost:8080/ in your browser and dismiss the security warning.
It will automatically initiate a websocket and the server and client start sending messages to each other.

It seems like messages are not arriving on the server unless I uncomment socket.send("hi") on line 116.

@caramboleyo
Copy link

I made a complex testcase now:
https://github.com/caramboleyo/deno-websocket-bug

@jespertheend
Copy link
Contributor

@caramboleyo Do you need 90 seconds with the script from #18977 (comment) as well? For me it happens immediately, but I wonder if it differs per system.

@caramboleyo
Copy link

caramboleyo commented Aug 8, 2023

At the end of the readme i mentioned that in case of my browser game it also happens immediately.
Yes when i run this script it needs 90 seconds.
And because of that at first i thought the reason might just be some internal timeout.
the script from the op shows the exact same behavior: it works first but after some time it just stops working.
Interestingly with Deno 1.36.0 the "No response from ping frame." error does not appear anymore. It just stops.
My server and local machine are both ubuntu 22.04

@mmastrac
Copy link
Contributor

mmastrac commented Oct 5, 2023

I'll see if I can get this fixed as part of #20518

jflatow added a commit to jflatow/deno that referenced this issue Oct 5, 2023
This is meant to be a test for denoland#18977, but encountering a different issue on the potentially fixed branch, at the moment.

A bit stuck as the client here gets an 'InvalidData: invalid data' error right away.
Opening a WebSocket from the browser to the server running in the test is fine.
And the test passes if the cert/key are commented out and wss -> ws.
mmastrac added a commit that referenced this issue Oct 31, 2023
…20518)

Use new https://github.com/denoland/rustls-tokio-stream project instead
of tokio-rustls for direct websocket connections. This library was
written from the ground up to be more reliable and should help with
various bugs that may occur due to underlying bugs in the old library.

Believed to fix #20355, #18977, #20948
@mmastrac
Copy link
Contributor

Should be fixed with #20518

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ext/websocket related to the ext/websocket crate needs investigation requires further investigation before determining if it is an issue or not
Projects
None yet
Development

No branches or pull requests

6 participants