[SSL N8N] - How to increase grade of ssl n8n

I’m getting grade B on this site (SSL Server Test: n8n-2.bordernd.com.br (Powered by Qualys SSL Labs)) that is served by n8n. I’m getting in some executions with http node 525 SSL fail handshake. Anyone already pass with this? Thanks for now.

Hey @rodrigoscdc,

How are you running n8n is from NPM or in a container? The quickest option would be to pop a reverse proxy in front of it and handle the TLS side from there.

The longer option is to clone the repo and edit packages/cli/src/server.ts and modify server = https.createServer(credentials, app.app); to include the changes needed by NodeJS / Express so you would have something like…

const options = {
  key: privateKey,
  cert,
  secureOptions: constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1,
};
server = https.createServer(options, app.app);

The above is untested so may not work without some changes but hopefully it helps point you in the right direction.

Hello @jon thanks for your quickly answer. I’m using my n8n with docker container as n8n documentation suggests.

Hey @rodrigoscdc,

Is that with Traefik or just n8n on it’s own?

is with traefik

Perfect, So it looks like it is more of a question for the Traefik team than n8n, That being said I have found this which seems to cover how to do what you want: Traefik v2 Secure TLS and Header Configuration with Docker Provider - Dale Picou Jr

2 Likes

Thanks I’ll read the link that you shared, and after I’ll post here if I can solve this issue.

Thanks a lot @jon and @rodrigoscdc! We can then add it to the default setup that it is more secure out of the box.

3 Likes

Would be so nice it.

Morning @rodrigoscdc & @jan,

I have just had a quick play with this one and the results are looking good (although could be better).

What I have done is added 2 lines to the Traefik service in docker-compose.yaml the first is under command and is - "--providers.file.filename=/traefik_conf.yaml" and the second is under volumes which is - ./traefik_conf.yaml:/traefik_conf.yaml

I have then created a traefik_conf.yaml file in the same directory as the compose file and this contains:

tls:
  options:
    default:
      minVersion: VersionTLS12
      sniStrict : true
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

    mintls13:
      minVersion: VersionTLS13

Once that is done it is just a case of starting up the container again with a docker-compose up -d (or whatever you normally use) and you are away.

Just to be complete you can find the 3 files you need below and as an added bonus a list of all the commands I ran on a clean Ubuntu Server 20.04 VPS can be found at the bottom.

docker-compose.yaml
version: "3"

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
      - "--providers.file.filename=/traefik_conf.yaml"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik_conf.yaml:/traefik_conf.yaml

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
    volumes:
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n
.env
# Folder where data should be saved
DATA_FOLDER=/root/n8n/

# The top level domain to serve from
DOMAIN_NAME=example.com

# The subdomain to serve from
SUBDOMAIN=n8n

# DOMAIN_NAME and SUBDOMAIN combined decide where n8n will be reachable from
# above example would result in: https://n8n.example.com

# The user name to use for authentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_USER=user

# The password to use for authentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_PASSWORD=password

# Optional timezone to set which gets used by Cron-Node by default
# If not set New York time will be used
GENERIC_TIMEZONE=Europe/Berlin

# The email address to use for the SSL certificate creation
[email protected]
traefik_conf.yaml
tls:
  options:
    default:
      minVersion: VersionTLS12
      sniStrict : true
      cipherSuites:
        - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

    mintls13:
      minVersion: VersionTLS13
Install Steps

These are the commands I ran on a clean Ubuntu 20.04 VPS, There is nothing odd in there but I do like to keep my container configs in a docker folder to make them easy to find and it makes it easier to back them up to git.

apt update && apt upgrade
apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt update
apt install docker-ce
curl -L https://github.com/docker/compose/releases/download/v2.0.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
mkdir -p ~/docker/n8n/
nano ~/docker/n8n/docker-compose.yaml
nano ~/docker/n8n/.env
nano ~/docker/n8n/traefik_conf.yaml
mkdir /root/n8n
docker-compose up -d

Hopefully this helps :+1:

2 Likes

Works for me Too.
Thank @jon

1 Like

That is good to know, it wouldn’t take much more work to bump up the cipher strength and key exchange a bit more but I think for most environments it is good with these settings.

1 Like