Nginx web server

Last updated on 2021-06-30 Tagged under  # nginx  # network  # linux

Part of "New life for an old laptop as a Linux home server"

Nginx is an open-source, high performance, lightweight HTTP and reverse proxy server.

Setup:

Install

Debian stable package for Nginx is quite old. Nginx provides its own mainline and stable Debian packages (see here for the difference).

Nginx install instructions for Debian

After install, check status ...

$ systemctl status nginx

By default, the Nginx service is enabled but not running. Start service ...

$ sudo systemctl start nginx

Configuration files are located in the /etc/nginx/ directory.

Navigate to http://server-ip-address and view the default Nginx webpage to confirm the server is up-and-running.

Dynamic DNS

My home server sits behind a router assigned an external dynamic IP address by the ISP. If I want to remotely connect to my server, I can use a Dynamic DNS (DDNS) service to create a domain name, automatically update the IP address whenever it changes, and redirect traffic to the new location.

I use the free DDNS service provided by Duck DNS, which permits the creation of up to five domains in the format <my-subdomain-name>.duckdns.org.

See the install instructions for setting up a cron job on the server that polls the external IP address assigned by the ISP, and notifies Duck DNS of the current address.

Use Network Address Translation (NAT) on a home router to setup port forwarding, which forwards traffic directed at one of the router's ports to the listening port on the home server.

Note: My ISP blocks incoming ports 80 and 443. Many ISPs do. Use an unassigned port on the router to listen for traffic to forward to Nginx. Example: forward port 58880 on router to port 80 on the server.

Navigate to http://my-subdomain-name.duckdns.org:58880 and confirm forwarding is working.

Custom website

To get started, copy contents of Nginx's default site to /home/my-username ...

$ cp -av /usr/share/nginx/html /home/my-username/

Customize index.html to differentiate it from the Nginx boilerplate text.

Each website hosted with Nginx should have its own configuration file in /etc/nginx/conf.d/, with the name formatted as my-website.conf ...

$ sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/my-website.conf

In the new my-website.conf, modify the server_name and location root. Example ...

server {
    listen       80;
    server_name  my-subdomain-name.duckdns.org;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /home/my-username/html;
        index  index.html index.htm;
    }

Check for syntax errors ...

$ sudo nginx -t

Activate the new *.conf by reloading nginx.service ...

$ sudo systemctl reload nginx.service

Navigate to http://my-subdomain-name.duckdns.org:58880 and confirm the new webpage is displayed.

SSL

Secure Socket Layer (SSL) is a protocol for establishing authenticated and encrypted links between networked computers.

Create a self-signed SSL certificate for Nginx ...

$ sudo openssl req -x509 -nodes -days 9999 -newkey rsa:4096 -keyout /etc/ssl/private/nginx-server-selfsigned.key -out /etc/ssl/certs/nginx-server-selfsigned.crt

Configure Nginx to use SSL by modifying /etc/nginx/conf.d/my-website.conf ...

server {
    listen 80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name my-subdomain-name.duckdns.org;

    ssl_certificate /etc/ssl/certs/nginx-server-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-server-selfsigned.key;

    [...]
    
}

Verify syntax ...

$ sudo nginx -t

Reload ...

$ sudo systemctl reload nginx.service

Forward traffic from the router to port 443 on the server. Like I did previously for the ISP-blocked port 80, use an unassigned port on the router to listen. Example: forward port 54443 on router to port 443 on the server.

Navigate to https://my-subdomain-name.duckdns.org:54443 and, because its a self-signed certificate, a web browser will display a warning (Firefox pops up Warning: Potential Security Risk Ahead). In this case, where the certificate was created by ourselves, confirm its OK to permit an exception.

In a production environment serving multiple users, instead of using a self-signed certificate, its best to use a certificate issued by a certificate authority such as Let's Encrypt.

Good stuff!


» Later: Self-host a personal calendar and address book using Radicale

« Earlier: A backup you don't have to think about is a backup that gets done