ERR_SSL_PROTOCOL_ERROR with Letsencrypt

Hello,

I have a problem with setting up Discourse forum with Letsencrypt SSL cert. For the sake of example, I will refer to my page as mypage.com.

THE GOAL:

I want to set up VPS where I will have wordpress blog working on blog.mypage.com, landingpage on mypage.com and Discourse forum on forum.mypage.com. I want to use nginx with mariadb and have Letsencrypt SSL certs installed.

THE PROBLEM:

When I enter the forum.mypage.com for the first time with “fresh” browser (cookies and history deleted, new profile) in chrome I have an error

“This site can’t provide a secure connection
forum.mypage.com sent an invalid response.
ERR_SSL_PROTOCOL_ERROR”

With FIrefox, nothing happens - the window is blank and page is not loading.

However, if I go to mypage.com FIRST, everything works as expected and if I THEN enter forum.mypage.com, the DISCOURSE FORUM LOADS WITHOUT PROBLEM.

THE SETUP:

  1. Digital Ocean DNS settings are configured properly, i.e. they redirect mypage.com, www.mypage.com, blog.mypage.com, www.blog.mypage.com, forum.mypage.com and www.forum.mypage.com to my VPS IP. (A record). Record for mailgun are also set properly, as I receive registarion mails from my Discourse installation.

  2. I use Ubuntu 16.04 DigitalOcean droplet where I installed newest stable versions of nginx 1.12.2, php 7.2.2 and mariadb 10.2.13 from maintainers PPAs. 2GB swap file is enabled as requested for Discourse.

  3. I installed certbot using instructions from https://certbot.eff.org/. I used syntax certbot --nginx -d mypage.com,www.mypage.com,blog.mypage.com,www.blog.mypage.com,forum.mypage.com,www.forum.mypage.com

  4. Here is my configuration files:

All files in /var/www are readable by www-data.

/etc/nginx/sites-enabled/default

