From Tim's website
Jump to: navigation, search

This Server's Configuration (Debian Lenny)

This server is configured with two network interfaces. One is external facing and connects to my router, the other is internal facing and connects to the other computers on my network. The server is fitted with two hard disks and software RAID is used for redundancy.

Prepare

  1. Connect up all the hardware
  2. If you're going to upgrade the firmware - now is the time to do it
  3. Download, burn and boot from the Ultimate Boot CD
  4. Run memtest, CPU-burn in and DBAN

Installing Debian

  1. Download, burn and boot from the small debian net-install CD
  2. Choose "Install" from the first menu
  3. Select language, country and keymap
  4. Wait for the list of network interfaces to be shown
  5. Connect router to the network interface that has been given the name eth0
  6. Select this as the primary network interface
    • If DHCP fails to obtain an address then it is likely that the router is not connected to the interface that has been given the name eth0. Select "Go Back" (using tab) and connect the router to a different interface before trying eth0 again.
  7. Enter a name for the server e.g. "server"
  8. Enter a domain name. For this server I use "timstyles.me.uk", but yours will be different

Configuring Software RAID

  1. Create two partitions on each hard disk (file system and swap space)
    1. Select "Guided - use entire disk"
    2. Select the first disk
    3. Select "All files in one partition"
    4. Select "Guided partitioning"
    5. Select "Guided - use entire disk"
    6. Select the second disk
    7. Select "All files in one partition" again
  2. Select each of the partitions in turn (including the new swap partitions)
    1. Select "Use as" and change to "physical volume for RAID"
    2. Select "Done setting up the partition" (leave the bootable flag the same)
  3. Select the "Configure software RAID" option, which has appeared at the top
    1. Select "Yes" to write the existing changes
    2. Select "Create MD device"
    3. Select RAID1
    4. Enter 2 devices
    5. Enter 0 spare devices
    6. Select the first partition on each disk (sda1 and sdb1)
    7. Repeat the above, selecting the remaining two partitions (sda5 and sdb5)
    8. Select Finish
  4. Select the partition on RAID1 device #0
    1. Change "Use as" to Ext3 journalling file system
    2. Change the mount point to "/ - root"
    3. Select "Done setting up the partition"
  5. Select the partition on RAID1 device #1
    1. Change "Use as" to Swap area
    2. Select "Done setting up the partition"
  6. Go to the bottom and select "Finish partitioning and write changes to disk"
  7. Confirm the changes by selecting "yes"
  8. Select "Continue" when informed about the need to reboot before using md1

Installing files

  1. Enter a root password
  2. Enter a Full name, username and password for your own account
  3. Select a package mirror (we will look for the fastest one later)
  4. Leave the HTTP proxy blank
  5. Deselect Desktop environment, since we don't want a GUI
    • Select "Web server", "DNS server", "File server" and "Mail server" software
    • Leave the standard installation selected
  6. Enter a workgroup name when prompted, e.g. HOME
    • This should be the same name used on other computers
  7. Select "No" when asked about getting WINS information from DHCP
  8. Select "Yes" to install the GRUB boot loader to the master boot record
  9. Remove the CD and select Continue to reboot

Install grub on mirrored drives

As far as I can tell, grub will only be installed on the first drive (/dev/sda). If this drive fails then the machine will not boot. To fix this install grub on /dev/sdb too, so that the machine can boot with either drive. It is also worth testing if this works, as not all machines will move on to the next drive by default.

grub-install /dev/sdb

Setting up package sources

  1. Login as root
  2. Look at the debian mirror list here: http://www.debian.org/mirror/list
  3. Use ping and wget to identify a mirror with good bandwidth to your internet connection
  4. Edit /etc/apt/sources.list using an editor such as nano
  5. Replace the web server name with the one you identified
  6. Replace "lenny" with "stable" if you wish to upgrade when releases are made

Using aptitude to select packages

  • As an example we will install ssh and remove netatalk
  1. Type "aptitude"
  2. Use "/" to search for packages
  3. Enter "netatalk"
  4. Select OK and use "-" to deselect the package for removal
  5. Use "/" to search for packages
  6. Enter "^ssh$" to search for the exact name "ssh"
  7. Select OK and use "+" to select the package for installation
  8. Use "g" to start the package installation. Notice that a number of other packages will be installed to support the ssh server.
  9. Use "g" again to download the packages and install them.
  10. Use "q" to quit aptitude

Setting up SSH

To restrict SSH access:

  • Uncomment the following line in /etc/pam.d/sshd
account  required     pam_access.so
  • Add these lines to /etc/security/access.conf (use your own domain and machine name)
# Allow su and root user login from local machine and mypc
+ : root : LOCAL
+ : root : mypc.timstyles.me.uk
# Allow nobody to login from cron
+ : nobody : cron
# Allow only tim to login from anywhere else
- : ALL EXCEPT tim : ALL

Setting up network interfaces

Add these lines to /etc/network/interfaces to configure the second network card

auto eth1
iface eth1 inet static
address 192.168.1.1
netmask 255.255.255.0

Our server will have IP address 192.168.1.1 on the internal network.

Install a DHCP server

  • Use aptitude to install "dhcp3-server"
  • Edit /etc/default/dhcp3-server
    • Change INTERFACES="" to INTERFACES="eth1" to limit the DHCP service to the internal network
  • Edit /etc/dhcp3/dhcpd.conf:
    • Change the domain-name option to your domain
    • Change the domain-name-servers to 192.168.1.1
    • Uncomment "authoritative;"
    • Uncomment the basic subnet declaration and modify it as follows:
# Dynamically assigned addresses will be in the range 192.168.1.10 to 192.168.1.20
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.10 192.168.1.20;
  option routers 192.168.1.1;
  option broadcast-address 192.168.1.255;
}
  • Fixed IP addresses can be defined in the bind configuration and assigned as follows: (use your own domain and machine name)
# Use the name "mypc" for network interface 00:0f:ea:8e:1b:b9
# The IP address assigned to "mypc" is defined in /etc/bind/
host mypc {
  hardware ethernet 00:0f:ea:8e:1b:b9;
  fixed-address mypc.timstyles.me.uk;
}
  • Try running /etc/init.d/networking restart
  • Wait for 30 seconds and run ifconfig
  • If eth0 isn't listed then change "allow-hotplug eth0" to "auto eth0" in /etc/network/interfaces
  • Start the DHCP server by running "/etc/init.d/dhcp3-server start"

Computers on the eth1 network should now be able to obtain an IP address dynamically

Enable gateway and firewall properties

  • Uncomment the following lines in /etc/sysctl.conf to enable spoof protection
net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
  • Name the following script "firewall" and place in /etc/network/if-pre-up.d
#!/bin/sh
# This firewall script is run before the interfaces are brought up
# It sets a policy of drop on all chains and clears them

# Apply default drop policy
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Flush and Delete existing rules
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --zero
iptables --table nat --zero

# Immediately allow outgoing traffic and loop back traffic
iptables -A OUTPUT -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

# Disable forwarding while the interfaces are brought up
echo 0 > /proc/sys/net/ipv4/ip_forward

# Set some other parameters to prevent certain types of attack
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

  • Name the following script "firewall" and place in /etc/network/if-up.d
    • Note that this script prevents forwarding traffic from internal machines to an external mail server. This prevents infected machines from sending spam through the firewall. This is OK if you use the gateway as a mail server (see below), otherwise you will need to uncomment the line to allow SMTP traffic to an ISP mail server, setting the IP address to your ISP mail server.
#!/bin/sh
# This script is run after the interfaces have been brought up.
# Another script is run in if-pre-up to set a default policy of drop,
# to flush and delete chains, and to disable forwarding

# Load the FTP connection tracking module to support Passive FTP
modprobe ip_conntrack_ftp

# Allow SMTP traffic from internal machines to our ISP
#iptables -A FORWARD -i eth1 -p tcp --dport 25 -d 212.74.114.25 -j ACCEPT

# Reject SMTP traffic from internal machines to prevent spam bots
iptables -A FORWARD -i eth1 -p tcp --dport 25 -j REJECT

# Allow connections and forwarding from the internal LAN
iptables -A INPUT   -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT

# Check for denied hosts using a new table "denied"
iptables -N denied
iptables -A INPUT -j denied
iptables -A FORWARD -j denied

# Allow replies from anyone we've established a connection with
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Set up IP FORWARDing and Masquerading (NAT)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Limit the rate of new connections using a new table "syn-flood"
iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A syn-flood -j DROP

# Make sure NEW tcp connections are SYN packets and drop all fragments
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP

# Forward incomming data on port 1234 to mypc computer
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 1234 -j DNAT --to 192.168.1.2
iptables -A FORWARD -p tcp -i eth0 -d 192.168.1.2 --dport 1234 -j ACCEPT

# Allow connections for specific services
iptables -A INPUT -p TCP --dport ssh   -j ACCEPT
iptables -A INPUT -p TCP --dport smtp  -j ACCEPT
iptables -A INPUT -p TCP --dport imaps -j ACCEPT
iptables -A INPUT -p TCP --dport www   -j ACCEPT
iptables -A INPUT -p TCP --dport https -j ACCEPT
iptables -A INPUT -p TCP --dport ftp   -j ACCEPT

# Allow UDP messages from 192.168.0.1 (router) for syslog
iptables -A INPUT -p UDP -s 192.168.0.1 --dport syslog -j ACCEPT

# Allow UDP messages from 192.168.0.1 (router) for ntp time
iptables -A INPUT -p UDP -s 192.168.0.1 --dport ntp -j ACCEPT

# Enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
  • Run /etc/init.d/networking restart again

You should now have a working gateway with DHCP and SSH access

Configure the DNS server

Tell the DHCP server about the DNS server

  • Edit /etc/dhcp3/dhclient.conf: Uncomment the following line and set the IP:
prepend domain-name-servers 192.168.1.1;
  • Run /etc/init.d/networking restart
  • Check /etc/resolv.conf contains "nameserver 192.168.1.1"

Configure the DNS server

  • Add "-4" to the bind options in /etc/default/bind9
  • Edit /etc/bind/named.conf.options and replace the listen-on-v6 line to look like
listen-on { 192.168.1.1; 127.0.0.1; };
  • Remove the following line from /etc/bind/zones.rfc1918
zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };
  • Uncomment the following line in /etc/bind/named.conf.local
include "/etc/bind/zones.rfc1918";
  • Add these lines to /etc/bind/named.conf.local
zone "1.168.192.in-addr.arpa" {
	type master;
	file "/etc/bind/db.1.168.192";
	allow-update { key rndc-key; };
};
  • Copy /etc/bind/db.0 to /etc/bind/db.1.168.192 and edit it to look like the following: (use your own domain and machine name)
;
; BIND reverse data file for local network zone
;
$TTL    604800
@       IN      SOA     localhost. root.localhost. (
                              1         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      localhost.
;
$ORIGIN 1.168.192.in-addr.arpa.
1               PTR     server.timstyles.me.uk.
2               PTR     mypc.timstyles.me.uk.
7               PTR     printer.timstyles.me.uk.

  • Add these lines to /etc/bind/named.conf.local (use your own domain)
zone "timstyles.me.uk" {
	type master;
	file "/etc/bind/db.timstyles.me.uk";
	allow-update { key rndc-key; };
};
  • Copy /etc/bind/db.local to /etc/bind/db.timstyles.me.uk and edit it to look like the following: (use your own domain and machine name)
;
; BIND data file for local network zone
;
$TTL    604800
@       IN      SOA     server.timstyles.me.uk. tim.timstyles.me.uk. (
                              2         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      server.timstyles.me.uk.
@       IN      A       192.168.1.1
;
$ORIGIN timstyles.me.uk.
ftp             A       192.168.1.1
mypc            A       192.168.1.2
printer         A       192.168.1.7
server          A       192.168.1.1
www             A       192.168.1.1
webmail         A       192.168.1.1

Configure the DHCP server to update the DNS server

  • Add the following line to /etc/bind/named.conf.local
include "/etc/bind/rndc.key";

Edit /etc/dhcp3/dhcpd.conf:

  • Change "ddns-update-style none" to "ddns-update-style interim"
  • Add the line "update-static-leases on;" if you are going to issue static IP addresses by dhcp
  • Copy the following lines from your /etc/bind/rndc.key file and paste them into dhcpd.conf, removing the quotes and semi-colon. e.g.
key rndc-key {
  algorithm hmac-md5;
  secret x3wdKJF6Ge43gh98ts/4Dg==;
}
  • Add these lines: (use your own domain)
zone timstyles.me.uk. {
  primary 192.168.1.1;
  key rndc-key;
}
zone 1.168.192.in-addr.arpa. {
  primary 192.168.1.1;
  key rndc-key;
}
ddns-domainname "timstyles.me.uk";

Finally, allow dhcp to write to the DNS database with the line

chmod g+w /etc/bind

If you're paranoid you can change the rndc.key

  • Stop bind with "/etc/init.d/bind9 stop"
  • Run the command "rndc-confgen -a -b 128"
  • Then "chmod g+r /etc/bind/rndc.key"
  • Restart bind with "/etc/init.d/bind9 start"
  • Run "/etc/init.d/dhcp3-server restart"

System monitoring

Hard disk

Enable S.M.A.R.T. for hard disk monitoring:

  • Install smartmontools
  • Uncomment start_smartd=yes in /etc/default/smartmontools
  • Comment out the line starting DEVICESCAN in /etc/smartd.conf
  • Add these lines to /etc/smartd.conf for two SATA disks (use your own email address)
/dev/sda -a -d sat -o on -S on -s (S/../.././01|L/../../5/03) -m tim@timstyles.me.uk
/dev/sdb -a -d sat -o on -S on -s (S/../.././02|L/../../6/03) -m tim@timstyles.me.uk
  • Add the following to the above lines to ignore specific fault reports:
-I 190 -I 194

UPS

If you have an APC UPS connected via a serial cable or USB then you can monitor it by following these steps

  • Install apcupsd
  • You may need to change the configuration in /etc/apcupsd/apcupsd.conf for your UPS
  • You will need to edit /etc/default/apcupsd and set IS_CONFIGURED to yes
  • Run apctest and choose option 1 to check connectivity, then exit
  • If all is well run /etc/init.d/apcupsd start

Temperature

You can log the temperatures as follows:

  • Install sensord for system temperatures
    • On my Dell machine it is also necessary to load the IPMI kernel modules ipmi_devintf and ipmi_si. This can be done with modprobe and they should be added to /etc/modules so they are loaded automatically on boot.
  • Install smartmontools (see above) for HDD temperatures
  • Install apcupsd (see above) for UPS temperatures
  • Create a file in /etc/cron.hourly containing the following:
#!/bin/sh
sys_t1=`ipmitool sdr | sed -n 's/^Temp  [^0-9]*\([0-9]*\).*/\1/p'`
sys_t2=`ipmitool sdr | sed -n 's/^Planar Temp[^0-9]*\([0-9]*\).*/\1/p'`
sda_t1=`smartctl -l scttempsts /dev/sda | sed -n 's/Current [^0-9]*\([0-9]*\).*/\1/p'`
sdb_t1=`smartctl -l scttempsts /dev/sdb | sed -n 's/Current [^0-9]*\([0-9]*\).*/\1/p'`
apc_t1=`apcaccess | sed -n 's/ITEMP [^0-9]*\([0-9\.]*\).*/\1/p'`
date_stamp=`date +"%d/%m/%Y %H:%M"`

echo -e "$date_stamp\t$sys_t1\t$sys_t2\t$sda_t1\t$sdb_t1\t$apc_t1" >> /var/log/temperature

Don't forget to make the file executable with "chmod a+x"

Network traffic

You can monitor traffic through the gateway using darkstat:

  • Install darkstat
  • Modify /etc/darkstat/init.cfg as follows
    • Change START_DARKSTAT to yes
    • Uncomment and set PORT="-p 12345"
    • Uncomment DNS="--no-dns"
  • Run /etc/init.d/darkstat start

You can now view graphs of network traffic with a web browser. Just go to http://server:12345/

FTP server

You can run an FTP server to share files externally. Since FTP is not secure, it only makes sense to provide anonymous access. You can prevent the server from being abused by setting up a write only upload folder and making all other folders read only.

  • Install the package "^vsftpd$"
  • Edit /etc/vsftpd.conf
    • Comment out the line starting rsa_cert_file=
    • Uncomment the lines "write_enable=YES", "anon_upload_enable=YES" and "anon_mkdir_write_enable=YES"
    • Add the following lines:
anon_root=/srv/ftp
anon_world_readable_only=YES
anon_other_write_enable=YES
anon_umask=003
file_open_mode=0660
hide_file={.*}
  • Create the directories /srv/ftp and /srv/ftp/upload
  • Change the ownership of the upload directory: "chown ftp:nogroup /srv/ftp/upload"
  • Run /etc/init.d/vsftp restart

Upload alert

You can create a cron job to email you if files are uploaded. Create a file in /etc/cron.hourly/ with the following contents:

#!/bin/sh
# List the contents of /srv/ftp/upload
# This will result in an email from cron if there are files
ls -Ah /srv/ftp/upload/

Don't forget to make the file executable with "chmod a+x"

SAMBA server

You can run a SAMBA server to share files internally with Windows machines. Windows can access the shared folders directly or by mapping them as a network drive.

  • Install samba
  • Edit /etc/samba/smb.conf
    • Change "workgroup = HOME" to your workgroup name
    • Uncomment "wins support" and change to "yes"
    • Uncomment "domain master" and change to "yes"
    • Uncomment "interfaces" and change to "lo eth1" (lo must be first to avoid "interface 1 has NULL IP address" warnings in log)
    • Uncomment "bind interfaces only = yes". This restricts access to the internal network only.
  • Comment out the [printers] and [print$] sections if they are not used
  • In the "Printing" section add:
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes
  • In the "Share Definitions" section add the line "valid users = tim"
  • Configure sections as follows:
[homes]
   comment = Home on %s
   browseable = no
   read only = no

[srv]
   comment = SRV on %h
   path = /srv
   read only = no

[ftp]
   comment = FTP on %h
   path = /srv/ftp
   read only = no
   create mask = 0755
  • Add your user to the samba database with the line
smbpasswd -a tim

Mail server

I use Exim as my SMTP server, which handles sending and receiving mail. I use Courier to access my mail folder using IMAP through an SSH tunnel. I use mutt to access my mail folder when running on a terminal and I use Squirrel mail to access my mail externally via a web interface.

MX and SPF records

To send and receive mail for your domain using your server, you will need:

  • A static IP address
  • An MX record in the DNS entries for your domain
  • The reverse DNS for your IP to match the A record in your DNS entries

You should ask your ISP to configure the reverse DNS entry. They should also be able to provide DNS entries, or you can use a third party. My email related DNS entries look like this:

A   server.timstyles.me.uk  83.67.36.182
MX  timstyles.me.uk         server.timstyles.me.uk  5
MX  timstyles.me.uk         mx1.freedom2surf.net    10
TXT timstyles.me.uk         v=spf1 a mx -all

The last entry is an SPF record, which tells spam filters that email from your domain will only be sent via your server. A matching reverse DNS entry also adds credibility to your domain when sending emails.

Exim SMTP server

The following configuration will receive mail for the timstyles.me.uk domain, and support for other virtual domains can be added easily. Mail can be sent from the internal network without authentication.

  • Edit /etc/exim4/update-exim4.conf.conf
    • Change dc_eximconfig_configtype to 'internet'
    • Change dc_other_hostnames to 'timstyles.me.uk' (use your own domain)
    • Change dc_local_interfaces to
    • Change dc_relay_nets to '192.168.1.0/24'
    • Change dc_use_split_config to 'true'
    • Change dc_localdelivery to 'maildir_home'

The following steps allow support for multiple domains, which I'm not using at the moment:

  • Add the file /etc/exim4/conf.d/router/350_exim4-config_vdom_aliases with the following contents
vdom_aliases:
  driver = redirect
  allow_defer
  allow_fail
  domains = dsearch;/etc/exim4/virtual
  data = ${expand:${lookup{$local_part}lsearch*@{/etc/exim4/virtual/$domain}}}
  retry_use_local_part
  pipe_transport   = address_pipe
  file_transport   = address_file
  no_more
  • Create the directory /etc/exim4/virtual
  • Create a file called timstyles.me.uk within the directory (use your own domain)
  • Add lines such as the following to the file (use your own user account)
hostmaster : tim@localhost
postmaster : tim@localhost
webmaster : tim@localhost
abuse : tim@localhost
root : tim@localhost
admin : tim@localhost

Multiple addresses can be created for the domain by adding them as lines in this file

  • Finally, install a mail client such as mutt and check you can send and receive email.

Installing Mutt

  • Install mutt
  • Edit ~/.muttrc
  • Tell mutt to use Maildir format for email storage
set mbox_type=Maildir
set folder="~/Maildir"
set mask="!^\\.[^.]"
set mbox="~/Maildir"
set spoolfile="~/Maildir"
  • Tell mutt your real name: (use your own name and email address)
set realname="Tim Styles"
set from=tim@timstyles.me.uk
  • I have mutt configured to show only a couple of lines from the header:
ignore *
unignore from date subject to cc
  • I have modified the date format so that the reply attribution looks like "On Mon 20/01/2010 13:45, Tim Styles wrote:"
set date_format="!%a %d/%m/%Y %H:%M"
  • When using multiple email addresses, you can configure mutt to reply from the same address the mail was sent to: (use your own domain)
set use_from
set reverse_name
alternates timstyles.me.uk

You can set your editor as follows (I use nano with aspell for spell checking):

  • Install nano and aspell
  • Add the following to ~/.muttrc
set editor="nano -I -A -S -r 80 -s \"aspell -x -c\""

You can add support for PGP signing as follows:

  • Add the following to ~/.muttrc
set pgp_auto_decode=yes
  • Install gnupg
  • Use "gpg --search-keys <name>" to find the keys of people who sign / encrypt their mail
  • You can also create your own key and use it to sign outgoing mail

Filtering

Mail filters can be added on a per user basis. These are processed by the mail server as the mail is received, and can include rules that cause the mail server to reject the mail as it is being received.

  • Add the line "allow_fail" to /etc/exim4/conf.d/router/600_exim4-config_userforward
  • Create a .forward file in the user directory. The following is an example:
# Exim filter
if error_message then finish endif

# Mail from the server
if $h_To: contains "root@server.timstyles.me.uk" or
   $h_To: contains "admin@timstyles.me.uk"
then save $home/Maildir/.Server/ finish endif

DKIM checking

Exim supports DKIM checking and reports the results in the log file. To take an action on the result:

  • Add the following to /etc/exim4/conf.d/main/02_exim4-config_options
.ifndef MAIN_ACL_CHECK_DKIM
MAIN_ACL_CHECK_DKIM = acl_check_dkim
.endif
acl_smtp_dkim = MAIN_ACL_CHECK_DKIM
  • Create /etc/exim4/conf.d/acl/30_exim4-config_check_dkim containing the following:
acl_check_dkim:
  deny
    message = X-DKIM-Check: Message from $sender_address_domain with invalid or missing signature
    sender_domains = ebay.co.uk:facebookmail.com:flickr.com:gmail.com:linkedin.com:info.paypal.co.uk:yahoogroups.com
    dkim_signers = ebay.co.uk:facebookmail.com:flickr.com:gmail.com:linkedin.com:info.paypal.co.uk:yahoogroups.com
    dkim_status = none:invalid:fail
  accept

ClamAV antivirus

Exim can use ClamAV to scan all mail for viruses as it is received.

  • Install "exim4-daemon-heavy" and "^clamav-daemon$"
  • Edit /etc/exim4/conf.d/main/02_exim4-config_options
    • Uncomment the line starting av_scanner and change it to "av_scanner = clamd:/var/run/clamav/clamd.ctl"
  • Edit /etc/exim4/conf.d/acl/40_exim4-config_check_data
    • Uncomment the lines that reject malware
  • Run "dpkg-reconfigure clamav-base"
    • Accept default answers
    • When asked "Groups for clamav-daemon" enter "Debian-exim"
  • Run "chmod g+ws /var/spool/exim4/scan"

SpamAssassin

SpamAssassin uses a wide variety of local and network tests to identify spam signatures. It is easy to configure and doesn't need updating. I find it reliable enough to simply drop mail identified as spam and let all other mail through. This configuration does not scan outgoing mail.

  • Install spamassassin and sa-exim
  • Edit /etc/exim4/sa-exim.conf
  • Comment out the line "SAEximRunCond: 0" and the default SAEximRunCond line:
# SAEximRunCond: ${if and {{def:sender_host_address} {!eq {$sender_host_address}{127.0.0.1}} {!eq {$sender_host_address}{::1}}}}
  • Uncomment this SAEximRunCond line (we'll set acl_m0 later):
SAEximRunCond: ${if !eq{$acl_m0}{noscan}}
  • Comment out "SApermreject: 12.0"

Spam should never be rejected. It results in backscattering spam i.e. your mail server sends a rejection message to the address the spammer pretended to send from. Since this rejection message is a type of spam, your server will look like a spam source. Don't do it! Simply drop the spam silently or filter it to a Spam folder.

The following lines will prevent the spam checker running on locally generated mail

  • Edit /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt
    • Add the line "set acl_m0 = noscan" after the line "authenticated = *"
    • Add the line "set acl_m0 = noscan" after the line "hosts = :"
    • Add the line "set acl_m0 = noscan" after the line "hosts = +relay_from_hosts"

Finally

  • Edit /etc/default/spamassassin
    • Change ENABLED from 0 to 1

SpamAssassin SPF

The following easy step will allow SpamAssassin to check the SPF record of the sender. It then uses the result when deciding if the email is spam or not.

  • Install libmail-spf-perl
  • Edit /etc/mail/spamassassin/local.cf and add the following line to the beginning:
#   Load the SPF checker
#
loadplugin Mail::SpamAssassin::Plugin::SPF

Configure Courier with Encryption

  • Add this to the bottom of /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs:
.ifndef MAIN_TLS_ENABLE
MAIN_TLS_ENABLE = 1
.endif

# Specify the file containing the private key and signed certificate
.ifndef MAIN_TLS_CERTKEY
MAIN_TLS_CERTKEY = /etc/ssl/server/server.pem
.endif
  • Install the package "^courier-imap-ssl$"
    • Answer "Yes" to creating directories for web-based administration

Create a certificate to validate the server

  • Create the directory /etc/ssl/imap/ and change to it
  • Create a CSR (Use server name for Common Name and use your own domain)
openssl req -newkey rsa:2048 -subj /CN=server.timstyles.me.uk -nodes -keyout imap.key -out imap.csr
  • Go to www.cacert.org and register an account
    • Select "New" from the Server Certificates menu
    • Enter the contents of the www.csr file we just created
    • Place the new certificate in /etc/ssl/imap/imap.crt
cat /etc/ssl/imap/imap.key /etc/ssl/imap/imap.crt > /etc/ssl/imap/imap.pem
openssl gendh >> /etc/ssl/imap/imap.pem
  • Change the following line in /etc/courier/imapd-ssl
TLS_CERTFILE=/etc/ssl/imap/imap.pem
  • Edit /etc/courier/imapd
    • Change IMAP_CHECK_ALL_FOLDERS=1
    • Comment out IMAP_EMPTYTRASH

It is a good idea not to use your login password when checking email. You can create an additional password just for your email:

  • Edit the line in /etc/courier/authdaemonrc
authmodulelist="authuserdb"
  • Change directory to /etc/courier
  • Run the following commands (use your own user name)
server:~# userdbpw -md5 | userdb tim set systempw
server:~# userdb tim set uid gid home mail
server:~# makeuserdb
server:~# /etc/init.d/courier-authdaemon restart

Allow exim to authorize SMTP from external machines:

  • Uncomment the courier-authdaemon sections in /etc/exim4/conf.d/auth/30_exim4-config_examples
  • Allow exim to access the courier authdaemon socket at /var/run/courier/authdaemon/socket
  • Run "adduser Debian-exim daemon"

To work around a current bug where gnutls packet size limit is smaller than all the ca-certificates:

  • Add this to the bottom of /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs:
.ifndef MAIN_TLS_VERIFY_CERTIFICATES
MAIN_TLS_VERIFY_CERTIFICATES = /dev/null
.endif

Web server

This site uses mediawiki, which generates HTML from a set of PHP scripts and a MySQL database. The HTML is then served using the Apache web server. Apache can also serve a static set of web pages, as found at http://server.timstyles.me.uk/. We'll start by setting up a static web site.

  • Install apache2
  • Create a directory for your web pages "mkdir /srv/www" and "mkdir /srv/www/default"
  • Create the default webpage /srv/www/default/index.html with the following contents
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <HTML>
 <HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
    <TITLE>My server</TITLE>
 </HEAD>
 <BODY>
 <H1>My server</H1>
 <A href="http://www.apache.org/">
 <IMG align="middle" height="32" width="259" src="icons/apache_pb2.png" alt="Apache">
 </A>
 </BODY>
 </HTML>
  • Edit /etc/apache2/sites-available/default
    • Add the line "ServerName server.timstyles.me.uk" (setting the domain to your own domain)
    • Change /var/www/ to /srv/www/default/
    • Change error.log to default_error.log
    • Change access.log to default_access.log

Now we'll create an additional virtual web site

  • Change directory to /etc/apache2/sites-available/
  • Copy default to timstyles (using your own domain as the name)
  • Edit timstyles
    • Change server.timstyles.me.uk to www.timstyles.me.uk (using your own domain)
    • Change /var/www/default/ to /srv/www/timstyles/
    • Change default_error.log to timstyles_error.log
    • Change default_access.log to timstyles_access.log

The sites we've created will only be served if they have a link in the sites-enabled directory

  • Change to the /etc/apache2/sites-enabled directory
  • Create symbolic links to the available web sites using:
ls -s ../sites-available/default
ls -s ../sites-available/timstyles
  • Run "/etc/init.d/apache2 restart"

If you point your browser to http://server.timstyles.me.uk/ (setting the domain and machine name to your own) you should see the web page you just created

SquirrelMail Webmail

First install the squirrelmail package, which will provide web pages in /usr/share/squirrelmail/

  • Install the package "^squirrelmail-secure-login$"
  • Run squirrelmail-configure
    • Select D and enter courier as the imap server, then select S to save

We'll create an additional virtual web site based on the default site above

  • Change directory to /etc/apache2/sites-available/
  • Copy default to webmail
  • Edit webmail
  • Add the following lines to the top of the file (setting the domain to your own domain)
 <VirtualHost *:80>
         ServerName webmail.timstyles.me.uk
         Redirect permanent / https://webmail.timstyles.me.uk/
         ErrorLog /var/log/apache2/webmail_error.log
 </VirtualHost>
  • Change the second <VirtualHost *:80> to <VirtualHost *:443>
  • Change server.timstyles.me.uk to webmail.timstyles.me.uk (using your own domain)
  • Add the following lines after the ServerName entry
 SSLEngine on
 SSLCertificateFile /etc/ssl/www/www.crt
 SSLCertificateKeyFile /etc/ssl/www/www.key
 <Location />
         RewriteEngine on
         RewriteCond %{HTTPS} !=on
         RewriteRule .* https://%{HTTP_HOST}:443%{REQUEST_URI} [QSA,R=permanent,L]
 </Location>
  • Change /var/www/default/ to /usr/share/squirrelmail/
  • Change default_error.log to webmail_error.log
  • Change default_access.log to webmail_access.log

The webmail site will not function until we have set up a certificate

  • Change to the /etc/apache2/mods-enabled directory
  • Create symbolic links to the ssl module using:
ln -s ../mods-available/ssl.conf
ln -s ../mods-available/ssl.load
ln -s ../mods-available/rewrite.load
  • Create the directory /etc/ssl/www/ and change to it
  • Create a CSR (Use server name for Common Name and use your own domain)
openssl req -newkey rsa:2048 -subj /CN=webmail.timstyles.me.uk -nodes -keyout www.key -out www.csr
  • Go to www.cacert.org and register an account
  • Select "New" from the Server Certificates menu
  • Enter the contents of the www.csr file we just created
  • Place the new certificate in /etc/ssl/www/www.crt
cat /etc/ssl/www/www.key /etc/ssl/www/www.crt > /etc/ssl/www/www.pem
openssl gendh >> /etc/ssl/www/www.pem
  • Change to the /etc/apache2/sites-enabled directory
ln -s ../sites-available/webmail
  • Run "/etc/init.d/apache2 restart"

If you point your browser to http://webmail.timstyles.me.uk/ (setting the domain to your own domain) you should see the SquirrelMail login page

Webalizer statistics

There are a number of packages able to process the access logs generated by apache and create statistics in HTML. Webalizer is an easy to use package, although there are better options for wiki sites. You can see the current statistics for this site here: http://www.timstyles.me.uk/webalizer/

  • Install "webalizer"
  • Rename /etc/webalizer/webalizer.conf to /etc/webalizer/webalizer_default.conf
  • Edit /etc/webalizer/webalizer_default.conf (these settings assume the apache settings shown above)
    • Change LogFile to /var/log/apache2/default_access.log.1
    • Change OutputDir to /srv/www/default/webalizer
    • Change DNSCache to /etc/webalizer/dns_cache.db
    • Change Incremental to yes and uncomment the line
    • Replace the list of search engines with this Webalizer SearchEngine List
  • Copy /etc/webalizer/webalizer_default.conf to /etc/webalizer/webalizer_timstyles.conf (use your own domain name)
  • Edit /etc/webalizer/webalizer_timstyles.conf (these settings assume the apache settings shown above)
    • Change LogFile to /var/log/apache2/timstyles_access.log.1
    • Change OutputDir to /srv/www/timstyles/webalizer
    • Change HostName to www.timstyles.me.uk (setting the domain to your own domain)
    • Uncomment HideSite and HideReferrer and set it for your own network (use your own domain)
HideSite        192.168.1.*
HideReferrer    www.timstyles.me.uk/

MediaWiki

This site is generated using mediawiki software. This is a set of PHP scripts which store the website contents in an SQL database and a directory of images. It automatically generates and stores thumbnails for images, and the web pages can be edited from anywhere, without the need to edit HTML directly.

  • Install "mediawiki" package
  • Set a password for the MySQL root user
mysqladmin -u root password “newpassword”
  • Restart mysql
/etc/init.d/mysql restart
  • Edit /etc/apache2/sites-available/timstyles and add the contents from /etc/mediawiki/apache.conf (this assumes the virtual site setup described above)
  • Restart apache
/etc/init.d/apache2 restart
  • Go to http://www.timstyles.me.uk/mediawiki/config/ (using your own domain)
  • Fill in the questions and at the bottom of the form:
    • Enable the super user account
    • Superuser name: root
    • Superuser password: password created for MySQL root user
  • Move /var/lib/mediawiki/config/LocalSettings.php to /etc/mediawiki
  • Set the ownership and access on LocalSettings.php
chgrp www-data /etc/mediawiki/LocalSettings.php
chmod o= /etc/mediawiki/LocalSettings.php
  • Remove /var/lib/mediawiki/config for security

See my MediaWiki Tricks page for the other changes I have made to my MediaWiki configuration

Security

Chkrootkit

Chkrootkit performs a number of tests to check for rootkits (viruses). This will send an email if the output changes. I have modified the default script so that restarting packet sniffers such as DHCP servers and darkstat does not trigger an email.

  • Install the package chkrootkit
  • Edit /etc/chkrootkit.conf
    • Change RUN_DAILY="true"
    • Change RUN_DAILY_OPTS="-q -e \"/lib/init/rw/.mdadm /lib/init/rw/.ramfs\""
    • Change DIFF_MODE="true"
  • Add sed to /etc/cron.daily/chkrootkit to filter out the PID of PACKET SNIFFERS:
$CHKROOTKIT $RUN_DAILY_OPTS | sed s/\[[0-9]*\]// > $LOG_DIR/log.new 2>&1

RKhunter

RKhunter performs a number of tests to check for rootkits (viruses). I have disabled the test that checks the versions of applications, since Debian stable only includes security fixes and does not upgrade to the latest version by default.

  • Install the package rkhunter
  • Edit /etc/rkhunter.conf
    • Change ALLOW_SSH_ROOT_USER=yes
    • Remove hidden_procs from DISABLE_TESTS
    • Add apps to DISABLE_TESTS
  • Edit /etc/default/rkhunter
    • Change REPORT_EMAIL="tim@timstyles.me.uk" (use your own email address)

Denyhosts

Denyhosts temporarily blocks IP addresses that try to login via SSH and fail.

  • Install the package denyhosts
  • Edit /etc/denyhosts.conf
    • Change PURGE_DENY to 1d
    • Comment out ADMIN_EMAIL
    • Uncomment RESET_ON_SUCCESS = yes

We can extend this to block all traffic from the IP address as follows:

  • Edit /etc/denyhosts.conf
    • Uncomment and set PLUGIN_DENY=/usr/share/denyhosts/deny
    • Uncomment and set PLUGIN_PURGE=/usr/share/denyhosts/purge
  • Create /usr/share/denyhosts/deny with executable permissions
#! /bin/sh

IPv4=^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$

# If an IPv4 address has been passed in then use it, otherwise try a DNS lookup
if [[ $1 =~ $IPv4 ]]
then HOST_IP_ADDRESS=$1
else HOST_IP_ADDRESS=`dig +short $1 A | sed -n 's/\([0-9\.]\{7,15\}\)/\1/p'`
fi

# Check that we have a valid IPv4 address
if [[ $HOST_IP_ADDRESS =~ $IPv4 ]]
then
  # Look for the IP address in denied list in iptables
  iptables -L denied -n | grep $HOST_IP_ADDRESS

  # If the IP address is not there then add it to the list
  if [ $? -ne 0 ]
  then iptables -A denied -s $HOST_IP_ADDRESS -j DROP ;
  fi
fi
  • Create /usr/share/denyhosts/purge with executable permissions
#! /bin/sh

IPv4=^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$

# If an IPv4 address has been passed in then use it, otherwise try a DNS lookup
if [[ $1 =~ $IPv4 ]]
then HOST_IP_ADDRESS=$1
else HOST_IP_ADDRESS=`dig +short $1 A | sed -n 's/\([0-9\.]\{7,15\}\)/\1/p'`
fi

# Check that we have a valid IPv4 address
if [[ $HOST_IP_ADDRESS =~ $IPv4 ]]
then
  # Remove the IP address from the list
  iptables -D denied -s $HOST_IP_ADDRESS -j DROP
fi
  • Run /etc/init.d/denyhosts restart

Further Tweaks

pcspkr error

If you're seeing the message "Error: Driver 'pcspkr' is already registered" during boot then add the following to /etc/modprobe.d/blacklist

blacklist snd-pcsp
NTP to keep your clock accurate
  • Install "ntp"
  • Add the following to /etc/ntp.conf
restrict 192.168.0.0 mask 255.255.254.0 nomodify notrap
  • Uncomment the line broadcast 192.168.1.255
  • Restart the NTP server
/etc/init.d/ntp restart
RAID management
  • Check the state of the RAID array
cat /proc/mdstat
  • If it shows resync=PENDING then the array is probably readonly, which is OK
  • If you want to allow the array to resync then issue
mdadm --readwrite /dev/md1
Spelling
  • Install the package "^aspell$"
  • Add the following line to .nanorc
set speller "aspell -x -c"
Nano options
set nowrap
set smarthome
set smooth
Other utilities
  • tofrodos fixes line endings when transferring files to and from Windows machines
  • zip allows zip files to be created and accessed
Unnecessary packages
  • The following can be uninstalled
    • qpopper
    • swat