User Tools

Site Tools


computing:apachesurvival

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
computing:apachesurvival [2019/06/16 02:29] oemb1905computing:apachesurvival [2024/02/20 23:00] (current) oemb1905
Line 3: Line 3:
   * **Jonathan Haack**   * **Jonathan Haack**
   * **Haack's Networking**   * **Haack's Networking**
-  * **netcmnd@jonathanhaack.com**+  * **webmaster@haacksnetworking.org**
  
 ------------------------------------------- -------------------------------------------
  
-//apachesurvival// +//apachesurvival//      
  
 ------------------------------------------- -------------------------------------------
  
-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 will cover:+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 
  
-  * Establish LAMP stack +  sudo apt install apache2 php mariadb-server
-  * Virtual hosts for more than one website  +
-  * TLS - Creation of self-signed SSL +
-  * TLS - Let's Encrypt with Certbot +
-  * MySQL survival commands +
-  * Installation of Joomla, Wordpress, Dokuwiki, Cacti +
-  * Installation and configuration of local sftp server +
-  * 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.  With the exception of Cacti, these are skills I learned on BSD / macOS and then migrated to Debian GNU/Linux which runs them better, has better implementations of the LAMP stack, more feature control, and most importantly is #freesoftware.   +
- +
-------------------------------------------- +
- +
-Installing apache, setting up two ore more websites.  If you are interested in setting up a website outside of /var/www/, say for example, /home/server, then please see the addenda at the bottom covering non-standard web root directories.  There is nothing wrong with this approach, but there are some simple precautions.  For now, proceed with the examples below which guide you through creating two virtual hosts, but this can be scaled to as many as you like:   +
- +
-  sudo apt install apache2 +
   sudo mkdir -p /var/www/site1.com/public_html   sudo mkdir -p /var/www/site1.com/public_html
   sudo mkdir -p /var/www/site2.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/site1.com/public_html
   sudo chown -R $USER:$USER /var/www/site2.com/public_html   sudo chown -R $USER:$USER /var/www/site2.com/public_html
-  sudo chmod -R 755 /var/www +  sudo chmod 755 /var/www 
-  nano /var/www/site1.com/public_html/index.html +  
-  +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 
   <html>   <html>
     <head>     <head>
Line 45: Line 30:
       <h1>site1</h1>       <h1>site1</h1>
     </body>     </body>
-  </html> +  </html>  
-   + 
-  nano /var/www/site2.com/public_html/index.html +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:
-   +
-  <html> +
-    <head> +
-      <title>site2</title> +
-    </head> +
-    <body> +
-      <h1>site2</h1> +
-    </body> +
-  </html> +
-   +
-  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+
      
 +  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   sudo nano /etc/apache2/sites-available/site1.com.conf
-   
   <VirtualHost *:80>   <VirtualHost *:80>
         ServerAdmin name@site1.com         ServerAdmin name@site1.com
Line 72: Line 45:
   </VirtualHost>   </VirtualHost>
      
-  sudo nano /etc/apache2/sites-available/site2.com.conf +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:
-   +
-  <VirtualHost *:80> +
-        ServerAdmin name@site2.com +
-        ServerName site2.com +
-        ServerAlias www.site2.com +
-        DocumentRoot /var/www/site2.com/public_html +
-        ErrorLog ${APACHE_LOG_DIR}/error.log +
-        CustomLog ${APACHE_LOG_DIR}/access.log combined +
-  </VirtualHost>+
      
   sudo a2ensite site1.com.conf   sudo a2ensite site1.com.conf
   sudo a2ensite site2.com.conf   sudo a2ensite site2.com.conf
-  sudo cp -r /var/www/html /root/+  sudo cp -r /var/www/html /root/html-bak
   sudo rm -r /var/www/html   sudo rm -r /var/www/html
   sudo a2dissite 000-default.conf   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   sudo nano /etc/hosts
      
-  127.0.0.1       localhost +Append something like this to the bottom
-  127.0.1.1       host.domain.com  hostname +   
-  # The following lines are desirable for IPv6 capable hosts +  xxx.xxx.xxx.xxx site1.com site1 
-  ::1     localhost ip6-localhost ip6-loopback + 
-  ff02::1 ip6-allnodes +Make sure to do this for each domain.  Check your configurations up until now and then restart the service and check if it starts: 
-  ff02::2 ip6-allrouters +
-  #Virtual Hosts - NOT Optional - replace xxx etc., with external IP +
-  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 +
- +
   sudo apache2ctl configtest   sudo apache2ctl configtest
   sudo systemctl restart apache2.service   sudo systemctl restart apache2.service
        
-Visit site1.com and site2.com debug, set up TLS repeat this for additional sites, set up firewall w/ common exceptions. +Visit site1.com and site2.com and debug.  Once both properly resolveit 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 ufw install +
-  sudo ufw allow 22 +
-  sudo ufw allow 80 +
-  sudo ufw allow 443+
  
