Enabling Services - Securing Your System - Hacking Ubuntu (2007)

Hacking Ubuntu (2007)

Part IV: Securing Your System

Chapter 12: Enabling Services

Ifind it somewhat ironic that the final chapter in this book covers turning on essential network servers such as FTP, e-mail, and the web. Part I of this book covers installation and system tweaking, mainly focusing on the local system, not network services. Part II discusses collaboration systems, where your Ubuntu system primarily operates as a client and details some services such as SMB, SSH, SOCKS, and LPD. Part III aims at improving performance, but not network services. That leaves Part IV. In Chapters 10 and 11, I show you how to lock down your system and network. In this chapter, I show you how to open it up.

Any time you make a network service externally accessible, you open yourself up to a possible network attack. For this reason, it is very important to know exactly what services you are offering and to limit access to only the services you explicitly want to offer. You will also want to monitor your system for possible threats. Basic network services, like web and e-mail systems, should expect to receive literally hundreds of probes and attack attempts per day. As luck usually has it, the day you stop monitoring for these events will be the day one of them becomes successful in compromising your system.

Finally, when you understand the risks and how to handle them, you should feel confident enough to open a network service to other people, including everyone on the Internet. Common services that you will probably want to run include SSH, FTP, e-mail, and web servers.


While booting from a USB drive is arguably the most difficult hack in this book (see Chapter 1), opening a network service (especially to the Internet) is the most dangerous. The question is not "will you be attacked?"-you will. You will probably be probed and attacked within a few hours, and the attempts will never end. Eventually some attack method may succeed. The only real question is, "when will you notice?"

Understanding the Ubuntu Default Services

Ubuntu has a simple default setting: no default network services. Although software firewalls are not configured (see Chapter 11), they are also not needed until you begin turning on services.

Although externally accessible services are disabled, some programs do use network connections to communicate between processes on the same system. For example, X-Windows uses some local network connections to communicate between applications. There are two common ways to identify what services are running: netstat and nmap.

Using netstat

As mentioned in Chapter 7, the netstat command provides useful statistics about the network interfaces on your system. Besides summarizing traffic flows, netstat can also show established network connections and open network services. Running the command all by itself generates a long list of current TCP, UDP (datagram), and Unix sockets.


The netstat command usually generates a large amount of data. You should pipe the output into a pager such as more or less. (The less command is similar to more, but enables you to scroll backwards.)

$ netstat | more

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 0 marvin.local.lan:55419 bugs.local.lan:ssh ESTABLISHED

tcp 0 0 localhost:44235 localhost:46274 ESTABLISHED

tcp 0 0 marvin.local.lan:38446 foghorn.local.lan:ssh ESTABLISHED

tcp 0 0 localhost:46274 localhost:44235 ESTABLISHED

tcp6 0 0 chutney.local.lan:ssh foghorn.local.lan:1074 ESTABLISHED

Active UNIX domain sockets (w/o servers)

Proto RefCnt Flags Type State I-Node Path

unix 4 [ ] DGRAM 13124361 /dev/log

unix 2 [ ] DGRAM 5610 @/org/kernel/udev/udevd

unix 2 [ ] DGRAM 12548 @/org/freedesktop/hal/u


unix 2 [ ] DGRAM 13232791

unix 2 [ ] DGRAM 13198909

unix 2 [ ] DGRAM 13124142

unix 3 [ ] STREAM CONNECTED 13123939 /var/run/cups/cups.sock

unix 3 [ ] STREAM CONNECTED 13123938

unix 2 [ ] DGRAM 13123531


The first part of the netstat output shows TCP connections. This can also be shown using netstat -t. Connections show the local address (in this case, my localhost is named marvin), the connected remote systems (bugs and foghorn), and the connection state. The states represent the TCP connection's status. There are two states that you will often see:

§ ESTABLISHED-A network connection exists between the two systems.

§ TIME_WAIT-A connection has terminated and the system is just waiting for any final packets before tearing down the connection.

Along with these common states, there are many other states that exist for very short durations. For example, SYN_SENT and SYN_RECV indicate that a connection is starting. These will quickly switch over to the ESTABLISHED state. There are also plenty of states that indicate a connection is closing. For example, FIN_WAIT1, FIN_WAIT2, CLOSE, and CLOSE_WAIT. These states rarely exist for more than the blink of an eye before switching over to the TIME_WAIT state.

The second part of the netstat output shows Unix services. These include connectionless UDP packets (DGRAM) and connection-oriented sockets (STREAM). You can limit the display to just these packets by using netstat -x.

Identifying Servers with netstat

Besides showing established connections, netstat can display waiting network services. The command netstat -l shows all the listening servers.

$ netstat -l | more

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 0 *:nfs *:* LISTEN

tcp 0 0 *:printer *:* LISTEN

tcp 0 0 *:40867 *:* LISTEN

tcp 0 0 localhost:42309 *:* LISTEN

tcp 0 0 *:935 *:* LISTEN

tcp 0 0 *:netbios-ssn *:* LISTEN

tcp 0 0 localhost:44235 *:* LISTEN

tcp 0 0 *:sunrpc *:* LISTEN

tcp 0 0 localhost:8118 *:* LISTEN

tcp 0 0 localhost:socks *:* LISTEN

tcp 0 0 *:smtp *:* LISTEN

tcp 0 0 localhost:9050 *:* LISTEN

tcp 0 0 localhost:6010 *:* LISTEN

tcp 0 0 *:668 *:* LISTEN

tcp 0 0 *:microsoft-ds *:* LISTEN

tcp6 0 0 *:ssh *:* LISTEN

tcp6 0 0 ip6-localhost:6010 *:* LISTEN

udp 0 0 *:32768 *:*

udp 0 0 *:nfs *:*

udp 0 0 *:netbios-ns *:*


This example shows a large number of available network services including Tor (port 9050), NFS and LPD (printer), and even Samba (netbios). If you only want to list TCP or UDP services, you can use netstat -lt or netstat -lu, respectively. netstat -lx shows the local Unix services and sockets.

Running nmap

Although netstat usually shows many services, not all are accessible from across the network. For example, the Unix services are usually restricted to the local system and are not externally accessible. In addition, many TCP and UDP services may be bound to the loopback interface rather than the external network interface. These are denoted by the localhost interface name.

A better way to identify running services is with the nmap command (sudo apt-get install nmap). This network-mapping tool can identify every network-accessible service on a host and can even scan an entire subnet in minutes.


