0

I facing trouble using Nginx reverse proxy.

I have a server on a private network that provide the following website:

  • a.example.com : 10.32.58.01 (internal DNS resolution)
  • b.other.com : 10.32.58.01 (internal DNS resolution)

I created a Nginx reverse proxy with give access to theses two websites. This reverse proxy have IP 52.00.00.01 (fake one).

Public DNS resolution is:

  • a.example.com : 52.00.00.01
  • b.other.com : 52.00.00.01

The Nginx server /etc/hosts file contains the following resolution:

  • 10.32.58.01 a.example.com b.other.com

The issue is that my two domains have different SSL certificate AND I want my reverse proxy to verify the SSL certificate.

Here is my failing Nginx reverse proxy configuration:

server {
  listen 80;

  server_name a.example.com;
  server_name b.other.com;

  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;

  server_name              a.example.com;

  ssl_session_cache        shared:SSL:100m;
  ssl_session_timeout      180m;
  ssl_ciphers              'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';

  ssl_session_tickets       off;
  ssl_certificate           ssl/chained.example.com.crt;
  ssl_certificate_key       ssl/example.com.key;

  location / {
    proxy_pass                    https://a.example.com;
    proxy_ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    proxy_ssl_ciphers             HIGH:!aNULL:!MD5;
    proxy_ssl_trusted_certificate /etc/nginx/ssl/ssl/chained.example.com.crt;

    proxy_ssl_server_name         on;
    proxy_ssl_verify              on;
    proxy_ssl_verify_depth        2;
    proxy_ssl_session_reuse       on;
  }
}

server {
  listen 443 ssl http2;

  server_name              b.other.com;

  ssl_session_cache        shared:SSL:100m;
  ssl_session_timeout      180m;
  ssl_ciphers              'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';

  ssl_session_tickets      off;
  ssl_certificate          ssl/chained.other.com.crt;
  ssl_certificate_key      ssl/other.com.key;

  location / {
    proxy_pass                    https://b.other.com;
    proxy_ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
    proxy_ssl_ciphers             HIGH:!aNULL:!MD5;
    proxy_ssl_trusted_certificate /etc/nginx/ssl/ssl/chained.other.com.crt;

    proxy_ssl_server_name         on;
    proxy_ssl_verify              on;
    proxy_ssl_verify_depth        2;
    proxy_ssl_session_reuse       on;
  }
}

The issue I got is when I'm requesting my reverse proxy, it returns 502 and I got in logs

[error] 2956#2956: *228502 upstream SSL certificate verify error: (2:unable to get issuer certificate) while SSL handshaking to upstream, client: 52.74.0.0, server: a.example.com, request: "GET / HTTP/1.1", upstream: "https://10.32.58.01:443/", host: "a.example.com"

So for now I disabled the upstream SSL verification -_-'

Thank You !

** EDIT **

In order to be more precise about the context here is my nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/cert/dhparam.pem;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

And my conf.d/proxy.conf

# if we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}

# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
  default off;
  https on;
}

access_log off;

proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";

proxy_ssl_server_name on;
proxy_ssl_session_reuse on;

server {
    server_name _; # This is just an invalid value which will never trigger on a real hostname.
    listen 80;
    access_log /var/log/nginx/access.log;
    return 503;
}


client_max_body_size 0;
proxy_request_buffering off;
client_body_buffer_size 1M;
client_header_buffer_size 512K;
proxy_connect_timeout       3600;
proxy_send_timeout          3600;
proxy_read_timeout          3600;
send_timeout                3600;
0

You have to use HTTP/1.1 for the backend connection. Nginx uses HTTP/1.0 per default.

location / {
    proxy_pass                    https://a.example.com;
    proxy_http_version            1.1;
    ...
}
  • Thanks, but it's already present in conf.d/proxy.conf file. And it's not working – moroine bentefrit Oct 18 '17 at 11:41
  • You are right, I haven't seen it. Based on the error message it could be an issue because your server does not have the issuer's certificates installed. Have you tried to curl or wget the backend server from your nginx host? – Jens Bradler Oct 18 '17 at 13:11
  • Yeah I did and curl works fine without any validity issue. – moroine bentefrit Oct 19 '17 at 9:19
0

Try adding this in your server config:

proxy_ssl_verify_depth 2;

This sets the verification depth in the proxied HTTPS server certificates chain.

source : nginx_http_proxy_module

  • It would be useful to explain why you think this would solve the problem described. – womble May 6 at 22:35
  • Unfortunately, I'm not working anymore on that project, so I have no way to test it. But it seems to be a good option to use. – moroine bentefrit Jun 11 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.