banner Debian GNU/Linux

Linux Small Business Server

Linux for the Small Office - Home Office ?

This is a write-up of an attempt to use Linux as a "Small Business Server". It is primarily a checklist for myself in case I want to repeat this setup and don't remember what I did and how. It also serves as an exploration into Linux system administration, and therefore I've chosen not just to run a GUI installation wizard, but to install and setup everything (more or less) by hand, from the command prompt. More or less, that is. Debian's apt-get and aptitude already take care of a lot of the installation and (pre-)configuration hassle.

An other reason for choosing Debian Linux is that it's free (as in free speech AND free beer), and that, imho, the guys at Debian keep a tight household where it comes to configuration files : the main configuration files for the applications I wanted to install were not very hard to find, and there is a certain logic to their locations.


What we're trying to do here is see whether a base Linux system can be turned into a "Small Business Server" - a server offering roughly the same services as a Microsoft Windows Small Business Server : some basic network services (DHCP, DNS, ... ), (Windows) file and printer sharing - preferably with centralized account management (i.e. a Domain Controller), a mail / groupware service and (optionally - re. Small Business Service Enterprise Edition) a database server. This is loosely related to these papers on system administration in the small business. I imagine that a Linux system could be an alternative for Microsoft Windows - Small Business Server, provided it can offer the following services to (a limited number of) Windows clients :

Ad "Added Value" we can incorporate some features that Microsoft SBS does not offer : a Wiki to serve as document management system or content management system, or the extensive network monitoring tools that Linux and the Open source community have to offer - nmap, nagios and nessus to name just a few.

The way we go about it is to do a quick and dirty but fast setup first : install the stuff, do minimal configuration to get it up and running, and provide a skeleton administration framework. Later, we can expand, elaborate, fine-tune, and optimize.

The assumption is that the Linux Small Business Server and all the clients are on a completely private LAN, with all private IP addresses, connected to the internet by means of a Linux router / firewall / internet gateway. This 'SOHO' setup could also be of use in a home network, e.g. to provide file and printer sharing services / extra storage in a home network. We may look into additional functionality such as offering files for download to remote hosts over the internet or make the website accessible from outside the LAN - e.g. to share pictures, movies and music with friends and relatives.


This is an exercise, and I'm doing this to learn : I may have gotten it all wrong, overlooked important issues, and done things that would freak a seasoned Linux user / administrator out of his/her mind. (if so : let me know).

Although it's entirely possible to do so, it is not necessarily a good idea to implement all of those services on 1 and the same server. Sure, it's convenient, and cheap in hardware, and Linux can handle it no problem, but you might want to split these network services over 2 servers : 1 in your LAN, to provide services to your LAN hosts, and 1 in a DMZ, talking to the internet.


Added Value

the rest :


For the purpose of this exercise, I've just thrown together whatever hardware I had lying around, which resulted in a pc with an Intel Pentium II CPU, 128 MB RAM, a 3com509 ISA PnP NIC and 3 harddisks : 2 GB, 2.5 GB and 5 GB. The 3 hard disks will give us the opportunity to play with partitions, directories and mount points. The Logical Volume Manager (LVM) was tempting as a means to collect the bits and pieces of disk space into a larger volume, but I decided against it : all of this hardware is old, and I don't know what will happen to "Logical Volumes" if one of the member disks/partitions would crash. I suspect the data would be very hard or impossible to recover. With each disk as a separate volume, at least I'd stand a change to recover some data - and as I'm planning to use this server as additional storage in my home LAN, that matters. Of course, in a real live production environment, you wouldn't rely on old hardware, and take the usual disaster recovery precautions : RAID and backups :-)

So, the disks :

The first decision, and a difficult one, is how to partition these disks.There's a lot of discussion about how an ideal disk and partitioning scheme would look, and I won't contribute. I just try it : this way, and see what happens :

hda : 1 partition, mount as /

