zadam / trilium

Build your personal knowledge base with Trilium Notes
GNU Affero General Public License v3.0
27.37k stars 1.92k forks source link

How to use custom domain and TLS/SSL with Cloudflare, nginx, docker & trilium? #3217

Closed leomeinel closed 2 years ago

leomeinel commented 2 years ago

I am currently trying to set up trilium behind Cloudflare with its Full(strict)* configuration and HSTS.

*Full(strict)

Encrypts end-to-end, using a self signed certificate on the server, but requires a trusted CA or Cloudflare Origin CA certificate on the server.

When accessing the domain (when also listening on 0.0.0.0) at https://`IP`:8081 it works fine, but I get an SSL error: This website does not supply ownership information because traffic is not routed through Cloudflare.

I am also running another domain on the same server, which is why I can only use port 8080. I would like to proxy the connection to my docker image of trilium:latest.

I didn't really find a lot of information on this and my current setup sadly doesn't work. Note: I don't know a lot about nginx and especially docker which I've never used before, but the same settings (except the proxy to docker) work on my website https://meinel.dev.

The problem I am facing is that https://meinel.click tries to redirect to https://meinel.dev and therefore shows an Invalid SSL certificate Error code 526. Probably because that website is listening on port 443 of the same IP. If I connect to https://meinel.click:8080/ I get a Secure Connection Failed notice from Firefox. http://meinel.click:8081/ can't be loaded directly, but that is expected.

Maybe I configured something entirely wrong, but I can't really find good information on how to do it otherwise, so I am asking if someone might be able to help me with my config :)

/etc/nginx/conf.d/meinel.click.conf (Host)

server {
    # SSL configuration - meinel.click
    listen 8080 ssl http2;
    listen [::]:8080 ssl http2;
    ssl_certificate         /etc/ssl/meinel.click/cert.pem;
    ssl_certificate_key     /etc/ssl/meinel.click/key.pem;
    ssl_client_certificate /etc/ssl/meinel.click/cloudflare.crt;
    ssl_verify_client on;

    # Enable session resumption
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # SSL session resumption
    ssl_stapling on;
    ssl_stapling_verify on;

    # DHE
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    # Server side protection from Beast Attacks
    ssl_prefer_server_ciphers on;

    # Select Protocols
    ssl_protocols TLSv1.3;

    # SSL Ciphers
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM';
    ssl_ecdh_curve secp384r1;

    # Do not limit size of payloads
    client_max_body_size 0;

    # Domain
    server_name meinel.click www.meinel.click;

    location / {
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8081/;
            proxy_read_timeout 90;
            proxy_redirect http://127.0.0.1:8081 https://meinel.click;
    }

    # HSTS
    add_header Strict-Transport-Security "max-age=15780000; includeSubDomains; preload" always;

    # XSS
    add_header X-XSS-Protection "1; mode=block";

    # No Sniff
    add_header X-Content-Type-Options nosniff;

    # Prevent iFrames
    add_header X-Frame-Options SAMEORIGIN;

    # Hide Server info
    server_tokens off;

    # Referrer
    add_header Referrer-Policy "strict-origin";
}

~/trilium-data/config.ini (Host)

[General]
# Instance name can be used to distinguish between different instances using backend api.getInstanceName()
instanceName=leomeinel

# set to true to allow using Trilium without authentication (makes sense for server build only, desktop build doesn't need password)
noAuthentication=false

# set to true to disable backups (e.g. because of limited space on server)
noBackup=false

# Disable automatically generating desktop icon
noDesktopIcon=true

[Network]
# host setting is relevant only for web deployments - set the host on which the server will listen
host=127.0.0.1
# port setting is relevant only for web deployments, desktop builds run on a fixed port (changeable with TRILIUM_PORT environment variable)
port=8081
# true for TLS/SSL/HTTPS (secure), false for HTTP (unsecure).
https=false
# path to certificate (run "bash bin/generate-cert.sh" to generate self-signed certificate). Relevant only if https=true
certPath=
keyPath=
# setting to give trust to reverse proxies, a comma-separated list of trusted rev. proxy IPs can be specified (CIDR notation is permitted),
# alternatively 'true' will make use of the leftmost IP in X-Forwarded-For, ultimately an integer can be used to tell about the number of hops between
# Trilium (which is hop 0) and the first trusted rev. proxy.
# once set, expressjs will use the X-Forwarded-For header set by the rev. proxy to determinate the real IPs of clients.
# expressjs shortcuts are supported: loopback(127.0.0.1/8, ::1/128), linklocal(169.254.0.0/16, fe80::/10), uniquelocal(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
trustedReverseProxy=loopback

docker run (Host)

docker run --name trilium --restart always -e "USER_UID=1003" -e "USER_GID=1003" -v ~/trilium-data:/home/node/trilium-data -d -p 127.0.0.1:8081:8081 zadam/trilium:latest

Thanks in advance for any response to this :+1: and thanks for such an awesome self-hosted notes application!

leomeinel commented 2 years ago

I am not sure if this is related to the proxy headers in my nginx config, maybe in combination with the https=false inside ~/trilium-data/config.ini. I did a lot of troubleshooting, but can't seem to find the problem. Or maybe can't find the right proxy settings for nginx.