Nginx – Empty reply from server when trying to redirect HTTP to HTTPS in nginx as a reverse proxy for jenkins

httphttpsJenkinsnginxredirect

I’m running Jenkins behind Nginx and I use Let’s Encrypt for the SSL Certificate. If I access the site via https://jenkins.mydomain.de/, everything works fine. But when I access it via http://jenkins.mydomain.de/, Firefox says “Connection was reset.” and curl says “Empty reply from server”

How do I debug this? I don’t really know where to look for the problem. The nginx logs don’t contain any thing about it. I suspect that the section about port 80 in the configuration down below is invalidated by some other directive, but I don’t know how I would investigate that.

$ curl -svL http://jenkins.mydomain.de/
* Hostname was NOT found in DNS cache
*   Trying my.ip.add.ress...
* Connected to jenkins.mydomain.de (my.ip.add.ress) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.38.0
> Host: jenkins.mydomain.de
> Accept: */*
> 
* Empty reply from server
* Connection #0 to host jenkins.mydomain.de left intact

When using telnet to speak to the server, the connection is closed as soon as I hit return only once (i. e. after GET / HTTP/1.1).

Even though Firefox doesn’t have a problem with the SSL Certificate, curl does:

$ curl -svL https://jenkins.mydomain.de/
* Hostname was NOT found in DNS cache
*   Trying my.ip.add.ress...
* Connected to jenkins.mydomain.de (my.ip.add.ress) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS alert, Server hello (2):
} [data not shown]
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
* SSLv3, TLS alert, Client hello (1):
} [data not shown]

My Nginx configuration:

upstream jenkins {
    server localhost:8080 fail_timeout=0;
}

server {
    listen 80 default;
    server_name jenkins.mydomain.de;
    return 301 https://$server_name$request_uri;
    # Replacing $server_name with $host does not work either.
}

server {
    listen 443 default ssl;
    server_name jenkins.mydomain.de;

    ssl on;
    ssl_certificate     /etc/letsencrypt/live/jenkins.mydomain.de/cert.pem;
    ssl_certificate_key /etc/letsencrypt/live/jenkins.mydomain.de/privkey.pem;

    ssl_ciphers HIGH:!ADH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_protocols  SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout  5m;
    ssl_session_cache  builtin:1000  shared:SSL:10m;

    location / {
        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_redirect http://localhost:8080 https://$server_name;
        proxy_pass https://jenkins;
    }
}

Nginx is listening on port 80:

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3895/nginx      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1048/sshd       
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3895/nginx      
tcp6       0      0 :::41117                :::*                    LISTEN      19911/java      
tcp6       0      0 :::8080                 :::*                    LISTEN      19911/java      
tcp6       0      0 :::22                   :::*                    LISTEN      1048/sshd       
tcp6       0      0 :::49208                :::*                    LISTEN      19911/java

Best Answer

Using the same server block as you for port 80 and 301 redirection, it worked on my setup, with Jenkins (I don't think the application backend has any influence but just to be sure). The problem I got was firewall not open for port 80. You should verify your own firewall.