this will be "everything except other mount points" (see further). For quite a simple system running no applications other than some standard network services, the 2.1 GB should be sufficient, and directories where a lot of disk space is important are moved to the other disks anyway. Some sources recommend separate /usr partition (and /tmp and /var etc.), but as partitions are not flexible, I decided against it : with the rather limited space, I could easily get stuck if a divide the available space into too many partitions;

Then, we take 2 swap partitions, 256 mb on each disk (for performance)

The system is supposed to be a file server, so we will reserve the 3th disk (the largest) for data, and mount it as /srv. '/srv' holds "data served by this systems" so that would be web pages/web sites if this system is a web server, shared files if this system is a file sharing server (samba), etc. This saves space in / (on hda) and avoids that data gets buried somewhere under /var. Subdirectories of /srv are not (yet) standardized so one could imagine subdirectories by service, possible spread across multiple partitions / disks (as illustrated with /srv/db on hdb - see further).

The standard Linux file system (which directory is to be used for what ?) is described in the File System Hierarchy.

for hdb :

The rationale is that we use disk hda as 'system' disk and disks hdb and hdc as 'data' disks. We've put the system in one partition, where as most literature suggests using separate partitions / disks for eg. /var, /usr, /etc. Given the limited size and number of the disks and the difficulties of resizing partitions, I've decided against it.

Again, this makes sense as an exercise, but in real live you'd also have to consider recovery planning, space requirements for log files and temporary files (/var, /tmp ), and performance issues re. the master/slave configuration (use SCSI instead ?). For performance, some sources suggest that you'd put directories that are likely to be used simultaneously, on separate disks / channels / controllers so that disk I/O is parrallelized. That requires insight is the sort of tasks your software will be doing, which parts of the operating system will be involved, etc. Too advanced for me - and probably of marginal importance for a small multi-purpose machine - but something to look into if you want to run servers in somewhat larger production environments.

More about disks, and some more advanced disk configurations such as logical volumes spanning multiple disks, raid configurations, etc.

Disks and partitions also matter when using quota. Quota are disk-specific, so if you assign disk quota to the user home directories and /home is a disk by itself, the quota won't affect a user's use of resources on other disks. This is a good thing : it prevents the quota from interfering with processes, programs, etc. that may require disk space (temp files, printer spools, ...)

the result

The configuration described in the remainder of this page results in disk usage as follows :

	df -h

	Filesystem            Size  Used Avail Use% 	Mounted on
	/dev/hda1             1.9G  680M  1.1G  39% 	/
	/dev/hdb4             1.2G   39K  1.1G   1% 	/home
	/dev/hdb1             447M  353K  423M   1% 	/root
	/dev/hdc2             5.5G   64K  5.2G   1% 	/srv
	/dev/hdb3             447M   14K  423M   1% 	/srv/db

!! The complete system uses less than 700 MB. That leaves us with a comfortable 1+ GB of unused space on the system disk - should cover temporary files, spools, logs etc nicely :-)

Installing the Debian Linux base system

To set up Linux, we download the net install CD (iso image) and use it to boot the machine and start the operating system setup. Additional / updated files will be downloaded during the operating system setup. This obviously requires internet access, so we have to configure the network (ip address, DNS servers, ...). This network configuration will be saved, so we will have to change that again later, when the machine assumes its role of network server.

The setup is quite straightforward. Things to consider :

Then, install ssh (server) and vim. SSH will let us log-in remotely to administer the server (which could then be a monitor-less, keyboard-less machine in the basement - or the server room). and you will at least need a text editor, so vim.

set up FTP service

apt-get install ftpd

We setup ftp so that we can use file transfer to upload modified config files etc. Not much configuration needed : as soon as the ftp daemon is running, users can ftp to their home directly.

configuration files :

More advanced (TO DO) : set up an ftp site : assign 'public' space under /srv where friends/relatives/colleagues can up- and download stuff ?

URL's to browse non-anonymous ftp sites take the form :

