Changes for page How to setup an Nginx reverse proxy and also provide a global X.509 certificate for it
Last modified by Alexandru Pentilescu on 2023/06/25 18:53
From version 7.1
edited by Alexandru Pentilescu
on 2022/06/11 22:13
on 2022/06/11 22:13
Change comment:
There is no comment for this version
To version 9.1
edited by Alexandru Pentilescu
on 2022/06/11 22:42
on 2022/06/11 22:42
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -173,8 +173,6 @@ 173 173 174 174 listen 80 default_server; 175 175 listen [::]:80 default_server; 176 - listen 443 ssl; 177 - listen [::]:443; 178 178 } 179 179 {{/code}} 180 180 ... ... @@ -195,7 +195,7 @@ 195 195 196 196 The second "server" block only matches for requests directed at "pentilescu.com", not for any of its subdomains. As the request was made specifically to passwords.pentilescu.com, which is a subdomain of pentilescu.com, this does not match with this block at all. Nginx continues. 197 197 198 -The third "server" block matches with the server_name directive (as the server name is the "_" wildcard once again), and italsomatcheswiththe ports(bothport 80and443 this time).Nginx willalsorememberthis oneasa viablecandidatefor resolving the request.196 +The third "server" block matches with the server_name directive (as the server name is the "_" wildcard once again). However, this matches only for incoming connections coming to port 80. Our request is to port 443 though. As such, this match fails and Nginx will continue to look for more "server" directives. 199 199 200 200 Then, Nginx will also take a look at the bitwarden.conf file. 201 201 ... ... @@ -209,7 +209,7 @@ 209 209 210 210 For example, suppose the aforementioned setup, but with a request for "abcdefg.pentilescu.com" port 443. Where should such a request go to? 211 211 212 -Well, it doesn't match the "passwords.pentilescu.com" server_name block in bitwarden.conf. Nor does it match the "pentilescu.com" server block either, as it's a subdomain for pentilescu.com. The only two matching candidates, as such,arethe firstand third"server" blocksin fallback.conf, which resolve to any name whatsoever, due totheirwildcard server_names. In this situation, Nginx will just takethe firstone,just becausethat's the one tocontainthe "default server" descriptor for port 443(i.e. it shouldhandleythingthatcomestoport443 and doesn'thave aorespecificmatch)anduses thatone. The action detailed for this "server" block is "return 404", which tells Nginx to simply return a 404 status code, immediately. The browser will then report this "404" status code to the visitor, letting him know that the service he/she was attempting to access does not exist on this server, an indication that their request was malformed.210 +Well, it doesn't match the "passwords.pentilescu.com" server_name block in bitwarden.conf. Nor does it match the "pentilescu.com" server block either, as it's a subdomain for pentilescu.com. Finally, it doesn't match to the third "server" directive in fallback.conf either, as that is destined only for connections incoming to port 80, not 443. The only matching candidate, as such, is the first "server" block in fallback.conf, which resolves to any name whatsoever, due to its wildcard server_name. In this situation, Nginx will just take it, as it's the only candidate. It also has the "default server" descriptor for port 443, which means that, even if the server name parameter didn't match, this would have still been the "server" block to handle it. The action detailed for this "server" block is "return 404", which tells Nginx to simply return a 404 status code, immediately. The browser will then report this "404" status code to the visitor, letting him know that the service he/she was attempting to access does not exist on this server, an indication that their request was malformed. 213 213 214 214 This block effectively handles all malformed requests or any request that does not have a specific resolver for it. 215 215 ... ... @@ -222,3 +222,65 @@ 222 222 Pretty cool, right? 223 223 224 224 Finally, let's see how we can configure an X509 certificate globally! 223 + 224 + 225 += Configuring a global X.509 certificate = 226 + 227 +This is the easiest part of this article. Whenever you wish to encrypt a request to a specific server block in Nginx, just add the "include /etc/nginx/snippets/ssl.conf" directive in its server block and you're pretty much done. 228 +Now, what should this ssl.conf snippets file contain? Easy: 229 + 230 +{{code language="nginx"}} 231 +ssl_certificate /etc/letsencrypt/live/pentilescu.com/fullchain.pem; # managed by Certbot 232 +ssl_certificate_key /etc/letsencrypt/live/pentilescu.com/privkey.pem; # managed by Certbot 233 +ssl_trusted_certificate /etc/letsencrypt/live/pentilescu.com/chain.pem; 234 +{{/code}} 235 + 236 +Now, I admit, these file paths are usually generated by the certbot utility. Configuring certbox is outside the scope of this article and I will not cover it. 237 +certbot is also an utility specific for the Let's Encrypt CA, which might differ from your own certificate authority. But, regardless of which CA you choose to use, everything should boil down to 3 ".pem" files at the end, one containing your public key that will be delived to the visitor, one containing the fullchain and one containing the private key which will be used by Nginx to decrypt incoming traffic with. 238 + 239 +As such, please change these file paths to the 3 files that you will be using from your respective CA. If in doubt, always ask for professional help from a sysadmin! 240 + 241 + 242 += Testing our setup and deploying = 243 + 244 +We're almost done! For completeness' sake, here's my gitea.conf Nginx configuration file as well, so that you have a base to start out with: 245 + 246 +{{code language="nginx"}} 247 + server { 248 + server_name git.pentilescu.com; 249 + 250 + listen [::]:443 ssl http2; # managed by Certbot 251 + listen 443 ssl http2; # managed by Certbot 252 + 253 + 254 + include /etc/nginx/snippets/ssl.conf; 255 + 256 + location / { 257 + proxy_pass http://localhost:3000; 258 + } 259 +} 260 +{{/code}} 261 + 262 +This will redirect all requests meant for "git.pentilescu.com" to localhost port 3000. It also supports TLS, as usual. 263 + 264 +Once you've got everything ready, run the following command to test all your configuration files at once: 265 + 266 +{{code language="bash"}} 267 + sudo nginx -t 268 +{{/code}} 269 + 270 +If Nginx reports that everything is OK, then proceed to restart the service with" 271 + 272 +{{code language="bash"}} 273 + sudo systemctl restart nginx 274 +{{/code}} 275 + 276 +Also, I don't remember if the Nginx daemon is set to run by default on system startup. This is pretty important, as you want all of your web services to be available even in the case of a system reboot. You shouldn't have to manually start Nginx after a system reboot! As such, I recommend running the following to make sure it's enabled: 277 + 278 +{{code language="bash"}} 279 + sudo systemctl enable nginx 280 +{{/code}} 281 + 282 +Also you might have to open firewall ports 80 and 443 to allow Nginx to listen to these. This is specific to your distro so please do that manually. On my end, I don't remember having to do that. I think just installing Nginx did that automatically. Your mileage may vary. 283 + 284 +That's it! Happy coding!