WebSocket support

From UnrealIRCd documentation wiki
Jump to navigation Jump to search

UnrealIRCd 4.0.10 and later support the WebSocket protocol (ws:// and wss://). This allows Javascript (internet browsers) to connect directly to IRC, without the need of intermediate 'gateways'.

A very crude example can be seen on https://www.unrealircd.org/files/dev/ws/websocket_unrealircd.html which should work on most browsers, include on mobile.

Configure the server

1. Load the websocket module

Add this to your unrealircd.conf:

loadmodule "websocket";

And then rehash the server.

That's all you need to do on the server in order to get ws:// to work! If you also want wss:// (SSL/TLS) then see Using SSL/TLS with websocket. Note that we recommend testing ws:// first, so connect a client.. see next.

Connect a client

You can now connect to your server from javascript using websockets. A very crude example can be found at https://www.unrealircd.org/files/dev/ws/websocket_unrealircd.html

IMPORTANT: If the site is https:// (like in case of unrealircd.org) then you can only use wss:// (SSL/TLS, see next) and not ws:// (plaintext). So if you wish to test ws:// to your server then copy-paste the HTML code from the above URL and put it on a HTTP site or your local computer.

Do you know a good/better true websocket-to-IRC client? Let us know in the websocket forum thread or tell me at syzop@unrealircd.org

Using SSL/TLS with websocket

Websocket has two URI's, ws:// which is plaintext and wss:// which is secure. This is similar to http and https, the former is plaintext and the later is over SSL/TLS.

First of all, you need to have a valid official SSL certificate for your server. This is the hardest part. You cannot use self-signed certificates as all browsers will reject them. How to acquire such a certificate is beyond the scope of this documentation. You can use a "real" certificate authority like Comodo or use free Let's Encrypt.

Now, you need to configure a special port for websocket:

listen {
    ip *;
    port 6800;
    options { ssl; };
    ssl-options {
        certificate "ssl/server.cert.pem";
        key "ssl/server.key.pem";
        options { no-client-certificate; };

And then you can connect to this server from javascript using wss://ip:6800/

The key thing here is the no-client-certificate. This tells UnrealIRCd NOT to ask for a client certificate. If you don't do this then wss will work fine in Firefox but not on Chrome and possibly other browsers.

As you can see, the certificate and key can be specified for this specific port. This may be useful when using Let's Encrypt.

Using port 443

You may want to have UnrealIRCd listen on port 443 (the standard HTTPS port) so your users can bypass firewall restrictions they may encounter. Now, do NOT let UnrealIRCd listen directly on port 443. Doing so would require root privileges and you must NOT run UnrealIRCd as root. You should use a firewall redirect instead. On Linux you can use iptables to redirect traffic to port 443 to another port (like 6800 in the example of above). This way UnrealIRCd can still run as a low privileged user (eg: ircd).

The command (run this as root) would be:

iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 6800

The beauty of this is that Linux will preserve the IP address of your clients as well. Be sure to change port 6800 in the example of above if you use another port, eg 6697.

NOTE: No other application should be using port 443! (eg: apache or nginx)

NOTE 2: You will want to add this somewhere to a startup script or firewall configuration file, otherwise after a reboot the firewall rule will be lost.

TODO: Example for FreeBSD

Technical information for client developers

This is basically the IRC protocol over WebSocket.

There's an important point regarding the use of CR/LF in websocket messages. There was some initial disagreement in the IRC community regarding this as in regular IRC CR/LF are part of the protocol but in websocket they are unnecessary:

  • UnrealIRCd and earlier:
    • client->server: requires you to send a \n at the end of each line
    • server->client: will send \r\n at the end of each line
  • UnrealIRCd 4.0.13 and later:
    • client->server: no \n required at the end of each line (but you may still send one). Assumes you will only issue one IRC command per websocket message.
    • server->client: no \r\n will be sent at the end of each line. This is OK since UnrealIRCd will only send one IRC command per websocket message.

Bottom line: if you want to maintain some compatibility with earlier (beta) websocket implementations then just send a \n (ASCII 10) at the end of each message and be prepared to strip \r\n at the end of each line if necessary.