TABLE OF CONTENT
Introduction
Prerequisites
Home/Small Office – Debian Server
Home/Small Office – Debian Server Initial Customization
Nginx Installation
apt install -y nginx-extras
For any questions the installer might ask during the installation, accept the defaults by pressing Enter on your keyboard. Once installed, you will find all configuration files at the default location in the /etc/nginx directory.
In the next section of this guide, we will observe the function of the essential configuration files and perform the initial configuration of the Nginx web server.
Nginx Configuration
Configuration Files Hierarchy
Once you install the Nginx, you will find all configuration files in the /etc/nginx directory. You will notice a couple of other files and sub-directories, along with the main configuration file, which allows us to fine-grain the Nginx configuration. Let's observe only the essential files required for Nginx to serve simple static content:
-
- nginx.conf - Nginx main configuration file. It contains mainly "global" settings required for Nginx to work in general. You can use this single file to perform a complete Nginx configuration, but I would not recommend it. In cases where you need to host many websites, putting everything in a main configuration file will clutter it, thus making it difficult to maintain. The "correct" way of doing things is to use the include core functionality of Nginx to split our configuration files into a set featuring specific files stored in the main /etc/nginx directory or sub-directories.
- mime.types - MIME types describe the media type of content. They are intended to help hint at how the content should be processed and displayed. This file is included in the main Nginx configuration:
include /etc/nginx/mime.types;
. - conf.d subdirectory - options previously specified in the primary nginx.conf file can be overridden by creating a file at this location. This file is included in the main Nginx configuration:
include /etc/nginx/conf.d/*.conf;
. - sites-available subdirectory - used to store all virtual host configurations, whether enabled or not.
- sites-enabled subdirectory - used to store all active (enabled) virtual hosts. The ln command is used to enable a virtual host, and the virtual host configuration is symlinked to the sites-enabled directory. This file is included in the main Nginx configuration:
include /etc/nginx/sites-enabled/*;
. - snippets subdirectory - I use this directory to store the configurations that may optionally be included in other configuration files. In most cases, the virtual host configurations.
You may notice other files and directories like fastcgi.conf, proxy_params, etc. They are used for more advanced Nginx configurations, so I will not cover them in this guide. Now that you know how and where to store Nginx configurations, we can start with the configuration itself, and I will show you how in the following subsections.
Snippets - General Security
systemctl stop nginx.service
# Basic Security Headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# . files
location ~ /\.(?!well-known) {
deny all;
}
Let me explain a bit what we did here:
-
- Strict-Transport-Security header - also known as HSTS header, it instructs browsers to communicate with your site only over HTTPS. Your website(s) will set this header every time someone visits, with an expiration date of two years (in seconds). I will cover all subdomains, including internal subdomains that are not publicly accessible. Use extra caution when setting preload.
- X-Frame-Options header - ensures a website cannot be embedded in a frame or iframe (DENY). Sites can use this to avoid clickjacking attacks by ensuring that their content is not embedded into other sites.
- X-Content-Type-Options header - this header is used to block browsers' MIME type sniffing, which can transform non-executable MIME types into executable MIME types.
- location block - in this block, I have denied access to all "dotted" (hidden) files except the ".well-known" directory, which is required by LetsEncrypt (certbot).
Snippets - General Vhost
# favicon.ico
location = /favicon.ico {
log_not_found off;
access_log off;
}
# robots.txt
location = /robots.txt {
log_not_found off;
access_log off;
}
Nginx Main Configuration File
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bkp
# Master Nginx Configuration
# User - change to nobody if using reverse proxy
#user nobody nogroup;
user www-data;
pid /var/run/nginx.pid;
worker_processes 4; # = number of CPU cores
worker_rlimit_nofile 65535;
timer_resolution 50ms;
# Include Modules
include /etc/nginx/modules-enabled/*.conf;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
charset utf-8;
sendfile on;
tcp_nopush off;
log_not_found off;
# AIO Threads
aio threads;
aio_write on;
# Server Tokens
server_tokens off;
more_set_headers 'Server: My WebServer';
# MIME Types
include mime.types;
default_type application/octet-stream;
# Logging
access_log off;
error_log /var/log/nginx/error.log warn;
# Mandatory Master Settings
# Enable if using reverse proxy
#proxy_temp_path /home/nginx/proxy_temp 1 2;
#proxy_buffers 16 16k;
#proxy_buffer_size 16k;
server_names_hash_max_size 2048;
server_names_hash_bucket_size 256;
keepalive_timeout 10s;
keepalive_requests 100;
keepalive_disable msie6;
# Optional Master Settings
client_body_timeout 60;
client_header_timeout 60;
gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
gzip_min_length 1000;
gzip_buffers 16 8k;
gzip_proxied expired no-cache no-store private auth;
gzip_comp_level 6;
gzip_http_version 1.0;
gzip_types text/plain text/css application/x-javascript application/javascript text/xml text/csv application/x-shockwave-flash image/svg+xml;
send_timeout 60;
# SSL Settings - https://syslink.pl/cipherlist/
# Enable (uncomment) only if SSL/HTTPS is used
#ssl_session_timeout 10m;
#ssl_session_cache shared:SSL:10m;
#ssl_session_tickets off;
#ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
#ssl_protocols TLSv1.3;
#ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
#ssl_ecdh_curve secp384r1;
#ssl_stapling on;
#ssl_stapling_verify on;
#ssl_prefer_server_ciphers on;
#resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=300s;
#resolver_timeout 5s;
# Includes
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Default Virtual Host Configuration
The default virtual host is something Nginx will use to "reply" in a case where everything else fails. To clarify, imagine you have several virtual hosts on your server, respectively, example01.com, example02.com, and example03.com. You also have a single public IP address that all virtual hosts are using (shared hosting), for example, 10.10.10.1. You can configure the "default virtual host" in one of the following three ways.
If you don't set the default virtual host, the server will elect a virtual host who is first in the alphabetical/numerical order to be the default virtual host. In our example, that will be example01.com.
You can select which virtual host you want to act as a default by setting the default and listen options in its configuration:
server_name example02.com default;
listen 10.10.10.1:80 default_server;
server {
server_name default;
listen 0.0.0.0:80 default_server;
##
# Include general vhost configuration snippet
##
include /etc/nginx/snippets/general-vhost.conf;
# redirect everything to example.com
rewrite ^(.*)$ https://example.com$1 permanent;
}
Virtual Hosts
In this subsection, we will configure our first virtual host (website). To do so, a few prerequisites need to be satisfied:
-
- Domain Name: your domain name. To use a public domain, you must register it with a domain register and set the correct name servers. In case you want to use a test domain, you will need to either have a local DNS server or you will have to modify local hosts file (/etc/hosts on Linux systems, C:\Windows\System32\drivers\etc\hosts on MS Windows) by entering a correct hostname/IP address record (i.e., 10.10.10.1 example.com).
- Content Location: a directory on the server where you will put your website content. The default location is /var/www/$DOMAIN (replace $DOMAIN with your domain name, i.e., example.com).
As an example, I will use the example.com domain name, and I will put the content in /var/www/example.com/public_html directory. I also want logging enabled for my website and logs to go into the/var/www/example.com/logs directory. I will first create the required directories:
mkdir -p /var/www/example.com/{public_html,logs}
server {
listen 10.10.10.1:80;
server_name example.com;
##
# Include general vhost configuration snippet
##
include /etc/nginx/snippets/general-vhost.conf;
##
# Logging
##
access_log /var/www/example.com/logs/access.log;
error_log /var/www/example.com/logs/error.log info;
root /var/www/example.com/public_html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl start nginx.service
Summary
10.10.10.1 example.com
curl example.com
Hello All!!!