server {
	root /var/www/html/;
	index index.php index.html index.htm index.nginx-debian.html;
	server_name mypage.com www.mypage.com _;
	location / {
		try_files $uri $uri/ =404;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
	}
	location ~ /\.ht {
		deny all;
	}
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mypage.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mypage.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.mypage.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    if ($host = mypage.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
	listen 80;
	listen [::]:80;
	server_name mypage.com www.mypage.com _;
    return 404; # managed by Certbot
}

/etc/nginx/sites-enabled/discourse

server {
    listen 80; listen [::]:80;
    server_name forum.mypage.com www.forum.mypage.com;  # <-- change this
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;  listen [::]:443 ssl http2;
    server_name forum.mypage.com;  # <-- change this
    ssl on;
    ssl_certificate      /var/discourse/shared/standalone/ssl/ssl.crt;
    ssl_certificate_key  /var/discourse/shared/standalone/ssl/ssl.key;
    ssl_dhparam          /var/discourse/shared/standalone/ssl/dhparams.pem;
    #ssl_certificate /etc/letsencrypt/live/mypage.com/fullchain.pem;    
    #ssl_certificate_key /etc/letsencrypt/live/mypage.com/privkey.pem;    
    #ssl_dhparam          /etc/letsencrypt/ssl-dhparams.pem;
    ssl_session_tickets off;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
    http2_idle_timeout 5m; # up from 3m default
    location / {
        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

/etc/nginx/sites-enabled/blog

server {

	root /var/www/blog;
	index index.php index.html index.htm index.nginx-debian.html;
	server_name blog.mypage.com www.blog.mypage.com;
	location / {
		try_files $uri $uri/ =404;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
	}
	location ~ /\.ht {
		deny all;
	}

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mypage.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mypage.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.blog.mypage.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    if ($host = blog.mypage.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

	listen 80;
	listen [::]:80;
	server_name blog.mypage.com www.blog.mypage.com;
    return 404; # managed by Certbot
}

/var/discourse/containers/app.yml

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.socketed.template.yml" 
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"
  db_shared_buffers: "128MB"
env:
  LANG: en_US.UTF-8
  UNICORN_WORKERS: 2
  DISCOURSE_HOSTNAME: forum.mypage.com
  DISCOURSE_DEVELOPER_EMAILS: 'my@mail.com'
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: postmaster@mg.mypage.com
  DISCOURSE_SMTP_PASSWORD: "mypassword"
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

To set up Discourse I followed instructions from Run other websites on the same machine as Discourse

EDIT: added nginx log

nginx error log (debug mode):

http proxy header:
"POST /message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t HTTP/1.1
Host: forum.mypage.com
X-Forwarded-For: 94.254.162.203
X-Forwarded-Proto: https
Connection: close
Content-Length: 154
user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0
accept: application/json, text/javascript, */*; q=0.01
accept-language: en-GB,en;q=0.5
accept-encoding: gzip, deflate, br
referer: https://forum.mypage.com/
x-csrf-token: undefined
content-type: application/x-www-form-urlencoded; charset=UTF-8
x-silence-logger: true
dont-chunk: true
x-requested-with: XMLHttpRequest
cookie: __cfduid=dabdb09c0c5b037b730155b7e7afd7be71517471541

"
http cleanup add: 00005651877B0FF8
get rr peer, try: 1
stream socket 13
epoll add connection: fd:13 ev:80002005
connect to unix:/var/discourse/shared/standalone/nginx.http.sock, fd:13 #4
connected
http upstream connect: 0
posix_memalign: 00005651877A3A50:128 @16
http upstream send request
http upstream send request body
chain writer buf fl:0 s:705
chain writer buf fl:1 s:154
chain writer in: 000056518772D348
writev: 859 of 859
chain writer out: 0000000000000000
event timer add: 13: 60000:1519655986745
http2 frame complete pos:0000565187806582 end:0000565187806582
http2 frame out: 0000565187733EB0 sid:0 bl:0 len:4
http2 frame out: 0000565187733BF0 sid:0 bl:0 len:0
malloc: 00005651878462C0:16384
SSL buf copy: 9
SSL buf copy: 13
SSL to write: 22
SSL_write: 22
http2 frame sent: 0000565187733BF0 sid:0 bl:0 len:0
http2 frame sent: 0000565187733EB0 sid:0 bl:0 len:4
event timer del: 3: 1519656226737
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream dummy handler
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream dummy handler
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream process header
malloc: 000056518772E040:4096
recv: eof:0, avail:1
recv: fd:13 547 of 4096
http proxy status 200 "200 OK"
http proxy header: "Server: nginx"
http proxy header: "Date: Mon, 26 Feb 2018 14:38:46 GMT"
http proxy header: "Content-Type: application/json; charset=utf-8"
http proxy header: "Transfer-Encoding: chunked"
http proxy header: "Connection: close"
http proxy header: "Vary: Accept-Encoding"
http proxy header: "Cache-Control: must-revalidate, private, max-age=0"
http proxy header: "Pragma: no-cache"
http proxy header: "Expires: 0"
http proxy header: "Access-Control-Allow-Origin: https://forum.mypage.com"
http proxy header: "Access-Control-Allow-Methods: GET, POST"
http proxy header: "Access-Control-Allow-Headers: X-SILENCE-LOGGER, X-Shared-Session-Key, Dont-Chunk, Discourse-Visible"
http proxy header: "X-Runtime: 0.012014"
http proxy header: "Content-Encoding: gzip"
http proxy header done
xslt filter header
http2 header filter
http2 output header: ":status: 200"
http2 output header: "server: nginx/1.12.2"
http2 output header: "date: Mon, 26 Feb 2018 14:38:46 GMT"
http2 output header: "content-type: application/json; charset=utf-8"
http2 output header: "vary: Accept-Encoding"
http2 output header: "cache-control: must-revalidate, private, max-age=0"
http2 output header: "pragma: no-cache"
http2 output header: "expires: 0"
http2 output header: "access-control-allow-origin: https://forum.mypage.com"
http2 output header: "access-control-allow-methods: GET, POST"
http2 output header: "access-control-allow-headers: X-SILENCE-LOGGER, X-Shared-Session-Key, Dont-Chunk, Discourse-Visible"
http2 output header: "x-runtime: 0.012014"
http2 output header: "content-encoding: gzip"
http2:15 create HEADERS frame 000056518772DB98: len:331
http cleanup add: 000056518772DC80
http2 frame out: 000056518772DB98 sid:15 bl:1 len:331
SSL buf copy: 9
SSL buf copy: 331
http2:15 HEADERS frame 000056518772DB98 was sent
http2 frame sent: 000056518772DB98 sid:15 bl:1 len:331
http cacheable: 0
http proxy filter init s:200 h:0 c:1 l:-1
http upstream process upstream
pipe read upstream: 0
pipe preread: 20
pipe buf free s:0 t:1 f:0 000056518772E040, pos 000056518772E24F, size: 20 file: 0, size: 0
pipe length: 3
http chunked byte: 66 s:0
http chunked byte: 0D s:1
http chunked byte: 0A s:3
http chunked byte: 1F s:4
input buf #0 000056518772E252
http chunked byte: 0D s:5
http chunked byte: 0A s:6
http proxy chunked state 0, length 3
input buf 000056518772E252 15
pipe write downstream: 1
pipe write busy: 0
pipe write buf ls:1 000056518772E252 15
pipe write: out:000056518772D348, f:0
http output filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http copy filter: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
image filter
xslt filter body
http postpone filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t" 000056518772D348
write new buf t:1 f:0 000056518772E040, pos 000056518772E252, size: 15 file: 0, size: 0
http write filter: l:0 f:1 s:15
http write filter limit 0
http2:15 available windows: conn:12582912 stream:12582912
http2:15 create DATA frame 000056518772DB98: len:15 flags:0
http2 frame out: 000056518772DB98 sid:15 bl:0 len:15
SSL buf copy: 9
SSL buf copy: 15
SSL to write: 364
SSL_write: 364
http2:15 DATA frame 000056518772DB98 was sent
http2 frame sent: 000056518772DB98 sid:15 bl:0 len:15
http write filter 0000000000000000
http copy filter: 0 "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
pipe write busy: 0
pipe write: out:0000000000000000, f:0
pipe read upstream: 0
pipe buf free s:0 t:1 f:0 000056518772E040, pos 000056518772E040, size: 0 file: 0, size: 0
pipe length: 3
event timer: 13, old: 1519655986745, new: 1519655986759
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream dummy handler
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream process upstream
pipe read upstream: 1
readv: eof:0, avail:1
readv: 1, last:4096
pipe recv chain: 13
pipe buf free s:0 t:1 f:0 000056518772E040, pos 000056518772E040, size: 13 file: 0, size: 0
pipe length: 3
http chunked byte: 38 s:0
http chunked byte: 0D s:1
http chunked byte: 0A s:3
http chunked byte: 8A s:4
input buf #1 000056518772E043
http chunked byte: 0D s:5
http chunked byte: 0A s:6
http proxy chunked state 0, length 3
input buf 000056518772E043 8
pipe write downstream: 1
pipe write busy: 0
pipe write buf ls:1 000056518772E043 8
pipe write: out:000056518772D348, f:0
http output filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http copy filter: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
image filter
xslt filter body
http postpone filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t" 000056518772D348
write new buf t:1 f:0 000056518772E040, pos 000056518772E043, size: 8 file: 0, size: 0
http write filter: l:0 f:1 s:8
http write filter limit 0
http2:15 available windows: conn:12582897 stream:12582897
http2:15 create DATA frame 000056518772DB98: len:8 flags:0
http2 frame out: 000056518772DB98 sid:15 bl:0 len:8
SSL buf copy: 9
SSL buf copy: 8
SSL to write: 17
SSL_write: 17
http2:15 DATA frame 000056518772DB98 was sent
http2 frame sent: 000056518772DB98 sid:15 bl:0 len:8
http write filter 0000000000000000
http copy filter: 0 "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
pipe write busy: 0
pipe write: out:0000000000000000, f:0
pipe read upstream: 0
pipe buf free s:0 t:1 f:0 000056518772E040, pos 000056518772E040, size: 0 file: 0, size: 0
pipe length: 3
event timer: 13, old: 1519655986745, new: 1519655986760
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream dummy handler
http upstream request: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http upstream process upstream
pipe read upstream: 1
readv: eof:0, avail:1
readv: 1, last:4096
pipe recv chain: 20
pipe buf free s:0 t:1 f:0 000056518772E040, pos 000056518772E040, size: 20 file: 0, size: 0
pipe length: 3
http chunked byte: 61 s:0
http chunked byte: 0D s:1
http chunked byte: 0A s:3
http chunked byte: 03 s:4
input buf #2 000056518772E043
http chunked byte: 0D s:5
http chunked byte: 0A s:6
http chunked byte: 30 s:0
http chunked byte: 0D s:1
http chunked byte: 0A s:8
http chunked byte: 0D s:9
http chunked byte: 0A s:10
http proxy chunked state 0, length 3
input buf 000056518772E043 10
pipe write downstream: 1
pipe write downstream flush in
http output filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http copy filter: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
image filter
xslt filter body
http postpone filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t" 000056518772D348
write new buf t:1 f:0 000056518772E040, pos 000056518772E043, size: 10 file: 0, size: 0
http write filter: l:0 f:0 s:10
http copy filter: 0 "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
pipe write downstream done
event timer: 13, old: 1519655986745, new: 1519655986760
http upstream exit: 0000000000000000
finalize http upstream request: 0
finalize http proxy request
free rr peer 1 0
close http upstream connection: 13
free: 00005651877A3A50, unused: 48
event timer del: 13: 1519655986745
reusable connection: 0
http upstream temp fd: -1
http output filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http copy filter: "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
image filter
xslt filter body
http postpone filter "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t" 00007FFDB2259F80
write old buf t:1 f:0 000056518772E040, pos 000056518772E043, size: 10 file: 0, size: 0
write new buf t:0 f:0 0000000000000000, pos 0000000000000000, size: 0 file: 0, size: 0
http write filter: l:1 f:0 s:10
http write filter limit 0
http2:15 available windows: conn:12582889 stream:12582889
http2:15 create DATA frame 000056518772DB98: len:10 flags:1
http2 frame out: 000056518772DB98 sid:15 bl:0 len:10
SSL buf copy: 9
SSL buf copy: 10
SSL to write: 19
SSL_write: 19
http2:15 DATA frame 000056518772DB98 was sent
http2 frame sent: 000056518772DB98 sid:15 bl:0 len:10
http write filter 0000000000000000
http copy filter: 0 "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t"
http finalize request: 0, "/message-bus/f4c00a7368eb483db0a50783f4188da6/poll?dlp=t" a:1, c:1
http request count:1 blk:0
http2 close stream 15, queued 0, processing 1
http close request
http log handler
free: 000056518772E040
free: 00005651877AF030, unused: 2
free: 00005651877B0040, unused: 8
free: 000056518772D030, unused: 35
free: 00005651877A1930, unused: 375
post event 00005651877E2470
delete posted event 00005651877E2470
http2 handle connection handler
free: 0000565187733BA0, unused: 3136
free: 00005651878462C0
reusable connection: 1
event timer add: 3: 300000:1519656226760
http2 idle handler
reusable connection: 0
posix_memalign: 0000565187733BA0:4096 @16
http2 read handler
SSL_read: 0
SSL_get_error: 1
SL_read() failed (SSL: error:140943F2:SSL routines:ssl3_read_bytes:sslv3 alert unexpected message:SSL alert number 10) while processing HTTP/2 connection, client: 94.254.162.203, server: 0.0.0.0:443
close http connection: 3
SSL_shutdown: 1
event timer del: 3: 1519656226760
reusable connection: 0
run cleanup: 00005651877A12C0
free: 0000565187733BA0, unused: 4016
free: 0000000000000000
free: 000056518772C020
free: 00005651877B1050
free: 00005651877A1130, unused: 8
free: 00005651877AE9B0, unused: 0
free: 000056518775D8A0, unused: 0
free: 000056518775DAB0, unused: 0
free: 00005651877A1D40, unused: 88

Turn session tickets on in the discourse nginx file.

4 Likes

Wow, that was easy! It works now. Following the nginx doxumentation: should I create ticket key ( openssl rand 80 > ticket.key) and then add ssl_session_ticket_key /path/to/ticket.key to the etc/nginx/sites-enabled/discourse? Is there any drawback from turning this on?

1 Like

I just turned it on, and it started working.

1 Like

This topic was automatically closed after 33 hours. New replies are no longer allowed.