By Rainer Wichmann [ support@la-samhna.de] (last update: Sep 14, 2005)
The following is a short tutorial that explains how to determine which network services are active, and how to shutdown/disable unneccessary services. It is intended mainly for unexperienced Linux users, although not all of the information given here is Linux-specific.
Which services are active ?
Internet services are provided by processes that listen on one or more port(s) for incoming requests (e.g. the request to deliver email to your computer). You can determine the active internet services with netstat -pant. Below is some sample output (truncated to the relevant part). It shows a list of port numbers (22, 25, 80, ...) on which some process is listening.
bash$ netstat -pant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:7 0.0.0.0:* LISTEN 376/xinetd tcp 0 0 0.0.0.0:9 0.0.0.0:* LISTEN 376/xinetd tcp 0 0 0.0.0.0:13 0.0.0.0:* LISTEN 376/xinetd tcp 0 0 0.0.0.0:19 0.0.0.0:* LISTEN 376/xinetd tcp 0 0 0.0.0.0:37 0.0.0.0:* LISTEN 376/xinetd tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 8439/mysqld tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11208/apache2 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 8717/sshd tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN 11244/cupsd tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 8527/master
With netstat -pat, you will see the name of the protocol instead of the port number. E.g., 22 will become ssh, 25 = smtp (email), 80 = www-http, etc. The protocols corresponding to numerical port numbers are listed in /etc/services.
If you want to disable a service, you need know which program provides this service. With netstat you need to specify the command line option -p to get the name of the command / executable listening on some port.
Alternatively, you can use another tool - lsof - that will tell you which program listens on which port. Below, you can see some sample output from lsof -i (this time with protocol names instead of port numbers):
bash$ lsof -i COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME xinetd 376 root 5u IPv6 265 UDP *:time xinetd 376 root 6u IPv6 266 TCP *:time (LISTEN) xinetd 376 root 7u IPv6 267 UDP *:daytime xinetd 376 root 8u IPv6 268 TCP *:daytime (LISTEN) xinetd 376 root 9u IPv6 269 UDP *:chargen xinetd 376 root 10u IPv6 270 TCP *:chargen (LISTEN) xinetd 376 root 11u IPv6 271 TCP *:echo (LISTEN) xinetd 376 root 12u IPv6 272 UDP *:echo xinetd 376 root 13u IPv6 273 TCP *:discard (LISTEN) xinetd 376 root 14u IPv6 274 UDP *:discard mysqld 8439 mysql 3u IPv4 12640 TCP *:mysql (LISTEN) master 8527 root 11u IPv4 12822 TCP *:smtp (LISTEN) sshd 8717 root 3u IPv4 13156 TCP *:ssh (LISTEN) apache2 11208 root 4u IPv4 25760 TCP *:www (LISTEN) apache2 11209 www-data 4u IPv4 25760 TCP *:www (LISTEN) apache2 11210 www-data 4u IPv4 25760 TCP *:www (LISTEN) apache2 11211 www-data 4u IPv4 25760 TCP *:www (LISTEN) apache2 11212 www-data 4u IPv4 25760 TCP *:www (LISTEN) apache2 11215 www-data 4u IPv4 25760 TCP *:www (LISTEN) cupsd 11244 cupsys 0u IPv4 25840 TCP *:ipp (LISTEN)
You can see that (e.g.) the ssh (secure shell) service is provided by the command sshd. Also, obviously there is one command xinetd that provides multiple services (time, daytime, chargen, echo, discard). xinetd (and inetd, which is a similar program) is a "super-daemon" that waits for requests on specified ports and then starts up the appropriate program to handle that request.
local services
Consider the following output of netstat -pant:
bash$ netstat -pant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 8439/mysqld tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN 11208/apache2 tcp 0 0 127.0.0.1:22 0.0.0.0:* LISTEN 8717/sshd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 11244/cupsd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 8527/master
... and compare it to the following:
bash$ netstat -pant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 8439/mysqld tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11208/apache2 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 8717/sshd tcp 0 0 0.0.0.0:631 0.0.0.0:* LISTEN 11244/cupsd tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 8527/master
Did you spot the difference? In the first example, each service was listed with 127.0.0.1 as 'Local Address', while in the second example the 'Local Address' is always 0.0.0.0.
If a service shows 127.0.0.1 as 'Local Address', it can only be accessed from the local host, not by any remote host, i.e. it is pretty safe to keep it running.
However, if a service shows 0.0.0.0 as 'Local Address', it can be accessed from any remote host, and you should reconsider whether you really need to run it this way. Here are a few tips to make a service local:
mysqld
In /etc/my.cnf (or /etc/mysql/my.cnf), set:
[mysqld] bind-address = 127.0.0.1
apache 2
Search for 'Listen' in /etc/apache2/*:
bash$ grep 'Listen' /etc/apache2/* /etc/apache2/ports.conf:Listen 80
...and modify it to include the string '127.0.0.1:' before the port number:
bash$ grep 'Listen' /etc/apache2/* /etc/apache2/ports.conf:Listen 127.0.0.1:80
sshd
In /etc/ssh/sshd_config, set:
ListenAddress 127.0.0.1
cupsd
In /etc/cups/cupsd.conf, search for 'Listen' and prefix the port number with '127.0.0.1:' as shown here:
Listen 127.0.0.1:631
postfix (master)
In /etc/postfix/main.cf, set:
inet_interfaces = loopback-only
switching off inetd/xinetd services
With the information you have gathered so far, you can shutdown and disable services that you don't need. First, let's discuss services run from the inetd or xinetd deamon. To switch these off, simply comment them out in the inetd / xinetd (whichever you use) configuration file.
inetd is configured by the file /etc/inetd.conf. To switch off services run from inetd, simply comment them out in the configuration file:
Before:
discard stream tcp nowait root internal discard dgram udp wait root internal daytime stream tcp nowait root internal daytime dgram udp wait root internal chargen stream tcp nowait root internal chargen dgram udp wait root internal time stream tcp nowait root internal time dgram udp wait root internal
After:
# discard stream tcp nowait root internal # discard dgram udp wait root internal # daytime stream tcp nowait root internal # daytime dgram udp wait root internal # chargen stream tcp nowait root internal # chargen dgram udp wait root internal # time stream tcp nowait root internal # time dgram udp wait root internal
You must send the SIGHUP signal to inetd for the changes to take effect. Use ps -aux | grep inetd to find the PID (process identification number):
# ps aux | grep inetd root 376 0.0 0.6 1796 852 ? S 00:43 0:00 /usr/sbin/inetd root 3131 0.0 0.4 1272 520 pts/0 S 10:33 0:00 grep inetd # kill -HUP 376
xinetd is configured by the file /etc/xinetd.conf. You can mark services as disabled in this file and send SIGUSR1 to the xinetd process to make the changes take effect:
Before:
defaults { .... }
After:
defaults { .... disabled = ftp disabled = discard disabled = chargen disabled = daytime disabled = time disabled = echo }
You must send the SIGHUP signal to xinetd for the changes to take effect. Use ps -aux | grep xinetd to find the PID (process identification number):
# ps aux | grep xinetd root 376 0.0 0.6 1796 852 ? S 00:43 0:00 /usr/sbin/xinetd root 3131 0.0 0.4 1272 520 pts/0 S 10:33 0:00 grep xinetd # kill -HUP 376
switching off standalone services
runlevels
Services not run from inetd / xinetd are usually started at system boot. This is controlled by a group of directories named /etc/rc1.d, /etc/rc2.d, ... (Debian, Fedora) or /etc/init.d/rc1.d, /etc/init.d/rc2.d/, ... (SuSE) or /etc/runlevels/.../ (Gentoo).
The numbers in the directory names correspond to runlevels (on Gentoo, runlevels are named, not numbered), and scripts (or links to scripts) in such a directory identify the services that are active in the respective runlevel.
A runlevel is basically a software configuration of the system. E.g. there is a single-user runlevel, a runlevel with network, multi-user, and X, etc. On Linux, the present runlevel can be determined from the runlevel command (order: previous(N=none), current), so this is runlevel 3:
# runlevel N 3
The default runlevel is configured in /etc/inittab. E.g. the following line in /etc/inittab selects 2 as the default runlevel.
# The default runlevel. id:2:initdefault:
There is usually a main directory (/etc/init.d or /etc/rc.d) that holds startup scripts for each service. Each script is named after the respective command (e.g. for starting sshd there is a script that also is named sshd). In the individual runlevel directories there are links to that script which are named (e.g.) Sxxsshd, Kxxsshd.
# ls -l /etc/rc3.d/*sshd lrwxrwxrwx 1 root root 11 Jul 30 19:18 /etc/rc3.d/K20sshd -> ../init.d/sshd lrwxrwxrwx 1 root root 11 Jul 30 19:18 /etc/rc3.d/S20sshd -> ../init.d/sshd
The links starting with "S" are for starting the service, and those with "K" are for stopping the service. The "xx" is a number indicating the order in which the startup/stop scripts are executed.
stopping a service
To stop the service immediately, execute the startup/stop script manually, using stop as argument:
# /etc/init.d/sshd stop
preventing a service from startup at system boot
To prevent a service from becoming active at system boot, simply remove the corresponding link for the runlevel into which your system boots by default (should you ever want to run the service again, just recreate the links).
Most Linux distributions provide tools to handle this. For all of them, the argument service-name is the name of the script in /etc/init.d that starts the respective service:
Debian, Ubuntu: update-rc.d -f service-name remove
SuSE: insserv -r service-name
Fedora: chkconfig --del service-name
Gentoo: rc-update del service-name
Of course, you can also just delete the symlinks manually. E.g. the following commands disable ssh in runlevel 2 on Debian:
# rm /etc/rc2.d/S20sshd # rm /etc/rc2.d/K20sshd