How to install NGINX Web Server on RHEL 8 - nomorespice/rhel8-howto GitHub Wiki
Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. This procedure will guide you through the installation process on a Red Hat Enterprise Linux 8 server.
This document assumes that:
- you installed the RHEL 8 x64 Operating System according to How to install RHEL 8 via kickstart
- you are performing these tasks as root
- you are performing these tasks in order, as some tasks require others to be completed first
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
yum-config-manager --disable epel
dnf -y install nginx
Be sure to modify this file with the correct number of available CPUs and affinity.
/bin/cat <<\EOT >/etc/nginx/nginx.conf
user nginx;
worker_processes 2;
worker_cpu_affinity 0101 1010;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
large_client_header_buffers 2 1k;
client_max_body_size 100K;
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 10;
send_timeout 10;
limit_conn_zone $binary_remote_addr zone=limitperip:10m;
limit_req_zone $binary_remote_addr zone=ratelimit:10m rate=5r/s;
include /etc/nginx/conf.d/*.conf;
}
EOT
Be sure to replace the STATE, CITY and ORG when creating the default SSL certificate.
mkdir -p /etc/nginx/ssl/default/
openssl req -new -newkey rsa:4096 -days 2000 -nodes -x509 -subj "/C=US/ST=STATE/L=CITY/O=ORG/CN=default" -keyout /etc/nginx/ssl/default/default.key -out /etc/nginx/ssl/default/default.pem
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
openssl x509 -pubkey < /etc/nginx/ssl/default/default.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
Be sure to update the PUBLIC-KEY-PIN with the output of the last command above
- Also update the allow section and include your IP addresses you which to allow to connect
/bin/cat <<\EOT >/etc/nginx/conf.d/default.conf
server {
listen 443 ssl http2 default_server;
server_name _;
ssl_certificate /etc/nginx/ssl/default/default.pem;
ssl_certificate_key /etc/nginx/ssl/default/default.key;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
ssl_ciphers ALL:!EXP:!NULL:!ADH:!LOW:!SSLv2:!SSLv3:!MD5:!RC4;
ssl_session_tickets off;
add_header Public-Key-Pins 'pin-sha256="base64+primary==PUBLIC-KEY-PIN"; max-age=5184000';
add_header Strict-Transport-Security "max-age=15768000;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'";
add_header Referrer-Policy "no-referrer";
server_tokens off;
limit_conn limitperip 10;
if ( $request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
location = / {
limit_req zone=ratelimit burst=10 nodelay;
allow 10.0.0.0/8;
deny all;
return 404;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires max;
log_not_found off;
}
error_page 404 /404.html;
location = /404.html {
root /var/www/;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/;
internal;
}
}
EOT
/bin/cat <<\EOT >/var/www/404.html
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Page not found</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<body>
<h1><strong>Page not found</strong></h1>
</body>
</html>
EOT
/bin/cat <<\EOT >/var/www/50x.html
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Page error</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<body>
<h1><strong>Page error</strong></h1>
</body>
</html>
EOT
/sbin/restorecon -Rv /var/www/*
Be sure to replace the STATE, CITY and ORG when creating the default SSL certificate. Also replace host.example.com with your host and domain.
yum -y --enablerepo=epel install certbot
certbot certonly --manual -d host.example.com --preferred-challenges dns
mkdir /etc/nginx/ssl/host.example.com
ln -s /etc/letsencrypt/live/host.example.com/privkey.pem /etc/nginx/ssl/host.example.com/server.key
ln -s /etc/letsencrypt/live/host.example.com/fullchain.pem /etc/nginx/ssl/host.example.com/server.crt
openssl x509 -pubkey < /etc/nginx/ssl/host.example.com/server.crt | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
As before, be sure to update the PUBLIC-KEY-PIN with the output of the last command above.
- Also update the allow section and include your IP addresses you which to allow to connect.
- Finally, replace host.example.com with your host and domain.
/bin/cat << EOT >/etc/nginx/conf.d/host.example.com.conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name host.example.com;
ssl on;
ssl_certificate /etc/nginx/ssl/host.example.com/server.crt;
ssl_certificate_key /etc/nginx/ssl/host.example.com/server.key;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
ssl_ciphers ALL:!EXP:!NULL:!ADH:!LOW:!SSLv2:!SSLv3:!MD5:!RC4;
ssl_session_tickets off;
add_header Public-Key-Pins 'pin-sha256="base64+primary==PUBLIC-KEY-PIN"; max-age=5184000';
add_header Strict-Transport-Security "max-age=15768000;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'";
add_header Referrer-Policy "no-referrer";
server_tokens off;
limit_conn limitperip 10;
if ( \$request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
root /var/www/html;
location / {
index index.php index.html index.htm;
limit_req zone=ratelimit burst=10 nodelay;
allow 10.0.0.0/8;
deny all;
}
location ~ \.php\$ {
try_files \$uri =404;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 /404.html;
location = /404.html {
root /var/www;
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www;
internal;
}
}
EOT
yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager -q --disable remi-safe
yum -y --enablerepo=remi-php74 --enablerepo=epel --enablerepo=remi-safe install php-fpm php-opcache php-cli php-gd php-curl php-mysql
/bin/sed -i "s/^user = apache/user = nginx/" /etc/php-fpm.d/www.conf
/bin/sed -i "s/^group = apache/group = nginx/" /etc/php-fpm.d/www.conf
/bin/sed -i 's/^listen = 127.0.0.1:9000/listen = \/run\/php-fpm\/www.sock/' /etc/php-fpm.d/www.conf
/bin/sed -i "s/^;listen.owner = nobody/listen.owner = nginx/" /etc/php-fpm.d/www.conf
/bin/sed -i "s/^;listen.group = nobody/listen.group = nginx/" /etc/php-fpm.d/www.conf
/bin/chown -R root:nginx /var/lib/php
setsebool httpd_execmem on
systemctl enable php-fpm
systemctl start php-fpm
Once your content is created under the web root directory, restore the SELinux context on those files
Only required if SELinux is enforcing on your system.
/sbin/restorecon -Rv /var/www/html/*
This step is optional
- Be sure to modify the SECRET
Insert the following configuration into the "server" section of the /etc/nginx/conf.d/host.example.com.conf file
location /files/ {
secure_link_secret SECRET;
if ($secure_link = "") { return 403; }
rewrite ^ /secure/$secure_link;
}
mkdir /var/www/html/secure
echo "Hello World" > /var/www/html/secure/file.txt
chown nginx:nginx /var/www/html/secure/file.txt
chmod 644 /var/www/html/secure/file.txt
restorecon -v /var/www/html/secure/*
echo -n '/var/www/html/secure/file.txt' | openssl md5 -hex
https://HOSTNAME.EXAMPLE.COM/files/7f70a978876be3d1652a2fa161d9242d/file.txt
systemctl --now enable nginx