Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack
-
If you have been following along with my articles on building a LAMP Stack with SaltStack and building a Varnish Web Cache with SaltStack then you know what we are missing - NGinx for SSL handling. We will address this now.
First we need to install the Nginx proxy server. In our example we will assume that we are doing this on the same host that was also our LAMP and Varnish server. Separating this out to its own VM or container is quite simple as the interface between the layers is a network one.
We need to add this bit to the end of our /srv/salt/lamp/init.sls state file:
/etc/httpd/conf.d/ssl.conf: file.absent nginx: pkg.installed: [] service.running: - enable: True - require: - pkg: nginx /etc/nginx/ssl.conf: file.managed: - source: - salt://lamp/files/ssl.conf - user: root - group: root - mode: 644
You'll notice that we block the SSL configuration from Apache (HTTPD) to make sure that Nginx is clear to grab port 443.
Then we also need to add specific configuration for our individual web or proxy nodes. In this case, webnode1. The file would be /srv/salt/webnode1/init.sls
/etc/nginx/nginx.conf: file.managed: - source: - salt://webnode1/files/nginx.conf - user: root - group: root - mode: 644
And then we need an Nginx configuration file created. This will have details about your website so you will need to alter it where obvious. /srv/salt/webnode1/files/nginx.conf
worker_processes 1; events { worker_connections 1024; } http { server { listen 443 ssl http2; server_name myserver.com www.myserver.com; ssl on; include ssl.conf; ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem; location / { proxy_pass http://127.0.0.1/; } }
In this example file we are assuming that our SSL Cert will be provided by LetsEncrypt, which is a free SSL service that I highly recommend. If you use something else, use the right path for your certs in the example. And I assume that our proxy pass is going to be to the localhost. If you are going to another server, replace the 127.0.0.1 with the IP address of the other server. In this example, the localhost server could be Apache, LighTTP or Varnish, does not matter. Whatever service is exposed on port 80. If you do my LAMP example, but not Varnish, then this would be Apache. If you add my Varnish step then Apache is replaced with Varnish. If you are using something else, this might be just about anything.
Lastly we need to address the "include" file of ssl.conf that is mentioned here. For me, I like to include this file with a base Nginx build or with my LAMP build because I always want it the same and available. But you could chose to migrate the file handling into the individual node builds if you wanted.
Here it is, /srv/salt/lamp/files/ssl.conf
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
This would all work just fine, but we need our initial LetsEncrypt certificates before continuing. We can do this quickly by logging into our server (or running the command remotely over Salt) like this...
letsencrypt certonly -a webroot --webroot-path=/var/www/html/myserver.com -d myserver.com -d www.myserver.com
That's it, we should be ready to go. You will need to restart your Nginx instance to pick up the new changed.
systemctl reload nginx
-
Worth noting that in this example, Nginx is exclusively used for SSL / TLS handling and will not be touched if the site is accessed via HTTP on port 80. That require will, if following the previous examples, go directly to either Apache or Varnish (depending on which articles you do first.)
Also worth noting, HTTP2 is enabled here.
-
Why edit the nginx.conf file directly instead of using the conf.d directory?
-
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
Why edit the nginx.conf file directly instead of using the conf.d directory?
I've been debating that, but a single file to manage rather than a directory and moving files about seems a lot easier for keeping track of s state machine. Otherwise you have to manage file removals, too.
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
Why edit the nginx.conf file directly instead of using the conf.d directory?
I've been debating that, but a single file to manage rather than a directory and moving files about seems a lot easier for keeping track of s state machine. Otherwise you have to manage file removals, too.
Why are you not using certbot? Even LE recommends that.
-
You might want to start leaving out SSLv3 now as well, according to ssllabs.com at least.
-
@travisdh1 said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
You might want to start leaving out SSLv3 now as well, according to ssllabs.com at least.
I was wondering about that.
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
Why edit the nginx.conf file directly instead of using the conf.d directory?
I've been debating that, but a single file to manage rather than a directory and moving files about seems a lot easier for keeping track of s state machine. Otherwise you have to manage file removals, too.
You wouldn't need to. As long as the configs are similar, just template them and have a dictionary, don't hard code the values in files. I don't know how to do it with Salt, but with Ansible it would be like this:
vars:
configs: server1: domain: server1.test.com server2: domain: server2.test.com
tasks:
- name: Create nginx configs template: src: conf.j2 dest: /etc/nginx/conf.d/{{ item.key }}.conf owner: root group: root mode: 0644 with_dict: "{{ configs }}"
template (configs.j2):
server { listen 443 ssl http2; server_name {{ item.value.domain }}; ssl on; include ssl.conf; ssl_certificate /etc/letsencrypt/live/{{ item.value.domain }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ item.value.domain }}/privkey.pem; location / { proxy_pass http://127.0.0.1/; } }
-
If doing a dictionary, is there any benefit to splitting up the files?
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
-
@aaronstuder said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller It's recommended by your favorite VPS provider
https://www.linode.com/docs/websites/hosting-a-website#configure-name-based-virtual-hosts
Are they using Salt for context?
-
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
-
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
A dictionary is much easier to read than those configs. I couldn't care less how you do it, but you're breaking convention. And again, if you screw up your main config it will bring everything down.
And if you need to remove a site, it's much easier to have it remove that specific config than it is to take out a whole
server {}
section in your main config. -
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
A dictionary is much easier to read than those configs. I couldn't care less how you do it, but you're breaking convention. And again, if you screw up your main config it will bring everything down.
And if you need to remove a site, it's much easier to have it remove that specific config than it is to take out a whole
server {}
section in your main config.Maybe I'm missing something but doesn't the effect in the end act exactly the same?
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
A dictionary is much easier to read than those configs. I couldn't care less how you do it, but you're breaking convention. And again, if you screw up your main config it will bring everything down.
And if you need to remove a site, it's much easier to have it remove that specific config than it is to take out a whole
server {}
section in your main config.Maybe I'm missing something but doesn't the effect in the end act exactly the same?
Not deleting. Doing it the way I had showed, it would have to know where the section is in the main config and be able to delete that section in the middle somehow. That's a ton more logic you have to create than
file:x.conf state: absent
-
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
A dictionary is much easier to read than those configs. I couldn't care less how you do it, but you're breaking convention. And again, if you screw up your main config it will bring everything down.
And if you need to remove a site, it's much easier to have it remove that specific config than it is to take out a whole
server {}
section in your main config.Maybe I'm missing something but doesn't the effect in the end act exactly the same?
Not deleting. Doing it the way I had showed, it would have to know where the section is in the main config and be able to delete that section in the middle somehow. That's a ton more logic you have to create than
file:x.conf state: absent
Yeah, then I have to make a second bit like that to actively remove everything. So if there are multiple hosts, they need to have a list of everything that might need to be removed, not just what is supposed to be there.
Seems really messy and manual.
-
There is probably some config for "fill this directory with ONLY these files" but I've not found that yet.
-
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@stacksofplates said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
@scottalanmiller said in Deploying an NGinx Reverse Proxy with SSL on a LAMP Server with SaltStack:
If doing a dictionary, is there any benefit to splitting up the files?
Abstraction. The main conf file is set up correctly, so it's harder to screw up if you don't edit that file. If you botch anything editing the main conf you risk taking down everything.
It's also easier to move configs between services (web servers in this case).
How is it easier?
You just plug your variables in the custom config for the other site. You don't need to know anything about the main config. It's already set up to correctly use other custom configs.
And it's much easier to figure out where something is wrong. You can pinpoint to certain configs not one monolithic config.
But if both are built from a single monolithic dictionary source, I don't get any of those benefits. That doesn't apply when building in this way. To me it remains one file, regardless of the end result.
A dictionary is much easier to read than those configs. I couldn't care less how you do it, but you're breaking convention. And again, if you screw up your main config it will bring everything down.
And if you need to remove a site, it's much easier to have it remove that specific config than it is to take out a whole
server {}
section in your main config.Maybe I'm missing something but doesn't the effect in the end act exactly the same?
Not deleting. Doing it the way I had showed, it would have to know where the section is in the main config and be able to delete that section in the middle somehow. That's a ton more logic you have to create than
file:x.conf state: absent
Yeah, then I have to make a second bit like that to actively remove everything. So if there are multiple hosts, they need to have a list of everything that might need to be removed, not just what is supposed to be there.
Seems really messy and manual.
It would just be an ad hoc command. Remove it from the dict and run the ad hoc.
Taking it out of the dict wouldn't remove it from the main config. You would still have to have a "second bit" to do that, which would be much messier.