<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Kevin Deldycke &#187; Server</title> <atom:link href="http://kevin.deldycke.com/tag/server/feed/" rel="self" type="application/rss+xml" /><link>http://kevin.deldycke.com</link> <description>Free software engineer &#38; wannabe videomaker</description> <lastBuildDate>Fri, 03 Feb 2012 19:08:27 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Installation Guide for a full-featured Debian server</title><link>http://kevin.deldycke.com/2011/10/installation-guide-full-featured-debian-server/</link> <comments>http://kevin.deldycke.com/2011/10/installation-guide-full-featured-debian-server/#comments</comments> <pubDate>Tue, 18 Oct 2011 10:32:20 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[apt]]></category> <category><![CDATA[cron]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[Exim]]></category> <category><![CDATA[fail2ban]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[maintenance]]></category> <category><![CDATA[munin]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[nut]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[SMART]]></category> <category><![CDATA[squeeze]]></category> <category><![CDATA[system]]></category> <category><![CDATA[Web]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3165</guid> <description><![CDATA[Here is a collection of articles I wrote during the past year. Together they form a guide that will let you setup a full-featured Debian server. All of these tutorials are based on the recent work I did to setup &#8230; <a href="http://kevin.deldycke.com/2011/10/installation-guide-full-featured-debian-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Here is a collection of articles I wrote during the past year. Together they form a guide that will let you setup a full-featured Debian server. All of these tutorials are based on the recent work I did to setup my personal server on Debian Squeeze.</p><p>These articles are independent with each other, meaning you can pick the one your interested in to customize your server and ignore the others.</p><ol><li>Setup <a href="http://kevin.deldycke.com/2011/05/setting-hdds-smart-monitoring-debian-squeeze/">SMART</a> monitoring tool for HDDs.</li><li>Setup <a href="http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/">Nut</a> to manage the UPS.</li><li>Setup <a href="http://kevin.deldycke.com/2011/09/cloud-based-server-backups-duplicity-amazon-s3/">Duplicity and Amazon S3</a> for cloud-based backups.</li><li>Setup <a href="http://kevin.deldycke.com/2011/05/how-to-gmail-send-mails-debian-squeeze/">Exim</a> to relay mails via Gmail.</li><li>Setup <a href="http://kevin.deldycke.com/2011/05/fresh-debian-thanks-to-cron-apt/">cron-apt</a> to keep our distribution up to date.</li><li>Add a <a href="http://kevin.deldycke.com/2011/06/configuring-fail2ban-debian-squeeze/">fail2ban</a> deamon.</li><li>Setup <a href="http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/">Munin</a> to monitor our machine.</li><li><a href="http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/">Basic setup of Nginx + PHP-FPM + MySQL</a> web stack.</li><li><a href="http://kevin.deldycke.com/2011/09/nginx-php-fpm-mysql-configuration/">Optimizing Nginx + PHP-FPM + MySQL</a> for performances.</li><li>Setup <a href="http://kevin.deldycke.com/2011/07/php-apc-debian-squeeze-munin-monitoring/">PHP APC</a> op-code cache.</li><li>Install <a href="http://kevin.deldycke.com/2011/08/entropy-debian-squeeze-server/">haveged</a> to get lots of entropy.</li><li>Setup a <a href="http://kevin.deldycke.com/2011/07/lighttpd-powered-webdavs-server-debian-squeeze/">WebDAVs</a> server with Lighttpd.</li><li>Setup <a href="http://kevin.deldycke.com/2011/09/setup-mailman-nginx-exim-debian-squeeze/">Mailman + Nginx + Exim</a> for mailing-lists.</li><li>Mailman <a href="http://kevin.deldycke.com/2011/10/mailman-migration/">mailing-list migration</a> and <a href="http://kevin.deldycke.com/2011/10/how-to-merge-mailman-mailing-lists/">merging</a>.</li></ol> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/10/installation-guide-full-featured-debian-server/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>My Nginx + PHP-FPM + MySQL configuration</title><link>http://kevin.deldycke.com/2011/09/nginx-php-fpm-mysql-configuration/</link> <comments>http://kevin.deldycke.com/2011/09/nginx-php-fpm-mysql-configuration/#comments</comments> <pubDate>Tue, 20 Sep 2011 10:22:13 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[debian squeeze]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[ovh]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[php-fpm]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[virtual server]]></category> <category><![CDATA[virtualization]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[WordPress]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3594</guid> <description><![CDATA[This article is a follow-up to the one I wrote 3 months ago, in which I explained how to install a web stack based on Nginx, PHP-FPM and MySQL on a Debian Squeeze server. Now it&#8217;s time to tune this &#8230; <a href="http://kevin.deldycke.com/2011/09/nginx-php-fpm-mysql-configuration/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>This article is a follow-up to the one I wrote 3 months ago, in which I explained how to <a href="http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/">install a web stack based on Nginx, PHP-FPM and MySQL</a> on a Debian Squeeze server. Now it&#8217;s time to tune this basic install to get some performance out of it.</p><p><a href="http://kevin.deldycke.com/wp-content/uploads/2011/08/ovh-vps-3-virtual-server.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/08/ovh-vps-3-virtual-server-150x150.png" alt="" title="ovh-vps-3-virtual-server" width="150" height="150" class="alignleft size-thumbnail wp-image-3801" /></a> The setup I&#8217;ll detail below runs on an <a href="http://www.ovh.co.uk/vps/">OVH VPS</a> instance. This virtual server has 4 CPU cores at 1.5GHz, 1 Go RAM and 50 Gb HDD.</p><p>I&#8217;m mostly running WordPress instances on that server, so you&#8217;ll see some reference of it in this post.</p><h2>MySQL</h2><p>First, let&#8217;s tune MySQL. That&#8217;s the easiest part of that article, as you only need to create a <code>.cnf</code> file in <code>/etc/mysql/conf.d/</code> and place there all your custom parameters. Here is the content of my <code>/etc/mysql/conf.d/kev.cnf</code>:</p><pre class="brush: plain; title: ; notranslate">
[mysqld]
interactive_timeout = 50
join_buffer = 1M
key_buffer = 250M
max_connections = 100
max_heap_table_size = 32M
myisam_sort_buffer_size = 96M
query_cache_limit = 4M
query_cache_size = 250M
query_prealloc_size = 65K
query_alloc_block_size = 128K
read_buffer_size = 1M
read_rnd_buffer_size = 768K
sort_buffer_size = 1M
table_cache = 4096
thread_cache_size = 1024
tmp_table_size = 32M
wait_timeout = 500
# Debug
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
# InnoDBinnodb_buffer_pool_size = 256Minnodb_additional_mem_pool_size = 10Minnodb_log_file_size = 32Minnodb_flush_method = O_DIRECTinnodb_file_per_table = 1innodb_flush_log_at_trx_commit = 0
[mysqld_safe]
nice = -5
open_files_limit = 8192

[isamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M
</pre><p>Most of these parameters were set for my particular usage and with insights from the <a href="http://launchpad.net/mysql-tuning-primer">MySQL Tuning Primer Script</a>.</p><h2>PHP-FPM</h2><p>Unlike MySQL, the structure of PHP configuration files on Debian Squeeze doesn&#8217;t let us easily add our customizations. We have to modify the default files provided at the package installation.</p><p>Here is my setup of the PHP processes pool:</p><pre class="brush: diff; title: ; notranslate">
--- /etc/php5/fpm/pool.d/www.conf.orig     2011-06-07 08:14:30.000000000 +0200
+++ /etc/php5/fpm/pool.d/www.conf  2011-08-15 17:34:09.000000000 +0200
@@ -237,3 +237,10 @@
 ;php_admin_value[error_log] = /var/log/fpm-php.www.log
 ;php_admin_flag[log_errors] = on
 ;php_admin_value[memory_limit] = 32M
+
+pm.max_children = 25
+pm.start_servers = 4
+pm.min_spare_servers = 2
+pm.max_spare_servers = 10
+pm.max_requests = 500
+request_terminate_timeout = 30
</pre><p>The second customization I made is not about performances but convenience. It just allow my WordPress&#8217; users to upload larger files:</p><pre class="brush: diff; title: ; notranslate">
--- /etc/php5/fpm/php.ini.orig      2011-06-18 13:32:37.000000000 +0200
+++ /etc/php5/fpm/php.ini   2011-06-22 22:50:49.000000000 +0200
@@ -725,7 +725,7 @@

 ; Maximum size of POST data that PHP will accept.
 ; http://php.net/post-max-size
-post_max_size = 8M
+post_max_size = 15M

 ; Magic quotes are a preprocessing feature of PHP where PHP will attempt to
 ; escape any character sequences in GET, POST, COOKIE and ENV data which might
@@ -876,7 +876,7 @@

 ; Maximum allowed size for uploaded files.
 ; http://php.net/upload-max-filesize
-upload_max_filesize = 2M
+upload_max_filesize = 15M

 ; Maximum number of files that can be uploaded via a single request
 max_file_uploads = 20
</pre><h2>Nginx</h2><p>Let&#8217;s say my WordPress blog is installed in <code>/var/www/my_wordpress</code>. To let it be served by Nginx, we add a configuration file for this site in <code>/etc/nginx/sites-available/my_wordpress</code>:</p><pre class="brush: plain; title: ; notranslate">
server {
  server_name blog.example.com;
  root /var/www/my_wordpress/;
  include /etc/nginx/wordpress.conf;
  location /static {
    autoindex on;
  }
}

server {
  listen 80 default_server;
  server_name .example.com .example.org .example.net;
  rewrite ^ http://blog.example.com$request_uri? permanent;
}
</pre><p>In the configuration above, you can see that I want my blog to be served at <code>http://blog.example.com</code>. I also added some domain redirections in the form of a second <code>server</code> section, and a way to better display my static file repository by letting Nginx generate index pages.</p><p>Then don&#8217;t forget to activate this site:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /etc/nginx/sites-available/my_wordpress /etc/nginx/sites-enabled/
</pre><p>The file above refer to <code>/etc/nginx/wordpress.conf</code> which is where I place all the configuration directives common to all the WordPress blogs on my server. Here is the content of that file:</p><pre class="brush: plain; title: ; notranslate">
# This order might seem weird - this is attempted to match last if rules below fail.
# See: http://wiki.nginx.org/HttpCoreModule
location / {
  try_files $uri $uri/ /index.php?q=$uri&amp;$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

include global.conf;

include php.conf;
</pre><p>Again, this file make a reference to <code>php.conf</code>, which is the same as <a href="http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/">the one featured in my previous article</a>. I only removed the <code>index</code> directive to place it elsewhere, and added a limit on the number of PHP requests a client can make:</p><pre class="brush: plain; title: ; notranslate">
location ~ \.php$ {
  # Throttle requests to prevent abuse
  limit_req zone=antidos burst=5;

  # Zero-day exploit defense.
  # http://forum.nginx.org/read.php?2,88845,page=3
  # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
  # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
  try_files $uri =404;

  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  include /etc/nginx/fastcgi_params;

  # As explained in http://kbeezie.com/view/php-self-path-nginx/ some fastcgi_param are missing from fastcgi_params.
  # Keep these parameters for compatibility with old PHP scripts using them.
  fastcgi_param PATH_INFO       $fastcgi_path_info;
  fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

  # Some default config
  fastcgi_connect_timeout        60;
  fastcgi_send_timeout          180;
  fastcgi_read_timeout          180;
  fastcgi_buffer_size          128k;
  fastcgi_buffers            4 256k;
  fastcgi_busy_buffers_size    256k;
  fastcgi_temp_file_write_size 256k;

  fastcgi_intercept_errors    on;
  fastcgi_ignore_client_abort off;

  fastcgi_pass 127.0.0.1:9000;
}
</pre><p>Here is where the <code>index</code> directive moved: <code>/etc/nginx/conf.d/kev.conf</code>. I also added there some tweaks and the global request throttling configuration:</p><pre class="brush: plain; title: ; notranslate">
# Hide Nginx version
server_tokens off;

# Set default index file names
index index.php index.html index.htm;

# Allow uploads up to 15 Mo
client_max_body_size 15m;

# Create a global request accounting pool to prevent DOS
limit_req_zone $binary_remote_addr zone=antidos:10m rate=3r/s;
</pre><p>The <code>global.conf</code> file we saw in <code>/etc/nginx/wordpress.conf</code> refer to <code>/etc/nginx/global.conf</code>, which contain additional measures to remove cruft from log files and enhance security:</p><pre class="brush: plain; title: ; notranslate">
# Do not log excessive request on common web content like favicon and robots.txt
location = /favicon.ico {
  log_not_found off;
  access_log off;
}
location = /robots.txt {
  allow all;
  log_not_found off;
  access_log off;
}

# Deny all attempts to access any dotfile (=hidden files) such as .htaccess, .htpasswd, .DS_Store, .directory, .svn, .git, ...
location ~ /\. {
  deny all;
  access_log off;
  log_not_found off;
}
</pre><p>All of default Nginx configuration can&#8217;t be overridden by additional files. We have to change <code>/etc/nginx/nginx.conf</code> itself:</p><pre class="brush: diff; title: ; notranslate">
--- /etc/nginx/nginx.conf.orig   2011-06-06 00:46:56.000000000 +0200
+++ /etc/nginx/nginx.conf        2011-08-15 17:44:58.000000000 +0200
@@ -3,8 +3,9 @@
 pid /var/run/nginx.pid;

 events {
-       worker_connections 768;
-       # multi_accept on;
+       use epoll;
+       worker_connections 1024;
+       multi_accept on;
 }

 http {
@@ -16,7 +17,7 @@
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
-       keepalive_timeout 65;
+       keepalive_timeout 3;
        types_hash_max_size 2048;
        # server_tokens off;
</pre><p>That&#8217;s all for our customizations. We can now restart all our servers:</p><pre class="brush: bash; title: ; notranslate">
$ /etc/init.d/mysql restart
$ /etc/init.d/php5-fpm restart
$ /etc/init.d/nginx restart
</pre><h2>Conclusion</h2><p>I&#8217;m running my websties under this configuration for about 3 months and I&#8217;m really happy with the results. I&#8217;m sure I can push optimizations further, but it may require lots of time and effort compared to the marginal gain I&#8217;ll get. My websites are responsive enough to me. And if they collapse in the future under the load of the Reddit crowd, I&#8217;ll still have the option to move to a bigger virtual server (vertical scaling FTW!).</p> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/09/nginx-php-fpm-mysql-configuration/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>WebPing Open-sourced !</title><link>http://kevin.deldycke.com/2011/08/webping-open-sourced/</link> <comments>http://kevin.deldycke.com/2011/08/webping-open-sourced/#comments</comments> <pubDate>Tue, 16 Aug 2011 10:10:06 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Apache]]></category> <category><![CDATA[email]]></category> <category><![CDATA[flot]]></category> <category><![CDATA[GitHub]]></category> <category><![CDATA[HTML]]></category> <category><![CDATA[HTTP]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[jquery]]></category> <category><![CDATA[munin]]></category> <category><![CDATA[nagios]]></category> <category><![CDATA[plone]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[sqlite]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[webping]]></category> <category><![CDATA[yaml]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3715</guid> <description><![CDATA[I&#8217;ve just released WebPing under a GPL license. It&#8217;s available right now on a GitHub repository. WebPing is a script I started to work on in 2009 while working at EDF. Back then, I needed a monitoring tool to keep &#8230; <a href="http://kevin.deldycke.com/2011/08/webping-open-sourced/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>I&#8217;ve just released WebPing under a GPL license. It&#8217;s available right now on a <a href="http://github.com/kdeldycke/webping">GitHub repository</a>.</p><p>WebPing is a script I started to work on in 2009 while working at <a href="http://www.edf.com/">EDF</a>. Back then, I needed a monitoring tool to keep an eye on the 80+ <a href="http://plone.org/">Plone</a> instances that my team managed. For several corporate reasons, I wasn&#8217;t allowed to use a proper monitoring tool like <a href="http://munin-monitoring.org/">Munin</a> or <a href="http://www.nagios.org/">Nagios</a>. So I created a small script to fill this need. That&#8217;s how WebPing came to be.</p><p>WebPing is just a stupid Python script that is designed to be ticked regularly by a cron job. It try to fetch a list of URLs and store response times in an SQLite database. Then it create a static HTML report you&#8217;re free to serve with any HTTP server (an <a href="http://github.com/kdeldycke/webping/blob/master/apache.conf">example Apache configuration</a> is provided). The configuration of WebPing and the list of URLs it monitor is stored in a YAML file.</p><p>The produced HTML report use the <a href="http://code.google.com/p/flot">Flot jQuery plugin</a> to render graphs. Here is how the dashboard looks like:<br /> <a href="http://kevin.deldycke.com/wp-content/uploads/2011/08/webping-dashboard.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/08/webping-dashboard-271x300.png" alt="" title="webping-dashboard" width="271" height="300" class="aligncenter size-medium wp-image-3777" /></a></p><p>Finally, WebPing is able to send reports and alerts by emails. Here is how a mail alert looks like:<br /> <a href="http://kevin.deldycke.com/wp-content/uploads/2011/08/webping-email-alert.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/08/webping-email-alert-300x293.png" alt="" title="webping-email-alert" width="300" height="293" class="aligncenter size-medium wp-image-3743" /></a></p><p>Since I created WebPing, I found several other projects more or less developed around the same idea. See <a href="http://github.com/ericholscher/django-kong">Kong</a>, which is based on Django and <a href="http://twill.idyll.org/">Twill</a>, a web-oriented <a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSL</a>. Another project I spotted after the facts was <a href="http://code.google.com/p/multi-mechanize">multi-mechanize</a>. Like Kong, it&#8217;s written in Python. But I never played with one or the other.</p> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/08/webping-open-sourced/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Lighttpd-powered WebDAVs server on Debian Squeeze</title><link>http://kevin.deldycke.com/2011/07/lighttpd-powered-webdavs-server-debian-squeeze/</link> <comments>http://kevin.deldycke.com/2011/07/lighttpd-powered-webdavs-server-debian-squeeze/#comments</comments> <pubDate>Tue, 26 Jul 2011 10:51:45 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[etch]]></category> <category><![CDATA[lighttpd]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[openssl]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[ssl]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[webdav]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=357</guid> <description><![CDATA[Here is a tiny article about how I used Lighttpd to serve content over WebDAV. First, install the required packages: As we want to provide a secure WebDAV access, we need to install OpenSSL: Then we create the file /etc/lighttpd/clear-creds.lst, &#8230; <a href="http://kevin.deldycke.com/2011/07/lighttpd-powered-webdavs-server-debian-squeeze/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Here is a tiny article about how I used <a href="http://www.lighttpd.net">Lighttpd</a> to serve content over <a href="http://wikipedia.org/wiki/WebDAV">WebDAV</a>.</p><p>First, install the required packages:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install lighttpd-mod-webdav
</pre><p>As we want to provide a secure WebDAV access, we need to install <a href="http://www.openssl.org">OpenSSL</a>:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install openssl
</pre><p>Then we create the file <code>/etc/lighttpd/clear-creds.lst</code>, that will contain credentials required for authentication, under the following form:</p><pre class="brush: plain; title: ; notranslate">
user1:password1
user2:password2
user3:password3
</pre><p>Logins and passwords are stored here in clear. This is stupid, but for this project I was looking to setup a quick and dirty server. For temporary tests this setup is OK, but I encourage you to switch to a better credential storage system.</p><p>Now I want to serve WebDAV content within a secure channel. A self-signed SSL certificate will be enough. Let&#8217;s generate one:</p><pre class="brush: bash; title: ; notranslate">
$ cd /etc/lighttpd/
$ openssl req -x509 -nodes -subj '/' -days 3650 -newkey rsa:2048 -keyout server.pem -out server.pem
</pre><p>We&#8217;ll configure Lighttpd by loading the default parameters of modules we use:</p><pre class="brush: bash; title: ; notranslate">
$ cd /etc/lighttpd/conf-enabled/
$ ln -s ../conf-available/05-auth.log
$ ln -s ../conf-available/10-ssl.conf
$ ln -s ../conf-available/10-webdav.conf
</pre><p>Now I create a custom configuration file:</p><pre class="brush: bash; title: ; notranslate">
$ touch /etc/lighttpd/conf-available/99-custom.conf
$ cd /etc/lighttpd/conf-enabled/
$ ln -s ../conf-available/99-custom.conf
</pre><p>Here is the content of that <code>99-custom.conf</code> configuration file:</p><pre class="brush: plain; title: ; notranslate">
# Hide server version
server.tag = &quot;lighttpd&quot;

# Force all request to be in HTTPs
# This also redirects all WebDAV requests to WebDAVs
$HTTP[&quot;scheme&quot;] == &quot;http&quot; {
  $HTTP[&quot;host&quot;] =~ &quot;(.*)&quot; {
    url.redirect = ( &quot;^/(.*)&quot; =&gt; &quot;https://%1/$1&quot; )
  }
}

# Valid credentials are required for any request
auth.backend = &quot;plain&quot;
auth.backend.plain.userfile = &quot;/etc/lighttpd/clear-creds.lst&quot;
auth.require = (
  &quot;/&quot; =&gt; (
    &quot;method&quot; =&gt; &quot;digest&quot;,
    &quot;realm&quot; =&gt; &quot;My WebDAV server&quot;,
    &quot;require&quot; =&gt; &quot;valid-user&quot;
  )
)

# Enable WebDAV in read and write mode
webdav.activate = &quot;enable&quot;
webdav.is-readonly = &quot;disable&quot;

# Customize directory listings a bit
dir-listing.set-footer = &quot;&lt;a href='http://example.com'&gt;Company&lt;/a&gt;'s document repository.&quot;
</pre><p>And do not forget to restart the server:</p><pre class="brush: bash; title: ; notranslate">
$ /etc/init.d/lighttpd restart
</pre><p><a href="http://kevin.deldycke.com/wp-content/uploads/2011/07/lighttpd-webdav-server.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/07/lighttpd-webdav-server-300x232.png" alt="" title="lighttpd-webdav-server" width="300" height="232" class="aligncenter size-medium wp-image-3441" /></a></p><p>As you can see in the screenshot above, you can now:</p><ul><li>Browse the file system in read/write mode with a WebDAV client via a <code>webdavs://12.34.56.78/</code> URL;</li><li>Access content in read-only mode with a browser by a classic <code>https://12.34.56.78/</code> URL.</li></ul> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/07/lighttpd-powered-webdavs-server-debian-squeeze/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>PHP APC on Debian Squeeze with Munin monitoring</title><link>http://kevin.deldycke.com/2011/07/php-apc-debian-squeeze-munin-monitoring/</link> <comments>http://kevin.deldycke.com/2011/07/php-apc-debian-squeeze-munin-monitoring/#comments</comments> <pubDate>Tue, 19 Jul 2011 10:28:10 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[apx]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[debian squeeze]]></category> <category><![CDATA[munin]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[Web]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3269</guid> <description><![CDATA[Installing APC on Debian Squeeze is as simple as installing the package: In my case this package come from the PHP bundle distributed by the Dotdeb repository. If installing APC is easy, monitoring it with Munin requires some extra manipulations. &#8230; <a href="http://kevin.deldycke.com/2011/07/php-apc-debian-squeeze-munin-monitoring/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Installing <a href="http://php.net/manual/en/book.apc.php">APC</a> on Debian Squeeze is as simple as installing the package:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install php5-apc
</pre><p>In my case this package come from the PHP bundle distributed by the <a href="http://www.dotdeb.org">Dotdeb repository</a>.</p><p>If installing APC is easy, monitoring it with Munin requires some extra manipulations. There is currently no good <a href="http://exchange.munin-monitoring.org/plugins/search?keyword=apc">APC plugin available on Munin Exhange</a>. So we&#8217;ll use the external <a href="http://code.google.com/p/munin-php-apc/">munin-php-apc project</a> instead.</p><p>The latter can&#8217;t get APC statistics by itself: it need an extra PHP file to be served locally. As you can read in my previous article, <a href="http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/">my Munin is powered by Nginx</a>. So now we&#8217;ll setup Nginx to serve this extra PHP file:</p><pre class="brush: bash; title: ; notranslate">
$ mkdir -p /var/www/apc
$ cd /var/www/apc
$ wget http://munin-php-apc.googlecode.com/svn/trunk/php_apc/apc_info.php
$ chown -R www-data:www-data /var/www/apc
</pre><p>Then I need to update my <code>/etc/nginx/sites-available/munin</code> file (see <a href="http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/">details about this file on my previous article</a>) to have the second <code>server</code> section look like this:</p><pre class="brush: plain; title: ; notranslate">
server {
  server_name localhost;
  include /etc/nginx/php.conf;
  root /var/www/apc;
  allow 127.0.0.1;
  deny all;
  location / {
    access_log off;
  }
  location /nginx_status {
    stub_status on;
    access_log off;
  }
}
</pre><p>Here the included <code>/etc/nginx/php.conf</code> file is the one in which I&#8217;ve concentrate all the Nginx directives required to activate PHP file parsing. The content and the mechanism behind this file is describe in my <a href="http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/">article on setting up Nginx with PHP-FPM</a>.</p><p>Let&#8217;s get back to our Munin monitoring setup. I can restart now Nginx and check that I can access locally to my raw statistics:</p><pre class="brush: bash; title: ; notranslate">
$ /etc/init.d/nginx reload
$ wget http://localhost/apc_info.php
$ wget http://localhost/nginx_status
</pre><p>The last step is to install and configure the Munin plugin:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install libwww-perl
$ wget http://munin-php-apc.googlecode.com/svn/trunk/php_apc/php_apc_ --output-document=/usr/share/munin/plugins/php_apc_
$ chmod -R 755 /usr/share/munin/plugins/
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_usage
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_hit_miss
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_purge
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_fragmentation
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_files
$ ln -s /usr/share/munin/plugins/php_apc_ /etc/munin/plugins/php_apc_rates
$ echo &quot;[php_apc_*]
user root
env.url http://localhost/apc_info.php?auto
&quot; &gt; /etc/munin/plugin-conf.d/php_apc
$ /etc/init.d/munin-node restart
</pre><p>And finally, after a while, you&#8217;ll get those beautiful graphs:<br /> <a href="http://kevin.deldycke.com/wp-content/uploads/2011/06/php-apc-munin-graphs.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/06/php-apc-munin-graphs-300x300.png" alt="" title="php-apc-munin-graphs" width="300" height="300" class="aligncenter size-medium wp-image-3347" /></a></p> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/07/php-apc-debian-squeeze-munin-monitoring/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Nginx + PHP-FPM + MySQL on a Debian Squeeze server</title><link>http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/</link> <comments>http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/#comments</comments> <pubDate>Tue, 28 Jun 2011 10:50:59 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[debian squeeze]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[php-fpm]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[Web]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3253</guid> <description><![CDATA[This post is not about optimization: it only describe a sure and fast way to get all those 3 components talk to each other. This article will help you bootstrap a minimal setup, something that I wouldn&#8217;t recommend for a &#8230; <a href="http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>This post is not about optimization: it only describe a sure and fast way to get all those 3 components talk to each other. This article will help you bootstrap a minimal setup, something that I wouldn&#8217;t recommend for a production server without serious tweaking (to get both high performances and security).</p><p>First, we&#8217;ll get all our packages from an up-to-date <a href="http://www.dotdeb.org/">DotDeb repository</a>. If this is not already done, add those repositories to aptitude:</p><pre class="brush: bash; title: ; notranslate">
$ echo &quot;deb http://packages.dotdeb.org squeeze all&quot; &gt; /etc/apt/sources.list.d/squeeze-dotdeb.list
$ gpg --keyserver keys.gnupg.net --recv-key 89DF5277
$ gpg -a --export 89DF5277 | apt-key add -
$ aptitude update
</pre><p>Now we can install the whole stack:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install nginx
$ aptitude install php5-fpm php5-mysql php5-gd php5-curl
$ aptitude install mysql-server
</pre><p>FYI, here is the list of versions I installed:</p><ul><li>Nginx 1.0.2</li><li>PHP 5.3.6</li><li>MySQL 5.1.57</li></ul><p>As a way to test that our setup is working, we&#8217;ll serve a simple PHP file:</p><pre class="brush: bash; title: ; notranslate">
$ mkdir -p /var/www/example.com/
$ cd /var/www/example.com/
$ echo &quot;
&lt;?php phpinfo(); ?&gt;
&quot; &gt; ./index.php
$ chown -R www-data:www-data /var/www
</pre><p>Now let&#8217;s create a minimal Nginx configuration file for this site:</p><pre class="brush: bash; title: ; notranslate">
$ touch /etc/nginx/sites-available/example.com
</pre><p>In this brand new file,  put the following directives:</p><pre class="brush: plain; title: ; notranslate">
server {
  server_name example.com;
  include /etc/nginx/php.conf;
  location / {
    root /var/www/example.com/;
    access_log on;
  }
}
</pre><p>This will only work if you&#8217;ve updated your DNS with an <code>A</code> record having <code>example.com</code> redirecting to the IP address of your Nginx server.</p><p>Now it&#8217;s time to create the <code>/etc/nginx/php.conf</code> file referenced in the Nginx configuration above. This file is where I put the generic setup making the bridge between Nginx and PHP-FPM. Here is what it should contain:</p><pre class="brush: plain; title: ; notranslate">
index index.php index.html index.htm;

location ~ \.php$ {
  # Zero-day exploit defense.
  # http://forum.nginx.org/read.php?2,88845,page=3
  # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
  # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
  try_files $uri =404;

  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  include /etc/nginx/fastcgi_params;

  # As explained in http://kbeezie.com/view/php-self-path-nginx/ some fastcgi_param are missing from fastcgi_params.
  # Keep these parameters for compatibility with old PHP scripts using them.
  fastcgi_param PATH_INFO       $fastcgi_path_info;
  fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

  # Some default config
  fastcgi_connect_timeout        60;
  fastcgi_send_timeout          180;
  fastcgi_read_timeout          180;
  fastcgi_buffer_size          128k;
  fastcgi_buffers            4 256k;
  fastcgi_busy_buffers_size    256k;
  fastcgi_temp_file_write_size 256k;

  fastcgi_intercept_errors    on;
  fastcgi_ignore_client_abort off;

  fastcgi_pass 127.0.0.1:9000;
}
</pre><p>Finally you can activate the site configuration and restart the whole stack:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
$ /etc/init.d/mysql restart
$ /etc/init.d/php5-fpm restart
$ /etc/init.d/nginx restart
</pre><p>If everything&#8217;s OK on your DNS, pointing your browser to <code>http://example.com</code> will show you the famous page produced by <code>phpinfo()</code>:<br /> <a href="http://kevin.deldycke.com/wp-content/uploads/2011/06/phpinfo-536.png"><img src="http://kevin.deldycke.com/wp-content/uploads/2011/06/phpinfo-536-168x300.png" alt="" title="phpinfo-536" width="168" height="300" class="aligncenter size-medium wp-image-3339" /></a></p><p>Note that MySQL doesn&#8217;t need any special attention to make it work out of the box. But again, if you plan to use it in production, its configuration needs special care, as for Nginx and PHP.</p> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/06/nginx-php-fpm-mysql-debian-squeeze-server/feed/</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Configuring Fail2Ban on Debian Squeeze</title><link>http://kevin.deldycke.com/2011/06/configuring-fail2ban-debian-squeeze/</link> <comments>http://kevin.deldycke.com/2011/06/configuring-fail2ban-debian-squeeze/#comments</comments> <pubDate>Tue, 21 Jun 2011 10:25:16 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Apache]]></category> <category><![CDATA[Exim]]></category> <category><![CDATA[fail2ban]]></category> <category><![CDATA[security]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[SSH]]></category> <category><![CDATA[Web]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3236</guid> <description><![CDATA[This always start with a package installation: Then I simply create a local configuration file where I&#8217;ll put all my custom config: Here is the content of that file: While adjusting Fail2Ban, I was surprised by how sensitive this software &#8230; <a href="http://kevin.deldycke.com/2011/06/configuring-fail2ban-debian-squeeze/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>This always start with a package installation:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install fail2ban
</pre><p>Then I simply create a local configuration file where I&#8217;ll put all my custom config:</p><pre class="brush: bash; title: ; notranslate">
$ touch /etc/fail2ban/jail.local
</pre><p>Here is the content of that file:</p><pre class="brush: plain; title: ; notranslate">
[DEFAULT]
# Do not filter connexion from my apartment and from the server itself
ignoreip  = 127.0.0.1 88.123.123.123 91.123.123.123
# Ban for a week
bantime   = 604800
maxretry  = 3
destemail = kevin@deldycke.com
banaction = iptables-allports
action    = %(action_mwl)s

[ssh]
enabled  = true
port     = 22
maxretry = 2

[ssh-ddos]
enabled = true
port     = 22

[apache]
# Apache basic auth
enabled   = true
maxretry  = 3
# Ban for 1 hour
bantime   = 3600

[apache-noscript]
enabled = true

[apache-overflows]
enabled = true

[apache-badbots]
enabled  = true
filter   = apache-badbots
port     = http,https
action   = iptables-allports
logpath  = /var/log/apache*/*access.log
maxretry = 1

[apache-nohome]
enabled  = true
filter   = apache-nohome
port     = http,https
action   = iptables-allports
logpath  = /var/log/apache*/*access.log
maxretry = 1

[exim]
enabled  = true
filter   = exim
port     = smtp,ssmtp
action   = iptables-allports
logpath  = /var/log/exim*/rejectlog
maxretry = 1

[exim-relay]
enabled  = true
filter   = exim-relay
port     = smtp,ssmtp
action   = iptables-allports
logpath  = /var/log/exim*/rejectlog
maxretry = 1
</pre><p>While adjusting Fail2Ban, I was surprised by how sensitive this software is. It can just refuse to start without any notice in the log or on the command line. Even if its <code>log_level</code> variable is set to <code>4</code> (= <code>DEBUG</code>) in <code>/etc/fail2ban/fail2ban.conf</code>.</p><p>In such a case, a sure way to find the culprit is to use a brute force debugging method: first set all the <code>enabled</code> variable of your <code>jail.local</code>&#8216;s sections to <code>false</code>. Then activate one section after another until Fail2Ban refuse to restart.</p><p>For me, the problem was that I forgot to add my custom <code>exim-relay</code> filter to Fail2Ban. So I fixed my issue by creating an empty file at <code>/etc/fail2ban/filter.d/exim-relay.conf</code> in which I pasted the following content:</p><pre class="brush: plain; title: ; notranslate">
# Based on default exim.conf filter by Cyril Jaquier
# Real life exemaple:
# 2009-07-02 08:16:42 H=118-167-129-21.dynamic.hinet.net (91.121.198.84) [118.167.129.21] F=&lt;titieueue@hotmail.com&gt; rejected RCPT &lt;s2288@mail2000.com.tw&gt;: relay not permitted

[Definition]

# Option:  failregex
# Notes.:  regex to match use of my exim mail server as a relay it does not
#          allow.
# Values:  TEXT
#
failregex = \[&lt;HOST&gt;\] .*(?:relay not permitted)

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
</pre><p>Speaking of custom filters, here is one to filter DFind scans (file located at <code>/etc/fail2ban/filter.d/apache-w00tw00t.conf</code>):</p><pre class="brush: plain; title: ; notranslate">
# Based on http://howflow.com/tricks/block_w00tw00t_scan_hosts_with_fail2ban
# Real life exemaple:
# [Sat Jun 27 16:43:08 2009] [error] [client 94.23.57.77] client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Definition]

# Option:  failregex
# Notes.:  regex to match the w00tw00t scan messages in the logfile.
# Values:  TEXT
failregex = ^.*\[client &lt;HOST&gt;\].*w00tw00t\.at\.ISC\.SANS\.DFind.*

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
ignoreregex =
</pre><p>And here is the corresponding section from my <code>jail.local</code> file:</p><pre class="brush: plain; title: ; notranslate">
[apache-w00tw00t]
enabled  = true
filter   = apache-w00tw00t
action   = iptables-allports
logpath  = /var/log/apache*/*error.log
maxretry = 1
</pre>]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/06/configuring-fail2ban-debian-squeeze/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Using Munin to monitor a Debian Squeeze server</title><link>http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/</link> <comments>http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/#comments</comments> <pubDate>Mon, 06 Jun 2011 10:25:41 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[acpi]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[fail2ban]]></category> <category><![CDATA[Hardware]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[lm-sensors]]></category> <category><![CDATA[munin]]></category> <category><![CDATA[nginx]]></category> <category><![CDATA[nut]]></category> <category><![CDATA[RAID]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[squeeze]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3192</guid> <description><![CDATA[Again, here is a tutorial article exposing the recipe I use to cook a Munin on a Debian Squeeze. As usual, let&#8217;s start by installing the main Munin package: FYI, the version that aptitude choose to install was Munin 1.4.5. &#8230; <a href="http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Again, here is a tutorial article exposing the recipe I use to cook a <a href="http://en.wikipedia.org/wiki/Munin_(network_monitoring_application)">Munin</a> on a Debian Squeeze.</p><p>As usual, let&#8217;s start by installing the main Munin package:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install munin
</pre><p>FYI, the version that aptitude choose to install was Munin 1.4.5. The default configuration coming along will make it produce graphs and HTML content to <code>/var/cache/munin/www</code>. Now we need to serve these pages via a web server.</p><p>As I wanted to play with <a href="http://en.wikipedia.org/wiki/Nginx">nginx</a> for a long time, I will use this opportunity to serve Munin&#8217;s content. The default version coming with Squeeze is quite old, so we&#8217;ll get the latest version from the <a href="http://www.dotdeb.org/">Dotdeb</a> repository:</p><pre class="brush: bash; title: ; notranslate">
$ echo &quot;deb http://packages.dotdeb.org squeeze all&quot; &gt; /etc/apt/sources.list.d/squeeze-dotdeb.list
$ aptitude update
$ aptitude install nginx
</pre><p>And if you don&#8217;t want to get those error messages about untrusted packages, don&#8217;t forget to <a href="http://www.dotdeb.org/2010/07/11/dotdeb-packages-are-now-signed/">add Dotdeb&#8217;s keys to your keyring</a>.</p><p>We can now test that nginx is working by starting it up then fetch the default served page:</p><pre class="brush: bash; title: ; notranslate">
$ /etc/init.d/nginx start
$ wget --output-document=- http://localhost | grep &quot;Welcome to nginx&quot;
</pre><p>Then we&#8217;ll disable the default nginx config and create a new one for Munin:</p><pre class="brush: bash; title: ; notranslate">
$ rm /etc/nginx/sites-enabled/default
$ touch /etc/nginx/sites-available/munin
</pre><p>In the latter, we put this minimal configuration:</p><pre class="brush: plain; title: ; notranslate">
server {
  server_name munin.example.com;
  root /var/cache/munin/www/;
  location / {
    index index.html;
    access_log off;
  }
}
</pre><p>Now we have to activate it before restarting nginx:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s  /etc/nginx/sites-available/munin /etc/nginx/sites-enabled/munin
$ /etc/init.d/nginx restart
</pre><p>Now we are free to point our browser to the <code>http://munin.example.com</code> URL to get our graphs.</p><p>You&#8217;ll see that by default, Munin refer to your machine as <code>localhost.localdomain</code>. It&#8217;s time to tweak Munin a little to get nice reports:</p><pre class="brush: bash; title: ; notranslate">
$ sed -i 's/\[localhost\.localdomain\]/\[munin\.example\.com\]/g' /etc/munin/munin.conf
</pre><p>By default Munin activate a lot of great graphs. But I always find that some crucial monitoring are missing. Let&#8217;s add some more monitoring scripts:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install munin-plugins-extra
</pre><p>Here is a collection of general purpose graphs I automatically add to Munin:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/df_abs  /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/netstat /etc/munin/plugins/
$ echo &quot;[netstat]
user root
&quot; &gt; /etc/munin/plugin-conf.d/netstat
</pre><p>It&#8217;s also good to have a clue about your connectivity to the rest of the world:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/ping_  /etc/munin/plugins/ping_google.com
$ ln -s /usr/share/munin/plugins/ping_  /etc/munin/plugins/ping_ovh.fr
$ ln -s /usr/share/munin/plugins/ping_  /etc/munin/plugins/ping_example.com
</pre><p>I also like to have insight about my <a href="http://kevin.deldycke.com/2011/09/cloud-based-server-backups-duplicity-amazon-s3/">automated backups</a>:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/ps_ /etc/munin/plugins/ps_duplicity
$ ln -s /usr/share/munin/plugins/ps_ /etc/munin/plugins/ps_sshd
</pre><p>Monitoring temperatures, voltages and other hardware metrics is a must, unless your machine is a virtual server <img src='http://kevin.deldycke.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> :</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/cpuspeed         /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/acpi             /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/hddtemp_smartctl /etc/munin/plugins/
$ aptitude install i2c-tools lm-sensors
$ sensors-detect
$ ln -s /usr/share/munin/plugins/sensors_ /etc/munin/plugins/sensors_temp
$ ln -s /usr/share/munin/plugins/sensors_ /etc/munin/plugins/sensors_volt
</pre><p>I sometimes have a Fail2Ban deamon running on a server, so that&#8217;s a good thing to monitor it:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/fail2ban /etc/munin/plugins/
$ echo &quot;[fail2ban*]
user root
&quot; &gt; /etc/munin/plugin-conf.d/fail2ban
</pre><p><a href="http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/">Having an UPS</a>, it&#8217;s good to monitor it too. Here is for the UPS on the local system having the <code>MGE-Ellipse750</code> ID (as defined in your <code>/etc/nut/ups.conf</code> file):</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/nutups_   /etc/munin/plugins/nutups_MGE-Ellipse750_voltages
$ ln -s /usr/share/munin/plugins/nutups_   /etc/munin/plugins/nutups_MGE-Ellipse750_charge
$ ln -s /usr/share/munin/plugins/nutups_   /etc/munin/plugins/nutups_MGE-Ellipse750_freq
$ ln -s /usr/share/munin/plugins/nutups_   /etc/munin/plugins/nutups_MGE-Ellipse750_current
$ ln -s /usr/share/munin/plugins/nut_misc  /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/nut_volts /etc/munin/plugins/
$ echo &quot;[nut*]
user root

[nut_*]
env.upsname MGE-Ellipse750@localhost
&quot; &gt; /etc/munin/plugin-conf.d/nut
</pre><p>And if you have a MySQL server running on the machine, that&#8217;s a good idea to get stats:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/mysql_threads     /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/mysql_slowqueries /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/mysql_queries     /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/mysql_bytes       /etc/munin/plugins/
</pre><p>I also use some other Munin plugins coming from <a href="http://exchange.munin-monitoring.org">Munin exchange</a>:</p><pre class="brush: bash; title: ; notranslate">
$ wget http://exchange.munin-monitoring.org/plugins/mysql_size_all/version/1/download --output-document=/usr/share/munin/plugins/mysql_size_all
$ ln -s /usr/share/munin/plugins/mysql_size_all /etc/munin/plugins/
</pre><p>An here is how I monitor my RAID array:</p><pre class="brush: bash; title: ; notranslate">
$ wget http://exchange.munin-monitoring.org/plugins/raid/version/3/download --output-document=/usr/share/munin/plugins/raid
$ ln -s /usr/share/munin/plugins/raid /etc/munin/plugins/
$ echo &quot;[raid]
user root
&quot; &gt; /etc/munin/plugin-conf.d/raid
</pre><p>Finally, it&#8217;s time to monitor nginx itself:</p><pre class="brush: bash; title: ; notranslate">
$ ln -s /usr/share/munin/plugins/nginx_status  /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/nginx_request /etc/munin/plugins/
$ echo &quot;[nginx_*]
env.url http://localhost/nginx_status
&quot; &gt; /etc/munin/plugin-conf.d/nginx
</pre><p>These two scripts above have some Perl module dependencies:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install libio-all-lwp-perl
</pre><p>If you don&#8217;t install the libraries above, you&#8217;ll get these kind of errors in <code>/var/log/munin/munin-node.log</code>:</p><pre class="brush: plain; title: ; notranslate">
2011/05/03-17:50:10 [2009] Error output from nginx_request:
2011/05/03-17:50:10 [2009]      Can't locate object method &quot;new&quot; via package &quot;LWP::UserAgent&quot; at /etc/munin/plugins/nginx_request line 106.
2011/05/03-17:50:10 [2009] Service 'nginx_request' exited with status 9/0.
2011/05/03-17:50:10 [2009] Error output from nginx_status:
2011/05/03-17:50:10 [2009]      Can't locate object method &quot;new&quot; via package &quot;LWP::UserAgent&quot; at /etc/munin/plugins/nginx_status line 109.
2011/05/03-17:50:10 [2009] Service 'nginx_status' exited with status 2/0.
</pre><p>But for this to work, we have to update the <code>/etc/nginx/sites-enabled/munin</code> file. Now it looks like this:</p><pre class="brush: plain; title: ; notranslate">
server {
  server_name munin.example.com;
  root /var/cache/munin/www/;
  # Restrict Munin access
  auth_basic &quot;Restricted&quot;;
  auth_basic_user_file /etc/nginx/htpasswd;
  location / {
    index index.html;
    access_log off;
  }
}
server {
  allow 127.0.0.1;
  deny all;
  location /nginx_status {
    stub_status on;
    access_log off;
  }
}
</pre><p>Note that I&#8217;ve added a simple HTTP authentication to Munin webpages and restricted access to nginx statistics from the local machine only.</p><p>At last, before rebooting Munin and Nginx, make sure all downloaded plugins are executables. This is important and always forgotten:</p><pre class="brush: bash; title: ; notranslate">
$ chmod -R 755 /usr/share/munin/plugins/
$ /etc/init.d/nginx restart
$ /etc/init.d/munin-node restart
</pre>]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/06/munin-monitor-debian-squeeze-server/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>MGE Ellipse 750 UPS on Debian Squeeze</title><link>http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/</link> <comments>http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/#comments</comments> <pubDate>Tue, 31 May 2011 10:22:58 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[nut]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[squeeze]]></category> <category><![CDATA[udev]]></category> <category><![CDATA[UPS]]></category> <category><![CDATA[USB]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=440</guid> <description><![CDATA[My home server is protected by an MGE Ellipse 750 UPS for years. I bought it for several reasons: it&#8217;s affordable, has good capacity and is Ubuntu certified. I also read back then rumors implying that Nut&#8217;s maintainer was employed &#8230; <a href="http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>My home server is protected by an <a href="http://www.mgeops.com/index.php/products__1/230v_products/ups/ellipse_asr">MGE Ellipse 750 UPS</a> for years. I bought it for several reasons: it&#8217;s affordable, has good capacity and is Ubuntu certified.</p><p>I also read back then <a href="http://blog.mansonthomas.com/2008/10/setting-up-ups-link-with-ubuntu-server.html">rumors</a> implying that Nut&#8217;s maintainer was employed by MGE. Having a hardware manufacturer employing a fellow open-source hacker has certainly influenced my purchase decision.</p><p>MGE is no more and has been <a href="http://www.eaton.com/Eaton/OurCompany/NewsEvents/NewsReleases/CT_136576">merged with EATON</a>. But my UPS is still supported, and the release of Debian Squeeze is a good opportunity to consolidate my knowledge in the form of this tutorial.</p><p>So here is how I setup Nut on Debian Squeeze to monitor my UPS.</p><p>First things first, we have to install the main package and its USB driver:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install nut nut-usb
</pre><p>Now let&#8217;s configure Nut and run it:</p><pre class="brush: bash; title: ; notranslate">
$ sed -i 's/MODE=none/MODE=standalone/g' /etc/nut/nut.conf
$ echo '
[MGE-Ellipse750]
driver = usbhid-ups
port = auto
desc = &quot;MGE UPS Systems&quot;
' &gt;&gt; /etc/nut/ups.conf
$ sed -i 's/# LISTEN 127\.0\.0\.1 3493/LISTEN 127\.0\.0\.1/g' /etc/nut/upsd.conf
$ echo '
[kevin]
password = badpassword
upsmon master
' &gt;&gt; /etc/nut/upsd.users
$ sed -i 's/# NOTIFYCMD \/usr\/local\/ups\/bin\/notifyme/NOTIFYCMD \/sbin\/upssched/g' /etc/nut/upsmon.conf
$ echo '
MONITOR MGE-Ellipse750@localhost 1 kevin badpassword master
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
' &gt;&gt; /etc/nut/upsmon.conf
$ sed -i 's/CMDSCRIPT \/upssched-cmd/CMDSCRIPT \/etc\/nut\/upssched-cmd/g' /etc/nut/upssched.conf
$ sed -i 's/# PIPEFN \/var\/run\/nut\/upssched\/upssched.pipe/PIPEFN \/var\/run\/nut\/upssched.pipe/g' /etc/nut/upssched.conf
$ sed -i 's/# LOCKFN \/var\/run\/nut\/upssched\/upssched.lock/LOCKFN \/var\/run\/nut\/upssched.lock/g' /etc/nut/upssched.conf
$ echo '
AT ONBATT * START-TIMER onbatt 30
AT ONLINE * CANCEL-TIMER onbatt
' &gt;&gt; /etc/nut/upssched.conf
$ echo '
#!/bin/sh
exit 0
' &gt; /etc/nut/upssched-cmd
$ /etc/init.d/nut restart
</pre><p>As you can see you have lots of stuff to configure before Nut can do what it was designed for. But after all of these commands, you should have a working UPS.</p><p>You can now test that your system works by using the command below, which list statistics of a given UPS:</p><pre class="brush: bash; title: ; notranslate">
$ upsc MGE-Ellipse750@localhost
</pre><p>But in some rare cases, your UPS will not be recognized and you&#8217;ll have like me the following messages in your <code>/var/log/syslog</code>:</p><pre class="brush: plain; title: ; notranslate">
May  5 16:12:36 paris-server upsmon[10773]: Poll UPS [MGE-Ellipse750@127.0.0.1] failed - Driver not connected
</pre><p>In this case, you should run Nut&#8217;s driver in debug mode:</p><pre class="brush: bash; title: ; notranslate">
$ /lib/nut/usbhid-ups -DDD -a MGE-Ellipse750
Network UPS Tools - Generic HID driver 0.34 (2.4.3)
USB communication driver 0.31
   0.000000     debug level is '3'
   0.013911     upsdrv_initups...
   0.189541     Checking device (0463/FFFF) (005/003)
   0.189705     - VendorID: 0463
   0.189741     - ProductID: ffff
   0.189767     - Manufacturer: unknown
   0.189794     - Product: unknown
   0.189819     - Serial Number: unknown
   0.189842     - Bus: 005
   0.189862     Trying to match device
   0.189906     Device matches
   0.189954     failed to claim USB device: could not claim interface 0: Operation not permitted
   0.189995     failed to detach kernel driver from USB device: could not detach kernel driver from interface 0: Operation not permitted
   0.190033     failed to claim USB device: could not claim interface 0: Operation not permitted
   0.190070     failed to detach kernel driver from USB device: could not detach kernel driver from interface 0: Operation not permitted
   0.190108     failed to claim USB device: could not claim interface 0: Operation not permitted
   0.190145     failed to detach kernel driver from USB device: could not detach kernel driver from interface 0: Operation not permitted
   0.190181     failed to claim USB device: could not claim interface 0: Operation not permitted
   0.190217     failed to detach kernel driver from USB device: could not detach kernel driver from interface 0: Operation not permitted
   0.190252     Can't claim USB device [0463:ffff]: could not detach kernel driver from interface 0: Operation not permitted
</pre><p>As you can see in messages above, Nut can&#8217;t see my UPS. By chance, forcing nut to use the <code>root</code> user let it see my UPS:</p><pre class="brush: bash; title: ; notranslate">
$ /lib/nut/usbhid-ups -DDD -u root -a MGE-Ellipse750
Network UPS Tools - Generic HID driver 0.34 (2.4.3)
USB communication driver 0.31
   0.000000     debug level is '3'
   0.001678     upsdrv_initups...
   0.172877     Checking device (0463/FFFF) (005/003)
   1.112408     - VendorID: 0463
   1.112464     - ProductID: ffff
   1.112489     - Manufacturer: MGE OPS SYSTEMS
   1.112516     - Product: ELLIPSE
   1.112542     - Serial Number: BDCJ3800Q
   1.112569     - Bus: 005
   1.112595     Trying to match device
   1.112647     Device matches
   1.112726     failed to claim USB device: could not claim interface 0: Device or resource busy
   1.113239     detached kernel driver from USB device...
   1.251394     HID descriptor, method 1: (9 bytes) =&gt; 09 21 00 01 21 01 22 01 03
   1.251460     HID descriptor, method 2: (9 bytes) =&gt; 09 21 00 01 21 01 22 01 03
   1.251491     HID descriptor length 769
   1.351379     Report Descriptor size = 769
   1.351456     Report Descriptor: (769 bytes) =&gt; 05 84 09 04 a1 01 09 24 a1 00 09 02 a1 00
   1.351509      55 00 65 00 85 01 75 01 95 05 15 00 25 01 05 85 09 d0 09 44 09 45 09 42 0b
(...)
</pre><p>So the issue is now clear and is related to permissions. I was able to fix this issue by changing the permissions on the USB device corresponding to my UPS:</p><pre class="brush: bash; title: ; notranslate">
$ chmod 0666 /dev/bus/usb/005/003
</pre><p>Another working way to fix this is to change the group of the device to <code>nut</code>:</p><pre class="brush: bash; title: ; notranslate">
$ chown :nut /dev/bus/usb/005/003
</pre><p>BTW, to get the bus number (<code>005</code> here) and device number (<code>003</code> in my case) of your UPS, run <code>lsudb</code>:</p><pre class="brush: bash; title: ; notranslate">
$ lsusb
Bus 005 Device 003: ID 0463:ffff MGE UPS Systems UPS
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
</pre><p>Of course this fix is absolutely temporary, as you&#8217;ll need to perform the change above after every reboot. This is far from practical. In fact, as describe in this <a href="http://bugzilla.redhat.com/show_bug.cgi?id=488368">Fedora 10 bug report</a>, but also in <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=529664">some</a> <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=334105">other</a> Debian <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=325878">bug report</a>, this issue is directly tied to conflicting Udev rules.</p><p>Based on clues from these bug reports you can fix Udev using different strategies. As I can&#8217;t decide which one is the cleanest, I just did something that is quite brutal, but works. It consist of replacing in <code>/lib/udev/rules.d/91-permissions.rules</code> the line setting rights for USBfs-like devices:</p><pre class="brush: diff; title: ; notranslate">
--- /lib/udev/rules.d/91-permissions.rules-orig 2011-05-05 18:49:08.015538434 +0200
+++ /lib/udev/rules.d/91-permissions.rules      2011-05-05 18:49:16.663537978 +0200
@@ -33,7 +33,7 @@

 # usbfs-like devices
 SUBSYSTEM==&quot;usb&quot;, ENV{DEVTYPE}==&quot;usb_device&quot;, \
-                               MODE=&quot;0664&quot;
+                               MODE=&quot;0666&quot;

 # serial devices
 SUBSYSTEM==&quot;tty&quot;,
</pre><p>Now all you have to do is to unplug the power cord and wait until your machine gracefully shut down as soon as batteries are low ! <img src='http://kevin.deldycke.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> ]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/05/mge-ellipse-750-ups-debian-squeeze/feed/</wfw:commentRss> <slash:comments>6</slash:comments> </item> <item><title>Setting up HDD&#8217;s SMART monitoring on Debian Squeeze</title><link>http://kevin.deldycke.com/2011/05/setting-hdds-smart-monitoring-debian-squeeze/</link> <comments>http://kevin.deldycke.com/2011/05/setting-hdds-smart-monitoring-debian-squeeze/#comments</comments> <pubDate>Tue, 17 May 2011 10:13:04 +0000</pubDate> <dc:creator>Kev</dc:creator> <category><![CDATA[English]]></category> <category><![CDATA[Debian]]></category> <category><![CDATA[HDD]]></category> <category><![CDATA[Linux]]></category> <category><![CDATA[Server]]></category> <category><![CDATA[smartmontools]]></category> <category><![CDATA[squeeze]]></category><guid isPermaLink="false">http://kevin.deldycke.com/?p=3169</guid> <description><![CDATA[Here is how I setup SMART monitoring and maintenance of an array of Hard-Disk Drives running a Debian Squeeze. First, let&#8217;s install the smartmontools package: We now have to check that SMART is activated on our drives: Nowadays all modern &#8230; <a href="http://kevin.deldycke.com/2011/05/setting-hdds-smart-monitoring-debian-squeeze/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Here is how I setup SMART monitoring and maintenance of an array of Hard-Disk Drives running a Debian Squeeze.</p><p>First, let&#8217;s install the <code>smartmontools</code> package:</p><pre class="brush: bash; title: ; notranslate">
$ aptitude install smartmontools
</pre><p>We now have to check that SMART is activated on our drives:</p><pre class="brush: bash; title: ; notranslate">
$ smartctl -a /dev/sdb | grep &quot;SMART support is: Enabled&quot;
$ smartctl -a /dev/sdc | grep &quot;SMART support is: Enabled&quot;
$ smartctl -a /dev/sdd | grep &quot;SMART support is: Enabled&quot;
$ smartctl -a /dev/sde | grep &quot;SMART support is: Enabled&quot;
</pre><p>Nowadays all modern drives are already activated in factories. But in case they&#8217;re not you can activate this feature with the following command:</p><pre class="brush: bash; title: ; notranslate">
$ smartctl -s on -a /dev/sdb
</pre><p>Now we have to activate the <code>smartd</code> daemon, and let it start automatically when the machine boot:</p><pre class="brush: bash; title: ; notranslate">
$ sed -i 's/#start_smartd=yes/start_smartd=yes/g'                           /etc/default/smartmontools
$ sed -i 's/#smartd_opts=&quot;--interval=1800&quot;/smartd_opts=&quot;--interval=1800&quot;/g' /etc/default/smartmontools
</pre><p>For some reason, I prefer to not let <code>smartd</code> select by itself drives it should check. Here is how to deactivate the auto-detection:</p><pre class="brush: bash; title: ; notranslate">
$ sed -i 's/^DEVICESCAN /#DEVICESCAN /g' /etc/smartd.conf
</pre><p>Now let&#8217;s specify by hand the way our drives should be monitored and maintained. Here are the lines I added to <code>/etc/smartd.conf</code>:</p><pre class="brush: plain; title: ; notranslate">
/dev/sdb -a -o on -S on -s (S/../.././02|L/../../6/03) -m kevin@deldycke.com
/dev/sdc -a -o on -S on -s (S/../.././04|L/../../6/05) -m kevin@deldycke.com
/dev/sdd -a -o on -S on -s (S/../.././06|L/../../6/07) -m kevin@deldycke.com
/dev/sde -a -o on -S on -s (S/../.././08|L/../../6/09) -m kevin@deldycke.com
</pre><p>Finally, we need to restart the SMART service to take into account all our changes:</p><pre class="brush: plain; title: ; notranslate">
$ /etc/init.d/smartmontools restart
</pre>]]></content:encoded> <wfw:commentRss>http://kevin.deldycke.com/2011/05/setting-hdds-smart-monitoring-debian-squeeze/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/48 queries in 0.018 seconds using apc
Object Caching 1207/1328 objects using apc

Served from: kevin.deldycke.com @ 2012-02-08 10:19:32 -->
