This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
computing:apachesurvival [2018/05/06 08:14] – oemb1905 | computing:apachesurvival [2020/03/27 13:24] – oemb1905 | ||
---|---|---|---|
Line 7: | Line 7: | ||
------------------------------------------- | ------------------------------------------- | ||
- | // | + | // |
------------------------------------------- | ------------------------------------------- | ||
- | This tutorial is for users of Debian GNU/Linux using the LAMP stack, wanting TLS encryption, multiple self-hosted websites, feature rich content management, etc., without sacrificing ownership or security. | + | This tutorial is for users of Debian GNU/Linux using the LAMP stack, wanting TLS encryption, multiple self-hosted websites |
- | * Establish LAMP stack | + | * Establish LAMP stack and set-up TLS w/ Let's Encrypt |
- | * Virtual hosts for more than one website | + | * Virtual hosts for more than one website |
- | * Creation of self-signed SSL | + | * Permissions |
- | * Let's Encrypt with Certbot | + | |
- | * MySQL survival commands | + | |
- | * Installation of Joomla, Wordpress, Dokuwiki, Cacti | + | |
- | * Installation | + | |
- | * Directory permissions | + | |
- | * firewall rules with ufw | + | |
- | * symbolic links for External Drive outside of root of webserver (risky) | + | |
- | There is probably a bit more ... but this will get us started. | + | The tutorial below creates two virtual hosts, for registered domain site1.com and site2.com, and this can be scaled |
- | ------------------------------------------- | + | |
- | + | ||
- | Installing apache, setting up two ore more websites. | + | |
- | + | ||
- | sudo apache2ctl configtest | + | |
- | | + | |
sudo mkdir -p / | sudo mkdir -p / | ||
sudo mkdir -p / | sudo mkdir -p / | ||
sudo chown -R $USER:$USER / | sudo chown -R $USER:$USER / | ||
sudo chown -R $USER:$USER / | sudo chown -R $USER:$USER / | ||
- | sudo chmod -R 755 /var/www | + | sudo chmod 755 /var/www |
- | nano / | + | |
- | + | Okay, for the first website, create your index.html: | |
+ | |||
+ | | ||
+ | |||
+ | Give it some simple html: | ||
< | < | ||
< | < | ||
Line 47: | Line 40: | ||
</ | </ | ||
</ | </ | ||
+ | |||
+ | Same for the second website, open the file: | ||
+ | | ||
+ | sudo nano / | ||
| | ||
- | nano / | + | Give it some simple |
| | ||
< | < | ||
Line 58: | Line 55: | ||
</ | </ | ||
</ | </ | ||
+ | | ||
+ | Now, copy the default virtual host configuration to a new .conf file for each site: | ||
| | ||
sudo cp / | sudo cp / | ||
sudo cp / | sudo cp / | ||
+ | | ||
+ | Open the first virtual host conf for the first website: | ||
| | ||
sudo nano / | sudo nano / | ||
+ | | ||
+ | Adjust to something like this: | ||
| | ||
< | < | ||
Line 73: | Line 76: | ||
</ | </ | ||
| | ||
- | sudo nano / | + | 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: |
- | + | ||
- | < | + | |
- | ServerAdmin name@site2.com | + | |
- | ServerName site2.com | + | |
- | ServerAlias www.site2.com | + | |
- | DocumentRoot / | + | |
- | ErrorLog ${APACHE_LOG_DIR}/ | + | |
- | CustomLog ${APACHE_LOG_DIR}/ | + | |
- | </ | + | |
| | ||
sudo a2ensite site1.com.conf | sudo a2ensite site1.com.conf | ||
sudo a2ensite site2.com.conf | sudo a2ensite site2.com.conf | ||
- | sudo cp -r / | + | sudo cp -r / |
sudo rm -r / | sudo rm -r / | ||
sudo a2dissite 000-default.conf | sudo a2dissite 000-default.conf | ||
+ | | ||
+ | Now, if you prefer put some local dns entries in /etc/hosts | ||
| | ||
sudo nano /etc/hosts | sudo nano /etc/hosts | ||
| | ||
- | 127.0.0.1 | + | Append something like this to the bottom: |
- | 127.0.1.1 | + | |
- | # The following lines are desirable for IPv6 capable hosts | + | |
- | ::1 | + | |
- | ff02::1 ip6-allnodes | + | |
- | ff02::2 ip6-allrouters | + | |
- | | + | |
xxx.xxx.xxx.xxx site1.com | xxx.xxx.xxx.xxx site1.com | ||
xxx.xxx.xxx.xxx www.site1.com | xxx.xxx.xxx.xxx www.site1.com | ||
Line 104: | Line 95: | ||
xxx.xxx.xxx.xxx www.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 | sudo systemctl restart apache2.service | ||
- | Visit site1.com and site2.com | + | Visit site1.com and site2.com |
| | ||
- | sudo ufw install | + | sudo apt install ufw |
- | sudo ufw allow ssh | + | |
sudo ufw allow 22 | sudo ufw allow 22 | ||
- | sudo ufw allow 222 | ||
- | sudo ufw allow http | ||
sudo ufw allow 80 | sudo ufw allow 80 | ||
- | sudo ufw allow https | ||
sudo ufw allow 443 | sudo ufw allow 443 | ||
- | sudo ufw allow 'WWW Secure' | ||
- | sudo ufw allow 'WWW Full' | ||
- | sudo ufw allow ' | ||
- | sudo ufw allow 1194/udp | ||
- | sudo ufw allow 1194 | ||
- | sudo ufw allow git | ||
- | sudo ufw allow openvpn | ||
- | sudo ufw allow samba | ||
- | sudo ufw allow nfs | ||
- | sudo ufw allow vnc | ||
- | sudo ufw allow 21 | ||
- | sudo ufw allow ftp | ||
sudo ufw enable | sudo ufw enable | ||
| | ||
- | Create | + | It is always a good idea to first create your own self-signed certificates for each virtual host: |
- | sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout / | + | sudo openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout / |
+ | sudo openssl req -x509 -nodes -days 7305 -newkey rsa: | ||
| | ||
- | Country Name (2 letter code) [AU]: <Country Initials> | + | 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. |
- | State or Province Name (full name) [Some-State]: | + | |
- | Locality Name (eg, city) []: <City or Township, etc., Name> | + | |
- | Organization Name (eg, company) [Internet Widgits Pty Ltd]: <Group or Entity, etc., Name> | + | |
- | | + | |
- | Common Name (e.g. server FQDN or YOUR name) []: <site1 ip address> | + | |
- | Email Address []: person@site1.com | + | |
| | ||
- | sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/ | + | You can simply add all of your TLS options to the default-ssl.conf, or you can create a snippet: |
| | ||
- | Country Name (2 letter code) [AU]: <Country Initials> | ||
- | State or Province Name (full name) [Some-State]: | ||
- | Locality Name (eg, city) []: <City or Township, etc., Name> | ||
- | Organization Name (eg, company) [Internet Widgits Pty Ltd]: <Group or Entity, etc., Name> | ||
- | Organizational Unit Name (eg, section) []: < | ||
- | Common Name (e.g. server FQDN or YOUR name) []: <site1 ip address> | ||
- | Email Address []: person@site1.com | ||
- | | ||
- | Configure diffie-hellman key for all TLS enabled virtual hosts, configure ssl-params.conf for all TLS enabled virtual hosts. | ||
- | |||
- | sudo openssl dhparam -out / | ||
- | sudo cp / | ||
sudo nano / | sudo nano / | ||
+ | | ||
+ | Having thus created the snippet, here are some recommended configurations and sources that document them: | ||
| | ||
# from https:// | # from https:// | ||
Line 165: | Line 130: | ||
# Disable preloading HSTS for now. You can use the commented out header line that includes | # Disable preloading HSTS for now. You can use the commented out header line that includes | ||
# the " | # the " | ||
- | | + | Header always set Strict-Transport-Security " |
Header always set Strict-Transport-Security " | Header always set Strict-Transport-Security " | ||
+ | #Nextcloud prefers this rule with the other Header rules below it for X, disabled: | ||
+ | #Header always set Strict-Transport-Security " | ||
Header always set X-Frame-Options DENY | Header always set X-Frame-Options DENY | ||
Header always set X-Content-Type-Options nosniff | Header always set X-Content-Type-Options nosniff | ||
Line 176: | Line 143: | ||
SSLOpenSSLConfCmd DHParameters "/ | SSLOpenSSLConfCmd DHParameters "/ | ||
- | Configure virtual hosts for TLS for each domain previously configured above. | + | Don't forget to enable this configuration: |
+ | |||
+ | sudo a2enconf ssl-params | ||
+ | |||
+ | Configure | ||
sudo cp / | sudo cp / | ||
- | sudo cp / | + | sudo cp / |
- | sudo cp / | + | sudo cp / |
- | + | ||
+ | Open the first TLS virtual host configuration file: | ||
sudo nano / | sudo nano / | ||
| | ||
+ | Uncomment the legacy support at the end and enter the standard configurations at the top: | ||
+ | |||
< | < | ||
< | < | ||
Line 189: | Line 164: | ||
ServerName site1.com | ServerName site1.com | ||
DocumentRoot / | DocumentRoot / | ||
- | ErrorLog ${APACHE_LOG_DIR}/ | ||
- | CustomLog ${APACHE_LOG_DIR}/ | ||
- | SSLEngine on | ||
- | SSLCertificateFile | ||
- | SSLCertificateKeyFile / | ||
- | < | ||
- | SSLOptions +StdEnvVars | ||
- | </ | ||
- | < | ||
- | SSLOptions +StdEnvVars | ||
</ | </ | ||
BrowserMatch "MSIE [2-6]" \ | BrowserMatch "MSIE [2-6]" \ | ||
Line 206: | Line 171: | ||
</ | </ | ||
- | sudo nano / | + | Repeat the steps above for the site2.com-ssl.conf |
- | + | ||
- | < | + | |
- | < | + | |
- | ServerAdmin name@site2.com | + | |
- | ServerName site2.com | + | |
- | ServerAlias www.site2.com | + | |
- | DocumentRoot / | + | |
- | ErrorLog ${APACHE_LOG_DIR}/ | + | |
- | CustomLog ${APACHE_LOG_DIR}/ | + | |
- | SSLEngine on | + | |
- | SSLCertificateFile | + | |
- | SSLCertificateKeyFile / | + | |
- | < | + | |
- | SSLOptions +StdEnvVars | + | |
- | | + | |
- | | + | |
- | SSLOptions +StdEnvVars | + | |
- | | + | |
- | BrowserMatch "MSIE [2-6]" \ | + | |
- | | + | |
- | | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | Leave both http and https, or only https; for https-only, add a line to the .conf below ('permanent' | + | |
sudo nano / | sudo nano / | ||
- | Redirect permanent "/" | + | |
- | | + | At the top, just under the DocumentRoot, |
- | Redirect permanent "/" | + | |
- | + | Redirect permanent "/" | |
- | Enable both TLS sites and re-directs, check configuration: | + | |
+ | Repeat this for the site2.conf file. Now, check your configuration | ||
+ | |||
sudo a2enmod ssl | sudo a2enmod ssl | ||
sudo a2enmod headers | sudo a2enmod headers | ||
- | sudo a2ensite site1.com.conf | + | sudo a2enconf ssl-params |
- | sudo a2ensite site2.com.conf | + | |
sudo apache2ctl configtest | 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 / | ||
- | Ignore error, restart web-server, debug: | + | sudo a2ensite site1.com-ssl.conf |
- | + | | |
- | | + | |
- | Syntax OK | + | |
- | + | ||
- | sudo systemctl restart apache2 | + | |
| | ||
- | Set up Let's Encrypt | + | Visit both sites using Firefox, and ensure they resovle. |
sudo apt install certbot letsencrypt python-certbot-apache | sudo apt install certbot letsencrypt python-certbot-apache | ||
- | certbot --authenticator standalone --installer apache -d site1.com --pre-hook " | + | |
- | | + | |
+ | Run the second command again, but adjust it for site2.com. Now, restart the service: | ||
sudo systemctl restart apache2 | sudo systemctl restart apache2 | ||
| | ||
- | Test them both, first clear cache and restart browser, set up cron job to update every week: | + | You can optionally verify |
- | + | ||
https:// | https:// | ||
https:// | https:// | ||
+ | | ||
+ | Let's Encrypt expires often, so you likely want a cron job to update everything for you when/if needed: | ||
| | ||
sudo crontab -e | sudo crontab -e | ||
Line 270: | Line 212: | ||
sudo systemctl restart apache2 | sudo systemctl restart apache2 | ||
| | ||
- | Manually | + | You can also manually |
- | sudo certbot renew | + | sudo certbot renew |
- | + | ||
- | Set up Cacti, Wordpress, Dokuwiki, Joomla (all of which rely on MySQL databases). | + | 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 / | ||
+ | sudo chmod 750 / | ||
+ | sudo chown $USER:$USER / | ||
+ | sudo nano / | ||
| | ||
+ | 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="/ | ||
+ | SERVICE=" | ||
+ | LOGFILE="/ | ||
+ | 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)" | ||
+ | fi | ||
+ | Okay, now let's make sure your log files do not get too large. | ||
+ | sudo nano / | ||
+ | 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: | ||
+ | / | ||
+ | daily | ||
+ | rotate 10 | ||
+ | delaycompress | ||
+ | compress | ||
+ | notifempty | ||
+ | missingok | ||
+ | size 100000k | ||
+ | } | ||
+ | |||
+ | Alright, no point in making an apache monitoring script unless it runs automatically, | ||
+ | |||
+ | sudo crontab -e | ||
+ | * * * * * /bin/bash / | ||
+ | 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: |
- | | + | |
+ | | ||
+ | |||
+ | Cool! You now have two websites that are TLS encrypted! | ||
+ | |||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | 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: | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | I keep the scripts up to date on my repo, over here: | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | This tutorial is a designated " | ||
+ | |||
+ | --- // |