set up DHCP service

apt-get install dhcp (alt: aptitude install --with-recommends dhcp)

the dhcp daemon starts right after the installation, but is unconfigured so it will start complaining as well. stop the service (/etc/init.d/dhcp stop) and edit the configuration file : /etc/dhcpd.conf. Then restart the service (/etc/init.d/dhcp start)

The configuration file /etc/dhcpd.conf describes your dhcp service : address pools and options. Options can be set per server or per address range. For a simple single server / single scope setup, the distinction does not make much sense. The dhcp.conf can become rather complex to allow for complex situations, but for a small business, something like this will do fine ;

	# server options _ apply to all ranges

	option domain-name "sillysoft.yx";
	option domain-name-servers;

	option subnet-mask;
	default-lease-time 600;
	max-lease-time 7200;

	# definition of an address range + options for that range

	subnet netmask {

   		range;	#pool of 150 addresses. The rest can be assigned manually, 
							#eg to servers and routers

   		option broadcast-address;
   		option routers;


In stead of dhcp, you may prefer dhcp3, which is more recent, and supports Dynamic Updating of DNS.

	apt-get install dhcp3-server

the configuration file for dhcp3 is /etc/dhcp3/dhcpd.conf

set up DNS service

We want to provide a dns service to our host so that, at least, names of important machines (servers, routers, ...) can be used in stead of ip addresses. A local dns server with forwarding to external dns servers is also (slightly) easier to firewall.

The DNS service is provided by 'named' (name daemon), which is implemented in the 'bind' program. Or something along those lines. Whatever. We apt-get install bind9 bind9-doc dlint lwresd . bind is the dns server, dlint is a tool to gather information on dns zones, and lwresd is an alternative name resolving protocol that some unix applications require. Since we're going to be serving Windows clients we don't really need that.

DNS is rather more complex than ftp or dhcp, and this is reflected in the configuration files :

named.conf describes the configuration of the dns server proper. In fact, named.conf is composed of 3 separate files :
default configuration that every dns server needs. No need to change anything here - except if you really know what you're doing.
  • As your dns server will be serving your local network, it will need to get information about dns names and ip addresses of external machines elsewhere. By putting the DNS servers of your ISP as 'forwarders' in options, your DNS server can get that information there and serve it to the hosts on your network. Ideally, you'd use a caching dns on your DMZ as a forwarder, so that there is no direct communication from the Linux SBS server to the internet.
  • Here, you can also set the source port that the DNS server will use when querying other dns servers. You need to set this, and adjust your firewall rules accordingly, or the forwarders will be unreachable from behind your firewall.
local configuration, i.e. the dns zone(s) relevant to your home/small office network

These configuration files define dns zones, and then refer to 'dns zone files', the actual dns databases that hold the resource records (start of authority record, address records, ...) of 1 zone each.
zone files :
you can choose whatever name for these files, as long as they are referenced by that name in the named.conf file(s). You'll need at least 1, probably 2 and most likely more than 2 zone files :
forward lookup zone - eg. mylan
indicates that this server is authoritative for 'mylan', and maps hostnames of 'mylan' to their IP addresses
reverse lookup zone. contains pointer records (PTR) that map IP addresses in the given range back to host names
other zones
there is also the localzone, where localhost lives, and the corresponding 127 reverse lookup zone, and a bunch of other zones that exist on any dns server.

So what you need to do here is create at least a forward and reverse lookup zone file, mention those in /etc/bind/named.conf.local, and put some external dns servers in /etc/bind/named.conf.options. Refer to basic dns configuration here. At this point, the server can act as its own dns server, so the references to external dns servers in resolv.conf can be removed.

Then, finally, you need to tell the server to reload the databases - or restart the dns service for all changes to take effect :

	rndc reload  || /etc/init.d/bind9 restart


Dynamic Update DNS

Once you have dns and dhcp working, you can configure dns and dhcp so that the dns records are updated automatically, either by the clients or by the dhcp server : Configuring Dynamic DNS & DHCP on Debian. Be sure you start by upgrading to dhcp3 and bind9.

time server

As you are going to be serving to a network, you might as well include a time server. This server will offer an accurate time to the hosts on your network, for them to synchronize with so that all computers on the network have exactly the same time. It's a 'nice to have' thingy in a lot of cases, but might become more important in cases you need an accurate "last modified" timestamp, e.g. when comparing versions or when having to restore a backup. Some authentication methods also use time and require the system time on the client and on the authentication server to be synchronized. Log files across your network will have accurate and reliable times. And so on.

This server will provide a time server to its clients (that might need some configuration in order to use the server to synchronize their clocks). In order to give accurate time, the server itself needs to synchronize with a reliable time source. On the internet, there are time servers that can provide this servers ("stratum 1 time servers"). Just google to find them.

To set up a time server, apt-get install ntp-simple ntp-server ntp . The configuration file is /etc/ntp.conf. You need to at least specify a server that your server will use as its reference (IP address or Fully qualified DNS name), and tell the server to which subnet its clients belong (they'll receive broadcasts to synchronize). see also man ntpd and this page. /etc/init.d/ntp-server restart will activate the server.

	server ntp.server.example

set up Windows File and Printer Sharing with Samba

Samba is probably the most interesting server for a small business or home network : it provides file sharing services so that you can store files on a central server, accessible to windows clients, without having to deal with (expensive) Windows Server licenses and client access licenses. Samba can do simple file serving, or can function as a domain controller in a simple domain context (single domain, no subdomains, ...), which is more than sufficient for most small businesses.

To install samba, we apt-get install the following packages :

during the installation of samba, we are prompted for the following input :

These values are saved to samba's main configuration file : /etc/samba/smb.conf. File and Printer sharing - and all other configuration - is done by adding the appropriate sections, keywords and values to this file. By default, the section [homes] will make the user's home directory available via the Windows Network Neighborhood. Other share's we'll have to define ourselves. This also requires us to create samba user accounts with smbpasswd -a <username> .

samba >> setting up shares and create users >> Samba as a File Server in a Windows Active Directory Domain >> Managing access control on shared files and directories >> advanced configuration, samba as Domain Controller

restart the samba daemons to load the new configuration : /etc/init.d/samba restart

For file sharing between Linux servers, the Linux (Unix) Network File System (NFS) is a better alternative : easier to set up, and pretty transparent.

set up an internet/intranet server with Apache Web Server

To install Apache, we apt-get install the following packages :

The configuration of the www server is found in /etc/apache2/apache2.conf. This file will refer to a 'directory root' or to virtual directories which will be the root of the hosted websites, . Running a (well configured) web server is rather complex : it's publicly accessible, so security is a major issue, and if you're running a 'real' web server, you'll be hosting multiple, most likely dynamic, database-driven web sites with server site scripts and what not.

We've just included a web server in our Small Business Server to allow our small office to run an intranet site - and it's not too complex just to get an intranet with Apache web server up and running. When that is done, you can make it more dynamic with apache, mysql and php, and possibly build a wiki on top of it.

set up a mail server

Mail on Linux (or Unix) is about as old as the internet itself. The first mail systems would simply drop text files (the mail messages) into a designated directory (the mailbox) on a given computer where the user could go and read them. Over time, additional tools were developed to add functionality and features. In true Unix style, a Linux 'mail system' consists of a collection of tools that work together to provide an email service.

Debian offers Exim as Mail Transfer Agent (MTA, the actual 'mail server'). You'll want to combine that with some other programs to offer webmail, IMAP, or POP accounts. Then, there are about a 100 ways to configure a mail server - it all depends on your network design and how you want to send and receive mail.

For the mail server (MTA, mail transfer agent) to work properly, it needs to be configured - and for it to allow scanning, it needs to be configured differently. We'll have a first look at that in a simple Linux mail server

To adequately mimic the Exchange server in Microsoft's Small Business Server, we need to include Groupware functionality.

set up a network fax server

No one uses faxes anymore. Everyone has email, right ? Still, occasionally, you find that the only way to get a document to a remote destination, is by fax. So you type up your message in a text processor, print it, find a fax machine, and fax it. That is, if you still can find a fax machine nearby.

Running a network fax server solves many of those problems. The server act as a fax machine - you connect it to a phone line by means of a modem. It's a network server, so you only need one machine for multiple clients. These clients create a document (in any application that you can print from), and you "print to fax". This is as easy as printing, except that the 'print' dialog will ask for a fax number. The fax server will receive this "print" job, and send it to the given number.

A fax server can also handle incoming faxes, and print them, or convert them to email + attachments and forward them to predefined email addresses. If you have a PBX, you can have multiple fax numbers rerouted to the same fax server, and you can route the resulting email to multiple destinations. We won't go in to that, and content ourselves with sending faxes. After all, we do have email.

Server setup

Client setup

Install a Hylafax Client on the PC's that need fax functionality. The Hylafax website has a list of fax clients for Linux, Mac and Windows. For Linux clients, you may want to base your choice on desktop integration (Gnome ? KDE ? ), integration with printing (CUPS) and Printer and File Sharing technology (Samba), or compatibility with user management software (LDAP, Samba as domain controller, MS Windows Active Directory), and so on.

WinPrint Hylafax looks like a easy to use, easy to set up 'print to fax' tool for Windows.

set up a database server with mySQL

apt-get install mysql-server mysql-client

This installs the mysql database server and a number of tools you can use to create databases. Of course, a database server is just sitting there doing nothing until you tell it what to do : you'll need to configure it, and create databases to make it usefull. see MySQL basic configuration.

In any case, set a password for the mysql 'root' administrator !

	#check that mysql daemon is up and running :	(alt: mysql ->status)
	/usr/bin/mysqladmin -s

	#set a root password
	/usr/bin/mysqladmin -u root password 'enter-your-good-new-password-here'

	less /usr/share/doc/mysql-server/README.Debian

You can ignore the warning about modifying the host file - Debian takes care of that all by itself. (check : less /etc/hosts)

set up user accounts

Because we want to limit access to the samba shares to authenticated users, we need to create both unix accounts and samba accounts for every user. It thus makes sense to create a script that takes us through the motions, lest we forget something. Here's a very primitive script - it really needs more work but it will have to do for now :

	# very basic script to add users listed in file 'userlist'
	# advantage : 
	#	creates both unix and samba accounts, 
	#	allows some standardization, eg. create homedir, set "no shell", group membership
	#	to do : find elegant yet secure way of providing passwords

	for user in $(cat userlist) ; do

		echo ""
		echo unix and samba accounts for $user
		# add unix user, create home directory, set password 
		# set shell to nothing (/bin/false) so user can only access through applications (ftp, smb, http, ...)
		useradd -s /bin/false -m $user
		passwd $user

		# create samba account and add user to unix group smbusers for filesystem security configuration
		smbpasswd -a $user
		usermod -g smbusers $user

		echo ""


Note that you will be prompted for passwords. Alternatively, you can leave the passwords blank and disable the accounts (see man pages for relevant command switches). It should also be possible to create encrypted passwords (man mkpasswd) and include those in the useradd commands ( -p <encrypted_password>) ...

Last bits

post-installation tasks

When we installed Debian, we decided to install only a base system, then pick and choose the software we need. Of course, we could list our selection in a script - a first step towards an unattended customized installation maybe ? This script could also take care of some bits and pieces of configuration (create a directory here, set some permissions there, ...) that we might otherwise overlook. Makes the setup reproducible without human error. Here's a start :

	# install stuff we need / want anyway 
	apt-get install aptitude vim ssh hdparm apm apmd

	# /root is a home directory, but we don't want other users coming there (through samba or so)
	chmod 700 /root

	# create directories
	mkdir /srv/smb			#samba file share root
					#see also ; samba user permissions

	# here you can list the services / applications you want your soho / small business server to run.
	# be aware that running services without further configuration me put holes in security
	# apt will try to pre-configure and ask input.
	# comment out the lines you don't want.
	aptitude update
	aptitude install --with-recommends ftpd
	aptitude install --with-recommends dhcp
	aptitude install --with-recommends bind9 bind9-doc dlint #lwresd	#dns server 'named' + docs + tools
	aptitude install --with-recommends samba samba-doc smbclient smbfs swat #file server 'samba' + docs + tools
	aptitude install --with-recommends apache				#www server 'Apache'
	aptitude install --with-recommends exim4				#just the mail server
										#then: the mail filtering stuff
	aptitude install --with-recommends spamassassin clamav-freshclam clamav mailscanner

	aptitude install --with-recommends mysql-server

	# aptitude install --with-recommends anything else ?

	# aptitude install --with-recommends squid	#consider squid proxy server. 
							#better : proxy in DMZ or on firewall host


You may also consider adding a minimalistic GUI : by adding an X-windows system and a web browser, you can use the web front-end that some servers provide (swat, webadmin). This will add 200-250 mb to your installation.

Also handy : apt-get install webmin . webmin is a web front-end for Linux (Unix) system administration. It listens on tcp port 10000 by default, so with http://yourservername:10000 you can administer you server from a browser anywhere on your LAN.

power management

As the machine is always on, you can reduce power consumption and wear & tear by applying power management. Support for Power Management is rather machine-specific. In any case, you could install apm and apmd (power management modules) and hdparm (tool to send ATA commands / parameters to the hard disks. With apm/apmd you can let your computer go in stand-by or suspend mode and things like that. with hdparm, you can set, a.o., the 'idle time-out' for hard disks : stop them from spinning while not being used.

here's a sample script that set the idle time-out for all 3 disks to 1 hour. With a symbolic link in the appropriate run-level directory, it will be re-activated at every system reboot.

		hdparm -S242 /dev/hda;
		hdparm -S242 /dev/hdb;
		hdparm -S242 /dev/hdc;
		# 'man hdparm' for an explanation on how -S 242 [hopefully] results in a timeout of 1 hour  :-)

You can also put them in /etc/hdparm.conf as

	command_line { 
		hdparm [options]

no monitor, no keyboard

As this is a server, you can have it always on and put it somewhere safe, where it doesn't bother anyone, and where noone messes with it. In the basement. In the server room. In the attic. With ssh, you'll be able to log in remotely, so you don't need monitor or keyboard. Check the machine's BIOS setup to enable features such as 'keyboardless operation' or disable 'halt on all errors': a missing keyboard could cause an error in the POST, and you want the machine to continue booting nonetheless.

backups and shortcuts

dhcp.conf, ftpusers, the dns config and zone files, ... make up the configuration of our small business server, and it would be a good idea to back them up, so that the can be restored to a new system if ever this server would give up. So, for starters, we will want to keep a copy elsewhere - away from the / partition in case we need to re-install the system. The /root directory could be a good idea. We can also create 'shortcuts' (symbolic links) there so we can find them back quickly.

	# symlinks to config files

	mkdir /root/links
	ln -s /etc/dhcp.conf /root/links/dhcp.conf
	ln -s /etc/ftpusers /root/links/ftpusers
	ln -s /etc/ftpchroot /root/links/ftpchroot
	#[and so on]

	# make copies of config files

	mkdir /root/bu

	cp /etc/dhcp.conf /root/bu/dhcp.conf
	cp /etc/ftpusers /root/bu/ftpusers
	cp /etc/ftpchroot /root/bu/ftpchroot
	#[and so on]

Koen Noens
October 2005