Haacking-Club/Apache Survival

--- * **apachesurvival** * **Jonathan Haack** * **Haack's Networking** * **netcmnd@jonathanhaack.com**

---

//apachesurvival//

---

This tutorial is for users of Debian GNU/Linux using the LAMP stack, wanting TLS encryption, multiple self-hosted websites and will cover:

* Establish LAMP stack and set-up TLS w/ Let's Encrypt * Virtual hosts for more than one website on same server * Permissions and Firewall

The tutorial below creates two virtual hosts, for registered domain site1.com and site2.com, and this can be scaled to as many as you like and/or your host will serve properly:

sudo apt install apache2 php mysql-server sudo mkdir -p /var/www/site1.com/public_html sudo mkdir -p /var/www/site2.com/public_html sudo chown -R $USER:$USER /var/www/site1.com/public_html sudo chown -R $USER:$USER /var/www/site2.com/public_html sudo chmod 755 /var/www Okay, for the first website, create your index.html:

sudo nano /var/www/site1.com/public_html/index.html

Give it some simple html:

site1 site1

Same for the second website, open the file: sudo nano /var/www/site2.com/public_html/index.html Give it some simple html to distinguish it: site2 site2 Now, copy the default virtual host configuration to a new .conf file for each site: sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/site1.com.conf sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/site2.com.conf Open the first virtual host conf for the first website: sudo nano /etc/apache2/sites-available/site1.com.conf Adjust to something like this:  ServerAdmin name@site1.com ServerName site1.com ServerAlias www.site1.com DocumentRoot /var/www/site1.com/public_html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined  Repeat the steps above for the second virtual host site2.com.conf. Ok, now time to enable the virtual hosts with the a2ensite command, and disable the default site since you won't need that any longer: sudo a2ensite site1.com.conf sudo a2ensite site2.com.conf sudo cp -r /var/www/html /root/html-bak sudo rm -r /var/www/html sudo a2dissite 000-default.conf Now, if you prefer put some local dns entries in /etc/hosts sudo nano /etc/hosts Append something like this to the bottom: xxx.xxx.xxx.xxx site1.com xxx.xxx.xxx.xxx www.site1.com xxx.xxx.xxx.xxx site2.com xxx.xxx.xxx.xxx www.site2.com Check your configurations up until now and then restart the service and check if it starts:

sudo apache2ctl configtest sudo systemctl restart apache2.service Visit site1.com and site2.com and debug. Once both properly resolve, it is time to set up TLS. If this is a public IP on a VPS, then at a minimum, set up ufw to allow http/https and provide access for you to ssh: sudo apt install ufw sudo ufw allow 22 sudo ufw allow 80 sudo ufw allow 443 sudo ufw enable It is always a good idea to first create your own self-signed certificates for each virtual host:

sudo openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout /etc/ssl/private/site1.key -out /etc/ssl/certs/site1.crt sudo openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout /etc/ssl/private/site1.key -out /etc/ssl/certs/site1.crt Answer the questions, and pay careful attention to the email parameter because when we switch to Let's Encrypt, it will harvest that email and use it to contact you. You should now configure a diffie-hellman key for secure key exchange:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 You can simply add all of your TLS options to the default-ssl.conf, or you can create a snippet: sudo nano /etc/apache2/conf-available/ssl-params.conf Having thus created the snippet, here are some recommended configurations and sources that document them: # from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLProtocol All -SSLv2 -SSLv3 SSLHonorCipherOrder On # Disable preloading HSTS for now. You can use the commented out header line that includes # the "preload" directive if you understand the implications. Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains" #Nextcloud prefers this rule with the other Header rules below it for X, disabled: #Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" Header always set X-Frame-Options DENY Header always set X-Content-Type-Options nosniff # Requires Apache >= 2.4 SSLCompression off SSLSessionTickets Off SSLUseStapling on  SSLStaplingCache "shmcb:logs/stapling-cache(150000)" SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

Don't forget to enable this configuration:

sudo a2enconf ssl-params

Configure the TLS virtual hosts for each domain previously configured above. If you chose not to do the snippet approach above, then you will start here and skip the snippet portion (and merely add any configurations you need to the ssl virtual hosts directly):

sudo cp /etc/apache2/sites-available/default-ssl.conf /root/default-ssl.conf.bak sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/site1.com-ssl.conf sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/site2.com-ssl.conf

Open the first TLS virtual host configuration file:

