====== Ubuntu - LAMP Server ====== A LAMP Server is a combination of: * Linux OS * Apache web server * MySql database * PHP support The following instructions setup a fully functional LAMP web server with SSL/TLS certificate, FTP server and software firewall. ---- ===== Ensure your system is up to date ===== Upgrade all packages to the latest versions: sudo apt update && apt upgrade ---- ===== Install MySql database server ===== The standard respositories may have an older version of MySQL. To get more recent version, additional steps are needed. ==== Download the MySQL APT repository config tool ==== See http://dev.mysql.com/downloads/repo/apt/ for latest version. wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb ---- ==== Install the MySQL APT repository config tool ==== sudo 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. ---- ===== Update APT ===== sudo apt update ---- ==== Install the MySQL server ==== sudo apt 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. ---- ===== 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. ==== Install the packages ==== sudo apt install apache2 libapache2-mpm-itk php php-mysql ---- ==== 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://). sudo a2enmod rewrite sudo a2enmod ssl ---- ==== 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. sudo apt install php-curl php-gd php-mcrypt php-mbstring php-xml ---- ==== Restart Apache ==== Restart Apache to enable the modules and any additional PHP modules installed. sudo systemctl restart apache2 ---- ==== 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. To provide the least amount of detail, let’s just empty the file. sudo echo "" > /var/www/html/index.html ---- ===== Create the Web Server ===== 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. ==== Create the local user ==== In this tutorial we’ll use the domain example.org 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. sudo 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. ---- ==== 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/example.org. 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. sudo mkdir /home/example/example.org sudo chown example.example /home/example/example.org ---- ==== Create a Apache site ==== Using this command we’ll tell Apache to respond to requests to the hosts example.org and www.example.org and use our web root directory for that hosts. Also here we’ll configure the local user that should be used. sudo echo " ServerName example.org ServerAlias www.example.org DocumentRoot /home/example/example.org AssignUserId example example Options -Indexes AllowOverride All Require all granted " > /etc/apache2/sites-available/example.org.conf ---- ==== 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: sudo a2ensite example.org ---- ==== Reload the Apache config ==== To tell Apache to use our new site reload the config. sudo systemctl reload apache2 Now if you go to http://example.org (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. ---- ===== 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. ==== Install certbot ==== Certbot is used to handle the certificate request and renewal sudo apt install python-certbot-apache ---- === 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. sudo echo "Alias /.well-known/acme-challenge /var/www/html/.well-known/acme-challenge AssignUserId www-data www-data " > /etc/apache2/mods-enabled/letsencrypt.conf ---- ==== Restart Apache ==== sudo systemctl restart apache2 ---- ==== Run certbot to select which sites should be protected and automatically request and install the certificate ==== sudo 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. https://example.org ---- ==== Configure auto renewal of letsencrypt certificates ==== sudo crontab -e 43 6 * * * certbot renew --post-hook "systemctl reload apache2" ---- ===== Install phpMyAdmin (optional) ===== phpMyAdmin is a tool written in PHP, intended to handle the administration of MySQL over the Web. ==== Install phpMyAdmin ==== sudo apt 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 https://example.org/phpmyadmin (if you have already created a letsencrypt certificate) or http://example.org/phpmyadmin (if you skipped the letsencrypt step). ---- ==== 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 ==== sudo systemctl restart apache2 ---- ===== 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. ==== Install vsftpd ==== sudo apt install vsftpd ---- ==== Setup User Permissions ==== 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 sudo echo "write_enable=YES chroot_local_user=YES" >> /etc/vsftpd.conf ---- ==== Restart vsftpd ==== sudo /etc/init.d/vsftpd restart ==== 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/example.org). sudo chmod u-w /home/example vsftpd is now installed and you can connect to the server using any FTP client. ---- ===== 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. ==== Enable ip_conntrack_ftp to allow passive FTP connections ==== sudo echo "ip_conntrack_ftp" >> /etc/modules sudo echo "net.netfilter.nf_conntrack_helper=1" >> /etc/sysctl.conf To get passive FTP running you need to restart the server ==== Allow ICMP, established and local connections ==== sudo iptables -A INPUT -p icmp -j ACCEPT sudo iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED sudo iptables -A FORWARD -j ACCEPT -m state --state ESTABLISHED,RELATED sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A FORWARD -o lo -j ACCEPT ---- ==== Allow all users to connect to web services (http and https), ssh and ftp ==== sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -p tcp -m tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT sudo iptables -A INPUT -p tcp -m tcp --dport 20 -m conntrack --ctstate ESTABLISHED -j ACCEPT sudo 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.8.8.8) ---- ==== Allow all outgoing connections from the server ==== sudo iptables -P OUTPUT ACCEPT ---- ==== 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. sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP ---- ==== Save iptable rules ==== 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. sudo apt install iptables-persistent sudo 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.