In some sensitive network environments, nmap will trigger intrusion detection systems. Before you scan a host cross a network, make sure you won't get in trouble with your local network administrators.

Table 12-1 lists some of the common command line parameters that I use with nmap. Other parameters are described in the man page for nmap.

Table 12-1: Common nmap Command-line Parameters
Open table as spreadsheet



-p portlist

By default, nmap only scans a set of well-known and common ports. This option can be used to specify one or more ports (for example, -p 80 or -p 80,443) or a range of ports (for example, -p 0-65535 or -p 1-1023).


Normally nmap pings the host before scanning it. However, if you enabled iptables or a firewall to drop ICMP packets, then the host cannot be pinged. This option disables pinging hosts before scanning them.


This performs a SYN-scan. Rather that performing a full TCP connection, only the initial connection is performed. This type of scan is not detected by some logging systems. I use it because it is faster than performing a full TCP scan.


Rather than scanning for TCP services, this will scan for UDP services.


When a network service is identified, only the port number is known. This option tells nmap to profile what is running on the port. In many cases, it will identify the name and version of the server.


While -sV profiles individual services, -O profiles the actual operating system. Using the option, nmap can try to determine the running operating system and version.

The results from an nmap scan show all of the accessible network services. For example:

$ sudo nmap -sS -sV -p 0-65535 -O

