====Reverse Proxy using Apache on CentOS 8==== This will install a Apache on CentOS 8 and use virtual hosts for reverse proxying. It includes fail2ban, SSH security, letsencrypt and auto updates. Install CentOS 8 minimal with 2 CPU, 512MB+ RAM, 10GB+ storage, set FQDN, set static IP, enable NTP. 3.) After install if finished reboot -> login -> perform a "dnf update". ==Create limited user account and add to wheel group for sudo== useradd example_user && passwd example_user usermod -aG wheel example_user ==Install dependencies and vim== dnf install unzip wget vim Logout of root and login using sudo user ==Disallow root login over SSH== sudo vim /etc/ssh/sshd_config then set PermitRootLogin no ==Generate SSH key for sudo user on client computer (not the webserver)== To help keep things organized we'll create a keypair that is specific to the user and the remote sudo user+host. \\ https://www.ssh.com/ssh/keygen/ ssh-keygen -C "your_email@example.com" -f ~/.ssh/your_email@example.com-remote_sudo_username_@remote_hostname -t ed25519 Record the private and public keys in a secure document for the webserver. \\ Copy the public key to the remote webserver. \\ ssh-copy-id -i ~/.ssh/your_email@example.com-remote_sudo_username_@remote_hostname.pub sudo_username@remote_hostname sudo vim /etc/ssh/sshd_config then set PasswordAuthentication no Restart sshd sudo systemctl restart sshd Login using SSH key ssh -i deployment_key.txt demo@192.237.248.66 https://www.tecmint.com/install-lamp-on-centos-8/ https://linuxize.com/post/how-to-install-php-on-centos-8/ https://www.linode.com/docs/web-servers/lamp/how-to-install-a-lamp-stack-on-centos-8/ https://www.linode.com/docs/web-servers/apache/how-to-install-and-configure-fastcgi-and-php-fpm-on-centos-8/ https://www.digitalocean.com/community/tutorials/how-to-run-multiple-php-versions-on-one-server-using-apache-and-php-fpm-on-ubuntu-18-04 https://certbot.eff.org/lets-encrypt/centosrhel8-apache.html ====Install Apache==== ==Configure hosts== sudo vim /etc/hosts Add a line for your FQDN 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.10.30 websrv01.domainname.com websrv01 sudo dnf install httpd httpd-tools mod_ssl sudo systemctl enable httpd sudo systemctl start httpd sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --reload ====Create Virtual Hosts==== https://www.gonscak.sk/?p=401 \\ https://ip-life.net/configuring-an-apache-reverse-proxy-for-multiple-domains/ \\ https://stackoverflow.com/questions/25107654/how-to-configure-apache-server-to-talk-to-https-backend-server \\ Create a virtual host for each web domain that is going to sit behind this proxy. ==Setup virtual host config files== sudo vim /etc/httpd/conf.d/site1.your_domain.conf Add the following content. ServerName subdomain.domain.com SSLProxyEngine On ProxyPreserveHost On ProxyPass / http://subdomain.domain.com/ ProxyPassReverse / http://subdomain.domain.com/ If you're back end servers have SSL/TLS setup already then change http to https. Make sure your proxy server trusts the SSL/TLS certificates. Save and close the file when you are finished. Then check the Apache configuration file for any syntax errors: sudo httpd -t You’ll see the following output: Output Syntax OK ==Disable Exposing Apache Server Info== https://www.if-not-true-then-false.com/2009/howto-hide-and-modify-apache-server-information-serversignature-and-servertokens-and-hide-php-version-x-powered-by/ \\ This will help to prevent being the target of a an attack if you're running an out of date or vunerable release sudo vim /etc/httpd/httpd.conf Add the following: ServerSignature Off ServerTokens Prod Finally, restart the Apache service to implement your changes: sudo systemctl restart httpd delete the welconf.conf to disable the default apache welcome page. sudo rm /etc/httpd/conf.d/welcome.conf ==Remove Default Access from httpd.conf== This is important as it would allow access to the /var/www/html path via HTTP. sudo vim /etc/httpd/conf/httpd.conf Comment out the following: DocumentRoot "/var/www/html" AllowOverride None # Allow open access: Require all granted Options Indexes FollowSymLinks AllowOverride None AllowOverride None AllowOverride None Options None Require all granted Enable HTTPD to access network (SELinux) sudo setsebool -P httpd_can_network_connect on Restart Apache sudo systemctl restart httpd ====Target Host Modification==== https://stackoverflow.com/questions/760283/apache-proxypass-how-to-preserve-original-ip-address/30784225#30784225 \\ In the logs on the target web server it will show the IP of the proxy server making the request, not the IP of the original client. To fix this you need to add a setting to Apache on the TARGET WEB SERVERS, not the proxy server. On CentOS 7 and 8 the remote_ip module is loaded by default. You'll need to add the option to httpd.conf sudo vim /etc/httpd/conf/httpd.conf Add the following: RemoteIPHeader X-Forwarded-For Restart Apache sudo systemctl restart httpd Now the IP of the original client should show up in the application logs. ====Letsencrypt==== ==Install certbot== wget https://dl.eff.org/certbot-auto sudo mv certbot-auto /usr/local/bin/certbot-auto sudo chown root /usr/local/bin/certbot-auto sudo chmod 0755 /usr/local/bin/certbot-auto Generate local certificates sudo /usr/libexec/httpd-ssl-gencerts Request and install certificates for virtual hosts sudo /usr/local/bin/certbot-auto --apache When prompted enabled Redirect so all requests go over https Enable autorenew via crontab echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto renew -q" | sudo tee -a /etc/crontab > /dev/null ====OR... Certificate manually via CA==== Enable SSL Apache https://www.thesslstore.com/knowledgebase/ssl-generate/generate-csr-apache-web-server-using-openssl-v-2/ https://forums.centos.org/viewtopic.php?t=43230 https://www.getpagespeed.com/server-setup/ssl-directory Install Mod SSL sudo dnf install mod_ssl ==Create Private Key and CSR== openssl req -new -newkey rsa:4096 -nodes -keyout clientdata.haddentech.com.key -out clientdata.haddentech.com.csr Move the files to your PKI folder sudo mv clientdata.haddentech.com.* /etc/pki/tls/private/ Set permissions on private key sudo chown root:root /etc/pki/tls/private/clientdata.haddentech.com.key sudo chmod 600 /etc/pki/tls/private/clientdata.haddentech.com.key sudo restorecon -RvF /etc/pki/tls/private/ Submit the CSR to your CA (public or private) Copy the BASE64 certificate from your CA to your cert folder sudo vim /etc/pki/tls/certs/clientdata.haddentech.com.crt Create the CA bundle associated with your certificate vim /etc/pki/tls/certs/clientdata.haddentech.com.ca-bundle Paste the subordinate followed by the root BASE64 certificates Edit the conf file for you website and change ServerName clientdata.haddentech.com SSLEngine on SSLCertificateFile /etc/pki/tls/certs/clientdata.haddentech.com.crt SSLCertificateKeyFile /etc/pki/tls/private/clientdata.haddentech.com.key SSLCertificateChainFile /etc/pki/tls/certs/clientdata.haddentech.com.ca-bundle .... .... .... Restart Apache sudo systemctl restart httpd Note: if you are using your own internal CA you'll need to import the root and any intermediate certificates into your browsers/etc. ====Automatic Updates for CentOS==== https://www.tecmint.com/dnf-automatic-install-security-updates-automatically-in-centos-8/ sudo dnf install dnf-automatic sudo vim /etc/dnf/automatic.conf Set: upgrade_type = security download_updates = yes system_name = (your system name) emit_via = motd Enable the auto-update timer sudo systemctl enable --now dnf-automatic.timer ====fail2ban==== https://idroot.us/install-fail2ban-centos-8/ https://www.digitalocean.com/community/tutorials/how-to-protect-an-apache-server-with-fail2ban-on-ubuntu-14-04 sudo dnf install fail2ban ==Create a Jail for SSHd== sudo vim /etc/fail2ban/jail.d/sshd.local Add the following: [sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s [selinux-ssh] enabled = true port = ssh logpath = %(auditd_log)s ==Create a Jail for Apache== sudo vim /etc/fail2ban/jail.d/apache.local Add the following: [apache-auth] enabled = true port = http,https logpath = %(apache_error_log)s [apache-badbots] enabled = true port = http,https logpath = %(apache_access_log)s bantime = 48h maxretry = 1 [apache-noscript] enabled = true port = http,https logpath = %(apache_error_log)s [apache-overflows] enabled = true port = http,https logpath = %(apache_error_log)s maxretry = 2 [apache-nohome] enabled = true port = http,https logpath = %(apache_error_log)s maxretry = 2 [apache-botsearch] enabled = true port = http,https logpath = %(apache_error_log)s maxretry = 2 [apache-fakegooglebot] enabled = true port = http,https logpath = %(apache_access_log)s maxretry = 1 ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot [apache-modsecurity] enabled = true port = http,https logpath = %(apache_error_log)s maxretry = 2 [apache-shellshock] enabled = true port = http,https logpath = %(apache_error_log)s maxretry = 1 sudo systemctl start fail2ban sudo systemctl enable fail2ban sudo fail2ban-client status sshd