0

I have a main nginx container which serves as reverse proxy and which redirects requests to a child nginx container which is part of a docker compose project (wordpress + php + nginx + mariadb...).

docker-compose.yml:

services:
  reverse-proxy:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
networks:
  default:
    name: my-network

nginx.conf:

server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  server_name website.com;

  ssl_certificate /etc/nginx/certs/website.com.crt;
  ssl_certificate_key /etc/nginx/certs/website.com.key;

  resolver 127.0.0.11 valid=30s;
  set $upstream wordpress;

  location / {
    proxy_ssl_server_name on;
    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 https;
    proxy_pass https://$upstream:443;
  }
}

And the "child" nginx container:

docker-compose.yml:

services:
  nginx:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    networks:
      default:
        aliases:
          - wordpress
    ports:
      - "80"
      - "443"
networks:
  default:
    name: my-network
    external: true

nginx.conf (and here is the problematic part):

server {
  listen [::]:443 ssl http2 default_server;
  listen 443 ssl http2 default_server;

  server_name _;

  ssl_reject_handshake on;
}

server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  server_name website.com;

  ssl_certificate /etc/nginx/certs/website.com.crt;
  ssl_certificate_key /etc/nginx/certs/website.com.key;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  [...]
}

I have the following error when I want to go to https://website.com:

2022/10/23 22:31:27 [crit] 494#494: *2073 SSL_do_handshake() failed (SSL: error:14094458:SSL routines:ssl3_read_bytes:tlsv1 unrecognized name:SSL alert number 112) while SSL handshaking to upstream, client: x.x.x.x, server: website.com, request: "GET / HTTP/2.0", upstream: "https://192.168.96.2:443/", host: "website.com" x.x.x.x - - [23/Oct/2022:22:31:27 +0000] "GET / HTTP/2.0" 502 559 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77" "-"

I tried all nginx solutions and guidelines I found on the internet, without success.

When I delete ssl_reject_handshake on section or move it to main nginx container, requests to https://website.com work well, but it's not what I want.

Can you help me? Why the directive works well when it's defined in the main nginx, and not in the child nginx?

I guess it has to do with SSL but I don't know why...

Thanks!

Pierre
  • 1
  • 2
  • *"which redirects requests to a child nginx container"* - it doesn't. "redirect", it "forwards" the requests instead. "redirect" means to tell the client to send the request somewhere else, "forward" is to send the request somewhere else itself. *"I tried all nginx solutions and guidelines I found on the internet, without success."* - which says exactly nothing what you actually did, so this is a useless statement. – Steffen Ullrich Oct 24 '22 at 04:41
  • In short - the internal server you access with `https://$upstream:443` does not expect $upstream as SNI name. Use `proxy_ssl_server_name` option to pass through the original name inside the TLS handshake to the upstream or use `proxy_ssl_name` to specify the expected name. – Steffen Ullrich Oct 24 '22 at 04:46
  • @SteffenUllrich I already added the directive `proxy_ssl_server_name on` as you should have seen in my question and it's not working. However, I added `proxy_ssl_name website.com` as you suggested and it works. But I want to understand why `proxy_ssl_server_name on` don't work in this situation? – Pierre Oct 24 '22 at 07:19
  • Is the external name really exactly the same as the internal one? You have "website.com" here in all cases, but is this really the same? – Steffen Ullrich Oct 24 '22 at 07:30
  • @SteffenUllrich I don't understand your questions :/ External name, internal name? All I do is access the website through my web browser at https://website.com. – Pierre Oct 24 '22 at 07:47
  • You have a URL you use in a browser, you have "main" nginx with server_name and certificates and you have a "child" nginx with server_name and certificates. So what are all the domain names in server_name and certificates in all these 5 places? Always the same or sometimes even slightly different? – Steffen Ullrich Oct 24 '22 at 07:52
  • @SteffenUllrich The values server_name ans certificates are exactly the same in the "main" and "child" nginx as the configuration files are generated via ansible. I just tested: - works: `proxy_ssl_server_name on` + `proxy_ssl_name website.com` - not works: `proxy_ssl_server_name on` (alone) - not works: `proxy_ssl_name website.com` (alone) – Pierre Oct 24 '22 at 08:03
  • Looks like proxy_ssl_server_name os only for enabling SNI but only proxy_ssl_name is for specifying the name to use inside SNI. Without the latter it would have used $upstream, which is not expected by the "child" nginx. – Steffen Ullrich Oct 24 '22 at 10:19

0 Answers0