-  sudo ufw enable+  sudo openssl req -x509 -nodes -days 7305 -newkey rsa:2048 -keyout /etc/ssl/private/site1.key -out /etc/ssl/certs/site1.crt
      
-Create self-signed TLS certificates, set up ssl.conf for each virtual host.+Repeat this for site2.com and make sure to answer the question about your FQDN correctly 
  
-  sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/site1.key -out /etc/ssl/certs/site1.crt +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):
-   +
-  Country Name (2 letter code) [AU]: <Country Initials> +
-  State or Province Name (full name) [Some-State]: <State or Commonwealth, etc., Name> +
-  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) []: <Department or Branch, 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/private/site2.key -out /etc/ssl/certs/site2.crt +
-   +
-  Country Name (2 letter code) [AU]: <Country Initials> +
-  State or Province Name (full name) [Some-State]: <State or Commonwealth, etc., Name> +
-  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) []: <Department or Branch, etc., Name> +
-  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 /etc/ssl/certs/dhparam.pem 4096 +
-  sudo cp /etc/apache2/conf-available/ssl-params.conf /root/ +
-  sudo nano /etc/apache2/conf-available/ssl-params.conf +
-   +
-  # 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 likes this: +
-  #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" +
- +
-Configure virtual hosts for TLS for each domain previously configured above.+
  
   sudo cp /etc/apache2/sites-available/default-ssl.conf /root/default-ssl.conf.bak   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.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.bak+
  
-Create TLS sites in sites-enabled:+Open the first TLS virtual host configuration file:
  
   sudo nano /etc/apache2/sites-available/site1.com-ssl.conf   sudo nano /etc/apache2/sites-available/site1.com-ssl.conf
-   
   <IfModule mod_ssl.c>   <IfModule mod_ssl.c>
         <VirtualHost _default_:443>         <VirtualHost _default_:443>
Line 178: Line 85:
                 ServerName site1.com                 ServerName site1.com
                 DocumentRoot /var/www/site1.com/public_html                 DocumentRoot /var/www/site1.com/public_html
-                ErrorLog ${APACHE_LOG_DIR}/error.log 
-                CustomLog ${APACHE_LOG_DIR}/access.log combined 
-                SSLEngine on 
-                SSLCertificateFile      /etc/ssl/certs/site1.crt 
-                SSLCertificateKeyFile /etc/ssl/private/site1.key 
-                <FilesMatch "\.(cgi|shtml|phtml|php)$"> 
-                                SSLOptions +StdEnvVars 
-                </FilesMatch> 
-                <Directory /usr/lib/cgi-bin> 
-                                SSLOptions +StdEnvVars 
                 </Directory>                 </Directory>
                 BrowserMatch "MSIE [2-6]" \                 BrowserMatch "MSIE [2-6]" \
Line 195: Line 92:
   </IfModule>   </IfModule>
  
-  sudo nano /etc/apache2/sites-available/site2.com-ssl.conf+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 </VirtualHost> line and start with <IfModules> and end with </IfModules> Before we test the website for functionality, we need to 
      
-    <IfModule mod_ssl.c> 
-        <VirtualHost _default_:443> 
-                ServerAdmin name@site2.com 
-                ServerName site2.com 
-                ServerAlias www.site2.com 
-                DocumentRoot /var/www/site2.com/public_html 
-                ErrorLog ${APACHE_LOG_DIR}/error.log 
-                CustomLog ${APACHE_LOG_DIR}/access.log combined 
-                SSLEngine on 
-                SSLCertificateFile      /etc/ssl/certs/site2.crt 
-                SSLCertificateKeyFile /etc/ssl/private/site2.key 
-                <FilesMatch "\.(cgi|shtml|phtml|php)$"> 
-                                SSLOptions +StdEnvVars 
-                </FilesMatch> 
-                <Directory /usr/lib/cgi-bin> 
-                                SSLOptions +StdEnvVars 
-                </Directory> 
-                BrowserMatch "MSIE [2-6]" \ 
-                               nokeepalive ssl-unclean-shutdown \ 
-                               downgrade-1.0 force-response-1.0 
-        </VirtualHost> 
-  </IfModule> 
-   
-Redirect the original sites-enabled to default to TLS. 
- 
-  sudo nano /etc/apache2/sites-available/site1.com.conf 
-        Redirect permanent "/" "https://site1.com/ 
-  sudo nano /etc/apache2/sites-available/site2.com.conf 
-        Redirect permanent "/" "https://site2.com/ 
- 
-Enable both TLS sites, check configuration: 
- 
   sudo a2enmod ssl   sudo a2enmod ssl
   sudo a2enmod headers   sudo a2enmod headers
-  sudo a2enconf ssl-params+  sudo apache2ctl configtest
   sudo a2ensite site1.com-ssl.conf   sudo a2ensite site1.com-ssl.conf
   sudo a2ensite site2.com-ssl.conf   sudo a2ensite site2.com-ssl.conf
-  sudo apache2ctl configtest+   
 +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: 
  
-Ignore error below, or set global ServerName (not advised) to avoid:+  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"
  
