5.3. Configuring Services
In this section we will take a look at services (sometimes called daemons), or programs that run as a background process and perform various functions for the system. We will start by discussing configuration files and will proceed to explain how some important services (such as SSH, PostgreSQL, and Apache) function and how they can be configured.
Kali Linux's policy is to have any network services disabled by default, which is a different behavior to other Linux operating systems. For more information see Section 1.5, “Kali Linux Policies”.
When you want to configure an unknown package, you must proceed in stages. First, you should read what the package maintainer has documented. The /usr/share/doc/package/README.Debian file is a good place to start. This file will often contain information about the package, including pointers that may refer you to other documentation. You will often save yourself a lot of time, and avoid a lot of frustration, by reading this file first since it often details the most common errors and solutions to most common problems.
Next, you should look at the software's official documentation. Refer to Section 6.1, "Documentation Sources" for tips on how to find various documentation sources. The dpkg -L package command gives a list of files included in the package; you can therefore quickly identify the available documentation (as well as the configuration files, located in /etc/). Also, dpkg -s package displays the package meta-data and shows any possible recommended or suggested packages; in there, you can find documentation or perhaps a utility that will ease the configuration of the software.
Finally, the configuration files are often self-documented by many explanatory comments detailing the various possible values for each configuration setting. In some cases, you can get software up and running by uncommenting a single line in the configuration file. In other cases, examples of configuration files are provided in the /usr/share/doc/package/examples/ directory. They may serve as a basis for your own configuration file.
SSH allows you to remotely log into a machine, transfer files, or execute commands. It is an industry standard tool (ssh) and service (sshd) for connecting to machines remotely.
While the openssh-server package is installed by default, the SSH service is disabled by default and thus is not started at boot time. You can manually start the SSH service with systemctl start ssh or configure it to start at boot time with systemctl enable ssh.
The SSH service has a relatively sane default configuration, but given its powerful capabilities and sensitive nature, it is good to know what you can do with its configuration file, /etc/ssh/sshd_config. All the options are documented in sshd_config(5) (see Section 6.1.1, “Manual Pages”).
The default configuration allows password-based logins. If this is not wanted, you can disable this by setting PasswordAuthentication to no. Doing so will mean that and SSH key will need to be generated. The SSH service listens by default on port 22 but you can change this with the Port directive.
To apply the new settings, you should run systemctl reload ssh.
PostgreSQL is a database server. It is rarely useful on its own but is used by many other services to store data. Those services will generally access the database server over the network and usually require authentication credentials to be able to connect. Setting up those services thus requires creating PostgreSQL databases and user accounts with appropriate privileges on the database. To be able to do that, we need the service to be running, so let's start it with systemctl start postgresql.
By default, PostgreSQL listens for incoming connections in two ways: on TCP port 5432 of the localhost interface and on file-based socket /var/run/postgresql/.s.PGSQL.5432. This can be configured in postgresql.conf with various directives: listen_addresses for the addresses to listen to, port for the TCP port, and unix_socket_directories to define the directory where the file-based sockets are created.
Depending on how they connect, clients are authenticated in different ways. The pg_hba.conf configuration file defines who is allowed to connect on each socket and how they are authenticated. By default, connections on the file-based socket use the Unix user account as the name of the PostgreSQL user, and it assumes that no further authentication is required. On the TCP connection, PostgreSQL requires the user to authenticate with a username and a password (though not a Unix username/password but rather one managed by PostgreSQL itself).
The postgres user is special and has full administrative privileges over all databases. We will use this identity to create new users and new databases.
The createuser command adds a new user and dropuser removes one. Likewise, the createdb command adds a new database and dropdb removes one. Each of these commands have their own manual pages but we will discuss some of the options here. Each command acts on the default cluster (running on port 5432) but you can pass --port=port to modify users and databases of an alternate cluster.
These commands must connect to the PostgreSQL server to do their job and they must be authenticated as a user with sufficient privileges to be able to execute the specified operation. The easiest way to achieve this is to use the postgres Unix account and connect over the file-based socket:
# su - postgres postgres@kali:~$ createuser -P king_phisher Enter password for new role: Enter it again: postgres@kali:~$ createdb -T template0 -E UTF-8 -O king_phisher king_phisher postgres@kali:~$ exit
In the example above, the -P option asks createuser to query for a password once it creates the new king_phisher user. Looking at the createdb command, the -O defines the user owning the new database (which will thus have full rights to create tables and grant permissions and so on). We also want to be able to use Unicode strings, so we add the -E UTF-8 option to set the encoding, which in turn requires us to use the -T option to pick another database template.
We can now test that we can connect to the database over the socket listening on localhost (-h localhost) as the king_phisher user (-U king_phisher):
# psql -h localhost -U king_phisher king_phisher Password for user king_phisher: psql (9.5.2) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. king_phisher=>
As you can see, the connection was successful.
First, it is worth noting that the concept of "PostgreSQL cluster" is a Debian-specific addition and that you will not find any reference to this term in the official PostgreSQL documentation. From the point of view of the PostgreSQL tools, such a cluster is just an instance of a database server running on a specific port.
That said, Debian's postgresql-common package provides multiple tools to manage such clusters: pg_createcluster, pg_dropcluster, pg_ctlcluster, pg_upgradecluster, pg_renamecluster, and pg_lsclusters. We won't cover all those tools here, but you can refer to their respective manual pages for more information.
What you must know is that when a new major version of PostgreSQL gets installed on your system, it will create a new cluster that will run on the next port (usually 5433) and you will keep using the old version until you migrate your databases from the old cluster to the new one.
You can retrieve a list of all the clusters and their status with pg_lsclusters. More importantly, you can automate the migration of your cluster to the latest PostgreSQL version with pg_upgradecluster old-version cluster-name. For this to succeed, you might have to first remove the (empty) cluster created for the new version (with pg_dropcluster new-version cluster-name). The old cluster is not dropped in the process, but it also won't be started automatically. You can drop it once you have checked that the upgraded cluster works fine.
A typical Kali Linux installation includes the Apache web server, provided by the apache2 package. Being a network service, it is disabled by default. You can manually start it with systemctl start apache2.
With more and more applications being distributed as web applications, it is important to have some knowledge of Apache in order to host those applications, whether for local usage or for making them available over the network.
Apache is a modular server and many features are implemented by external modules that the main program loads during its initialization. The default configuration only enables the most common modules, but enabling new modules is easily done by running a2enmod module. Use a2dismod module to disable a module. These programs actually only create (or delete) symbolic links in /etc/apache2/mods-enabled/, pointing at the actual files (stored in /etc/apache2/mods-available/).
There are many modules available, but two are worth initial consideration: PHP and SSL (used for TLS). Web applications written with PHP are executed by the Apache web server with the help of the dedicated module provided by the libapache-mod-php package, and its installation automatically enables the module.
Apache 2.4 includes the SSL module required for Hypertext Transfer Protocol Secure (HTTPS) out of the box. It first needs to be enabled with a2enmod ssl, then the required directives must be added to the configuration files. A configuration example is provided in /etc/apache2/sites-available/default-ssl.conf. See https://httpd.apache.org/docs/2.4/mod/mod_ssl.html for more information.
The full list of standard Apache modules can be found online at https://httpd.apache.org/docs/2.4/mod/index.html.
With its default configuration, the web server listens on port 80 (as configured in /etc/apache2/ports.conf), and serves pages from the /var/www/html/ directory by default (as configured in /etc/apache2/sites-enabled/000-default.conf).
A virtual host is an extra identity for the web server. The same Apache process can serve multiple websites (say www.kali.org and www.offensive-security.com) because the HTTP requests embed both the name of the website requested and the URL localpart (this feature is known as name-based virtual hosts).
The default configuration for Apache 2 enables name-based virtual hosts. In addition, a default virtual host is defined in the /etc/apache2/sites-enabled/000-default.conf file; this virtual host will be used if no host matching the request sent by the client is found.
Each extra virtual host is then described by a file stored in /etc/apache2/sites-available/. The file is usually named after the hostname of the website followed by a .conf suffix (for example: www.kali.org.conf). You can then enable the new virtual host with a2ensite www.kali.org. Here is a minimal virtualhost configuration for a website whose files are stored in /srv/www.kali.org/www/ (defined with the DocumentRoot option):
ServerName www.kali.org ServerAlias kali.org DocumentRoot /srv/www.kali.org/www
You might also consider adding CustomLog and ErrorLog directives to configure Apache to output logs in files dedicated to the virtual host.
This section briefly reviews some of the commonly-used Apache configuration directives.
The main configuration file usually includes several Directory blocks; they allow specifying different behaviors for the server depending on the location of the file being served. Such a block commonly includes Options and AllowOverride directives:
Options Includes FollowSymLinks AllowOverride All DirectoryIndex index.php index.html index.htm
The DirectoryIndex directive contains a list of files to try when the client request matches a directory. The first existing file in the list is used and sent as a response.
The Options directive is followed by a list of options to enable. The None value disables all options; correspondingly, All enables them all except MultiViews. Available options include:
- ExecCGI—indicates that CGI scripts can be executed.
- FollowSymLinks—tells the server that symbolic links can be followed, and that the response should contain the contents of the target of such links.
- SymLinksIfOwnerMatch—also tells the server to follow symbolic links, but only when the link and its target have the same owner.
- Includes—enables Server Side Includes (SSI). These are directives embedded in HTML pages and executed on the fly for each request.
- Indexes—tells the server to list the contents of a directory if the HTTP request sent by the client points to a directory without an index file (that is, when no files mentioned by the DirectoryIndex directive exist in this directory).
- MultiViews—enables content negotiation; this can be used by the server to return a web page matching the preferred language as configured in the browser.
In some circumstances, access to part of a website needs to be restricted, so only legitimate users who provide a username and a password are granted access to the contents.
The .htaccess file contains Apache configuration directives enforced each time a request concerns an element from the directory where the .htaccess file is stored. These directives are recursive, expanding the scope to all subdirectories.
Most of the directives that can occur in a Directory block are also legal in an .htaccess file. The AllowOverride directive lists all the options that can be enabled or disabled by way of .htaccess. A common use of this option is to restrict ExecCGI, so that the administrator chooses which users are allowed to run programs under the web server's identity (the www-data user).
Example 5.3. .htaccess File Requiring Authentication
Require valid-user AuthName "Private directory" AuthType Basic AuthUserFile /etc/apache2/authfiles/htpasswd-private
The /etc/apache2/authfiles/htpasswd-private file contains a list of users and passwords; it is commonly manipulated with the htpasswd command. For example, the following command is used to add a user or change their password:
# htpasswd /etc/apache2/authfiles/htpasswd-private user New password: Re-type new password: Adding password for user user
The Require directive controls access restrictions for a directory (and its subdirectories, recursively).
It can be used to restrict access based on many criteria; we will stop at describing access restriction based on the IP address of the client but it can be made much more powerful than that, especially when several Require directives are combined within a RequireAll block.
For instance, you could restrict access to the local network with the following directive:
Require ip 192.168.0.0/16