The Perfect Server - Debian Wheezy (nginx, BIND, Dovecot, ISPConfig 3) - Page 3

4 Install The SSH Server (Optional)

If you did not install the OpenSSH server during the system installation, you can do it now:

apt-get install ssh openssh-server

From now on you can use an SSH client such as PuTTY and connect from your workstation to your Debian Wheezy server and follow the remaining steps from this tutorial.


5 Install vim-nox (Optional)

I'll use vi as my text editor in this tutorial. The default vi program has some strange behaviour on Debian and Ubuntu; to fix this, we install vim-nox:

apt-get install vim-nox

(You don't have to do this if you use a different text editor such as joe or nano.)


6 Configure The Network

Because the Debian Wheezy installer has configured our system to get its network settings via DHCP, we have to change that now because a server should have a static IP address. Edit /etc/network/interfaces and adjust it to your needs (in this example setup I will use the IP address (please note that I replace allow-hotplug eth0 with auto eth0; otherwise restarting the network doesn't work, and we'd have to reboot the whole system):

vi /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
#allow-hotplug eth0
#iface eth0 inet dhcp
auto eth0
iface eth0 inet static

Then restart your network:

/etc/init.d/networking restart

Then edit /etc/hosts. Make it look like this:

vi /etc/hosts       localhost.localdomain   localhost     server1

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Now run

echo > /etc/hostname
/etc/init.d/ start

Afterwards, run

hostname -f

It is important that both show now!


7 Update Your Debian Installation

First make sure that your /etc/apt/sources.list contains the wheezy-updates repository (this makes sure you always get the newest updates for the ClamAV virus scanner - this project publishes releases very often, and sometimes old versions stop working), and that the contrib and non-free repositories are enabled (some packages such as libapache2-mod-fastcgi are not in the main repository).

vi /etc/apt/sources.list

deb wheezy main contrib non-free
deb-src wheezy main contrib non-free

deb wheezy/updates main contrib non-free
deb-src wheezy/updates main contrib non-free

# wheezy-updates, previously known as 'volatile'
deb wheezy-updates main contrib non-free
deb-src wheezy-updates main contrib non-free


apt-get update

to update the apt package database and

apt-get upgrade

to install the latest updates (if there are any).


8 Change The Default Shell

/bin/sh is a symlink to /bin/dash, however we need /bin/bash, not /bin/dash. Therefore we do this:

dpkg-reconfigure dash

Use dash as the default system shell (/bin/sh)? <-- No

If you don't do this, the ISPConfig installation will fail.


9 Synchronize the System Clock

It is a good idea to synchronize the system clock with an NTP (network time protocol) server over the Internet. Simply run

apt-get install ntp ntpdate

and your system time will always be in sync.


10 Install Postfix, Dovecot, MySQL, phpMyAdmin, rkhunter, binutils

We can install Postfix, Dovecot, MySQL, rkhunter, and binutils with a single command:

apt-get install postfix postfix-mysql postfix-doc mysql-client mysql-server openssl getmail4 rkhunter binutils dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-sieve sudo

You will be asked the following questions:

General type of mail configuration: <-- Internet Site
System mail name: <--
New password for the MySQL "root" user: <-- yourrootsqlpassword
Repeat password for the MySQL "root" user: <-- yourrootsqlpassword

Next open the TLS/SSL and submission ports in Postfix:

vi /etc/postfix/

Uncomment the submission and smtps sections as follows (leave -o milter_macro_daemon_name=ORIGINATING as we don't need it):

submission inet n       -       -       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       -       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING

Restart Postfix afterwards:

/etc/init.d/postfix restart

We want MySQL to listen on all interfaces, not just localhost, therefore we edit /etc/mysql/my.cnf and comment out the line bind-address =

vi /etc/mysql/my.cnf

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           =

Then we restart MySQL:

/etc/init.d/mysql restart

Now check that networking is enabled. Run

netstat -tap | grep mysql

The output should look like this:

root@server1:~# netstat -tap | grep mysql
tcp        0      0 *:mysql                 *:*                     LISTEN      26796/mysqld



11 Install Amavisd-new, SpamAssassin, And Clamav

To install amavisd-new, SpamAssassin, and ClamAV, we run

apt-get install amavisd-new spamassassin clamav clamav-daemon zoo unzip bzip2 arj nomarch lzop cabextract apt-listchanges libnet-ldap-perl libauthen-sasl-perl clamav-docs daemon libio-string-perl libio-socket-ssl-perl libnet-ident-perl zip libnet-dns-perl

The ISPConfig 3 setup uses amavisd which loads the SpamAssassin filter library internally, so we can stop SpamAssassin to free up some RAM:

/etc/init.d/spamassassin stop
update-rc.d -f spamassassin remove

Share this page:

24 Comment(s)

Add comment


From: Unit at: 2013-05-12 19:21:04


thank you for the tutorial. I just installed nginx & ISPConfig on my server, but I get an 500 Internal Error after uploading wordpress files and the .sql database in mysql.

I also tried to delete .htaccess, but it didn't help. The 500 Error appears on index, but I have no problem to access the admin backend of wordpress at domain/wp-admin...

Can someone please tell me what could fix it? 

From: Kubek at: 2013-05-19 10:54:20

Check your error.log in log/ directory of your site.

From: at: 2013-08-27 10:51:45

Disable "Own Error-Documents"

From: Bulk sms gateway at: 2013-05-20 10:59:19

Thank you for posting this info.

From: meth at: 2013-08-15 18:07:05

If you want to use it using vagrant or install everything in your own server using puppet you can try

All contributions are welcomed :) 


From: Bradley Gillap at: 2014-02-15 20:21:52

Why not munit in this guide? Is it apache only?

From: at: 2014-03-26 11:15:31

You should use  insserv -rf spamassassin instead of update-rc.d -f spamassassin remove

From: Arthur at: 2014-04-22 22:08:05


Why do I need to change the configuration for a static IP address? Why not suitable DHCP?

From: at: 2014-10-24 09:00:49

I have been setting a few of these as Proxmox OpenVZ VMs.

Before diving into this tutorial:

Basically, you start out by downloading the current Wheezy OpenVZ template (at the time of this writing that's 7.0.2) and creating an openVZ container. Once that is up and running and reachable from the outside world, you can come back to the perfect server tutorial.

Since your virtual machine is already up and running, you can skip over the installation/setup parts. I'm assuming if you're setting up a VM, you already know how to set up your network, and can assign an IP to the VM through venet. Setting all this up would be part of a proxmox tutorial, and goes beyond what makes sense here.

Basically, after skipping the installation steps of this manual, you start directly with step 7 ("Update Your Debian Installation"), and right after that, continue with:


apt-get install console-data keyboard-configuration

This should bring up debconfig with a menu where you can configure your keyboard layout. Pick the keyboard layout you wish to use here.


dpkg-reconfigure locales

Here you choose which locales your system should use. The debian template seems to not set any default here. In my case, I choose both of these:


Personally, I then set de_DE.UTF-8 as my default locale (German). If you're from the US, you can of course simply not install this locale at all. If you're from the UK, you might prefer to install and select en_GB.UTF-8, etc. - use your common sense here.


dpkg-reconfigure tzdata

This is to configure your timezone. By default, your server will use UTC time. This may be fine for you. If not, you can choose a different timezone here (e.g. "Europe/Berlin" for a server in Germany).

You can now continue with step 8 of the perfect server tutorial.

From: Sam at: 2013-07-28 13:03:09

If you are getting an error message like this - it's because you are propably using some sort of apt-cacher software.

Failed to fetch  Size mismatch
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

Try without the apt-cacher conf file.

rm /etc/apt/apt.conf.d/90httpproxy

From: Anonymous at: 2013-11-12 16:43:07

in /etc/nginx/sites-enabled/000-apps.vhost I had to change location /images/mailman/ { alias /usr/share/images/mailman/; } to location ^~ /images/mailman/ { alias /usr/share/images/mailman/; } to display images on the mailman web interface properly. from location ^~ /images/ { # matches any query beginning with /images/ and halts searching, # so regular expressions will not be checked. [ configuration D ] }

From: Arthur at: 2014-04-23 17:18:24

 Where should I add this line?


 My config.

proc  /proc       proc    defaults    0    0
none  /dev/pts    devpts  rw,gid=5,mode=620    0    0
none  /run/shm    tmpfs   defaults    0    0

From: Danny at: 2014-06-06 15:34:43

All what you need to do is a reweite for the whole server/vhost  

server {
        listen       80;
         rewrite ^/(.*)$ /phpmyadmin/$1;
         location /phpmyadmin {
                root /usr/share;
                index index.php index.html index.htm;
                location ~ ^/phpmyadmin/(.+\.php)$ {
                        try_files $uri =404;
                        root /usr/share/;
                        fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        fastcgi_param SCRIPT_FILENAME $request_filename;
                        include /etc/nginx/fastcgi_params;
                        fastcgi_param PATH_INFO $fastcgi_script_name;
                        fastcgi_buffer_size 128k;
                        fastcgi_buffers 256 4k;
                        fastcgi_busy_buffers_size 256k;
                        fastcgi_temp_file_write_size 256k;
                        fastcgi_intercept_errors on;
                location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                        root /usr/share;
         location /phpMyAdmin {
                rewrite ^/* /phpmyadmin last;

From: Raj at: 2014-08-29 11:59:21

Where do i add this?

kindly elaborate 

noob here

From: A Scott at: 2014-12-17 19:31:22

At the Jailkit install step, if you get errors like below:

make: dpkg-architecture: Command not found
make: dpkg-architecture: Command not found
make: dh_testdir: Command not found
make: *** [config.status] Error 127

Run the following command to install dependancies.

apt-get install dpkg-dev debhelper


Jailkit is at version 2.17 as of December 2014, so do this instead of the jailkit step in the how-to:

cd /tmp
tar xvfz jailkit-2.17.tar.gz
cd jailkit-2.17
./debian/rules binary

From: Saevar at: 2013-05-12 16:39:47

That would be so great if we could have this setup in .img format so it would be possible to dd this setup on HDD, keep up the good work, p.s. i would buy this setup :) 

From: guntbert at: 2013-05-30 16:13:43

The first link under Links should be Debian:  :-))

From: x42 at: 2013-06-25 05:37:43

some libs moved to gnu. chroot doesn't work. edit /etc/jailkit/jk_init.ini wrote:

# this section probably needs adjustment on 64bit systems
# or non-Linux systems
comment = common files for all jails that need user/group information
libraries = /lib/, /lib64/, /lib/libnss*.so.2, /lib64/libnss*.so.2, /lib/x86_64-linux-gnu/, /lib/x86_64-linux-gnu/libnss*.so.2
regularfiles = /etc/nsswitch.conf, /etc/

comment = common files for all jails that need any internet connectivity
libraries = /lib/, /lib64/, /lib/x86_64-linux-gnu/
regularfiles = /etc/resolv.conf, /etc/host.conf, /etc/hosts, /etc/protocols

From: at: 2013-07-23 22:11:20

Wordpress issue - just a note that once I installed WordPress I could browse to the home page fine but all other pages gave me Error 500.

Thanks, Matt

From: Mindbuild at: 2014-05-09 10:28:58

Thanks for the excellent tutorial. Everything worked really well.

After installing ispconfig and using the above code to configure squirrelmail with Nginx, I was unable to send email. I got the error 404 not found. 

I had to replace the above code (non https) with this:

location /squirrelmail {
       root /usr/share/;
       index index.php index.html index.htm;
       location ~ ^/squirrelmail/(.+\.php)$ {
               try_files $uri =404;
               root /usr/share/;
               include /etc/nginx/fastcgi_params;
               # To access SquirrelMail, the default user (like www-data on Debian/Ubuntu) must be used
               fastcgi_index index.php;
               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               fastcgi_buffer_size 128k;
               fastcgi_buffers 256 4k;
               fastcgi_busy_buffers_size 256k;
               fastcgi_temp_file_write_size 256k;
       location ~* ^/squirrelmail/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
               root /usr/share/;
location /webmail {
       rewrite ^/* /squirrelmail last;

 found here:

After that I had  no problem in sending emails.


From: Florian at: 2014-09-16 18:55:55

Excellent work! Everything writen here works out of the box! This is a precious save of time! 

From: Idso at: 2014-12-05 19:42:30

Thanks for the excellent tutorial !! I just set it up on a testserver, but I should have no problem doing this on a production server thanks to this guide.

From: sidbyron at: 2015-01-25 02:19:34


This is the correct code for NGINX directives in Debian and ISPConfig.

First this is the code for http access without SSL:


#Configuration of phpMyAdmin

location /phpmyadmin/ {

   root /var/www/apps;               

   index index.php index.html index.htm;

     location ~ ^/(.+\.php)$ {

try_files $uri =404;                       

root /var/www/apps;

fastcgi_pass unix:/var/run/php5-fpm.sock;

fastcgi_index index.php;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include /etc/nginx/fastcgi_params;

fastcgi_buffer_size 128k;

fastcgi_buffers 256 4k;

fastcgi_busy_buffers_size 256k;

fastcgi_temp_file_write_size 256k;

fastcgi_intercept_errors on;


      location ~* ^/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {

 root /var/www/apps;




location /phpMyAdmin {

   rewrite ^/* /phpmyadmin last;



#Finish configuration of phpMyAdmin


Second This is for phpmyadmin with SSL certificate:


#Configuration de phpMyAdmin

location /phpmyadmin/ {

   root /var/www/apps;               

   index index.php index.html index.htm;

     location ~ ^/(.+\.php)$ {

try_files $uri =404;                       

root /var/www/apps;

fastcgi_pass unix:/var/run/php5-fpm.sock;

        fastcgi_param HTTPS $https; # <-- add this line

fastcgi_index index.php;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include /etc/nginx/fastcgi_params;

fastcgi_buffer_size 128k;

fastcgi_buffers 256 4k;

fastcgi_busy_buffers_size 256k;

fastcgi_temp_file_write_size 256k;

fastcgi_intercept_errors on;


      location ~* ^/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {

 root /var/www/apps;


      location ~* ^/{

          if ($scheme = http) {

   return 301 https://$server_name$request_uri;





location /phpMyAdmin {

   rewrite ^/* /phpmyadmin last;



#Finish Configuration phpMyAdmin

This configuration is for people that setup the phpmyadmin on directory /var/www/apps and want to get load for each site without create a new site.

Kind Regards.

From: newtesla at: 2015-03-09 19:44:07

Please, abandon ntpdate in future: it has already created problems.