Project

General

Profile

Support #666

Updated by Daniel Curtis over 8 years ago

These are a few tips for hardening nginx on FreeBSD. 

 h2. Nginx 

 h3. Disable nginx server_tokens 

 * Edit the main nginx config file: 
 <pre> 
 vi /usr/local/etc/nginx/nginx.conf 
 </pre> 
 #* And add the following line inside the http block to disable nginx server_tokens: 
 <pre> 
 server_tokens off; 
 </pre> 

 h3. Configure an X-Frame-Options header 

 * Edit the main nginx config file: 
 <pre> 
 vi /usr/local/etc/nginx/nginx.conf 
 </pre> 
 #* And add the following line inside the http block to configure an X-Frame-Options header: 
 <pre> 
 add_header X-Frame-Options "SAMEORIGIN"; 
 </pre> 

 h3. Redirect to HTTPS 

 * Edit the nginx server block: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/www.example.com.conf 
 </pre> 
 #* And add the following inside the server block to redirect all regular HTTP requests to HTTPS: 
 <pre> 
 # Redirect to HTTPS 
 if ($scheme = http) { 
     return 301 https://$server_name$request_uri; 
 } 
 </pre> 

 h3. Disable unwanted HTTP methods 

 * Edit the nginx server block: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/www.example.com.conf 
 </pre> 
 #* And add the following inside the server block to disable unwanted HTTP methods: 
 <pre> 
 # Disable unwanted HTTP methods 
 if ($request_method !~ ^(GET|HEAD|POST)$ ) { 
     return 444; 
 } 
 </pre> 
 #* (Optional) For websites that use WebDAV, like owncloud, additional requests methods can be included.: 
 <pre> 
 # Disable unwanted HTTP methods 
 if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|REPORT|PROPFIND)$ ) { 
     return 444; 
 } 
 </pre> 

 h3. Limit the maximum upload file size 

 * Edit the nginx server block: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/www.example.com.conf 
 </pre> 
 #* And add the following inside the server block to limit the maximum upload file size: 
 <pre> 
 client_max_body_size 20m; 
 client_body_buffer_size 128k; 
 </pre> 

 h3. Deny access to hidden files 

 * Edit the nginx server block: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/www.example.com.conf 
 </pre> 
 #* And add the following inside the server block to deny access to hidden files: 
 <pre> 
 location ~ /\. { 
     access_log off; 
     log_not_found off;  
     deny all; 
 } 
 </pre> 

 h2. PHP-FPM 

 * Edit the main php-fpm config file: 
 <pre> 
 vi /usr/local/etc/php-fpm.conf 
 </pre> 
 #* And add the following: 
 <pre> 
 include=/usr/local/etc/fpm.d/*.conf 
 </pre> 

 * Create the php-fpm directory to store each individual site php-fpm configs: 
 <pre> 
 mkdir /usr/local/etc/fpm.d 
 </pre> 

 h3. Define a pool for www.example.com 

 * Create the *www.example.com* website user: 
 <pre> 
 pw add user -n wwwexamplecom -m -s /usr/sbin/nologin -c "www.example.com" 
 </pre>  

 * Define a new pool for *www.example.com*: 
 <pre> 
 vi /usr/local/etc/fpm.d/www.example.com.conf 
 </pre> 
 #* And add the following 
 <pre> 
 [www.example.com] 
 listen = /var/run/www.example.com-php-fpm.sock 
 listen.owner = wwwexamplecom 
 listen.group = www 
 listen.mode = 0660 
 user = wwwexamplecom 
 group = www 
 pm = dynamic 
 pm.max_children = 50 
 pm.start_servers = 20 
 pm.min_spare_servers = 5 
 pm.max_spare_servers = 35 
 </pre> 

 * Edit the server config for *www.example.com*: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/www.example.com.conf 
 </pre> 
 #* And modify the PHP location handler: 
 <pre> 
 server { 
   location ~ \.php$ { 
     try_files $uri =404; 
     fastcgi_pass unix:/var/run/php5-fpm/www.example.com-php-fpm.sock; 
     fastcgi_index index.php; 
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
     fastcgi_param PATH_INFO $fastcgi_script_name; 
     include /etc/nginx/fastcgi_params; 
   } 
 } 
 </pre> 

 h3. Define a pool for mail.example.com 

 * Create the *mail.example.com* website user: 
 <pre> 
 pw add user -n mailexamplecom -m -s /usr/sbin/nologin -c "mail.example.com" 
 </pre>  

 * Define a new pool for *mail.example.com*: 
 <pre> 
 vi /usr/local/etc/fpm.d/mail.example.com.conf 
 </pre> 
 #* And add the following 
 <pre> 
 [mail.example.com] 
 listen = /var/run/mail.example.com-php-fpm.sock 
 listen.owner = mailexamplecom 
 listen.group = www 
 listen.mode = 0660 
 user = mailexamplecom 
 group = www 
 pm = dynamic 
 pm.max_children = 50 
 pm.start_servers = 20 
 pm.min_spare_servers = 5 
 pm.max_spare_servers = 35 
 </pre> 

 * Edit the server config for *mail.example.com*: 
 <pre> 
 vi /usr/local/etc/nginx/conf.d/mail.example.com.conf 
 </pre> 
 #* And modify the PHP location handler: 
 <pre> 
 server { 
   location ~ \.php$ { 
     try_files $uri =404; 
     fastcgi_pass unix:/var/run/php5-fpm/mail.example.com-php-fpm.sock; 
     fastcgi_index index.php; 
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
     fastcgi_param PATH_INFO $fastcgi_script_name; 
     include /etc/nginx/fastcgi_params; 
   } 
 } 
 </pre> 

 h2. Resources 

 * https://www.howtoforge.com/php-fpm-nginx-security-in-shared-hosting-environments-debian-ubuntu 
 * http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/ 
 * https://www.acunetix.com/blog/articles/nginx-server-security-hardening-configuration-1/ 
 * https://www.acunetix.com/blog/articles/nginx-security-hardening-configuration-2/ 
 * http://sabre.io/dav/building-a-caldav-client/

Back