-------------------------------------------
  * **apachesurvival** 
  * **Jonathan Haack**
  * **Haack's Networking**
  * **webmaster@haacksnetworking.org**
-------------------------------------------
//apachesurvival//      
-------------------------------------------
This tutorial is for users of Debian GNU/Linux to set up a LAMP stack, TLS encryption, and a web-server which can serve two or more websites using apache's virtual hosts.  I will also discuss how to set up basic protection on your firewall and a script that will make sure apache stays running and keep down time to a minimum.  The first step is to create two content directories for each of the websites.  Later, we will configure two virtual host configuration files in apache for each of these. Using site1.com and site2.com as an example, do the following and/pr adjust as needed:  
  sudo apt install apache2 php mariadb-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
 
Later, when you change one or both of these sites to a content management system (CMS), you will need to adjust ownership/permissions.  For example, WP requires that many directories be owned by www-data, and not the root or other user.  however, those changes should be done after this tutorial - not during.  Before setting those up, follow these steps and ensure both http/https are working, set up a cert cron job for TLS with LE, and then at that point, install your CMS and tweak ownership/permissions at that time.  The next step is to make a small website in each directory:
  sudo nano /var/www/site1.com/public_html/index.html 
  
    
      site1
    
    
      site1
    
   
Make sure to repeat the above steps for site2.com.  Once that's done, it is time to set up the virtual host configuration files in Debian's apache implementation:
  
  sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/site1.com.conf  
  sudo nano /etc/apache2/sites-available/site1.com.conf
  
        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
  
  
Make sure to 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/backup 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, in order for the server to correctly identify itself in headers, for example, when WP or another CMS sends an email to a user to restore their account, you need to adjust your host and domain name in the hosts file. 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 site1
Make sure to do this for each domain.  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 https.  Before we setup Let's Encrypt, we will 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
  
Repeat this for site2.com and make sure to answer the question about your FQDN correctly.  
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
Open the first TLS virtual host configuration file:
  sudo nano /etc/apache2/sites-available/site1.com-ssl.conf
  
        
                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 .  Before we test the website for functionality, we need to 
  
  sudo a2enmod ssl
  sudo a2enmod headers
  sudo apache2ctl configtest
  sudo a2ensite site1.com-ssl.conf
  sudo a2ensite site2.com-ssl.conf
  
Visit both sites using Firefox, and ensure they resolve - if not, check each step and debug.  Remember, you can trust the browser warning, because you set this cert up!  However, for others to access your site, you need to use a trusted authority like Let's Encrypt.  Here's how we do this: 
  sudo apt install certbot letsencrypt python3-certbot-apache
  sudo certbot --authenticator standalone --installer apache -d site1.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"
When LE prompts you, make sure to specify to "redirect" traffic to https.  Make sure to run the second command again changing the domain to site2.com.  Now, restart the service:
  sudo systemctl restart apache2
  
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
If this is a public IP on a VPS and you are new to GNU/Linux, then you should set up a firewall as a precaution.  Here is a basic way to do this:
  
  sudo apt install ufw
  sudo ufw allow 22
  sudo ufw allow 80
  sudo ufw allow 443
  sudo ufw enable
  
If you are comfortable with GNU/Linux and know how to check ''netstat -tulpn'' etc., and properly monitor what services are listening and to what netmask, then you can skip the firewall step.  The last thing I usually do on new setups is make a script called apache-restart.sh that monitors apache to ensure its running every minute:
  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/sh
  #functions
  RESTART="/bin/systemctl restart apache2.service"
  SERVICE="apache2.service"
  LOGFILE="/home/sexa/Desktop/apache.log"
  #check for the word dead in the service output from systemctl
  if
          systemctl status apache2.service | grep dead
  then
          echo "Person, apache2 failed at $(date), so I restarted it for you." >> $LOGFILE
          $RESTART >> $LOGFILE
          mail -s "[apache-restart]-$(hostname)-$(date)" email@email.com < $LOGFILE
  else
  exit
  fi
Alright, no point in making an apache monitoring script unless it runs automatically, so let's create a cron job to do that:
  sudo crontab -e
  * * * * * /bin/bash /usr/local/bin/apache-restart.sh >> /home/user/Desktop/apache-restart.log
  sudo systemctl restart cron
Also, log files can build up quickly, so adjust logrotate so that you don't use up precious storage recklessly!  First, create a new entry in the logrotate daemon directory:
  sudo nano /etc/logrotate.d/apache-restart
  /home/user/Desktop/apache-restart.log {
        daily
        rotate 10
        delaycompress
        compress
        notifempty
        missingok
        size 100000k
  }
Awesome!  You now have to super basic websites that both resolve and use TLS.  Now, consider replacing those basic website shells with some type of CMS or other content.  Here are some examples that I provide:
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:selfhostedwp|Self-Hosted Word Press]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:migratewp|Manually Migrating Word Press]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:nextcloud|Nextcloud]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:moodle|Moodle]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:dokuwiki|Dokuwiki]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:smokeping|Smokeping]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:cactiwebserver|Cacti]]
  * [[https://wiki.haacksnetworking.org/doku.php?id=computing:gitlab-ce|Gitlab-ce]] (requires extensive mods)
This tutorial is a designated "Invariant Section" of the "Technotronic" section of Haack's Wiki as described on the [[https://wiki.haacksnetworking.org/doku.php?id=start|Start Page]].
 --- //[[webmaster@haacksnetworking.org|oemb1905]] 2024/02/20 23:00//