Debian Tutorials

Debian Tutorials

Step by step tutorials showing you how to install and configure various applications and services on Debian based Linux distros.

July 2024


How to set up a web server (LAMP) on Debian 9 (stretch)

Ástþór IPÁstþór IP
The acronym LAMP refers to a software stack combination of a Linux OS with Apache web server, MySql database server and PHP support.


This tutorial has been tested on the following Linux distributions:

Debian Linux 9 (Squeeze)

Last updated:
7th of April 2018

In this tutorial we’ll install the Debian Linux 9 (squeeze), Apache 2 with mpm-itk (to run each web as a isolated user), PHP 7 support and MySql 5.7 database server. Additionally the tutorial covers installation of the vsftp server to provide FTP service, setting up letsencrypt and requesting a free certificate, installation of phpMyAdmin and configuring the iptables firewall to protect the server and only allow required ports. Once you have followed the tutorial you’ll have a fully functional and secure web server ready to host your web sites.

1. Get your system up to date

Before moving any further, let’s upgrade all packages to the latest versions.

apt-get update && apt-get upgrade

2. Install MySql 5.7 database server

By default MySql 5.5 is included in the standard debian repositories which is a very old version. We’ll install MySql 5.7 in this tutorial which requires a few additional steps.

2.1. Download the MySQL APT repository config tool (you can see more details and the latest version of the tool here:


2.2. Install the MySQL APT repository config tool

dpkg -i mysql-apt-config_0.8.9-1_all.deb

You will be asked to select product and version that you want to install. In the first step, select Server and next select mysql-5.7. Then click Apply.

2.3. Update APT

apt-get update

2.4. Install the server

apt-get install mysql-community-server

When the server has been installed you’ll have to provide a password for the root user. Choose any password here but make sure it’s a strong password and something you remember.

3. Install and configure Apache web server with mpm-itk and PHP7 support

The mpm-itk is ideal when hosting multiple web sites on a single server to isolate the sites. Using mpm-itk you can make sure one web site cannot access files from another one if the permissions are configured correctly, more on that later.

3.1. Install the packages

apt-get install apache2 libapache2-mpm-itk php php-mysql

3.2. Enable the rewrite and ssl modules

The rewrite module is very useful to create SEO friendly urls for your web site and required by many frameworks and web applications. The SSL module is required to secure your web site with SSL/TLS (to use https:// instead of http://).

a2enmod rewrite
a2enmod ssl

3.3. Install additional PHP modules (optional)

You may need some additional PHP modules to run your web applications. The modules required will vary but using the command below you can install some commonly used modules.

apt-get install php-curl php-gd php-mcrypt php-mbstring php-xml

3.4. Restart Apache to enable the modules and any additional PHP modules installed

systemctl restart apache2

3.5. Remove the default index site provided with Apache (optional)

If you access your server now using http://yourserver you’ll see the default index page with some details about your server. You probably don’t want to tell people too much about the server so I suggest replacing this file with something different. Too provide the least amount of detail, let’s just empty the file.

echo "" > /var/www/html/index.html

4. Create a web (user, web root and apache virtual host)

For each web site that you want to host on this server, you should create a separate local user and to isolate the webs. The mpm-itk will make sure that every action is executed using the user you provide in the apache virtual host.

4.1. Create the local user

In this tutorial we’ll use the domain but you should of course replace the domain with the one that you’ll be using. The username containing the web root can be anything and doesn’t have to be related to the web’s domain at all but we’ll use example as the username here.

adduser example

This command will create a user with the username example and create a home directory for that user in /home/example. You’ll have to provide a password and you can provide some optional information about the user.

4.2. Create a web root directory

The web root is the directory that your web site is stored. The directory can be located anywhere but you just have to make sure that the user has access to read from it. In this tutorial the web root will be located in /home/example/

Using the chown command we’ll change the ownership of the new directory so that the example user (and the example group) have access to it.

mkdir /home/example/
chown example.example /home/example/

4.3. Create a Apache site

Using this command we’ll tell Apache to respond to requests to the hosts and and use our web root directory for that hosts. Also here we’ll configure the local user that should be used.

echo "<VirtualHost *:80>
DocumentRoot /home/example/
AssignUserId example example
<Directory /home/example/>
Options -Indexes
AllowOverride All
Require all granted
" > /etc/apache2/sites-available/

4.4. Enable the Apache site

We’ve located the site config in the sites-available directory. This can be useful to be able to easily enable and disable sites using the a2ensite and a2dissite commands. To enable the site we’ll have to execute the following command:


4.5. Reload the Apache config

To tell Apache to use our new site reload the config.

systemctl reload apache2

Now if you go to (or a domain that’s pointing to your server’s IP address) you’ll see a 403 Forbidden error if you haven’t already placed any files in the web root. This is normal because in the site’s config we have disabled directory indexing.

5. Secure your site with Letsencrypt (optional)

Let’s Encrypt is a certificate authority that provides free SSL/TLS certificates that are instantly validated and signed and can be used to secure your web site. Certificates are valid for 90 days but you can easily set up a task to handle the renewal automatically.

5.1. Install certbot which is used to handle the certificate request and renewal.

apt-get install python-certbot-apache

5.2. Configure Apache to allow the http verification

Since we’re using mpm-itk certbot won’t work out of box as the verification files are created using the root user and are not accessible from your website. To work around this we’ll add a new Apache module to force Apache to use a different user to read these files.

echo "Alias /.well-known/acme-challenge /var/www/html/.well-known/acme-challenge
<Directory /var/www/html/.well-known>
AssignUserId www-data www-data
</Directory>" > /etc/apache2/mods-enabled/letsencrypt.conf

Restart Apache

systemctl restart apache2

5.3 Run certbot to select which sites should be protected and automatically request and install the certificate.

certbot --authenticator webroot --installer apache

You need to follow a few steps to complete the request and installation of the certificate:

Step 1: Type a comma separated list of the numbers representing the hostnames that should be protected. If you have only one Apache site configured, you can type 1,2 here.

Step 2: Provide a e-mail address used for urgent renewal and security notices. Type a valid e-mail address here that you monitor frequently.

Step 3: Agree to the terms of service.

Step 4: Provide a web root. Type 1 and type the well-known root configured earlier: /var/www/html. Next you’ll have to confirm that directory for each additional hostname that will be included in the certificate.

Step 5: Certbot will automatically create a Apache web site with your new SSL/TLS certificate. In this step you can select whether both http and https are allowed or if http requests should be redirected to https. Select the method you prefer.

You can now access your site using https, ex.

5.4 Configure auto renewal of letsencrypt certificates

crontab -e
43 6 * * * certbot renew --post-hook "systemctl reload apache2"

6. Install phpMyAdmin (optional)

phpMyAdmin is a tool written in PHP, intended to handle the administration of MySQL over the Web.

6.1. Install phpMyAdmin

apt-get install phpmyadmin

There are a few steps required to configure phpMyAdmin:

Step 1: You’ll be asked which web server should be configured. Check apache2 and continue.

Step 2: Configure a database for phpmyadmin. Select Yes.

Step 3: Set a password for the phpmyadmin user. This is used only by phpmyadmin so you can go ahead and allow the tool to create a random password.

Step 4: You need to provide the root password selected when you installed the MySql server.

phpMyAdmin is now installed and you can access it on (if you have already created a letsencrypt certificate) or (if you skipped the letsencrypt step).

6.2. IP Restrict access to phpMyAdmin (optional)

phpMyAdmin is a great tool for managing MySql but you should not allow anyone to access the tool as that will make it easier to access your databases. Although a password is required, brute force method or vulnerabilities in phpMyAdmin could be used to gain access.

Let’s only allow certain IP addresses to access phpMyAdmin.

Open /etc/apache2/conf-available/phpmyadmin.conf in your favorite text editor (ex. nano /etc/apache2/conf-available/phpmyadmin.conf)

Add these lines below DirectoryIndex index.php (7. line):

order deny,allow
deny from all
allow from x.your.ip.address

Restart Apache

systemctl restart apache2

7. Install and configure FTP service

vsftpd is a secure, fast and stable FTP server. In this tutorial we’ll install the vsftpd allowing local users to access their home directories.

7.1. Install vsftpd

apt-get install vsftpd

7.2. Allow users to upload files instead of just reading files and enable chroot to make sure the users won’t be able to read files outside their home directories.

echo "write_enable=YES
chroot_local_user=YES" >> /etc/vsftpd.conf

7.3. Restart vsftpd

/etc/init.d/vsftpd restart

7.4. Change the permissions on the user’s home directory

When chroot is enabled, we must remove write access to the home directory which means that the user cannot upload new files directly to the home directory. The user can however upload files to subfolders in the home directory, including the web root directory, (ex. /home/example/

chmod u-w /home/example

vsftpd is now installed and you can connect to the server using any FTP client.

8. Configure iptables firewall

It’s generally a good idea to disallow access to any ports that doesn’t have to be accessed by anonymous users. Even if all services are password protected they can be hacked using brute force or vulnerabilities in the applications.

We’ll use the iptables firewall and only allow http, https, ssh and ftp for anonymous users.

8.1. Enable ip_conntrack_ftp to allow passive FTP connections

echo "ip_conntrack_ftp" >> /etc/modules
echo "net.netfilter.nf_conntrack_helper=1" >> /etc/sysctl.conf

To get passive FTP running you need to restart the server

8.2. Allow ICMP, established and local connections

iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
iptables -A FORWARD -j ACCEPT -m state --state ESTABLISHED,RELATED
iptables -A INPUT -i lo -j ACCEPT
iptables -A FORWARD -o lo -j ACCEPT

8.3. Allow all users to connect to web services (http and https), ssh and ftp

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 20 -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Consider restricting access to ssh and ftp only to required ip addresses using the -s parameter (ex. -s

8.4. Allow all outgoing connections from the server.


8.5. Drop all incoming connections that don’t match the previous created rules. Make sure you have already allowed your ip address (or all ip addresses) to connect to SSH because otherwise your connection will be dropped and you’ll be locked out from your server.

iptables -P INPUT DROP
iptables -P FORWARD DROP

8.6. Now we’ve set up all required iptables rules but they are temporary and will be lost on next reboot. To store the rules permanently, we’ll have to install the iptables-persistent package and save the rules.

apt-get install iptables-persistent
iptables-save > /etc/iptables/rules.v4

That’s it! Now you should have a fully functional LAMP web server with SSL/TLS certificate, FTP server and software firewall.

Comments 0
There are currently no comments.