Category Archives: Nginx

No space left on device.

Sometimes we can be fooled by error messages. For example one sunny day you see that for some reason your web or mail server doesn’t work. So you go to check the logs and find something similar to this:

2016/12/28 09:02:37 [crit] 24668#24668: *472674 open() "/var/cache/nginx/client_temp/0020878597" failed (28: No space left on device), client: 192.168.1.1, server: www.domain.com, request: "GET /cart/add/uenc/aHR0cDovL3d3dy5hYmNob21lLmNvbS9zaG9wL2xvdi1vcmdhbmljLWxvdi1pcy1iZWF1dGlmdWwtdGVh/product/19471/form_key/N8l3OyVkC1el9T8q/?product=19471&related_product=&send_to_friend=%2F%2Fwww.domain.com%2Fshop%2Fsendfriend%2Fproduct%2Fsend%2Fid%2F19471%2F&form_key=N8l3OyVkC1el9T8q&super_group%5B19425%5D=1&super_group%5B19424%5D= HTTP/1.1", host: "www.domain.com", referrer: "http://www.domain.com/shop/organic-tea"

Then when you check the free space you see that you have more than enough, and all kind of irrational thoughts start flowing into your mind, when it is the simple inodes space.

Usually it is just that there is not enough inodes left free on your files system, simple as that, but is easy to overlook as for some people this doesn’t happen often (and it shouldn’t).

[root@hostname client_temp]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/os-root 1703936 1703103 833 100% /
tmpfs 1524264 4 1524260 1% /dev/shm
/dev/sda1 51000 50 50950 1% /boot
/dev/mapper/os-tmp 131072 2155 128917 2% /tmp
/dev/mapper/data-data
19660800 578302 19082498 3% /data

Nginx basic authentication

Setting up basic authentication in Nginx is pretty easy, you need to first add couple of directives in block config, you can out them directly in the server if you want the whole site not be accessible or just on some parts-

    auth_basic "Restricted Content";
    auth_basic_user_file /etc/nginx/.htpasswd;

Then in the .htpasswd file add the user and use openssl to generate hash for the chosen password –

echo "password" | openssl passwd -apr1 -stdin

Nginx simple load balancing.

Nginx is amazing and load balancing with it is so easy, since it is a proxy too we can have everything working perfectly on the same domain.
First you will need few application servers that are listening to some ports, and the might be different like 81, 82, 83 etc. But that is not necessarily.

Then you need something like this on the load balancer, and voila –

server {

  listen 80;
  server_name balancer;

  location / {
     proxy_pass  http://balancer;
     include /etc/nginx/proxy_params;
  }

}
    
upstream balancer {
   ip_hash;
   server ha1.com;
   server ha2.com:82;
   server ha3.com:83;
}

ip_hash is important for sessions and logins, if you don’t want to have users logged out from your site, as the default behavior is round-robin which mean the users will cycle on the next node after every request.

There is other configuration options, but this is just quick syntax reference, you can check the documentation here – http://nginx.org/en/docs/http/load_balancing.html

Count the visitors from the access log

Sometimes is handy to see what number of visitors you had on you site/server based on the access log – in this case Nginx access log. This will count every different IP, so a chunk of these visitors will be bots.


grep "\[13/Jul/2015" /var/log/nginx/access.log | cut -d" " -f1 | sort | uniq | wc -l

Another slightly different variation

cat access_log | awk '{print $1}' | sort | uniq -c | sort -n | tail

Fix weak Diffie-Hellman (DH) key exchange parameters.

This will fix security vulnerability called Logjam. In short the vulnerability allow man-in-the-middle attack by downgrading TLS connection and manipulating data. You can find full disclosure here.

The solution bellow is just for Nginx, because currently I don’t Apache anywhere right now and I don’t care, but should be pretty easy to do on Apache as well. Also you should fix all other services which are using SSL like FTP, Mail etc.

First check if you have the directory

/etc/ssl/private

If you don’t have it, you will need to create it, and change it’s permissions:

mkdir -p /etc/ssl/private
chmod 710 /etc/ssl/private

Then you need to create DH parameter file, and change the permissions:

cd /etc/ssl/private
openssl dhparam -out dhparams.pem 2048
chmod 600 dhparams.pem

Be patient as this might take a little while, and will consume your CPU.
It was few minutes in my case.

Now you need to edit few things in the nginx config file:

nano /etc/nginx/nginx.conf

Replace or add the fallowing to the httpd section:

ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

and then add the fallowing two lines:

ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/private/dhparams.pem;

Run configtest to see if you forgot some semicolon:

service nginx configtest

and if it says it is OK, you can restart it.

WooCommerce can’t remove items from cart on Nginx

Just finished moving client site from Apache to Nginx, and upon testing I noticed when I try to remove some product from the cart, it wasn’t working . All is happening is to reload the page.

It turns out that the problem is in my Nginx config (as I suspected).

A really simple fix.

If you have section like this in your config file:

    location / {
                try_files $uri $uri/ /index.php;
        }

you will need to add ?$args after index.php, so it is going to look like this:

    location / {
                try_files $uri $uri/ /index.php?$args;
        }