Starting Nmap 4.10 ( http://www.insecure.org/nmap/ ) at 2006-12-02 10:56 MST

Interesting ports on localhost (

Not shown: 65518 closed ports


21/tcp open ftp vsftpd 2.0.4

22/tcp open ssh OpenSSH 4.2p1 Debian-7ubuntu3 (protocol 2.0)

25/tcp open smtp Postfix smtpd

111/tcp open rpcbind 2 (rpc #100000)

139/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)

445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)

515/tcp open printer

668/tcp open mountd 1-3 (rpc #100005)

935/tcp open status 1 (rpc #100024)

1080/tcp open socks?

2049/tcp open nfs 2-4 (rpc #100003)

6010/tcp open unknown

8080/tcp open http-proxy Microsoft ISA Server http proxy

8118/tcp open http-proxy Junkbuster/Privoxy webproxy

9050/tcp open tor-socks Tor SOCKS Proxy

40867/tcp open nlockmgr 1-4 (rpc #100021)

42309/tcp open hpssd HP Services and Status Daemon

44235/tcp open hpiod HP Linux Imaging and Printing System

Device type: general purpose

Running: Linux 2.4.X|2.5.X|2.6.X

OS details: Linux 2.4.0 - 2.5.20, Linux 2.4.18 - 2.4.20, Linux 2.5.25 - 2.6.8

or Gentoo 1.2 Linux 2.4.19 rc1-rc7, Linux 2.6.0 (x86), Linux 2.6.3 - 2.6.10

Service Info: Host: localhost; OSs: Unix, Linux, Windows

Nmap finished: 1 IP address (1 host up) scanned in 36.204 seconds

Using nmap to scan your local system won't generate the same results as scanning from a remote host. This is because some network services are restricted to the local host. Also, some network services do their own filtering (for example, Tcpwrappers from Chapter 11) and only permit local connections. Ideally, you will want to scan your system from a different host on the same local network. Scanning my host from a remote system shows:

$ sudo nmap -sS -sV -O -p 0-65535 marvin

Starting Nmap 4.10 ( http://www.insecure.org/nmap/ ) at 2006-12-02 11:00 MST

Interesting ports on marvin (

Not shown: 65525 closed ports


21/tcp open ftp vsftpd 2.0.4

22/tcp open ssh OpenSSH 4.2p1 Debian-7ubuntu3 (protocol 2.0)

25/tcp open smtp Postfix smtpd

111/tcp open rpcbind 2 (rpc #100000)

139/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)

445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)

515/tcp open printer

668/tcp open mountd 1-3 (rpc #100005)

935/tcp open status 1 (rpc #100024)

2049/tcp open nfs 2-4 (rpc #100003)

40867/tcp open nlockmgr 1-4 (rpc #100021)

MAC Address: 00:11:D8:AB:39:2C (Asustek Computer)

Device type: general purpose|broadband router

Running: Linux 2.4.X|2.5.X|2.6.X, D-Link embedded

OS details: Linux 2.4.0 - 2.5.20, Linux 2.4.18 - 2.4.20, Linux 2.4.26,

Linux 2.4.27 or D-Link DSL-500T (running linux 2.4), Linux 2.4.7 - 2.6.11,

Linux 2.6.0 - 2.6.11

Service Info: Host: localhost; OSs: Unix, Linux

Nmap finished: 1 IP address (1 host up) scanned in 25.491 seconds

Note that the remote scan shows fewer ports and a slightly different operating system profile. (In this case, it discovered my D-Link router as well as my Linux system.)


Some of the nmap options require root privileges. These include -O and -sS. If you are the only user on your system and you plan to use nmap often, consider making it run with root permissions: sudo chmod u+s /usr/bin/nmap. This way, you don't need to use sudo to do scans.

Recognizing Network Threats

Every network service that is remotely accessible offers a path onto your system. If there is an exploit (available today or some time in the future), then you will have a risk that needs to be addressed. In addition, many network services run with root privileges; an exploit can potentially access your entire file system as root. Even if the exploit only gives user-level access, there are plenty of options for escalating privileges from a "regular" local user to root.


As far as bug discovery goes, local exploits are much more common than remote exploits. However, if you periodically update your system with apt-get update and apt-get upgrade, then you should have most of the local exploits under control. Periodically updating your system will also take care of any known remote exploits.

Having open ports accessible within your home or office network is usually not as serious as having ports accessible to anyone on the Internet. For example, I'm not too worried about my RedHat system having access to my Ubuntu box. On the other hand, I certainly don't want everyone in the world to access my Ubuntu NFS service.

What's My Motivation?

Security is a measurement of risk. A good system is "secure enough" for your needs. With security comes tradeoffs for performance, accessibility, and functionality. In order to understand your risks, you need to understand your potential attacker. For example, in your home environment, your main risks are probably restricted to physical access from kids, cats, and the occasional guest (anyone who might download a virus or accidentally delete something critical). However, other risks may include burglary, disk crashes, and viruses that you accidentally download.

Threats at home are different than threats at work. In your office are dozens or hundreds of people with network access, including a few disgruntled employees, and sensitive or company confidential information. However, local access is still limited to people who are usually trusted. This is different from Internet-accessible services, where anyone in the world has access and you know that you cannot trust everyone.

The big question becomes: who is your likely attacker, and what does the attacker probably want? In directed attacks, someone wants something on your system- files, passwords, credit cards, secret files, or anything else of value. However, more common are broadcast attacks, where the attacker wants a computer and not specifically your computer. Even if you have a slow CPU and very little disk space, the fact that you have Internet access means that you can relay spam, act as a proxy for anonymous attacks, or become part of a botnet. If you happen to have a fast computer or a few gigabytes of disk space, then that's just icing on the cake for the attacker. They can use your computer to store porn or warez (stolen software), crack passwords, host chat rooms for other undesirable associates, or worse. That one network service that you temporarily opened to the Internet could be the reason you are at the epicenter of a massive network attack and child pornography ring.

Attackers are constantly scanning the Internet for computers with vulnerable network services. If you open up a web, FTP, or e-mail server, then potential attackers will probably discover it within a few hours. If you open some other service, then it might take longer to be discovered, but eventually someone will find it.

Mitigating Risks Before Going Public

There are a couple of things you can do to mitigate risks before opening a network service to the Internet.

§ Remove defaults-Any sample scripts and default documentation should be removed. In many cases, sample code can be used to exploit a system, and documentation usually tells an attacker what they are up against. If there is a default login or account name, then change it.

§ Limit service access-Restrict Internet access to only the necessary services. For example, if you only want to give access to your SSH server, then you don't need to offer your HTTP server to the world. You can restrict access with Tcpwrappers or IP Tables (see Chapter 11). Some services can be bound to the loopback interface rather than the network card. A better alternative to local access restrictions is to use a stand-alone firewall. This way, hostile network traffic never reaches your computer in the first place.

§ Limit services per system-Ideally, each open network service should be on a different computer system. This way, an attacker who compromises your web server won't also have access to your e-mail, SSH, and other services. In reality, you may not have many computers sitting around, acting as dedicated service providers. Maintenance may also be a hassle. However, if you have a particularly critical service, definitely consider placing it on a standalone system.

§ Limit host access-If only a few hosts will be accessing the service, consider restricting connections to just those hosts. The restrictions may be based on IP addresses (if they are static), or on VPN technology such as IPsec (see Chapter 11) or SSH (see Chapter 5).

§ Use a firewall-Anyone using a computer connected to the Internet (or an ISP) without a firewall is just asking for trouble. A simple NAT-based home firewall usually costs under $50 and is well worth the investment.

§ Use a DMZ-A DMZ (de-militarized zone) is a network buffer region that is surrounded by firewalls. The concept is pretty simple: all inbound traffic must stop at the computer in the DMZ before continuing into the internal network. The DMZ provides a choke point for monitoring suspicious network traffic and authenticating desirable traffic. Configuring a DMZ requires two firewalls and one computer (the computer can even be that old 75 MHz Pentium that you have collecting dust in your closet).

§ Configure an IDS-An IDS (Intrusion Detection System) watches network traffic for potential threats and alerts you when something questionable is identified.

§ Monitor logs-Local network services usually generate log files. So do firewalls and IDSs. If you don't periodically look at the logs, then you will never see attacks when they happen.

§ Keep backups-Being able to recover from a compromise is just as important as knowing how and when the compromise happens. Chapter 3 offers a very simple backup system, but your backups should really match your needs.

§ Patch! Patch! Patch!-While a home computer with no services may only need to be updated monthly, systems with Internet-accessible services should be patched much more often. Attackers won't wait for you to catch up with the latest exploit.

Monitoring Attacks

Regardless of the type of network service you want to enable, you should have lots of log files that identify what happened and when. You're going to need a way to sort through all the noise and clutter for those few items that might indicate a possible attack-or a successful attack.

What Should You Look For?

There are a couple of different types of attacks, each of which should show up in various log files.

§ Brute force-Brute force attacks are usually tried against login systems. You should see logs that have a high number of failed connection attempts.

§ Reconnaissance scans-Before attacking a target, many systems initially perform some type of reconnaissance. This should appear in the logs as a scan. Scans usually look like a bunch of connections or simple queries. There may be one per host, or a suite of connections per host. If the scan finds anything useful, then the attack will come later.

§ One-time tries-Many automated attack systems blindly try exploits. If the attack works, then you are compromised. If it fails, then you're safe. These should appear in log files as one-time oddities. Or in the case of a massive worm, lots of the same oddity as each infected system tries to spread.

A quick hack for analyzing log files simply looks at file size. If you rotate logs hourly or daily, then look for a sharp increase in log size-this will indicate some new worm or network scan. As far as one-time attacks go, look over some logs to get an idea of "normal" and then look for things that stand out as odd.

Periodic scans of your own systems with tools like nmap should be used to look for new, unexpected services. If there is a new, unexpected service running on your system, then take the time to find out why. If there are lots of new ports, then it is a good sign that the system is compromised. Similarly, look for unexpected network traffic. If you never use IRC and start seeing IRC traffic, then find out where it is coming from!

What Now? After a Compromise…

Ok, so you started a new network service, you put it on the Internet, and you've been compromised. Do you know what you will do? Turning off the system is a good start, but how and when will you turn it back on? Do you reset or restore the system? This could simply reintroduce the same environment that led to the initial compromise!

Regardless what you plan to do, have a plan in place before making a service public. For example, what will you do if you are on vacation and you suddenly hear that your hobby FTP server is sending millions of spam e-mail messages? It is better if you take care of it than having your ISP disconnect you.

I have a very simple plan: there is always someone available to pull out the power cord if a system is acting fishy. Later, I can remove the hard drive and mount it under a different Linux system and see what went wrong and recover log files. Later, I can restore from a backup and apply the most recent patches as needed.

Logging Logins

Many types of services provide login access. Failed logins should be placed in log files. Under the default Ubuntu installation, successful logins are stored in /var/log/wtmp. This is a binary file that stores the login account name, date of access (login and logout), and if it is a remote connection, then the name of the remote host. You can access this log file with the last command.

$ last

nealk pts/2 foghorn.local.lan Sun Dec 3 10:36 still logged in

nealk :0 Sat Dec 2 15:31 still logged in

reboot system boot 2.6.15-26-686 Sat Dec 2 15:30 (1+00:51)

wtmp begins Sat Dec 2 11:10:17 2006

Unfortunately, Ubuntu does not normally log failed login attempts. To log failed attempts, you will need to create a /var/log/btmp file. Simply creating this file enables logging and all new login failures will be recorded.

sudo touch /var/log/btmp

sudo chown root:utmp /var/log/btmp

sudo chmod 660 /var/log/btmp


The /var/log/btmp file is usually used by text-based login windows. The graphical login screen, such as Dapper's gdm version 2.14, does not record login failures to btmp. To test btmp, press Alt+F2 and try a few failed logins, then login and use lastb to see the results.

You can access the btmp logs using the lastb command:

$ sudo lastb

UNKNOWN Sun Nov 12 15:36 - 15:36 (00:00)

root Sun Nov 12 15:36 - 15:36 (00:00)

root Sun Nov 12 15:35 - 15:35 (00:00)

111 Sun Nov 12 12:05 - 12:05 (00:00)

ggg Sun Nov 12 12:05 - 12:05 (00:00)

UNKNOWN Sun Nov 12 12:01 - 12:01 (00:00)

UNKNOWN Sun Nov 12 12:01 - 12:01 (00:00)

UNKNOWN Sun Nov 12 12:00 - 12:00 (00:00)

nealk Sun Nov 12 11:58 - 11:58 (00:00)

nealk Sun Nov 12 11:58 - 11:58 (00:00)

UNKNOWN Sun Nov 12 11:56 - 11:56 (00:00)

UNKNOWN Sun Nov 12 11:56 - 11:56 (00:00)

btmp begins Sun Nov 12 11:56:40 2006


The wtmp and btmp log files rotate. You may need to use lastb -f to specify a specific log file. For example, sudo lastb -f /var/log/btmp.1.

Normally btmp only logs valid user names and the time of the failed login attempts. Unknown user names are logged as UNKNOWN. You can change btmp to log all unknown usernames, enabling you to see what user names are used by a brute force attack:

1. As root, edit /etc/login.defs.

2. Change LOG_UNKFAIL_ENAB from no to yes. There is no need to restart the system-this change takes affect immediately.


Users sometimes accidentally enter their password instead of a user name. This means that their passwords will be logged to /var/log/btmp. If you accidentally enter your password at the login prompt of a multi-user system, then login and immediately change your password.


Make sure btmp is not world-readable (sudo chmod o-r /var/log/wtmp) to prevent other users from potentially seeing login-password mistakes.

Although last and lastb record login events, not every remote-access system uses them. For example, the SSH daemon logs to /var/log/auth.log. To see the list of failed logins, you will need to search the log files:

$ zgrep "Invalid user" /var/log/auth.log* | sed -e 's/^.*: //' | sort | uniq -c

2 Invalid user bill from

1 Invalid user cow from

3 Invalid user dog from

This command searches all of the auth.log files for the lines containing Invalid user.It then displays each invalid user name, where the attempt came from, and how many times it was tried (sorted by user name).


The zgrep command searches regular logs and compressed (.gz) files.

Enabling Intrusion Detection Systems

Snort is a very powerful tool. As mentioned in Chapter 11, it can be used to sniff packets. However, Snort can do much more than just collect packets. The default installation (sudo apt-get install snort) enables an Intrusion Detection System (/etc/init.d/snort).

This constantly watches for suspicious traffic and generates an activity report. To generate a report, you can use the snort-stat command:

$ sudo id # make sure the next sudo command does not prompt for a password

$ sudo cat /var/log/snort/alert | snort-stat -a | less

Events between 11 28 05:29:52 and 12 02 10:26:15

Total events: 1289

Signatures recorded: 21

Source IP recorded: 8

Destination IP recorded: 21

Events from same host to same destination using same method


# of from to method


1088 NETBIOS name query overflow attempt UDP

73 WEB-IIS %2E-asp access

24 ATTACK-RESPONSES 403 Forbidden

21 ICMP Destination Unreachable

Communication with Destination Host is Administratively Prohibited

9 ICMP Destination Unreachable

Communication with Destination Host is Administratively Prohibited


4 SNMP trap tcp

4 SNMP AgentX/tcp request

3 WEB-CGI redirect access

3 (spp_rpc_decode) Multiple RPC Records

3 WEB-CGI count.cgi access

2 (portscan) TCP Portscan

2 (portscan) TCP Portscan

2 (portscan) TCP Portsweep


The log report shows the number of suspicious packets, as well as the type of attack. For example, there were a couple of port scans and port sweeps identified, as well as some suspicious web traffic, but the main concern is a NETBIOS name query overflow attempt. (In this case, it was due to a misconfigured OS/2 system running an old SMB configuration.) Although there are likely to be many false-positive findings, some items such as port scans and known attacks should be closely examined. All of the suspicious packets are saved in /var/log/ snort/tcpdump.log.* files. These can be viewed using Ethereal (see Chapter 11).

The actual set of IDS rules used by Snort are found in /etc/snort/rules/. There are dozens of attack signatures that trigger alerts. If you have some known false-positives, you can remove the IDS rule by commenting out the rule in the /etc/snort/snort.conf configuration file. Similarly, if you learn of a new rule, then you can easily add it to the rules directory and tell snort.conf to include the new rule. After changing any of the rules, be sure to restart the IDS: sudo /etc/init.d/snort restart.

The Snort IDS configuration files (/etc/snort/snort.conf and /etc/snort/snort. debian.conf) have a large number of configuration items, and most have excellent default values. The main items you may want to change are your home network (the HOME_NET variable) and the interface. For example, one of my systems has two network adapters: eth0 and eth1. One adapter (eth0) is used for regular network traffic, while the other (eth1) is connected to a hub in the DMZ and monitors suspicious traffic. To change Snort so that it watches only the second network card, I changed the interface name in /etc/snort/snort.debian. conf from DEBIAN_SNORT_INTERFACE="eth0" to DEBIAN_SNORT_INTERFACE="eth1".

Running Services

There are literally hundreds of different types of servers that you can install and use. However, when it comes to services on the Internet, there are a couple of main ones that you will probably want to enable. These include SSH, FTP, e-mail, and web.

Hardening SSH

The Secure Shell server (sshd) provides encrypted and authenticated remote connectivity for logins, file transfers, and remote command execution. The basic SSH server installation (sudo apt-get install openssh-server, discussed in Chapter 5) is secure enough to immediately place on the Internet. However, there are some parameters in the /etc/ssh/sshd_ config file that you might want to modify for added security (see Table 12-2).

Table 12-2: Commonly Modified SSH Server Parameters
Open table as spreadsheet


Default Value



AllowUsers *

Restricts login access to a list of user names (separated by white space). You can also specify user@host to restrict access to a specific user logging in from a specific host. If only some users should have remote access, then you can use this to explicitly block all other users.


AllowGroups *

Similar to AllowUsers, you can specify group names found in /etc/group. Only users who are members of the specified groups are allowed to login. To find the groups you are in, use the groups command.


LoginGraceTime 120

Specifies the number of seconds a user should sit at the password prompt before being disconnected. The sshd has a limit on the number of concurrent connections. If someone is trying to block your connection by tying up all available connections, then consider lowering this value from 120 seconds to 5. You may also want to lower this value if you have users who connect but take too long trying to remember their passwords.


MaxStartups 10

Specifies how many concurrent login attempts are permitted (before successfully entering your password). The default is 10 concurrent, unauthenticated connections. You should consider changing this to 10:30:60. This specifies allowing 10 concurrent. If the 10 are connected, then drop them at a rate of 30/100-there is a 30-percent chance that some connection will be dropped before LoginGraceTime. This will continue until the maximum of 60 connections is reached; then all new connections are dropped.


Port 22

For servers on the Internet, consider moving them to a port other than 22/tcp. Although this is technically "security by obscurity", it will deter most simple reconnaissance attacks from finding your server and attempting brute-force logins.


There are two parameters in /etc/ssh/sshd_config that are serious risks any to system on the Internet: PermitRootLogin and PermitEmptyPasswords. By default, users with empty passwords cannot log in. Although the default setting does permit root logins, Ubuntu does not give root a password. Still, setting either of these to yes is a serious risk for system on the Internet. You should consider changing both of them to no.

After you change anything in the /etc/ssh/sshd_config file, you will need to restart the server:

sudo /etc/init.d/ssh restart

Restarting the server will apply all the changes to new connections, but existing connections will be unaffected.

Using SSH Keys

SSH supports different types of authentication. Basic password authentication is the most common approach. However, password authentication isn't very good for automated tasks like cron jobs (see Chapter 7) that use SSH for network administration.

Another form of authentication uses keys. These can be used in place of passwords. The SSH keys are similar to PGP (see Chapter 10) in that they are asymmetrical; there is a public and a private key. Creating SSH keys requires generating keys on the client and transferring the public key to the server.

1. The ssh-keygen program is used to generate SSH keys on the client. You will need to specify the algorithm (DSA or RSA) and the bit size. For security, use a key size of at least 2048 bits.

2. % ssh-keygen -t dsa -b 2048

3. Generating public/private dsa key pair.

4. Enter file in which to save the key (/home/user/.ssh/id_dsa): [enter]

5. Enter passphrase (empty for no passphrase): [password][enter]

6. Enter same passphrase again: [password][enter]

7. Your identification has been saved in /home/user/.ssh/id_dsa.

8. Your public key has been saved in /home/user/.ssh/id_dsa.pub.

9. The key fingerprint is:

10. 82:be:37:65:df:d9:f6:20:0a:fc:85:76:8a:c6:61:10 user@ubuntu

Generating keys longer than 2048 bits may take awhile. Be patient and it will eventually ask you where to save the keys.


The passphrase is used to protect the key from theft. If you are not worried about other users on the system stealing your SSH key file, then you can leave this blank. For automated system, you should probably leave it blank.

11. Generating keys creates two files. $HOME/.ssh/id_dsa (or id_rsa) holds the private key, whereas $HOME/.ssh/id_dsa.pub (or id_rsa.pub) is the public key. Transfer the public key from the client to the remote server.

12. scp $HOME/.ssh/id_dsa.pub remote:id_dsa.pub

This will use SSH to copy the public key from your local system to the server named remote. The file will be copied to $HOME/id_dsa.pub (not $HOME/.ssh/id_dsa.pub on the remote host).

13. You will need to tell the server which keys are permitted for logins. Copy the contents of id_dsa to $HOME/.ssh/authorized_keys. If the file exists, then you can just append to it.

14. mkdir $HOME/.ssh # in case it does not exist

15. cat $HOME/id_dsa.pub >> $HOME/.ssh/authorized_keys

16. On some SSH servers, you may need to make sure the server accepts keys. Edit (or have the administrator edit) the /etc/ssh/sshd_config file and make sure RSAAuthentication and PubkeyAuthentication are both set to yes. (Under the default installation for Ubuntu, they are already set to yes.) If you made changes, then you will also need to restart the SSH server.

17. Test the connection. You should be able to use ssh and connect to the host using only your key. If you entered a passphrase for the key, then you will be prompted for it but it will not be transferred across the network. Without a passphrase, you should immediately get a command-line prompt.


If the server does not accept the key, then it will regress to using the user's login password. If you want to disable password-based logins, then set PasswordAuthentication to no in /etc/ssh/sshd_config.

Debugging SSH Connections

The most common problem with SSH is an unknown server key. During the server installation, a server key is generated. The OpenSSH client caches this key the first time you connect to the server, and then compares new keys during subsequent connections. There are only a few real reasons why the server key may not match. First and most common, the server was reinstalled for some reason and generated a new key, or was replaced by a different server with a different key. The alternative is that someone is trying to hijack your connection. Both will appear as a message that looks something like this:





Someone could be eavesdropping on you right now (man-in-the-middle attack)!

It is also possible that the RSA host key has just been changed.

The fingerprint for the RSA key sent by the remote host is


Please contact your system administrator.

Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.

Offending key in /home/user/.ssh/known_hosts:7

RSA host key for localhost has changed and you have requested strict checking.

Host key verification failed.

To resolve this problem, you'll need to remove the offending server's key from the SSH cache file: $HOME/.ssh/known_hosts. In this case, delete line 7 as specified in the warning:



Although hijacking is extremely rare, it is definitely possible! Do not just fix the cache file without making sure that it isn't a real attack. If you are at a coffeehouse (or hacker conference) and you own this server and nothing should have changed, then don't try to fix the connection to the server! If nothing should have changed then this probably is an attack and removing the cached entry can allow the attacker access to your system.

Enabling FTP

I use a variety of operating systems-some new and some very old. Using SSH to log in and transfer files between Unix and Linux systems is convenient. However, other operating systems may not be as convenient for using SSH. For example, in my opinion the best SSH clients for Windows are commercial and costly (although some free ones do exist). In some cases (for example, my OS/2 system) SSH is unavailable.

Since I need to transfer files between systems, I have found that FTP is ubiquitous, and usually a little faster than SSH even if it is not as secure. For a local network, FTP is a great file transfer option. For direct Internet access, FTP can be secure enough as long as you lock down the system and recognize that anyone may gain access to the server. Besides being universally available to all clients, FTP also overcomes one serious limitation found in SSH: SSH does not permit anonymous logins. With FTP, anyone can connect to a shared directory for collaboration.

Installing VSFTPD

Ubuntu offers a variety of FTP servers (apt-cache search ftpd). My personal preference is the Very Secure FTP Daemon (VSFTPD). I like all of the customizable features and the fact that it is secure enough to be given direct Internet access immediately after being installed. However, you'll probably want to customize the system since the basic installation gives no access.

Installing the server is straightforward:

sudo apt-get install vsftpd

The installation will start the server as a stand-alone process (not requiring inetd), configure the /etc/init.d/vsftpd startup script, and create the user ftp for anonymous access. The server immediately permits anonymous read-only access to the directory /home/ftp. You can log in using the user name anonymous or ftp with any password.

$ ftp localhost

Connected to localhost.

220 (vsFTPd 2.0.4)

Name (localhost:ubuntu): anonymous

331 Please specify the password.

Password: ********

230 Login successful.

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> ls -la

200 PORT command successful. Consider using PASV.

150 Here comes the directory listing.

drwxr-xr-x 2 0 65534 4096 Dec 09 16:30 .

drwxr-xr-x 2 0 65534 4096 Dec 09 16:30 ..

226 Directory send OK.

Any files or directories placed in the /home/ftp/ directory will be accessible by the anonymous FTP user. However, regular users do not have access until you explicitly enable it (see the section "Adjusting Regular FTP Access" later in this chapter).

Adjusting Anonymous FTP Access

If you don't want anonymous FTP access, then you can disable it.

1. As root, edit /etc/vsftpd.conf.

2. Change the configuration value anonymous_enable=YES to anonymous_enable=NO.

3. Restart the FTP server:

4. sudo /etc/init.d/vsftpd restart


You will need to restart the server any time you make a change to /etc/vsftpd.conf.

However, if you want to enable FTP access, then there are many configuration options you might want to change. Table 12-3 shows some of the anonymous FTP configuration options. Other options can be found in the online manual (man vsftpd.conf).

Table 12-3: Anonymous FTP Options for /etc/vsftpd.conf
Open table as spreadsheet





anon_upload_ enable=YES

Allow anonymous users to upload files to the /home/ftp/directory.



Allow anonymous users to create directories under /home/ftp/ with the mkdir FTP command.



Allow anonymous users to rename or delete files under /home/ftp/.



Throttle file transfer rates for anonymous users. This specifies 131,072 bytes per second (or 1 megabit per second).


anon_world_readable_ only=YES

Restrict anonymous users to downloading only files that are world-readable. This way, the user ftp may have private files that cannot be downloaded.



Changes all user and group IDs so they look like ftp. By default, all IDs are shown by their numeric values.


secure_email_list_ enable=YES

Force anonymous users to provide a valid password. You will need to create the file /etc/vsftpd. email_passwordsand give it a list of passwords, one per line. Any of these passwords are acceptable for anonymous access.


If you allow anonymous users to upload files, consider enabling disk quotas for user ftp (see Chapter 8). This way, anonymous FTP users won't consume all of your disk space.

Adjusting Regular FTP Access

By default, VSFTPD disables FTP access for regular users. To enabling FTP access for local (non-anonymous) users:

1. Edit /etc/vsftpd.conf.

2. Uncomment the local_enable=YES line.

3. Restart the server:

4. sudo /etc/init.d/vsftpd restart

After these changes, any user may FTP to his or her account by specifying a valid username and password. There are other local user options for /etc/vsftpd.conf that you may want to modify (see Table 12-4).

Table 12-4: Local User FTP Options for /etc/vsftpd.conf
Open table as spreadsheet






Limit the number of client connections. In this case, up to 20 clients can be connected at once. The default value is 0 meaning no limit.



Specify how many FTP connections may come from the same IP address. The default is 0 meaning no limit.



Specify the number of bytes per second for throttling FTP connections. This example sets a limit of one megabyte (eight megabit) per second. If you have an 8 Mbps connection, then consider setting the limit to 6 Mbps or less so the FTP server will not consume all available network bandwidth. The default value has no limit.



Restrict local users to their home directories rather than letting them access anything on the system.



Specify a list of users that should or should not be limited to their home directories. If chroot_local_ user is NO, then this is a list of users who should be restricted. If chroot_local_user is YES, then this is a list of users who should not be restricted. The list of users (one user name per line) is stored in /etc/vsftpd.chroot_list (you'll need to create this file).


VSFTPD logs every connection, file transfer, and anonymous login password to the file /var/log/vsftpd.log. If your system is connected to the Internet, then you should monitor this log file for possible attacks or abuse. The log file is rotated weekly by the logrotate configuration file /etc/logrotate.d/vsftpd (see Chapter 10 for rotating log files).

Securing Internet FTP

FTP is not a secure protocol. Every user name and password is transmitted in plain text across the network. If your server is accessible from the Internet, then anyone capable of capturing your packets will see your valid user name and password. If you need to give users FTP access, consider creating a second account strictly for FTP access. By default, new accounts are given a unique group name. You can create an FTP-only account for each user, and assign the accounts to the user's group name. For example, user bill can be given the account bill-ftp in the group bill:

sudo useradd -m -g bill -c "FTP for Bill" bill-ftp

Be sure to give bill write-access to the bill-ftp directory:

sudo chmod -R g+w /home/bill-ftp

Then you can give this account a different password than Bill's regular account.

sudo passwd bill-ftp

Finally, you can block SSH and remote login access for any account containing -ftp in the account name.

1. Edit /etc/ssh/sshd_config.

2. Add the following option: DenyUsers *-ftp

3. Restart the SSH server: sudo /etc/init.d/ssh restart

This way, user bill can access the directory bill-ftp. But if his login credentials are ever compromised, then the attacker will be unable to access the account through SSH.

Enabling Postfix

E-mail is pretty much a mandatory network service. If you don't want to host your own e-mail, then you just need an e-mail client (see Chapter 5). However, if you plan to actually receive e-mail on your own system, then you will need an e-mail server. In addition, many applications generate status reports using e-mail. You will need a server if you want to send the e-mails directly to yourself.


I have a home firewall that can e-mail its system logs. Rather than sending the logs out to my ISP, I have them sent directly to my own, internal mail server running on an Ubuntu system.

Ubuntu offers many different e-mail servers. However, Sendmail, Qmail, and Postfix are the most common under Linux. Of these servers, Sendmail is the oldest and most widely used, but it is also historically the most insecure. My personal preference is Postfix because of its security, speed, and reliability. Each of these mail servers support configurations that vary from plug- and-play simple to extremely complex. Unfortunately, none of these mail servers are trivial to configure. (Sendmail is one of the most complicated ones to configure-another reason that I like Postfix.)

To get started with your mail server, you will need to install the server package, configure it, and test it. If it tests well and seems to work, then you can be really daring and open it to the world.

1. Install the Postfix server. This will create the appropriate startup scripts, place default files, and start the server:

2. sudo apt-get install postfix

3. During the installation, you will be prompted for the type of installation. Your options are:

o No configuration-Install the server but leave it unconfigured. (Probably not what you want unless you are trying to repair a broken installation.)

o Internet Site-Assume the server will be directly connected to the Internet. Use this if you actually intend to send and receive e-mail directly. This is the default option but it is probably not what you want if you are installing on a home system, private network, or for a small business.

o Internet with smarthost-This configuration is useful for most home users who need to relay out-bound e-mail through an ISP's smart mail relay. This can be used to provide a mail server to a local never even if the host is not accessible from the Internet.


A smarthost is a mail relay that knows how to route e-mail across the Internet. Many ISPs provide a smarthost for sending e-mail. You'll need to ask your ISP if they have an SMTP server for outbound delivery.

§ Satellite system-This option configures Postfix as a system for sending e-mail through a smart mail relay, but not for receiving. This is a great option if your actual e-mail is stored on some other server.

§ Local only-Choose this configuration if you have no external systems that will be relaying e-mail through this host.

I usually choose the Internet Site or Internet with smarthost option for primary servers. However, for secondary servers and workstations, I use the Satellite system. Depending on the option you choose, you will be prompted to supply your own mailing domain, smarthost name, and other configuration values. Then the installation will complete and the server will start up.

Post-Installation Configuration

There are a couple of options in /etc/postfix/main.cf that you might want to modify or add after the installation.

§ relayhost-This option is the IP address or host name of the smarthost. If it is blank, then no smarthost is used.

§ mydestination-This is a comma-separated list of host names and domains that are used for local delivery. You probably should add your system's host name to this list. Also, if this server is expected to receive e-mail for multiple domains, then you'll want to add every domain here.

§ myhostname-This option specifies you host's Internet host name that is revealed when sending e-mail. I usually make this my Internet domain name rather than my private LAN's domain since seeing e-mail from neuhaus.roach.lan won't make sense to anyone but me.

§ mydomain-Similar to myhostname, this specifies your Internet domain name. If you have a vanity (personal) domain, you can put it here rather than using your ISP or any private domain name.

§ inet_interfaces-You can specify one or more network interfaces for receiving e-mail. If your system has multiple network interfaces but only one that should receive e-mail, then you definitely need to modify this line. If you're just testing, you can always say inet_interfaces = loopback-only and only receive e-mail from yourself.

§ mynetworks-If other systems will be relaying e-mail through your server, then you will need to specify the networks that can relay e-mail. For example, I use:

§ mysetworks =,

This setting enables me to send e-mail from localhost (the subnet) and from my private, local network: 10.x.x.x. All other machines (not on these networks) that connect to my mail server can only deliver e-mail directly to this host; they cannot relay. This way, my host will not be used to relay spam to other networks.

§ smtpd_banner-This is the welcome banner that is displayed any time a mail client connects to the mail server. For security, it should display as little information as possible about the system-don't display the server's version since that can be used by an attacker to gain knowledge about the server. The default setting does not give a version, but it does state Ubuntu (I recommend removing that). I usually make a simple banner:

§ smtpd_banner = Private System - All connections are logged.

There are many more configuration options. The file /usr/share/postfix/main.cf.dist is a template that describes every default option and configuration. Alternately, you can consult the man page: man 5 postconf. When you finish tweaking your configuration file, you need to tell Postfix to reload it:

sudo /etc/init.d/postfix reload

Testing Postfix

When you have it all configured, try sending an e-mail to yourself-both locally and to a remote system so that you can verify network access. Also, if any systems on your network will be relaying through your server, then try relaying e-mail. If there are any problems or errors, you should see them logged in /var/log/mail.log.

Opening Postifx

If you are going to be making your mail server publicly accessible from the Internet, then you will need to open port 25/tcp in your firewall. This traffic should go to your mail server. After opening the firewall, you can try e-mailing yourself from outside your network and see if you receive it.


Opening your mail server to the Internet is not as easy as opening a port in a firewall. You're also going to need to configure your DNS entry for your domain so the server is listed as a mail exchanger (DNS MX record). How to do this depends on your domain registrar or DNS hosting provider. Contact them if you have questions.

Enabling Apache

Web servers play an important role on most networks. You can use them to create official web sites, or to test web pages before making them public. On internal networks, placing a file on a web site for download can be more convenient than using an FTP server. In addition, server- side scripts such as CGI scripts and PHP can create dynamic content. As a software developer, I frequently use HTML and CGI scripts to mock up graphic interfaces and user flows before devoting time to creating the final "real" interface.

The Ubuntu repositories contain a wide variety of web servers. For example, thttpd is a tiny server that is ideal for minimal-resource systems. Other server packages include dhttpd, fnord, and the Roxen Challenger server (roxen4). However, Apache is by and far the most common server. Although it isn't tiny, it is fast, stable, secure, and extremely flexible.

The basic Apache package installs the core web server: sudo apt-get install apache. This provides the server (httpd), startup script (/etc/init.d/apache), and log management file (/etc/logrotate.d/apache). You should be able to connect to it using http://localhost/ and see a generic web page (see Figure 12-1).

Image from book
Figure 12-1: The default Apache server web page

Are You Being Served?

There are actually two different branches of Apache web servers: 1.x and 2.x. The Apache Software Foundation supports both versions. Basically, the 2.x branch is a complete rewrite and offers features such as IPv6 support and a new software API. However, unless you plan to create plug-ins for Apache (not CGI), you'll probably never notice a difference.

For Ubuntu, the apache package installs Apache 1.x, while apache2 installs the 2.x version. My preference is usually for Apache 1.x since it seems a little faster to me. (Unless I'm developing plug-ins, in which case I like the 2.x API). However, if I'm just creating web pages and CGI scripts, or installing web applications like Wikis and blogs, then either version works well.

Post-Installation Configuration

After installing Apache, there are a few configuration items that you will want to tweak. These are stored in the /etc/apache/httpd.conf file.

§ ServerName-This configuration option specifies the host name to use during a redirection. It defaults to localhost-that's fine for testing but it really should be a network identifiable host name. Use either the machines public IP address or public domain name instead of localhost.

§ ServerAdmin-This is the person to contact in case of a problem. It defaults to webmaster@localhost. I recommend creating a webmaster account for your domain and setting that as the contact. I try not to use specific users since people in companies have a tendency to move around-it's easier to change the mail alias than contact everyone who has the webmaster e-mail address.

§ DocumentRoot-The default root is /var/www/. I usually change this to /home/ www-data/ (after creating a directory for the www-data user). I mainly do this because on my systems /home/usually has more disk space than /var/ and if I'm enabling disk quotas, then /home/ usually has quotas enabled.

Beyond the basic contact and host name configurations, I also modify some of the default directories and files listed in the /etc/apache/httpd.conf file. Most of this is done for additional security.

§ Remove unneeded aliases-Anything that is not needed on the server can be used to profile and potentially attack the server. I usually remove the web server's /doc/ entry, /images/, and /perl/. For example, /doc/ is defined as:

§ <IfModule mod_alias.c>

§ Alias /doc/ /usr/share/doc/

§ </IfModule>


§ <Location /doc>

§ order deny,allow

§ deny from all

§ allow from

§ Options Indexes FollowSymLinks MultiViews

§ </Location>

I remove all of this. Even though /doc/ is only accessible from the local system, I have never needed to use any of these files from the web browsers. Providing these over the web could tell an attacker exactly what software (and vulnerabilities) are on my system.

§ Disable indexes-Throughout the configuration file are Options lines that reference Indexes. For example:

§ <Directory /var/www/>

§ Options Indexes Includes FollowSymLinks MultiViews

§ ...

Just remove the Indexes keyword. With this option, a directory without an index.html file will actually show the directory contents. This enables anyone to browse any file that may be accessible from the web server-including backup versions, temporary files, and hidden or personal directories. Removing the Indexes option blocks open directories and returns an error. If a specific directory should be open, then I can open it on an as- needed basis.

§ Enable CGI scripts-I do a lot of programming, so I like to have CGI scripts enabled. I usually edit the public_html section and add ExecCGI to the list of options. This way, any executable in any user's public_html directory will act as a CGI script. The entire section ends up looking like:

§ <Directory /home/*/public_html>

§ AllowOverride FileInfo AuthConfig Limit

§ Options MultiViews SymLinksIfOwnerMatch ExecCGI


§ Order allow,deny

§ Allow from all

§ </Limit>


§ Order deny,allow

§ Deny from all

§ </Limit>

§ </Directory>

You will also need to go down to the AddHandler section and uncomment the CGI handler line:

AddHandler cgi-script .cgi .sh .pl

This handler allows any file that ends with .cgi, .sh, or .pl to be used as a CGI script.


Enabling CGI scripts is definitely not for everyone. There are huge security implications here. If you enable CGI scripts for everyone, then there is a very serious threat of an attacker exploiting a weak script and compromising your system. For public servers that host many different users, I strongly recommend not enabling ExecCGI for everyone. But if it is just you on a private server, then this is a very convenient option.

After changing the /etc/apache/httpd.conf file, you will need to reload the configuration file.

sudo /etc/init.d/apache reload

Extending Apache

The basic Apache installation is good for serving web pages and handling basic CGI scripts. However, there are many additional packages that can be added to extend the server's functionality. These additional modules provide functionality that integrates into the web server. The full list of available modules can be found with apt-cache search libapache-mod.

Table 12-5 lists some of the available packages and the functionality that they provide. You can install any of them using apt-get install package. In some cases, there will be additional configuration steps needed before the modules can be used.

Table 12-5: Additional Apache Packages
Open table as spreadsheet




Adds support for Perl support. You can use <Perl>…</Perl> sections in your HTML to execute server-side scripting with Perl.


Adds SSL support to the Apache server. This enables you to use HTTP or HTTPS. However, you will need to configure your SSL certificates before enabling SSL.


Provides PHP version 4 server-side scripting support. (If you are using Apache 2.x, then install libapache2-mod-php4 instead.)


Provides PHP version 5 server-side scripting support for Apache 2.x. Unfortunately, at the time of this writing, libapache-mod-php5 was not available as a package for the Apache 1.x server. However, the php5-cgi package provides similar functionality.


This module provides support for Java and JSP web pages. Unlike the other modules, this one requires a large number of dependencies for supporting the Java environment.


For many of these modules, you can install them as an Apache plug-in or statically linked into the web server. For example, mod_perl can be loaded using libapache-mod-perl or statically provided by apache-perl. From my viewpoint, there is no real reason to have most of these libraries statically linked.

Creating Web Pages

After configuring the web server, you will want to create some HTML web pages. At minimum, you will want to replace the default placeholder (as previously shown in Figure 12-1) with your own page-or a blank page. Unless you change it (like I usually do), the default server web pages are located in /var/www/ and the placeholder is /var/www/index.html. Individual users can create a public_htmldirectory (mkdir $HOME/public_html) and place their personal files in this directory. For example, Bill (my technical reviewer) can use:

mkdir /home/bill/public_html

echo "Test page" > /home/bill/public_html/index.html

He can then access his test page using http://localhost/˜bill/.


If you get an error accessing your page, check the file and directory permissions. Your home directory, public_html directory, and every web page need to be accessible by user ww-data or group www-data. This usually means making your home directory at least world-executable (chmod a+x $HOME) and the web directory world readable: find $HOME/public_html -type d -exec chmod 755 ‘{}‘ \; and chmod -R a+r $HOME/public_html.


It does not take much skill to install a basic Ubuntu system and use the out-of-the-box configuration. However, configuring, tuning, optimizing, and securing the system to fit you needs takes serious skills. If you want to safely enable network services, then you'll need to start with a basic system and customize it to your needs. Although these services enable you to provide support for other systems on the network, they also open up your system and provide vectors for attackers. However, these hacks for network services should enable you to run the servers you want and need, without opening you up to too much risk.