Install NGINX
sudo su -
apt update
apt upgrade
apt install nginx
nginx -v
Confirm NGINX is working by navigation to localhost
NGINX Files and Directories
/etc/nginx
(Configurations)var/log/nginx
(Access and error logs)var/www/html
(Default directory)
Commonly Used Commands
systemctl status nginx # check status
systemctl start nginx # start server
systemctl stop nginx # stop server
systemctl is-active nginx
systemctl reload nginx
nginx -h # help
nginx -t # test config without reboot
nginx -T # test config and cat file on screen
Main configuration file of nginx is located in /etc/nginx/nginx.conf
(review this) but we will keep our configuration in /etc/nginx/conf.d
Unlink default unlink /etc/nginx/sites-enabled/default
Configuring Virtual Host
Add file in /etc/nginx/sites-enabled
with the convention of site-name.conf
.
Define server directive
server {
listen 80;
root /var/html/[folder_name]
}
nginx -t
for test and then systemctl reload nginx
. Check status via systemctl status nginx
and navigate to localhost to confirm the change.
Defines define server and set virtual host i.e. http://site-name.local
server {
listen 80 default_server; # set this as default because nginx can host multiple sites
root /var/www/[site_name]; # folder
server_name [site_name].local www.[site_name].local; # virtual host name
index index.html;
}
Configure Location
Use the location directive to extend our configuration based on URI
server {
location [modifier] location_definition {
location [modifier] location_definition { # can be nested }
}
}
Examples
server {
location / {
try_files $uri $uri/ =404;
}
location /images/ {
# show content of images folder
autoindex on;
}
}
Error Page Directives
error_page 404 /404.html;
location = /404.html {
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
internal;
}
location = /500 {
fastcgi_pass unix:/this/will/fail;
}
Configuring LEMP Stack
Install php-fpm
and mysql
on our machine.
apt install php-fpm mysql-server
mysql_secure_installation # for easy security setup
php --version
mysql --version
Configure PHP
Add nginx configuration for php files.
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_intercept_errors on;
}
Create php file on your site root and test it by accessing it from browser. For test purposes you can use following code.
<?php
phpinfo(); // Show all information, defaults to INFO_ALL
phpinfo(INFO_MODULES); // Show just the module information.
?>
Configure MySQL
Create user, grant privileges and confirm the new user.
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
CREATE DATABASE database-name;
GRANT ALL PRIVILEGES ON database-name.* TO "newuser"@"hostname";
FLUSH PRIVILEGES;
mysql -u newuser -p
NGINX Security
We can allow and deny certain urls from nginx configurations.
location /secure_directive_url/ {
# only allow IPs from the same network the server is on
allow 192.168.0.0/24;
allow 10.0.0.0/8;
deny all;
}
Create 403 page and and path that is always denied for testing purposes.
location /deny {
deny all;
}
error_page 403 /403.html;
location = /403.html {
internal;
}
Configure Password Authentication
Install http basic auth module, test installation and setup authentication.
apt install apache2-utils -y
htpasswd
htpasswd -c /etc/nginx/passwords username # create encrypted password file with user and their passwords
chown www-data /etc/nginx/passwords # add nginx user as owner for security
chmod 600 /etc/nginx/passwords # change permissions
Now configure nginx to use this password for our secure_directive_url
directory.
location /secure_directive_url/ {
auth_basic 'Authentication is required...';
auth_basic_user_file /etc/nginx/passwords;
# This will get prioritized
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_intercept_errors on;
}
# only allow IPs from the same network the server is on
# allow 192.168.0.0/24;
# allow 10.0.0.0/8;
# deny all;
}
Configure HTTPS
Create a SSL Certificate
Check openssl
and install if necessary
which openssl
apt install openssl -y
There are several methods but we will use the simplest one which create a key and certificate in one command.
openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/ssl/private/nginx.key -out /etc/ssl/certs/nginx.csr -batch
Certificates should be public and private keys should be private.
Install an SSL Certificate on NGINX
Open configuration file and make following changes.
Force all traffic to https
server {
listen 80 default_server;
return 301 https://$server_addr$request_uri;
}
Configure traffic coming from https
server{
listen 443 ssl default_server;
ssl_certificate [path_to_certificate];
ssl_certificate_key [path_to_private_key];
}
If you are using Amazon Certificate Manager for ssl
and Amazon ELB for forwarding requests to your web server then all of those requests will be forwarded by just port 80
so in this case nginx configs will be updated as following:
server {
listen 80 default_server;
# ELB stores the protocol used between the client
# and the load balancer in the X-Forwarded-Proto request header.
# Check for 'https' and redirect if not
if ($http_x_forwarded_proto != 'https')
{
return 301 https://$host$request_uri;
}
}