Installing a Debian-Linux Server (5.0 / Lenny)
Table of Content
last modified: March 01 2017


The first time I set up my Debian-Server was in 2004. At that time the system was running on a 200MHz PC in a room of mine, and it served its purposes quite well. After a bit less than a year however, I came to the conclusion that it would be better to have the server hosted in a professional computer center. There are several advantages of having the server hosted: - uptime A computer center will guarantee a certain availability. The risks of downtime (such as someone mistakenly unplugging the system) are smaller. - static IP-Address One of the most important things (especially for the mailserver) is to have a static IP-Address. Dynamic IP-Address ranges are very often blacklisted. - Internet speed - reverse DNS For spam reasons, the reverse DNS of your server should be the same as your main forward DNS name of your mailserver. - private browsing If your server has the same IP-Address as your PC, then your web-browsing can be traced to your server (which has a DNS-Name). - standard installation A hosted server will normally have a stable basic-installation of the operating system. So this guide will build on a basic installation of a Debian 5.0 system. Basic steps such as partitioning discs are not part of this documentation.


- Time, patience and motivation. You will certainly stumble over some problems which you will have to resolve yourself. - Basic UNIX-knowledge (you should be familiar with shell-commands like 'cd/pwd/ls/cp/mv' and so on - A server with a minimal Debian installation. - A domain of your own whith the A-record and MX-record pointing to the IP-Address of the server.

Base System

Install LAMP Base System: # installed: (L)inux - apt-get install apache2 # installs (A)pache - apt-get install mysql-server # installs (M)ySQL - apt-get install php5 phpmyadmin # installs (P)HP and mySQL Webtool - Installation of the webmin system-administration webapplication (cgi-perl with its own webserver): -> since etch, there is no official webmin debian package anymore. However webmin can still be downloaded as .deb package. Here is how it is done: $ wget # webmin application $ wget # usermin application -> note: now make sure nothing is running on port 10000, else stop the service temporarily $ dpkg --install webmin_1.420_all.deb # installs webmin on port 10000 (install the missing packages if dependency fails) $ dpkg --install usermin_1.350_all.deb # installs usermin on port 20000 -> Check Webmin on this URL: -> if you should get an access-denied-error, do this: -> vi /etc/webmin/miniserv.conf -> delete row containing: allow= -> here you can also change your port and reactivate the service you previously had running -> /etc/init.d/webmin restart # restarts webmin-service

Debian as fully functional Mail System

# install the exim4 MTA: $ apt-get install exim4-daemon-heavy

Enable pop3/pop3s, imap/imaps with dovecot

You probably want your users to be able to download their mails using pop3 or imap. This is easily done with the dovecot-package (New in the lenny-distribution!). - Install the packages: $ apt-get install dovecot-imapd dovecot-pop3d -> this will install all you need for imap(s) and pop3(s). In previous Debian-distributions I have installed qpopper for pop3(s) and the crappy uw-imapd for imap(s). Furthermore you can use dovecot for exim-authentication, but more of that later. All I had to change from the default configuration was: /etc/dovecot/dovecot.conf: mail_access_groups = mail this enables dovecot to read and write in /var/mail

Customize the exim4-deamon-heavy debian package to use dkim

To avoid your mails being marked as spam, you can sign them with dkim. It is not nessessary but recommended to do so:

Enable Anti-Spam measures on the MTA (exim4)

Add SPF-library: $ apt-get install libmail-spf-query-perl Add these lines at the top of the config-file /etc/exim4/exim4.conf.template to enable various quality checks on incoming mail: CHECK_RCPT_VERIFY_SENDER = yes CHECK_RCPT_REVERSE_DNS = yes CHECK_RCPT_SPF = yes CHECK_DATA_VERIFY_HEADER_SENDER = yes CHECK_RCPT_IP_DNSBLS = : MAIN_TLS_ENABLE = yes # certificate keys need to be set in tls_certificate / tls_privatekey # test if TLS is enabled: # $ openssl s_client -connect localhost:25 -starttls smtp Enable Exim to run an integrated SpamAssassin Check: Search for spamd_address and uncomment it with the SpamAssassin defaults: spamd_address = 783 Note: SpamAssassin must be installed (see further below)

deny IP-Blacklisted servers:

I suggest to deny the ip-blacklisted MTA's. This will block a good deal of your spam before SpamAssassin does anything. search for string 'CHECK_RCPT_IP_DNSBLS' in the ACL-Block then replace "warn" with "deny": ################## deny message = your ip-address $sender_host_address is blacklisted at $dnslist_domain ($dnslist_value: $dnslist_text) ##################

activate the changes using:

$ dpkg-reconfigure exim4-config # writes changes into /var/lib/exim4/config.autogenerated and restarts exim4 - check the logfiles for blocked mails and you will see the vast amount it blocks (providing you get much spam): /var/log/exim4/rejectlog

Relay mail with SMTP-Authentication

Authentication should be used if you want to relay mails. E.g. users are able to send mails from their PC's through your mailserver. There are several ways to enable SMTP-Authentication. I have chosen to use the dovecot authentication interface, since I already use dovecot as IMAP- and POP3 server. $ vi /etc/dovecot/dovecot.conf # search for "socket listen" socket listen { client { # The client socket is generally safe to export to everyone. Typical use # is to export it to your SMTP server so it can do SMTP AUTH lookups # using it. path = /var/run/dovecot/auth-client group = Debian-exim mode = 0660 } } Now edit the exim config: $ vi /etc/exim4/exim4.conf.template # go to the auth/30_exim4-config_examples section dovecot_login: driver = dovecot public_name = LOGIN server_socket = /var/run/dovecot/auth-client # setting server_set_id might break several headers in mails sent by authenticated smtp. So be careful. server_set_id = $auth1 dovecot_plain: driver = dovecot public_name = PLAIN server_socket = /var/run/dovecot/auth-client server_set_id = $auth1 The next step will help your mails not to be marked as spam: $ vi /etc/exim4/exim4.conf.template # search for dnslookup: in the router section dnslookup: ## some other lines # remove the "Received"-header and all Spamassassin Reports for direct-outgoing mails: headers_remove = Received:X-Spam_report:X-Spam_bar:X-Spam_score_int:X-Spam_score: -> so why should this be good? Answer: Assuming you have set up the authentication so that your mailserver can be used by your users to send mails from their PC's (or other devices). The problem is that PC's mostly have dynamic IP-Addresses (which actually should be no problem at all). But it IS a problem, because most dynamic IP-Addresses are listed in databases used by Spamassassin (or other Spam filters), and many dynamic IP-Addresses are even blacklisted (for instance at If you have such an IP-Address in your header, the chances are big that the remote Spam-Software will falsely add spam-points to your mail, just because it was originally sent by a PC with a dynamic IP-Address. Also there is no need to show the spam report for outgoing mails, if the users are trusted.

SpamAssassin as Mailbox Safeguard

Configuring the MTA is far not enough to prevent spam. One of the most powerful anti-spam tools is probably SpamAssassin. SpamAssassin (SA) is a perl-program which checks email. According to these various checks, SA will rate the mail with Spampoints. Many Spampoints = bad (e.g. most likely spam) Few Spampoints (or better: negative Spampoints) = good (e.g. most likely ham). Per default a message is flagged as Spam as soon as it has more than 5 SA-Spam-Points. Install SpamAssassin: $ apt-get install spamassassin Install ProcMail: $ apt-get install procmail -> procmail will deliver the mail to the correct mail- or spamfolder by reading the Spam/Ham-Flag in the mail-header. - edit /etc/default/spamassassin -> ENABLED=1 # starts spamd at boot-time - edit /etc/exim4/exim4.conf.template: procmail: debug_print = "R: procmail for $local_part@$domain" driver = accept domains = +local_domains check_local_user transport = procmail_pipe # emulate OR with "if exists"-expansion require_files = ${local_part}:\ ${if exists{/etc/procmailrc}\ {/etc/procmailrc}{${home}/.procmailrc}}:\ +/usr/bin/procmail no_verify no_expn - reconfigure your exim4 with your changes from above: $ dpkg-reconfigure exim4-config (the changes are written into the file '/var/lib/exim4/config.autogenerated' - edit /etc/procmailrc: #### start procmailrc ### MAILDIR=/var/mail LOGFILE=/var/log/procmail/procmail.log # our only condition: :0 * ^X-Spam_bar: [+][+][+][+][+] $HOME/mail/Spam #### end procmailrc ### -> if the mail is marked as spam by SA through Exim, procmail delivers it to the spamfolder $HOME/mail/Spam

Configure SpamAssassin

(applies to both conventional and SA-Exim) - create directory for global bayes-database: mkdir -p /var/spamassassin - edit /etc/spamassassin/ (see perldoc for further info) bayes_path /var/spamassassin/bayes report_safe 0 rewrite_subject 0 - The bayes component of SpamAssassin is only effective, if it has learned from Spam and Ham (Non-Spam) mails. see $ perldoc sa-learn -> important to know: sa-learn --spam/ham --mbox /home/user/mail/NewSpam - Redefine a score for one of the tests: -> check /usr/share/spamassassin/ -> here you see the default-scores (this file is regenerated after an update, so it is not wise to edit) -> edit /etc/spamassassin/ -> overwrite the score in this file (this file will persist after an update) example: disable check for dynamic IP-Address (this test is real rubbish, because it will give loads of spam-points to a mail sent by webmail on a pc with a dynamic IP-address ..and most PC's have dynamic IP-addresses) score HELO_DYNAMIC_IPADDR2 0 example2: add new SpamAssassin-rule to check header (this example marks reverse-DNS-lookup with 4 Spam-points): header RULE_REVERSE_DNS_FAIL X-Host-Lookup-Failed =~ /failed/ score RULE_REVERSE_DNS_FAIL 4 -> restart spamassassin: /etc/init.d/spamassassin restart - A special SpamAssassin configuration for Horde users: Configure SpamAssassin so that it automatically whitelists the email-addresses in the personal horde-addressbook. Here SpamAssassin reads the addressbook directly from the MySQL-horde-database. -> Of course email-addresses can be faked, but spammers normally don't know the email addresses in your addressbooks. If you don't protect your domain with an SPF-Record, you may want to ommit your own domain, as spammers often try to fake your own email-address as sender. for the following configuration you should: -> substitute <horde-db> with your horde-database -> substitute <password> with your password -> substitute with your own domain a) Create the MySQL database-user "spamassassin" b) Grant select to spamassassin on table <horde-db>:turba_objects c) edit /etc/default/spamassassin. Add the option '--username Debian-exim --nouser-config --sql-config' to the OPTIONS-string. d) edit /etc/spamassassin/ Add the following lines: user_scores_dsn DBI:mysql:<horde-db>:localhost user_scores_sql_username spamassassin user_scores_sql_password <password> user_scores_sql_custom_query select distinct 'whitelist_from' as preference, object_email as value from turba_objects where object_email not like '' e) $ /etc/init.d/spamassassin restart

Update SpamAssassin

If need be: Update Spamassassin from the testing (or unstable) distribution - Spammers are fast in changing tactics and Spamassassin needs to adapt. It might help to get the latest Spamassassin version. Here is how you can get a specific package from 'testing' or even 'unstable': - vi /etc/apt/apt.conf APT::Default-Release stable; -> this ensures, that your main distribution tree is stable. - vi /etc/apt/sources.list # add a row containing the testing and unstable distribution : deb testing main deb unstable main - update Spamassassin from the testing (or unstable) branch: $ apt-get -t testing install spamassassin # installs spamassassin from testing branch $ apt-get -t unstable install spamassassin # installs spamassassin from unstable branch


Protect your own domain with SPF-settings (Sender Policy Framework): Go to your domain-name services at your DNS-provider. Add the following TXT record to your domain-name ( "v=spf1 +a +mx -all" This is the e-mail rule for your domain and it says: -> v=spf1: this marks the start of the SPF-rule -> +a: If the IP-Address of the sending MTA is the one of your domain (DNS A-Record) the mail should be accepted. -> +mx: If the IP-Address of the sending MTA is one of your defined MX-servers (DNS MX-Record), the mail should be accepted. -> -all: If the IP-Address of the sending MTA is any other than listed above, the mail should be rejected. With this "-all" you can block unauthorized MTA's sending emails from your domain. Of course this only works, if the receiving MTA checks your SPF-rule. My mailserver does. It only costs a few minutes to make an SPF policy for your domain. Doing this does not mean you have to enable the SPF-check on your MTA, but it helps other receiving MTA's (with enabled SPF-check) to verify if the sender is authorized to send mail from your domain or not. It is in your interest that no spam is sent from your email-addresses. For more details see

Debian as Webserver

Enabling HTTPS on port 443

- enable SSL-Modules (you need to create symbolic links): $ ln -s /etc/apache2/mods-available/ssl.* /etc/apache2/mods-enabled - Check if the links have been created: $ ls -l /etc/apache2/mods-enabled | grep ssl The output should look as follows: lrwxrwxrwx 1 root root 36 Nov 2 19:18 ssl.conf -> /etc/apache2/mods-available/ssl.conf lrwxrwxrwx 1 root root 36 Nov 2 19:18 ssl.load -> /etc/apache2/mods-available/ssl.load - configure your apache-daemon to listen on ports 443 and 80 (default HTTPS, HTTP) $ vi /etc/apache2/ports.conf Listen 80 Listen 443 - create the basic setup for your https-server: $ vi /etc/apache2/conf.d/apache2-https ************************************************** <VirtualHost *:443> ServerName DocumentRoot /var/www-ssl # SSL-Configuration: SSLEngine on SSLCertificateFile /etc/ssl/certs/yourcert.pem </VirtualHost> ************************************************** - configure the default (non-ssl) port, edit the first few lines, so that it looks like this: $ vi /etc/apache2/sites-available/default ************************************************** <VirtualHost *:80> ServerAdmin ServerName SSLEngine off DocumentRoot /var/www/ ... bla ... bla ... bla ************************************************** - create the https-directory $ mkdir /var/www-ssl - put any html-file into the HTTPS-directory, rename it to 'index.html' - restart the webserver $ apache2 -k restart - check your website using the URL:

Useful Server Configurations

Create a restricted ftp-user without shell-login

- Add user 'restricteduser' into /etc/passwd (using useradd) and edit the shell to '/bin/false' restricteduser:x:uid:gid:'Description':/home/restrictedfolder:/bin/false - Add username 'restricteduser' to the file /etc/ftpchroot. This will restrict the ftp-rootdirectory to the users home-directory. - Add '/bin/false' to the file /etc/shells. FTP checks for a valid shell. We can fake the /bin/false as a valid shell. -> The ftpuser 'restricteduser' now has access to the folder /home/restrictedfolder (and subfolders) only through FTP. The user does not have a shell-login and therefore cannot browse your system.

Create a ssh-connection without using a password

-> we want to use a public-key authentication, so there is no need for the password anymore. - on server: Edit your sshd-config file '/etc/ssh/sshd_config' and make sure these lines are set: -------------------------- RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys -------------------------- - on client: generate a public key $ ssh-keygen -t rsa # this will generate the files $HOME/.ssh/, $HOME/.ssh/id_rsa - on server: paste the generated public key ( from the client into the file $HOME/.ssh/authorized_keys (on server)

Restrict the ssh-sessions

-> to restrict ssh-sessions to certain trusted users just add the following line to '/etc/ssh/sshd_config': AllowUsers user1 user2 user3 # only these users have permissions to open an ssh-shell, all others are automatically prohibited. DenyUsers root user4 # This will prohibit root and user4 from opening a ssh-shell (only valid if AllowUsers is not set) -> edit these files to block ip-addresses/ranges: /etc/hosts.allow /etc/hosts.deny example: only allow subnet 192.168.0.x: /etc/hosts.allow sshd: /etc/hosts.deny sshd: ALL note: unlike AllowUsers/DenyUsers in sshd_config, the blocked IP-Addresses need to be set in /etc/hosts.deny, even if /etc/hosts.allow is set.

Change hostname

-> edit /etc/hostname $ /etc/init.d/

Useful packages

apt-get install acl # extended file-permissions (getfacl/setfacl) apt-get install rdate # synchronize date with remote server, ie apt-get install host # dns-lookup tool for hostnames

Distribution Upgrade

The distribution upgrade ist the part where you can do the most damage to the system. To avoid this risk, I do the distribution upgrade as follows: - Wait until there is a virtual root-server available with the new stable Debian-distribution. Personal note: My current hoster is: I'm quite content with this hoster. What I really like is that you can quit the contract online, which is (for reasons I cant understand) not common in this business. That is the main reason why Hosteurope has become my favorite hoster after having tested 3 others. - Rent the new server with the new distribution and install all the new software. - Once the new server works as it should, synchronize the content from the old server using the rsync command. - Update the DNS-entries to point to the new server.

Useful debian-commands and files

- set default editor: $ update-alternatives --config editor - Network Info: /etc/inetd.conf - services on ports: /etc/services - system wide variables: /etc/environment - nmap localhost # lists all the binded TCP-ports - nmap -Su localhost # lists all the binded UDP-ports - netstat -ap # lists binded and used ports programs and PID's - traceroute # network traffic - strace -p <pid> # monitor what the process is doing - ipcalc # ip subnet calculator - iptables -L -n # display firwall settings - dpkg -l # package list (stored in /var/cache/apt/archives) - dpkg-reconfigure <pkg-name> # Reconfigure a package - dpkg -S <file-pattern> # searches for a file and lists the package from which it was installed - dpkg -L <pkg-name> # lists the files of a package - apt-get install/remove # installs/removes packages - apt-cache search <pkg> # searches for <pkg> in available packages