Apologies in advance: I am new to servers and certificates.
I have two nodejs apps running on one server instance. The first is the client facing app (http://localhost:3000), and this makes calls to the second app (webservices http://localhost:3001).
This is my nginx sites available:
server {
root /var/www/mydomain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name mydomain.com www.mydomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed >
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # manage>
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
Thanks to the LetsEncrypt certificate, the site is available at https://mydomain.com. This calls http://localhost:3001 to reach the webservices. The services are reached, but I need them to be HTTPS also.
Is this possible with one LetsEncrypt certificate? I’m trying to avoid spinning up another droplet and domain for my webservices.
Why? If you're afraid someone can Man-in-the-Middle your localhost connections, you've got a lot more to worry about IMO TLS doesn't have any security benefit when connecting to localhost/127.0.0.1/::1
I have no experience with NodeJS, but in theory you could use one single certificate for as much services as possible.
I think my services may need to be HTTPS in order to connect with my managed database server as sslmode=require is specified on the given connection string. I’m trying to figure out if changing to HTTPS on my webservices will allow the connection.
Sorry, server:port in the connection string is for the remote managed database. The connection string above resides in the webservices on localhost:3001 on my app server.
I think I maybe have been getting confused, and if so, I’m sorry for wasting your time. I think I need to be specifying CA certificates in my connection string parameters. ie. nothing to do with my webservers being HTTPS.
Personally, I’m not having any “overview” of what’s connecting to what, which connections are to localhost, which are to remote. Which are giving errors complaining about a lack of HTTPS, which are not. Et cetera. For me, the information now is too fragmented and possibly incomplete.
First, let me restate some things with the typical terms:
You have a nginx server that is configured for “SSL Termination”.
Your nginx server proxies the decrypted HTTPS traffic to the local network (in this case, the same machine)
Your postgresql server is configured to use SSL authentication (https://www.postgresql.org/docs/current/libpq-ssl.html). This is a fairly esoteric authentication system. You don’t need to do this, and if you do use this - there is no need to use LetsEncrypt certificates, and I’m not even sure they are compatible. This system typically uses self-signed certificates, which you would install on the client (web application) and the database (postgresql).
You should be fine with the 3000 and 3001 applications running decrypted. As far as browsers are concerned, they are talking to a HTTPS server.
You can secure/lock-down postgresql in other ways. Using SSL Certificates is one of the least popular and most complex options to choose.
I just want to clarify two points that I should have made better:
you would install the root certificate onto the postgresql directory, and the client/leaf certificate into the home directory of the user the webapp runs on. So it’s more about installing on the machines, not an app.
This may be worth reconsidering, since everything is on the same machine. SSL is usually used in clustered environments you do not trust, or when servers in different geographical regions and need to communicate over public networks. If you are prepping to do one of those things in the future, it is great to get it over with now… but if you don’t have definite plans to do that, you’re just encrypting traffic between two applications on the same machine and there is little benefit to this.
I solved this by installing the client certificate to the app home directory, then specified this sslrootcert location in a connection string parameter. So the parameters looked like the following: