Saturday, October 16, 2010

Fedora 8 Server Setup: LAMP, Email, DNS, FTP, ISPConfig (a.k.a. The Perfect Server)

This is a detailed description about how to set up a Fedora 8 server that offers all services needed by ISPs and hosters: Apache web server (SSL-capable), Postfix mail server with SMTP-AUTH and TLS, BIND DNS server, Proftpd FTP server, MySQL server, Dovecot POP3/IMAP, Quota, Firewall, etc. This tutorial is written for the 32-bit version of Fedora 8, but should apply to the 64-bit version with very little modifications as well.

I will use the following software:

  • Web Server: Apache 2.2.6
  • PHP 5.2.4
  • Database Server: MySQL 5.0.45
  • Mail Server: Postfix
  • DNS Server: BIND9 (chrooted)
  • FTP Server: proftpd
  • POP3/IMAP server: Dovecot
  • Webalizer for web site statistics

In the end you should have a system that works reliably, and if you like you can install the free webhosting control panel ISPConfig (i.e., ISPConfig runs on it out of the box).

I want to say first that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!


1 Requirements

To install such a system you will need the following:


2 Preliminary Note

In this tutorial I use the hostname server1.example.com with the IP address 192.168.0.100 and the gateway192.168.0.1. These settings might differ for you, so you have to replace them where appropriate.

3 Install The Base System

Boot from your Fedora 8 DVD. Select Install or upgrade an existing system:

It can take a long time to test the installation media so we skip this test here:

The welcome screen of the Fedora installer appears. Click on Next:

Choose your language next:


Select your keyboard layout:


I'm installing Fedora 8 on a fresh system, so I answer Yes to the question Would you like to initialize this drive, erasing ALL DATA?:


Next we do the partitioning. Select Remove Linux partitions on selected drives and create default layout. This will give you a smalll /boot partition and a large / partition which is fine for our purposes:


We want to remove all Linux partitions (remember, this is a fresh system), so we answer Yes to the following question:


On to the network settings. The default setting here is to configure the network interfaces with DHCP, but we are installing a server, so static IP addresses are not a bad idea... Click on the Edit button at the top right:


In the window that pops up select Enable IPv4 support > Manual configuration and give your network card a static IP address and netmask (in this tutorial I'm using the IP address 192.168.0.100 and netmask 255.255.255.0 for demonstration purposes; if you are not sure about the right values, http://www.subnetmask.info might help you). Uncheck Enable IPv6 support:


Set the hostname manually, e.g. server1.example.com, and enter a gateway (e.g. 192.168.0.1) and two DNS servers (e.g. 213.191.92.86 and 193.174.32.18):


Give root a password:


Now we select the software we want to install. Uncheck Office and Productivity and check Software Development andWeb server instead. Then check Customize now, and click on Next:


Now we must select the package groups we want to install. Select Editors, Text-based Internet, Development Libraries, Development Tools, DNS Name Server, FTP Server, Mail Server, MySQL Database, Server Configuration Tools, Web Server, Administration Tools, Base, Hardware Support, Java, System Tools (unselect all other package groups) and click on Next:


The installer checks the dependencies of the selected packages:

Click on Next to start the installation:


The hard drive is being formatted:


The installation begins. This will take a few minutes:


Afterwards, the GRUB bootloader gets installed:


Finally, the installation is complete, and you can remove your DVD from the computer and reboot it:


After the reboot, you will see this screen. Leave it by hitting Exit:


Now, on to the configuration...

# Do not remove the following line, or various programs # that require network functionality will fail. 127.0.0.1               localhost.localdomain localhost 192.168.0.100           server1.example.com server1 ::1             localhost6.localdomain6 localhost6

It is important that you add a line for server1.example.com and remove server1.example.com and server1 from the127.0.0.1 line.

5 Configure Additional IP Addresses

(This section is totally optional. It just shows how to add additional IP addresses to your network interface eth0 if you need more than one IP address. If you're fine with one IP address, you can skip this section.)

Let's assume our network interface is eth0. Then there is a file /etc/sysconfig/network-scripts/ifcfg-eth0 which looks like this:

cat /etc/sysconfig/network-scripts/ifcfg-eth0

# Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.0.255 HWADDR=00:0C:29:08:8F:8E IPADDR=192.168.0.100 NETMASK=255.255.255.0 NETWORK=192.168.0.0 ONBOOT=yes

Now we want to create the virtual interface eth0:0 with the IP address 192.168.0.101. All we have to do is to create the file /etc/sysconfig/network-scripts/ifcfg-eth0:0 which looks like this (we can leave out the HWADDR line as it is the same physical network card):

vi /etc/sysconfig/network-scripts/ifcfg-eth0:0

DEVICE=eth0:0 BOOTPROTO=static BROADCAST=192.168.0.255 IPADDR=192.168.0.101 NETMASK=255.255.255.0 NETWORK=192.168.0.0 ONBOOT=yes

Afterwards we have to restart the network:

/etc/init.d/network restart

You might also want to adjust /etc/hosts after you have added new IP addresses, although this is not necessary.

Now run

ifconfig

You should now see your new IP address in the output:

[root@server1 ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:08:8F:8E
inet addr:192.168.0.100 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe08:8f8e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:327 errors:0 dropped:0 overruns:0 frame:0
TX packets:337 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:28434 (27.7 KiB) TX bytes:56947 (55.6 KiB)
Interrupt:17 Base address:0x1400

eth0:0 Link encap:Ethernet HWaddr 00:0C:29:08:8F:8E
inet addr:192.168.0.101 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Interrupt:17 Base address:0x1400

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 b) TX bytes:560 (560.0 b)

[root@server1 ~]#


6 Configure The Firewall

I want to install ISPConfig at the end of this tutorial which comes with its own firewall. That's why I disable the default Fedora firewall now. Of course, you are free to leave it on and configure it to your needs (but then you shouldn't use any other firewall later on as it will most probably interfere with the Fedora firewall).

Run

system-config-securitylevel

Click to enlarge

Select Disabled and press OK.

To check that the firewall has really been disabled, you can run

iptables -L

afterwards. The output should look like this:

[root@server1 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@server1 ~]#

7 Disable SELinux

SELinux is a security extension of Fedora that should provide extended security. In my opinion you don't need it to configure a secure system, and it usually causes more problems than advantages (think of it after you have done a week of trouble-shooting because some service wasn't working as expected, and then you find out that everything was ok, only SELinux was causing the problem). Therefore I disable it (this is a must if you want to install ISPConfig later on).

Edit /etc/selinux/config and set SELINUX=disabled:

vi /etc/selinux/config

# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: #       enforcing - SELinux security policy is enforced. #       permissive - SELinux prints warnings instead of enforcing. #       disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of these two values: #       targeted - Targeted processes are protected, #       mls - Multi Level Security protection. SELINUXTYPE=targeted # SETLOCALDEFS= Check local definition changes SETLOCALDEFS=0  

Afterwards we must reboot the system:

shutdown -r now

8 Install Some Software

First we import the GPG keys for software packages:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*

Then we update our existing packages on the system:

yum update

Now we install some software packages that are needed later on:

yum install fetchmail wget bzip2 unzip zip nmap openssl lynx fileutils ncftp gcc gcc-c++

To install quota, we run this command:

yum install quota

Edit /etc/fstab and add ,usrquota,grpquota to the / partition (/dev/VolGroup00/LogVol00):

vi /etc/fstab

/dev/VolGroup00/LogVol00 /                       ext3    defaults,usrquota,grpquota        1 1 LABEL=/boot             /boot                   ext3    defaults        1 2 tmpfs                   /dev/shm                tmpfs   defaults        0 0 devpts                  /dev/pts                devpts  gid=5,mode=620  0 0 sysfs                   /sys                    sysfs   defaults        0 0 proc                    /proc                   proc    defaults        0 0 /dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0

Then run

touch /aquota.user /aquota.group
chmod 600 /aquota.*
mount -o remount /
quotacheck -avugm
quotaon -avug

to enable quota.

10 Install A Chrooted DNS Server (BIND9)

To install a chrooted BIND9, we do this:

yum install bind-chroot

Next, we change a few permissions and start BIND:

chmod 755 /var/named/
chmod 775 /var/named/chroot/
chmod 775 /var/named/chroot/var/
chmod 775 /var/named/chroot/var/named/
chmod 775 /var/named/chroot/var/run/
chmod 777 /var/named/chroot/var/run/named/
cd /var/named/chroot/var/named/
ln -s ../../ chroot
chkconfig --levels 235 named on
/etc/init.d/named start

BIND will run in a chroot jail under /var/named/chroot/var/named/. I will use ISPConfig to configure BIND (zones, etc.).

11 MySQL (5.0)

To install MySQL, we do this:

yum install mysql mysql-devel mysql-server

Then we create the system startup links for MySQL (so that MySQL starts automatically whenever the system boots) and start the MySQL server:

chkconfig --levels 235 mysqld on
/etc/init.d/mysqld start

Now check that networking is enabled. Run

netstat -tap | grep mysql

It should show something like this:

[root@server1 named]# netstat -tap | grep mysql
tcp 0 0 *:mysql *:* LISTEN 2059/mysqld
[root@server1 named]#

Click here to find out more!

If it does not, edit /etc/my.cnf and comment out the option skip-networking:

vi /etc/my.cnf

[...] #skip-networking [...]

and restart your MySQL server:

/etc/init.d/mysqld restart

Run

mysqladmin -u root password yourrootsqlpassword
mysqladmin -h server1.example.com -u root password yourrootsqlpassword

to set a password for the user root (otherwise anybody can access your MySQL database!).

2 Postfix With SMTP-AUTH And TLS

Now we install Postfix and Dovecot (Dovecot will be our POP3/IMAP server):

yum install cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi cyrus-sasl-md5 cyrus-sasl-plain postfix dovecot

Now we configure SMTP-AUTH and TLS:

postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
postconf -e 'inet_interfaces = all'
postconf -e 'mynetworks = 127.0.0.0/8'

We must edit /usr/lib/sasl2/smtpd.conf so that Postfix allows PLAIN and LOGIN logins. It should look like this:

vi /usr/lib/sasl2/smtpd.conf

pwcheck_method: saslauthd mech_list: plain login

Afterwards we create the certificates for TLS:

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024

chmod 600 smtpd.key
openssl req -new -key smtpd.key -out smtpd.csr

openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt

openssl rsa -in smtpd.key -out smtpd.key.unencrypted

mv -f smtpd.key.unencrypted smtpd.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

Next we configure Postfix for TLS:

postconf -e 'smtpd_tls_auth_only = no'
postconf -e 'smtp_use_tls = yes'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt'
postconf -e 'smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
postconf -e 'tls_random_source = dev:/dev/urandom'
postconf -e 'smtpd_sasl_authenticated_header = yes'

Then we set the hostname in our Postfix installation (make sure you replace server1.example.com with your own hostname):

postconf -e 'myhostname = server1.example.com'

After these configuration steps you should now have a /etc/postfix/main.cf that looks like this (I have removed all comments from it):

cat /etc/postfix/main.cf

queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/libexec/postfix mail_owner = postfix inet_interfaces = all mydestination = $myhostname, localhost.$mydomain, localhost unknown_local_recipient_reject_code = 550 alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases debug_peer_level = 2 debugger_command =          PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin          xxgdb $daemon_directory/$process_name $process_id & sleep 5  sendmail_path = /usr/sbin/sendmail.postfix newaliases_path = /usr/bin/newaliases.postfix mailq_path = /usr/bin/mailq.postfix setgid_group = postdrop html_directory = no manpage_directory = /usr/share/man sample_directory = /usr/share/doc/postfix-2.4.5/samples readme_directory = /usr/share/doc/postfix-2.4.5/README_FILES smtpd_sasl_local_domain = smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination mynetworks = 127.0.0.0/8 smtpd_tls_auth_only = no smtp_use_tls = yes smtpd_use_tls = yes smtp_tls_note_starttls_offer = yes smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom smtpd_sasl_authenticated_header = yes myhostname = server1.example.com

Now start Postfix, saslauthd, and Dovecot:

Click here to find out more!

chkconfig --levels 235 sendmail off
chkconfig --levels 235 postfix on
chkconfig --levels 235 saslauthd on
chkconfig --levels 235 dovecot on
/etc/init.d/sendmail stop
/etc/init.d/postfix start
/etc/init.d/saslauthd start
/etc/init.d/dovecot start

To see if SMTP-AUTH and TLS work properly now run the following command:

telnet localhost 25

After you have established the connection to your Postfix mail server type

ehlo localhost

If you see the lines

250-STARTTLS

and

250-AUTH LOGIN PLAIN

everything is fine.

[root@server1 ssl]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 server1.example.com ESMTP Postfix
ehlo localhost
250-server1.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit
221 2.0.0 Bye
Connection closed by foreign host.
[root@server1 ssl]#

Type

quit

to return to the system's shell.

12.1 Maildir

Dovecot uses Maildir format (not mbox), so if you install ISPConfig on the server, please make sure you enable Maildir under Management -> Server -> Settings -> Email. ISPConfig will then do the necessary configuration.

If you do not want to install ISPConfig, then you must configure Postfix to deliver emails to a user's Maildir (you can also do this if you use ISPConfig - it doesn't hurt ;-)):

postconf -e 'home_mailbox = Maildir/'
postconf -e 'mailbox_command ='
/etc/init.d/postfix restart

13 Apache2 With PHP5

Now we install Apache with PHP5 (this is PHP 5.2.4):

yum install php php-devel php-gd php-imap php-ldap php-mysql php-odbc php-pear php-xml php-xmlrpc curl curl-devel perl-libwww-perl ImageMagick libxml2 libxml2-devel

Then edit /etc/httpd/conf/httpd.conf:

vi /etc/httpd/conf/httpd.conf

and change DirectoryIndex to

[...] DirectoryIndex index.html index.htm index.shtml index.cgi index.php index.php3 index.pl [...]

Now configure your system to start Apache at boot time:

chkconfig --levels 235 httpd on

Start Apache:

/etc/init.d/httpd start

13.1 Disable PHP Globally

(If you do not plan to install ISPConfig on this server, please skip this section!)

In ISPConfig you will configure PHP on a per-website basis, i.e. you can specify which website can run PHP scripts and which one cannot. This can only work if PHP is disabled globally because otherwise all websites would be able to run PHP scripts, no matter what you specify in ISPConfig.

To disable PHP globally, we edit /etc/httpd/conf.d/php.conf and comment out the AddHandler and AddType lines:

vi /etc/httpd/conf.d/php.conf

# # PHP is an HTML-embedded scripting language which attempts to make it # easy for developers to write dynamically generated webpages. #  LoadModule php5_module modules/libphp5.so  # # Cause the PHP interpreter to handle files with a .php extension. # #AddHandler php5-script .php #AddType text/html .php  # # Add index.php to the list of files that will be served as directory # indexes. # DirectoryIndex index.php  # # Uncomment the following line to allow PHP to pretty-print .phps # files as PHP source code: # #AddType application/x-httpd-php-source .phps

Afterwards we restart Apache:

/etc/init.d/httpd restart

14 ProFTPd (Part 1)

ISPConfig has better support for proftpd than vsftpd, so let's remove vsftpd and install proftpd:

yum remove vsftpd

yum install proftpd

Now we can create the system startup links for Proftpd and start it:

chkconfig --levels 235 proftpd on
/etc/init.d/proftpd start

15 Webalizer

To install webalizer, just run

yum install webalizer

16 Synchronize The System Clock

If you want to have the system clock synchronized with an NTP server do the following:

yum install ntp

chkconfig --levels 235 ntpd on
ntpdate 0.pool.ntp.org
/etc/init.d/ntpd start

17 Install Some Perl Modules

ISPConfig comes with SpamAssassin which needs a few Perl modules to work. We install the required Perl modules with a single command:

yum install perl-HTML-Parser perl-DBI perl-Net-DNS perl-Digest-SHA1

18 The End

The configuration of the server is now finished, and if you wish you can now install ISPConfig on it, following these instructions: http://www.ispconfig.org/manual_installation.htm

18.1 A Note On SuExec

If you want to run CGI scripts under suExec, you should specify /var/www as the web root for websites created by ISPConfig as Fedora's suExec is compiled with /var/www as Doc_Root. Run

/usr/sbin/suexec -V

and the output should look like this:

[root@server1 ~]# /usr/sbin/suexec -V
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=100
-D AP_HTTPD_USER="apache"
-D AP_LOG_EXEC="/var/log/httpd/suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=500
-D AP_USERDIR_SUFFIX="public_html"
[root@server1 ~]#

So if you want to use suExec with ISPconfig, don't change the default web root (which is /var/www) if you use expert mode during the ISPConfig installation (in standard mode you can't change the web root anyway so you'll be able to use suExec in any case).

18.2 ProFTPd (Part 2)

(This chapter applies only if you have installed ISPConfig!)

After you have installed ISPConfig, you must modify the template file for /etc/proftpd_ispconfig.conf which is called/root/ispconfig/isp/conf/proftpd_ispconfig.conf.master, because otherwise the users that you create with ISPConfig won't be able to log in using FTP. Instead of modifying/root/ispconfig/isp/conf/proftpd_ispconfig.conf.master (which gets overwritten each time you update ISPConfig) we copy /root/ispconfig/isp/conf/proftpd_ispconfig.conf.master to/root/ispconfig/isp/conf/customized_templates/ and modify that one. If ISPConfig finds a template in/root/ispconfig/isp/conf/customized_templates/, it will use that one instead of the default template in/root/ispconfig/isp/conf/. Templates in /root/ispconfig/isp/conf/customized_templates/ don't get overwritten when you update ISPConfig.

Click here to find out more!

cp /root/ispconfig/isp/conf/proftpd_ispconfig.conf.master /root/ispconfig/isp/conf/customized_templates/

Now open /root/ispconfig/isp/conf/customized_templates/proftpd_ispconfig.conf.master and comment out theDefaultAddress 127.0.0.1 line:

vi /root/ispconfig/isp/conf/customized_templates/proftpd_ispconfig.conf.master

################################### # # ISPConfig proftpd Configuration File #         Version 1.0 # ###################################  #DefaultAddress 127.0.0.1            DefaultRoot             ~         AllowOverwrite          on         Umask                   002         {ANON_FTP}