openec2 Article Description
I had issues on wordpress freezing with one Linode site and added these lines to nginx.conf after the gzip on line:
proxy_buffer_size 16K; proxy_buffers 4 16K; proxy_max_temp_file_size 0; client_body_buffer_size 1240K;
If nginx error.log shows memory issues you can increase client_body_buffer_size.
If you want to add URL’s that do not have a domain name, do the same as phpMyAdmin.conf, but add a dummy server domain name, like null.com or something, otherwise you get an error log warning.
See https://openec2.com/article-items/scripts-part-1-nginx-configuration-files/ for more security on nginx.conf and adding phpMyAdmin access to you own static IP address.
Debian 11 and Nginx – Part 7
Configure Nginx, SSL certificate
Make sure you have your previous SES e-mail bucket lessons covered, particularly the lesson “AWS – SES e-mail bucket – Part 3 – SES Identity, DNS, SSL” and that you already have a paid SSL certificate, or, after configuring Nginx, we add a free Let’s Encrypt certificate.This lesson has the toggle called “Attend to important SSL and DNS Prerequisites”: https://openec2.com/lesson/aws-ses-e-mail-bucket-part-3-ses-identity-dns-ssl/
First, we will configure Nginx for http:// rather than https://Replace “mydomain.com” with your own domain name.
cd /etc/nginx cp -p nginx.conf nginx.conf.bak vi nginx.conf user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; 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; keepalive_timeout 65; gzip on; # include /etc/nginx/conf.d/*.conf; server_names_hash_bucket_size 64; add_header Strict-Transport-Security "max-age=31536000; includeSubdomains"; ssl_session_timeout 10m; add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';" always; add_header X-Xss-Protection "1; mode=block" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "origin-when-cross-origin" always; client_max_body_size 50M; upstream _php { server unix:/run/php/php8.2-fpm.sock; } # include /etc/nginx/memcached.conf; server { listen 80; listen [::]:80; server_name mydomain.com www.mydomain.com; # return 301 https://mydomain.com$request_uri; root /var/www/html; index index.php index.html index.htm; include /etc/nginx/default.d/*.conf; location / { index index.php index.html index.htm; try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { # SECURITY : Zero day Exploit Protection try_files $uri =404; # ENABLE : Enable PHP, listen fpm sock fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } # end port 80 } # end nginx config } [save and exit]
We will uncomment and modify the file shortly.
Fix a “racing” error:
When we start nginx, we likely receive an error from the status command: [you have to make your shell terminal screen quite wide to see full error messages displayed] systemctl status -l nginx nginx.service: Can't open PID file /run/nginx [If you get this, our reference for the fix is: https://serverfault.com/questions/1042526/open-run-nginx-pid-failed-13-permission-denied] mkdir -p /etc/systemd/system/nginx.service.d [Create these lines:] vi /etc/systemd/system/nginx.service.d/override.conf [Service] ExecStartPost=/bin/sleep 0.1 [save and exit] systemctl daemon-reload systemctl restart nginx systemctl status -l nginx
Start nginx:
systemctl stop nginx nginx -t [If no errors to correct - if so refer to systemctl status -l nginx, and the /var/log error logs] systemctl restart nginx
You should be able to check these:
http://mydomain.com and http://mydomain.com/phpinfo.php
Do not log into phpMyAdmin as you are not using https:// as yet.
You can scroll through the phpinfo page and see you are on php8.2.
To check for memcached, search on session.save_path showing the 127 values rather than “file”.
session.save_handler memcached memcached
session.save_path 127.0.0.1:11211 127.0.0.1:11211
Search for max_input_vars, and memory_limit to verify your php.ini edits.
Search for Opcode Caching to verify it is up and running.[/vc_wp_text][mk_padding_divider][vc_wp_text]
Paid SSL Certificate
Let’s say you have your paid SSL certificate, you have edited it to have the full content, as per my previous SES e-mail bucket Part 3 lesson, and that DNS shows the correct CAA record.You will need to upload the mydomain_com.crt and mydomain_com.key files using FileZilla to /home/admin.
From there, install the certificate:
cd /etc/ssl/certs cp /home/admin/*crt . ls cd ../private cp /home/admin/*.key . ls
We now add this to the SSL section of nginx.conf and remove a couple of commented fields.
[Remember to use your own domain and SSL certificate names] cd /etc/nginx vi memcached.conf upstream memcached_backend { server 127.0.0.1:11211; # Address and port of your Memcached server } [save and exit] vi nginx.conf [uncomment the line # include /etc/nginx/memcached.conf;] [uncomment the line # return 301 https://mydomain.com$request_uri;] [Before the last curly } bracket, add the port 443 SSL section:] # port 443 server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name mydomain.com; root /var/www/html; ssl_certificate "/etc/ssl/certs/mydomain_com.crt"; ssl_certificate_key "/etc/ssl/private/mydomain_com.key"; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+AES; ssl_ecdh_curve X25519:prime256v1:secp521r1:secp384r1; sl_prefer_server_ciphers on; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; include /etc/nginx/default.d/*.conf; location / { set $memcached_key "$uri?$args"; error_page 404 502 504 = @fallback; default_type text/html; index index.php index.html index.htm; try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { # SECURITY : Zero day Exploit Protection try_files $uri =404; # ENABLE : Enable PHP, listen fpm sock fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location = /robots.txt { allow all; log_not_found off; access_log off; try_files $uri /index.php?$args; } # include /etc/nginx/w3tc.conf; # include /etc/nginx/wpsuper.conf; # include /etc/nginx/inc.conf; # DISABLE DB.CONF if issues with phpmyadmin # include /etc/nginx/db.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } # end port 443 }
Remember, there will be the last } bracket below the above port 443 stanza/section.
Now try “nginx -t”
Of okay, use “systemctl restart nginx”. Then try https://mydomain.com
At this stage you can test the https://mydomain.com/phpMyAdmin login.
Remember, if it fails with a permissions error, go to the directories in the error message and change all group ownerships from apache to nginx with a “chgrp -R DIRECTORIES” command for each directory.
You see above a few other included .conf files that can help with WordPress plugins (if you use WP Super Cache or W3 Total Cache), and various security protections. As an example, in inc.conf, we will have lines that block a WordPress login unless it is your own IP address, and lines that prevent WordPress updates. You may install these and work out which stanzas you would like to remove, or simply comment out the include files, restart nginx, and do an WordPress update. Up to you. I have not spent too much time on this so far.
If you want a way of restarting all services, you can use this shell script:
cd /home/admin vi restart.sh #!/bin/sh /usr/bin/systemctl stop nginx /usr/bin/systemctl stop mariadb /usr/bin/systemctl stop memcached /usr/bin/systemctl reload php8.2-fpm /usr/bin/systemctl start memcached /usr/bin/systemctl start mariadb /usr/bin/systemctl start nginx exit [save and exit] chown root restart.sh chgrp admin restart.sh chmod 777 restart.sh
To run the script, which is a good idea to do now:
/home/admin/restart.sh
To see shell scripts and additional Nginx .conf files, please see my webpage for those examples.
I do not use deny lists in Nginx, as we can use the script blacklist.sh to block known BAD ip addresses and/or countries.
Please rename the phpinfo.php to phpinfo.php.bak as it too quickly reveals information to hackers:
cd /var/www/html mv phpinfo.php phpinfo.php.bak
[/vc_wp_text][mk_padding_divider][vc_wp_text]
Let’s Encrypt / Certbot Free SSL
We will use the next lesson for Let’s Encrypt free certificates, as there is quite a bit of information to put there.[/vc_wp_text][mk_padding_divider][vc_wp_text]Multiple Sites
There is no configuration difficulty for mutiple top level domains or subdomain websites, however, this impacts the use of PHP memory_limit, and how many sites are practical to have, given your CPU and RAM.Please see the next lesson on installing multiple free certificates which shows how you edit “includ” .conf files for each site.
Very straight forward.
Once running WordPress, you can include other .conf files, such as inc.conf and db.conf my scripting examples shown elsewhere.
These includes go into the port 443 stanzas. If not using a plugin like w3tc and its associated .conf file, you can manuall add gzip lines in the port 443 stanza as shown below. Anywhere you duplicate an entry, nginx -t will let you know the line you need to look at. I use the “cat -n FILE | more” command to help find these lines.
cd /etc/nginx vi shop.mydomain.com.conf [Go to the port 443 stanxa and after the "root" line - or anywhere really, add these lines if gzip is not already enabled elswhere:] gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 256; gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf image/svg+xml text/css text/javascript text/plain text/xml; [save and exit] nginx -t
SSL Labs and Pingdom Tests
You can see if your certificate is okay, or if a paid certificate that you edited it correctly for the right bundled order with ssllabs.com.You can see how your website shapes up with https://tools.pingdom.com/
Pingdom is a quick way to see how the site is, but varies in that you could have two sites configured the same and one gets good results and the other 80% type of results. A little odd, but still useful.