sudo nano /etc/apache2/sites-available/site1.com-ssl.conf Uncomment the legacy support at the end and enter the standard configurations at the top:

        ServerAdmin name@site1.com ServerName site1.com DocumentRoot /var/www/site1.com/public_html  BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0  

Repeat the steps above for the site2.com-ssl.conf virtual host. If you want to enter some modules, then do so after the "downgrade line" and before the  line and start with  and end with . Now, you can redirect the original sites-enabled to default to TLS (or, skip this, and let Let's Encrypt handle it - but do not do both). Open site1.com virtual host (non TLS) conf file:

sudo nano /etc/apache2/sites-available/site1.com.conf At the top, just under the DocumentRoot, enter something like: Redirect permanent "/" "https://site1.com/ Repeat this for the site2.conf file. Now, check your configuration again and enable headers and mods:  sudo a2enmod ssl  sudo a2enmod headers  sudo a2enconf ssl-params  sudo apache2ctl configtest You may get a trivial error if you do not have your ServerName set to localhost in the global configuration file located at /etc/apache2/apache2.conf.  Once that is done, and if everything looks good, enable the TLS virtual hosts:

sudo a2ensite site1.com-ssl.conf sudo a2ensite site2.com-ssl.conf Visit both sites using Firefox, and ensure they resovle. Now, set up Let's Encrypt so that you have your TLS certificates managed by a proper authority. I have never been able to get the stock certbot instructions to work, so I found this on a certbot tech support git repo, and have used it every since

sudo apt install certbot letsencrypt python-certbot-apache sudo certbot --authenticator standalone --installer apache -d site1.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"

Run the second command again, but adjust it for site2.com. Now, restart the service:

sudo systemctl restart apache2 You can optionally verify them with ACME:

https://www.ssllabs.com/ssltest/analyze.html?d=site1.com&latest https://www.ssllabs.com/ssltest/analyze.html?d=site2.com&latest Let's Encrypt expires often, so you likely want a cron job to update everything for you when/if needed: sudo crontab -e 30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log sudo systemctl restart cron.service sudo systemctl restart apache2 You can also manually check certificates by:

sudo certbot renew I have some servers in production that seem to just stop apache for whatever reason, so to limit downtime after all this work, you can create a simple monitoring script called apache-restart.sh:

sudo touch /usr/local/bin/apache-restart.sh sudo chmod 750 /usr/local/bin/apache-restart.sh  sudo chown $USER:$USER /usr/local/bin/apache-restart.sh  sudo nano /usr/local/bin/apache-restart.sh Ok, now that we created the script file and made it executable, paste in the contents below but adjust them to your needs:

#!/bin/bash #functions RESTART="/bin/systemctl restart apache2.service" SERVICE="apache2.service" LOGFILE="/home/username/Desktop/apache-restart.log" if     systemctl status apache2.service | grep dead then echo "Sir, apache2 failed at $(date), so I restarted it for you." >> $LOGFILE else echo "Ms., apache2 was running as of $(date)" >> $LOGFILE #or leave the else empty if you prefer fi

Okay, now let's make sure your log files do not get too large. First create a new entry in the logrotate daemon directory:

sudo nano /etc/logrotate.d/apache-restart

In that file that you just opened, enter some common sense limits for the log file so your computer does not fill up with logs:

/home/user/Desktop/apache-restart.log { daily rotate 10 delaycompress compress notifempty missingok size 100000k }

Alright, no point in making an apache monitoring script unless it runs automatically, so let's create a cron job:

sudo crontab -e * * * * * /bin/bash /usr/local/bin/apache-restart.sh >> /home/user/Desktop/apache-restart.log sudo systemctl restart cron

Test it, by stopping the service, and then waiting a minute.

sudo systemctl stop apache2 Check the logfile to verify it is working:

cat /home/user/Desktop/apache-restart.log

Cool! You now have two websites that are TLS encrypted! Now, it is time to put some content on that site, so consider these tutorials:

* [|Self-Hosted Word Press] * [|Manually Migrating Word Press] * [|Nextcloud] * [|Moodle] * [|Dokuwiki] * [|Smokeping] * [|Cacti] * [|Gitlab-ce] (requires extensive mods)

Also, you probably want to keep this host up to date, and you may have others, so consider reading the tutorial below, which covers how to do remote upgrades easily:

* [|Upgrades]

I keep the scripts up to date on my repo, over here:

* [|Haacking Club]

This tutorial is a designated "Invariant Section" of the "Technotronic" section of Haack's Wiki as described on the [|Start Page].

--- //oemb1905 2019/07/27 00:15//