By Rainer Wichmann rainer@
la-samhna.de (last update: May 08, 2014)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
tcp6 0 0 ::1:631 :::* LISTEN 11244/cupsd
tcp6 0 0 :::25 :::* 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.
As you can see, some services may be offered both on IPv4 as well as on IPv6 (the latter being marked as 'tcp6' by netstat), e.g. in the example above the smtp (email) server and the cupsd (printer) server listen both on IPv4 as well as IPv6. Yoa also see that the printer server (cupsd) only liustens on the local IPv6 interface (::1) and therefore cannot be accessed from the outside.
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.
For IPv6, the equivalent of "127.0.0.1" is "::1", so any service showing up with this address is only accessible from the local host. The IPv6 equivalent of "0.0.0.0" is "::"
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 - Ubuntu 'upstart'
This section explains how to switch off a service handled by the 'upstart' service which is used by Ubuntu Linux. For the traditional SYS V init method see next section.
Temporarily switching off/on a service
To switch off a service temporarily, use the command service servicename stop, e.g.
# service ssh stop
To switch on a service again, use the command service servicename start, e.g.
# service ssh start
Prevent a service from starting at boot
For every service handled by upstart, there exist an init script in the directory /etc/init which is named /etc/init/servicename.conf
To prevent a service from starting at system boot, you could just remove that script or simply rename it to remove the .conf at the end. However, this isn't really a good idea because the next software update will likely restore it. You can also edit the file and comment out the line near the top starting with "start on".
The recommended way (as of Ubuntu 11.10) is to create a file /etc/init/servicename.override with the single line manual:
# echo "manual" > /etc/init/servicename.override
switching off standalone services - tradidional SYS V
This section explains how to switch off a service handled by traditional SYS V init scripts.
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
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Germany License.