Reference Pages:
This article demonstrates how to configure nginx on a 32-bit slice to serve dynamically-created content. Nginx first-timers will also find it shows how to link an nginx configuration to the static pages provided by applications like Nagios - a task usually automated during Nagios installs - but only for Apache web-servers.
We show how to test each newly-install component of the installation is working properly as we install - a good practice that will save us from having to trace through the entire installation if we discover any problems at the end.
Finally, our choice of Debian 5.0 Lenny enables us to illustrate how to overcome the issue of there being no pre-compiled fcgi package in standard repositories for Debian 5.0 Lenny. You can export our work-around to any distribution that lacks an fcgi binary.
First, install nginx and set it to start on boot:
sudo aptitude install nginx sudo update-rc.d nginx defaults
Test browse to the server's external IP and check you see nginx's default “It works!” message. If it doesn't, the problem is probably that the server's built-in firewall is blocking the incoming HTTP request.
You can confirm that by testing if nginx's listener is visibly running on the server. Do that by listing the TCP listeners now running on the slice and using grep to filter for the port 80 listener. Do that by issuing:
netstat -pantl | egrep ':80'
You should see a result something like:
nagios:~# netstat -pantl | egrep ':80' tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 16689/nginx
We know nginx is listening - ie responding - on port 80, so we can test if it is able to see our incoming requests. If we use netcat to make a test connection to nginx's listener. We should see an “open” response as below:
nagios:~# nc -v localhost 80 localhost [127.0.0.1] 80 (www) open
If we see nothing, we can be pretty sure a firewall - iptables - is blocking the connection attempt. Iptables configuration is explained elsewhere so let's assume that we do see nginx listening and we do see its default web page.
Install Nagios. The default Nagios3 package pulls in some Samba and WINS-related monitoring features that will ask you to configure a domain. If you have no WINS domain, just accept the defaults:
sudo aptitude install nagios3
Start Nagios:
sudo /etc/init.d/nginx start
And set Nagios to start on boot:
sudo update-rc.d nagios3 defaults
Uninstall apache2 if the Nagios install includes apache2 as a dependency:
sudo aptitude remove apache2
Configure Nagios access permissions. Not having Apache installed, we use Perl to generate htpasswd credentials. To generate passwords, run:
perl -le 'print crypt("<password>", "salt")'
and copy the encrypted password it generates. Using your favorite text editor, write the ID and password in the file:
/etc/nagios3/htpasswd.users
in this colon-separated format:
nagiosadmin:<encrypted password string>:'My comment here'
Configure nginx:
First, optimise nginx for performance and security:
sudo vim /etc/nginx/nginx.conf
user www-data; worker_processes 4; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; sendfile on; tcp_nopush on; keepalive_timeout 3; gzip on; gzip_comp_level 2; gzip_proxied any; gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
Second, let's assume this nginx installation will only serve Nagios so we need add no new vhosts. Instead, we replace the default server installation with a new server that is configured to point to Nagios's various static and dynamic components.
sudo mv /etc/nginx/sites-enabled/default /etc/nginx/sites-enabled/orig.default sudo vim /etc/nginx/sites-enabled/default
The Nagios install left its static pages at:
and its cgi files at:
So we use the location directive to point nginx's root to the static pages, and include two sets of rewrite commands to correctly point URIs requests to the stylesheets and Nagios' cgi files.
server { server_name nagios.demo.com listen 80; add_header Cache-Control public; access_log /var/log/nginx/nagios.demo.com_access.log; error_log /var/log/nginx/nagios.demo.com_error.log info; expires 31d; location / { root /usr/share/nagios3/htdocs; index index.html; # A rewrite serves URI requests to the stylesheets rewrite ^/nagios3/stylesheets/(.*)$ /../stylesheets/$1 break; rewrite ^/nagios3/(.*)$ /$1 break; } location ~ \.cgi$ { root /usr/lib/cgi-bin/nagios3; include /etc/nginx/fastcgi_params; # Another rewrite serves URI requests to the cgi files rewrite ^/cgi-bin/nagios3/(.*)$ /$1; auth_basic "Restricted"; auth_basic_user_file /etc/nagios3/htpasswd.users; fastcgi_pass 127.0.0.1:8998; fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin/nagios3$fastcgi_script_name; fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; } } # end server
We can test that this nginx configuration is able to serve Nagios' static pages by browsing to the root URL of our nginx server. We should find that Nagios' static pages display correctly to present us with Nagios' lefthand menu bar. However, attempts to click on the links in the menu produce a “502 Bad Gateway” error. That's because nginx is not yet able to find a working cgi-handler to handle Nagios' dynamically-generated pages. We'll fix that in a moment.
If nginx is not able to serve Nagios' static pages at this point, check that the correct static page locations were provided correctly in the /etc/nginx/sites-enabled/default configuration.
Also, check the server-specific logs at:
and nginx's default logs at:
They should provide clues to what nginx is doing when errors occur. You can 'tail -f' each log while browsing the site to see in real-time what is logged as you test-click different links.
If Nagios' CGI processes are to work, we need to link nginx up to a cgi handler,which we did in the line in the above file:
fastcgi_pass 127.0.0.1:8998;
So we need to install a FastCGI handler that will listen on port 8998. We'll take the fcgi handler that is bundled with Lighttpd, wrap it with a script and start it on boot.
Step 1: Install spawn-fcgi:
sudo aptitude install lighttpd cp /usr/bin/spawn-fcgi* /tmp/ sudo aptitude remove lighttpd sudo mv /tmp/spawn-fcgi.lighttpd /usr/bin/spawn-fcgi
Now install fcgiwrap to run fcgi the way we configured nginx to use it.
Install the fcgiwrap tarball directly from its author's page at: http://nginx.localdomain.pl/wiki/FcgiWrap
Or follow the instructions at: http://wiki.nginx.org/Fcgiwrap
sudo aptitude install git-core build-essential libfcgi-dev autoconf libtool automake cd /usr/local/src/ sudo git clone git://github.com/gnosek/fcgiwrap.git cd /usr/local/src/fcgiwrap sudo autoreconf -i sudo ./configure sudo make sudo mv fcgiwrap /usr/local/bin/
Now we need a script that starts fcgi with the the parameters we configured nginx to expect. So, in /usr/bin/, create a script called fcgi.sh:
sudo vim /usr/bin/fcgi.sh sudo chmod 755 /usr/bin/fcgi.sh
The /usr/bin/fcgi.sh script should contain:
#!/bin/sh # /usr/bin/fcgi.sh /usr/bin/spawn-fcgi -f /usr/local/bin/fcgiwrap -a 127.0.0.1 -p 8998 -P /var/run/fastcgi-c.pid \ -u www-data -g www-data
We can start fcgi with this fcgi.sh script to test it and we can set it to start or stop using a System V-style /etc/init.d/ start-up script at boot:
sudo vim /etc/init.d/fcgi
That start-up script should contain:
#!/bin/bash FCGI_SCRIPT=/usr/bin/fcgi.sh RETVAL=0 case "$1" in start) echo "Starting fastcgi" $FCGI_SCRIPT RETVAL=$? ;; stop) echo "Stopping fastcgi" killall -9 fcgiwrap RETVAL=$? ;; restart) echo "Restarting fastcgi" killall -9 fcgiwrap $FCGI_SCRIPT RETVAL=$? ;; *) echo "Usage: /etc/init.d/fcgi {start|stop|restart}" exit 1 ;; esac exit $RETVAL
And set the permissions on our start-up script:
sudo chmod 755 /etc/init.d/fcgi
Now, attempting to start the fcgi wrapper with:
sudo /etc/init.d/fcgi start
should produce:
Starting fastcgi spawn-fcgi.c.197: child spawned successfully: PID: 16510
Set the spawner to start on boot:
sudo update-rc.d fcgi defaults
Nginx should now find a listening daemon on port localhost's port 8998 so browsing to the root URL of your nginx server should now produce a fully-working Nagios website.
If not, check the nginx configuration again, check that fcgi is listening and consult the logs as described above.
If it is, we can clean up the remaining debris from our fcgi installation:
sudo aptitude remove git-core build-essential libfcgi-dev autoconf libtool automake
You should now have a clean Nagios installation ready for you to configure which hosts and services you want to monitor.
If you want to go on to add Python support to nginx, you can do that too.
Discussion