How to make nginx passthrough on 443 and redirect 80 to 443? - ssl

I have a winstone server (Jenkins) listening on 8443.
Jenkins has a valid cert, and Jenkins is doing the cert termination successfully:
JENKINS_ARGS="--httpPort=-1 --httpsKeyStore=/secure/jenkins.keystore --httpsKeyStorePassword=MY_PASSWORD --httpsPort=8443"
The only problem is that users now have to go:
https://example.com:8443
I don't want that port number in the URL.
I want:
https://example.com:8443 -> https://example.com
https://example.com -> https://example.com
http://example.com -> https://example.com
So I figure I'll run nginx on the same instance that is running Jenkins.
So my question is:
Do I have to reconfigure jenkins to NOT do cert termination so that nginx does it only?
Can nginx redirect 80 and 443 to localhost:8443 without a cert (Since Jenkins is doing cert termination)?
Do BOTH nginx AND Jenkins need to do cert termination?
Sorry for those similar questions.
I'm pretty sure an AWS ELB cannot replace what nginx is doing here, but I thought I'd throw it out there, in case an ELB can solve this for me too.

1) No, you can have Nginx Stream the connection directly to the Jenkins using the Stream Module.
Do note this was added in 1.9.0 but is not part of the default build so you might have to build it yourself.
It works a lot like an http server block but you have to set it up outside of the http block.
stream {
upstream jenkins_server {
server jenkins:443;
}
server {
listen 443;
proxy_pass jenkins_server;
}
}
2) You do not need a cert on nginx but you should have a http server block for port 80 that does a 301 to the 443 stream talked about in answer part 1.
server {
listen 80;
server_name your_server_name_here;
return 301 https://$host$request_uri;
}
3) No, you don't as you can use the nginx stream to passthru the ssl from the client to the Jenkins server.

Related

SSL Termination on NGINX

