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

Setup Secure WebSockets #293

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```apacheconf
# (...)
SSLProxyEngine on
ProxyRequests off
ProxyPass / ws://localhost:9944
ProxyPassReverse / ws://localhost:9944
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
```bash
apt install apache2
a2dismod mpm_prefork
a2enmod mpm_event proxy proxy_html proxy_http proxy_wstunnel rewrite ssl
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/selfsigned.key -out /etc/ssl/certs/selfsigned.crt
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
```conf
server {
(...)
location / {
proxy_buffers 16 4k;
proxy_buffer_size 2k;
proxy_pass http://localhost:9944;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
```conf
http {
limit_req_zone "$http_x_forwarded_for" zone=zone:10m rate=2r/s;
(...)
}
location / {
limit_req zone=zone burst=5;
(...)
}
```
2 changes: 1 addition & 1 deletion infrastructure/running-a-node/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ nav:
- index.md
- 'Set Up a Full Node': setup-full-node.md
- 'Set Up a Bootnode': setup-bootnode.md
# - 'Common Node Flags': common-node-flags.md
- 'Setup Secure Websocket': setup-secure-wss.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 'Setup Secure Websocket': setup-secure-wss.md
- 'Set Up Secure Websocket': setup-secure-wss.md

For consistency

93 changes: 93 additions & 0 deletions infrastructure/running-a-node/setup-secure-wss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: Setup Secure WebSocket
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
title: Setup Secure WebSocket
title: Set Up Secure WebSocket

description: Instructions on enabling SSL for your node and setting up a secure WebSocket proxy server using nginx for remote connections.
---

# Setup Secure WebSocket

## Introduction

Ensuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache. By the end of this guide, you'll be able to secure your node's WebSocket port, enabling safe remote connections without exposing your node to unnecessary risks.

!!!info
The following instructions are for UNIX-based systems.

## Secure a WebSocket Port

You can convert a non-secured WebSocket port to a secure WSS port by placing it behind an SSL-enabled proxy. This approach can be used to secure a bootnode or RPC server. The SSL-enabled apache2/nginx/other proxy server redirects requests to the internal WebSocket and converts it to a secure (WSS) connection. You can use a service like [LetsEncrypt](https://letsencrypt.org/){target=\_blank} to obtain an SSL certificate.

### Obtain an SSL Certificate

You can follow the [LetsEncrypt](https://letsencrypt.org/){target=\_blank} instructions for your respective web server implementation to get a free SSL certificate:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can follow the [LetsEncrypt](https://letsencrypt.org/){target=\_blank} instructions for your respective web server implementation to get a free SSL certificate:
LetsEncrypt suggests using the [Certbot ACME client](https://letsencrypt.org/getting-started/#with-shell-access/){target=\_blank} for your respective web server implementation to get a free SSL certificate:

I found it confusing when these links didn't open to LetsEncrypt, so added some language to clarify where the user can expect to end up


- [nginx](https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal){target=\_blank}
- [apache2](https://certbot.eff.org/instructions?ws=apache&os=ubuntufocal){target=\_blank}

LetsEncrypt will auto-generate an SSL certificate and include it in your configuration.

You can generate a self-signed certificate and rely on your node's raw IP address when connecting. However, self-signed certificates aren't optimal because you have to whitelist the certificate to access it from a browser.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can generate a self-signed certificate and rely on your node's raw IP address when connecting. However, self-signed certificates aren't optimal because you have to whitelist the certificate to access it from a browser.
When connecting, you can generate a self-signed certificate and rely on your node's raw IP address. However, self-signed certificates aren't optimal because you must include the certificate in an allowlist to access it from a browser.


Use the following commmand to generate a self-signed certificate using OpenSSL:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use the following commmand to generate a self-signed certificate using OpenSSL:
Use the following command to generate a self-signed certificate using OpenSSL:


--8<-- 'code/infrastructure/running-a-node/setup-secure-wss/install-openssl.md'

## Install a Proxy Server

There are a lot of different implementations of a WebSocket proxy; some of the more widely used are [nginx](https://www.nginx.com/){target=\_blank} and [apache2](https://httpd.apache.org/){target=\_blank}, both of which are commonly used web server implementations. See the following section for configuration examples for both implementations.

### Use nginx

1. Install the `nginx` web server:
```bash
apt install nginx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add a note somewhere that all the steps presented in this guide are for Ubuntu-like oss

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a note for unix based systems