-  AH00558: apache2: Could not reliably determine the server's fully qualified domain nameusing 127.0.1.1. Set the 'ServerName' directive globally to suppress this message +When LE prompts youmake 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:
-  Syntax OK +
-  sudo systemctl restart apache2 +
-   +
-Set up Let's Encrypt for free certificate authority on the SSL certs you just made.+
  
-  sudo apt install certbot letsencrypt python-certbot-apache 
-  certbot --authenticator standalone --installer apache -d site1.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2" 
-  certbot --authenticator standalone --installer apache -d site2.com --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2" 
   sudo systemctl restart apache2   sudo systemctl restart apache2
      
-Test them bothfirst clear cache and restart browser, set up cron job to update every week: +Let's Encrypt expires oftenso you likely want a cron job to update everything for you when/if needed:
-   +
-  https://www.ssllabs.com/ssltest/analyze.html?d=site1.com&latest +
-  https://www.ssllabs.com/ssltest/analyze.html?d=site2.com&latest+
      
   sudo crontab -e   sudo crontab -e
Line 258: Line 115:
   sudo systemctl restart cron.service   sudo systemctl restart cron.service
   sudo systemctl restart apache2   sudo systemctl restart apache2
-   
-Manually check certificates by: 
  
-  sudo certbot renew+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
      
-Okay, now you need to make sure that your server stays running and that uptime is maximized.  Let's create two simple shell scripts that check the status, and restart the service if needed.  First create apache-notify.sh:+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-notify.sh +  sudo touch /usr/local/bin/apache-restart.sh 
-  sudo chmod 750 /usr/local/bin/apache-notify.sh +  sudo chmod 750 /usr/local/bin/apache-restart.sh 
-  sudo chown $USER:$USER /usr/local/bin/apache-notify.sh +  sudo chown $USER:$USER /usr/local/bin/apache-restart.sh 
-  sudo nano /usr/local/bin/apache-notify.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.+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   #!/bin/sh
Line 276: Line 137:
   RESTART="/bin/systemctl restart apache2.service"   RESTART="/bin/systemctl restart apache2.service"
   SERVICE="apache2.service"   SERVICE="apache2.service"
-  LOGFILE="/home/username/Desktop/apache-restart.log"+  LOGFILE="/home/sexa/Desktop/apache.log"
   #check for the word dead in the service output from systemctl   #check for the word dead in the service output from systemctl
   if   if
-      systemctl status apache2.service | grep dead+          systemctl status apache2.service | grep dead
   then   then
-      echo "Sir, apache2 failed at $(date), so I restarted it for you." >> $LOGFILE+          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   else
-      echo "Ms., apache2 was running as of $(date)" >> $LOGFILE [or leave empty]+  exit
   fi   fi
  
- +Alrightno point in making an apache monitoring script unless it runs automatically, so let'create a cron job to do that:
-Thanks to @varange on a Digital Ocean forum who inspired these scripts, but I had to change them for systemdand I also changed them into two scripts because the way he had originally composed them together with an "else" comment, there was always a minute discrepancy between the notification it was down, and the time it restarted.  Lastly, these will not run automatically, so create a cron job:+
  
   sudo crontab -e   sudo crontab -e
-  * * * * * /bin/bash /usr/local/bin/apache-notify.sh +  * * * * * /bin/bash /usr/local/bin/apache-restart.sh >> /home/user/Desktop/apache-restart.log
-  * * * * * /bin/bash /usr/local/bin/apache-restart.sh +
-  sudo systemctl stop apache2+
   sudo systemctl restart cron   sudo systemctl restart cron
-  sudo systemctl status apache2 [Wait 1 minute, and then run same command again to confirm working]  
  
-Make sure to run the cron job as rootor it will not work.  You can also run the scripts manually if you want since we added them to the default user PATH above.  Alsomake sure your log files do not explode by adding some entries to /etc/logrotate.d/+Alsolog files can build up quickly, so adjust logrotate so that you don't use up precious storage recklessly!  Firstcreate a new entry in the logrotate daemon directory:
  
 +  sudo nano /etc/logrotate.d/apache-restart
   /home/user/Desktop/apache-restart.log {   /home/user/Desktop/apache-restart.log {
         daily         daily
Line 308: Line 168:
   }   }
  
 +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:
  
-Ok, now that you have a few self-hosted sites that are protected, running, and monitored, you can start creating your [[https://jonathanhaack.com/dokuwiki/doku.php?id=computing:selfhostedwp|Self-Hosted Word Press]]!+  * [[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://jonathanhaack.com/dokuwiki/doku.php?id=start|Start Page]].+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]].
  
- --- //[[netcmnd@jonathanhaack.com|oemb1905]] 2019/01/02 20:36// + --- //[[webmaster@haacksnetworking.org|oemb1905]] 2024/02/20 23:00//
- +
- +
-   +
- +
-  +
computing/apachesurvival.1560652178.txt.gz · Last modified: 2019/06/16 02:29 by oemb1905