I have purchased an SSL cert and bundled it up correctly in so much as when I verify the modulus (i.e. https://kb.wisc.edu/middleware/4064) then the hashes are the same.
I have moved the cert and key to my server # /etc/ssl and ensured that the folder permissions are 700 and each file is 600.
I have then the following nginx config:
server {
listen 80;
listen 443 ;
server_name escapehatch.chrisjowen.uk;
ssl on;
ssl_certificate /etc/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/secret.txt;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
location / {
proxy_pass http://localhost:8080;
}
}
Finally, to test this, I have a Python SimpleHTTPServer running on port 8080. When I hit the URL on HTTPS, I receive an error
This site can’t provide a secure connection
Looking at the logs from the Python server, I see:
218.186.183.142 - - [21/Aug/2019 04:45:53] code 400, message Bad HTTP/0.9 request type ('\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03\x01a\x96\x061LE\x88I\xf1i\x7f\xc3\xdc%d\x18r\xbbzq9q<\xeb\x1dD\xa3\x8b\x01\x10\x7f')
218.186.183.142 - - [21/Aug/2019 04:45:53] "�a�1LE�I�i��%dr�zq9q<�D�� n��Z���΀��SN�F���j;X.Zw�s^�"**�+�/�,�0̨̩����/5" 400 -
218.186.183.142 - - [21/Aug/2019 04:45:53] code 400, message Bad request version ('\x0fb\x03g\x8d\x04\x8b\xbe!\xad\x98W\x9bV\xd2\x8e\x1e\xc6\xf3\xaa\xff\xce\x0f\x1b\xc9\x0f\xebY\xae\xc4\x00"\xfa\xfa\x13\x01\x13\x02\x13\x03\xc0+\xc0/\xc0,\xc00\xcc\xa9\xcc\xa8\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00/\x005\x00')
So, it seems like nginx is not decrypting the request and terminating the SSL connection, instead it's passing it to the upstream server, which I do not want.
Checking the nginx logs /var/log/nginx/nginx.vhost.access.log shows nothing.
So, now I am stumped what to do to debug the issue, it appears that either nginx config is wrong or there is something wrong with the cert, but as mentioned I checked this with the following method https://kb.wisc.edu/middleware/4064
listen 80;
listen 443 ;
If you want it to listen for plain http on port 80 and https on port 443 the second line should be listen 443 ssl;.
ssl on;
From the documentation:
This directive was made obsolete in version 1.15.0. The ssl parameter of the listen directive should be used instead.
Also you have the following in the logs of your Python server:
218.186.183.142 - - [21/Aug/2019 04:45:53] code 400, ....
This Python server is clearly visited directly by an external IP address. If the request would be forwarded by the local nginx then the source IP should be 127.0.0.1 instead. This shows, that you don't hit nginx at all but somehow make a direct request to the Python server.

Nginx reverse proxy to https location causes ssl_error_rx_record_too_long

ttI am adding an nginx reverse proxy in front of my existing nextcloudpi server in order to be able to route traffic to different servers in my network depending to the domain that is used. Currently the nextcloudpi server is the only one running, so all traffic is directly routed to it.
The server is only accessible via https and letsencrypt handles the certifactes on the nextcloudpi server.
In order to route traffic from my reverse proxy to the nextcloudpi server via https, I have set up the default.conf file to look like this:
server {
listen 443;
listen [::]:443;
server_name <my-public-url>;
location / {
proxy_pass https://<hostname-of-my-nextcloudpi-server>;
}
}
Unfortunately that doesn't work. Firefox returns SSL_ERROR_RX_RECORD_TOO_LONG and Chrome ERR_SSL_PROTOCOL_ERROR
I have also not seen anywhere where traffic is proxied to a https location. I am aware that in my internal network I can and should just route to the target location on port 80 but since the server is already set up to use https I want to keep it that way.
Thanks for your help

nginx returns SSL certificate for subdomain that should have no certificate

I have a nginx server that manages a few domains and subdomains. There are some subdomains that have an own SSL certificate and they work fine. The problem is that if I try to open blablabla.mydomain.com (this subdomain is not configured in nginx) then firefox shows me an error "Connection is not secure" and "The certificate is only valid for xyz.mydomain.com" (this domain is configured with SSL and works well)
The same happens when I open the root domain mydomain.com. Then the server also returns the certificate for xyz.mydomain.com which is rejected by firefox.
I only want nginx to return the SSL certificate for domains/subdomains I explicitly have configured HTTPS. For what I understand, my configuration should be doing exactly this.
I configured all my https-subdomains like this:
server {
listen 443 ssl;
server_name xyz.mydomain.com;
root /var/www/xyz.mydomain/;
ssl on;
ssl_certificate /etc/letsencrypt/live/xyz.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xyz.mydomain.com/privkey.pem;
...
}
The root domain (which should have no SSL) is configured like this:
server {
listen 80;
server_name mydomain.com;
return http://some-redirection.com;
}
There is no SSL server block for this domain. Nor is for the other subdomains that do not exist. So why does nginx in these cases return the certificate for xyz.mydomain.com?
I don't use any wildcards in my server config. Is there some way to debug this? I mean, there must be a reason why nginx always returns the certificate for xyz.mydomain.com for every non-configured domain/subdomain. Why not another configured and working certificate?
I use an Ubuntu 14.04 server with nginx 1.4.6
If you need more info on my config, let me know
EDIT: I think I know why my config does not work. When using https the client encrypts also the domain name and this causes nginx to try all available server defintions. When it doesn't find one it returns the last one? And xyz.mydomain.com seems to be the last one (alphabetically)
So is there a way to avoid this? Would I have to create a ssl cert for every other subdomain?

Nginx serves different website (on the same sever) when using HTTPS

I have several websites hosted on the same sever. To simplify I have just 2 (http-only.com and https.com) and using nginx to handle requests.
One has SSL enabled. And another doesn't. I noticed links like this in Google Search Console http-only.com/https_server_path and when accessing an http-only.com server with https protocol I get requests served by an https.com server instead.
https.com:
server {
listen 443 ssl;
server_name https.com;
ssl on;
}
only-http.com:
server {
listen 80;
server_name only-http.com;
}
I think I should define something like a default ssl server to handle ssl for http.com, but don't know how to do it properly. I guess nginx should redirect https request to an http url if corresponding server doesn't handle https. Or maybe there is a better solution?

How to configure nginx to make ssh server via subdomain.domain.tld:80 available

I want to make the ssh server on port 22 available through a subdomain on port 80.
I thought it should by something like this:
server {
listen ssh.domain.tld:80;
server_name ssh.domain.tld;
location / {
proxy_pass http://localhost:22;
}
}
But it won't work. nginx will accept this and start with this configuration, but I only get empty responses from ssh.domain.tld:80.
What am I missing?
Since Nginx Version 1.9.0,NGINX support ngx_stream_core_module module, it should be enabled with the --with-stream. When stream module is enable they are possible to ssh protocol tcp proxy
stream {
upstream ssh {
server localhost:22;
}
server {
listen 80;
proxy_pass ssh;
} }
https://www.nginx.com/resources/admin-guide/tcp-load-balancing/
You should use sslh.
Configure nginx to run on a different port than 80, say 800, and then configure sslh to redirect web traffic to that port in /etc/default/sslh.conf file.
This setup may take 15 min. or less.
basically you're looking in the wrong place:
stock nginx can proxy web and/or email traffic, it doesn't handle ssh traffic at all
the subdomain is a dns isue: configure it in your dns settings, you need an A and/or AAAA record linking ssh.domain.tld to your ssh server's ip-adres
the port your ssh server listens on is a ssh server setting (see man sshd_config specifically the ListenAddress and Port directives)