Cyberciti.biz Webserver Security
Caching Minified files with Nginx
Multiple Django and Flask Sites with Nginx and uWSGI Emperor
rtCamp Wordpress Nginx Tutorials
PHP-FPM: Socket vs TCP/IP and sysctl tweaking
fastcgi_cache with conditional purging
Checklist For Perfect WordPress-Nginx Setup
Perfect way to check if fastcgi-cache is working
Nginx location directive doesn't seem to be working. Am I missing something?
Set nginx.conf to deny all connections except to certain files or directories
kbeezie.com Search Page Getting Hammered?
Top 20 Nginx WebServer Best Security Practices
CentOS / Redhat Linux: Install Keepalived To Provide IP Failover For Web Cluster
nginx: Setup SSL Reverse Proxy (Load Balanced SSL Proxy)
20 Linux Server Hardening Security Tips
25 PHP Security Best Practices For Sys Admins
Top 20 Nginx WebServer Best Security Practices
Top 20 OpenSSH Server Best Security Practices
Tips To Protect Linux Servers Physical Console Access
Optimizing web server performance with Nginx and PHP
Performance tuning: Intel 10-gigabit NIC
3 Million and Beyond – Creating Scalable Web Clusters with LVS
How to Generate Millions of HTTP Requests
Tuning Nginx for Best Performance
Building a Load-Balancing Cluster with LVS
Turn Off Headers¶
Server nginx/1.2.4
X-Powered-By PHP/5.3.17-1~dotdeb.0
It´s necessary to edit php.ini & nginx.conf as follows.
PHP: To remove X-Powered-By completely, expose_php should be disabled in php.ini.
...
expose_php = Off
...
Nginx: To remove Server Version from Header, server_tokens should be disabled in nginx.conf.
...
server_tokens off;
proxy_hide_header X-Powered-By;
...
See also:
http://wiki.nginx.org/HttpCoreModule#server_tokens
http://forum.nginx.org/read.php?11,1646
http://wiki.nginx.org/NginxHttpHeadersMoreModule
Gzip Compression for Static Web Pages¶
Below script can be used to generate gzipped static web pages. It can be added into cron.
#! /bin/bash
# this script checks a list of directories for a list of extensions and
# generated gzipped versions of the files that are found
#
# if the modification date of a file is newer than its gzipped version
# then the gzip file is regenerated
# specify a filetype like *.css or a filename like index.html
# leave one space between entries
FILETYPES="*.css *.jpg *.jpeg *.gif *.png *.js *.html"
# specify a list of directories to check recursively
DIRECTORIES="/var/www/nginx_default/*"
for currentdir in $DIRECTORIES
do
for extension in $FILETYPES
do
find $currentdir -iname $extension -exec bash -c 'PLAINFILE={};GZIPPEDFILE={}.gz;
if [ -e $GZIPPEDFILE ];
then if [ `stat --printf=%Y $PLAINFILE` -gt `stat --printf=%Y $GZIPPEDFILE` ];
then echo "$GZIPPEDFILE outdated, regenerating";
gzip -9 -f -c $PLAINFILE > $GZIPPEDFILE;
fi;
else echo "$GZIPPEDFILE is missing, creating it";
gzip -9 -c $PLAINFILE > $GZIPPEDFILE;
fi' ;
done
done
Nginx: Nginx configuration to serve gziped files:
gzip on;
gzip_disable "msie6";
gzip_static on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 9;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
Test if nginx is serving .gz files :
# ps ax | grep nginx
## Strace the nginx worker
# strace -p 5383 2>&1 | grep gz
More info:
http://wiki.linuxwall.info/doku.php/en:ressources:dossiers:nginx:nginx_performance_tuning
http://stackoverflow.com/questions/2460821/how-can-i-check-that-the-nginx-gzip-static-module-is-working
http://wiki.nginx.org/HttpGzipStaticModule
OpenVPN Sharing a TCP Port with SSL on NGINX and Apache?¶
Use SSLH
Or
The reason I say “it’s possible” is because for the longest time I didn’t think it was because I couldn’t get anything to explain how it works. I’m absolutely baffled there isn’t more information out there about this. It seems like web managers and techs would be all over this, but there’s barely any information out there on this. I had a hard time finding documentation on OpenVPN’s site itself! As one guy stated here (the post where I finally understood how this works) it’s not really “sharing” the port per se, but OpenVPN is deciphering between HTTP/S traffic and OpenVPN traffic and then forwarding web traffic over to another port, defined below. That’s crucial to understand. Before I start, I want to note this doesn’t have to be done on an SSL port, as I understand it. I’m just using that as an example because it seems to be the most logical way to make it work if this is your configuration (you know, an SSL VPN going to an SSL port). It should also be noted in this configuration example that OpenVPN, using the port-share parameter, is actually doing the listening on TCP port 443 and acting as a proxy itself that forwards non-OpenVPN traffic to the NGINX SSL port which we’ll layout below. You cannot do this utilizing UDP, that I know of. So here’s what you do.
Set your NGINX or Apache listening ports. Set your NGINX standard ttp port 80 and SSL listening port to something OTHER than 443 … so, for arguments’ sake, let’s set it to 4443. So it would look like this for Apache and NGINX: For Apache, in the main httpd.conf (Windows) or in ports.conf (Ubuntu/Linux):
Listen 4443
For NGINX, in /etc/nginx/sites-available/defaults:
server {
listen 4443;
location / {
root /web/etc/blah;
}
}
Once implemented, restart your respective service, Apache or NGINX.
2) Next, you’re going to set your OpenVPN server parameters. Set your listening port to 443 from its standard 1194 and add the port-share parameter to point to the Apache or NGINX port created above. The config should look as follows now:
port 443
port-share 127.0.0.1 4443
proto tcp
OpenVPN will now be ready to accept connections over 443 and route the appropriate https/SSL traffic to Apache or NGINX.
3) Change your firewall settings. Leave your TCP port 80 rule pointing directly to Apache or NGINX. Then point your SSL rule to TCP port 443 running on your OpenVPN server. OpenVPN will now catch the traffic directed at it and decipher between OpenVPN traffic and HTTPS traffic.
4) Change the configuration in your OpenVPN clients. Point your OpenVPN clients to TCP port 443 instead of the port you were using before:
remote domain.name.com 443
or
remote [IP ADDRESS] 443
Make A Self-signed SSL certificate¶
cd /etc/nginx
openssl req -new -x509 -nodes -out server.crt -keyout server.key
chmod 600 server.key
Example Configuration Part
ssl on;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
Redirect to HTTPS
location / {
return 301 https://example.com$request_uri;
}
As A Force-HTTPS Reverse Proxy
proxy_redirect http:// $scheme://
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Scheme $scheme;
Verify A CRT Matches A KEY
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in myserver.key | openssl md5
If the output are not the same, then they do not match and won't work on Nginx.
Generating a Certificate Signing Request (CSR)
openssl req -new -newkey rsa:2048 -nodes -keyout $DOMAIN.key -out $DOMAIN.csr
CSR Fields
Country Code: The two-letter International Organization for Standardization (ISO-) format country code for the country in which your organization is legally registered. Click the link below for a complete list of ISO country codes. ISO Country Codes
State/Province: Name of state, province, region, territory where your organization is located. Please enter the full name. Do not abbreviate
City/Locality: Name of the city/locality in which your organization is registered/located. Please spell out the name of the city/locality. Do not abbreviate.
Organization: The name under which your business is legally registered. The listed organization must be the legal registrant of the domain name in the certificate request. If you are enrolling as a small business/sole proprietor, please enter the certificate requester's name in the "Organization" field, and the DBA (doing business as) name in the "Organizational Unit" field.
Organizational Unit: Optional. Use this field to differentiate between divisions within an organization. For example, "Engineering" or "Human Resources." If applicable, you may enter the DBA (doing business as) name in this field.
Common name: The name entered in the "CN" (common name) field of the CSR MUST be the fully-qualified domain name for the website you will be using the certificate for (e.g., "www.domainnamegoeshere"). Do not include the "http://" or "https://" prefixes in your common name. Do NOT enter your personal name in this field.
If you are requesting a Wild Card certificate, please add an asterisk () on the left side of the common name (e.g., ".domainnamegoeshere.com"). This will secure all subdomains of the common name.
NOTE: If you enter "www.domainnamegoeshere.com" as the Common Name in your certificate signing request, the certificate will secure both "www.domainnamegoeshere.com" and "domainnamegoeshere.com." And vice versa.
References:
http://dracoblue.net/dev/https-nginx-with-self-signed-ssl-certificate/188/
http://serverfault.com/questions/372886/prevent-nginx-from-redirecting-traffic-from-https-to-http-when-used-as-a-reverse
http://support.godaddy.com/help/article/3601/generating-a-certificate-signing-request-nginx
http://support.godaddy.com/help/category/746/ssl-certificates-csr-generation-instructions
https://support.comodo.com/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=1250