```

2. In an SSL-enabled virtual host add:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. In an SSL-enabled virtual host add:
2. In an SSL-enabled virtual host, add:

--8<-- 'code/infrastructure/running-a-node/setup-secure-wss/nginx-config.md'

3. Optionally, you can introduce some form of rate limiting:
--8<-- 'code/infrastructure/running-a-node/setup-secure-wss/nginx-rate-limit.md'

### Use Apache2

Apache2 can run in various modes, including `prefork`, `worker`, and `event`. In this example, the [`event`](https://httpd.apache.org/docs/2.4/mod/event.html){target=\_blank} mode is recommended for handling higher traffic loads, as it is optimized for performance in such environments. However, depending on the specific requirements of your setup, other modes like `prefork` or `worker` may also be appropriate.

1. Install the `apache2` web server:
--8<-- 'code/infrastructure/running-a-node/running-a-node/setup-secure-wss/install-apache2.md'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--8<-- 'code/infrastructure/running-a-node/running-a-node/setup-secure-wss/install-apache2.md'
--8<-- 'code/infrastructure/running-a-node/setup-secure-wss/install-apache2.md'

Code snippet wasn't rendering


2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled `virtualhost` add:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled `virtualhost` add:
2. The [`mod_proxy_wstunnel`](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html){target=\_blank} provides support for the tunneling of WebSocket connections to a backend WebSocket server. The connection is automatically upgraded to a WebSocket connection. In an SSL-enabled virtual host add:

It was written this way in the earlier instances/steps so let's keep consistent

--8<-- 'code/infrastructure/running-a-node/setup-secure-wss/apache2-config.md'

!!!warning
Older versions of `mod_proxy_wstunnel` don't upgrade the connection automatically and will need the following config added:
```apacheconf
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://localhost:9944/$1 [P,L]
RewriteRule /(.*) http://localhost:9944/$1 [P,L]
```

3. Optionally, some form of rate limiting can be introduced:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Optionally, some form of rate limiting can be introduced:
3. Optionally, some form of rate limiting can be introduced by first running the following command:


```bash
apt install libapache2-mod-qos
a2enmod qos
```

And edit `/etc/apache2/mods-available/qos.conf`:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
And edit `/etc/apache2/mods-available/qos.conf`:
Then edit `/etc/apache2/mods-available/qos.conf` as follows:


```conf
# allows max 50 connections from a single ip address:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# allows max 50 connections from a single ip address:
# allows max 50 connections from a single IP address:

QS_SrvMaxConnPerIP 50
```

## Connect to the Node

1. Open [Polkadot.js Apps interface](https://polkadot.js.org/apps){target=\_blank} and click the logo in the top left to switch the node
2. Activate the **Development** toggle and input your node's address - either the domain or the IP address. Remember to prefix with `wss://` and if you're using the 443 port, append `:443` as follows:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Activate the **Development** toggle and input your node's address - either the domain or the IP address. Remember to prefix with `wss://` and if you're using the 443 port, append `:443` as follows:
2. Activate the **Development** toggle and input either your node's domain or IP address. Remember to prefix with `wss://` and, if you're using the 443 port, append `:443` as follows:


```bash
wss://example.com:443
```

![A sync-in-progress chain connected to Polkadot.js UI](/images/infrastructure/general/setup-secure-wss/secure-wss-01.webp)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This image is missing