Apache
Apache Basics (old notes):
To check Apache status:
systemctl status httpd systemctl status apache2 service apache2 status # Ubuntu service httpd status
To start, stop... Apache:
systemctl start|stop|restart httpd service httpd start|stop|restart
To auto start Apache upon boot up:
systemctl enable httpd chkconfig httpd on
Virtual Hosts, Redirects, and SSL
Redirect examples that have worked for me using VirtualHost in the /etc/httpd/conf/httpd.conf file. These configurations assumes you have <Directory "/var/www"> in the other directives of that file:
- This worked for me in my old set up, but for whatever reason when I rebuilt this wiki, this configuration didn't work anymore as I kept getting error "Too many redirects":
<VirtualHost *:80> DocumentRoot "/var/www" ServerName dikapedia.com RewriteEngine on RewriteCond %{REQUEST_URI} ^/$ RewriteRule (.*) /mediawiki/ [R=301] Options FollowSymLinks </VirtualHost>
- This is my 2nd version configuration for this wiki website which works. But when I check with my redirect.sh script, it shows it redirecting 4 times until it finally gets 200:
<VirtualHost *:80> DocumentRoot "/var/www" ServerName dikapedia.com RewriteEngine on RedirectMatch ^/$ /wiki/ Options FollowSymLinks </VirtualHost>
- This is my current configuration. I found that this configuration works as well, and is better as it decreases the number of redirects to 2 before it reaches the 200 HTTP status code (check redirect.sh script):
<VirtualHost *:80> DocumentRoot "/var/www" ServerName dikapedia.com RewriteEngine on RewriteRule ^/*$ %{DOCUMENT_ROOT}/wiki/index.php [L] Options FollowSymLinks </VirtualHost>
For more information regarding redirects, visit Apache
Vhost *:443 (SSL) Configuration:
- This is my current configuration for Vhost *:443 (SSL) configuration.
- I used Certbot/Let's Encrypt, in which it created the Vhost block for 443 in the /etc/httpd/conf/httpd-le-ssl.conf file.
- The Vhost block for 443 contains the same first 6 lines as for Vhost *:80, with an additional 'ServerAlias' line.
- Notice the Include /etc/letsencrypt/options-ssl-apache.conf line with the SSLCertificateFile and SSLCertificateKeyFile.
# cat /etc/httpd/conf/httpd-le-ssl.conf <VirtualHost *:443> DocumentRoot "/var/www" ServerName dikapedia.com ServerAlias www.dikapedia.com RewriteEngine on RedirectMatch ^/$ /wiki/ Options FollowSymLinks Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/dikapedia.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/dikapedia.com/privkey.pem </VirtualHost>
HTTP > HTTP redirect: https://www.tecmint.com/redirect-http-to-https-on-apache/
Another example:
<VirtualHost *:80> ServerName www.example.com # customer didnt have A record for their website, so remove www Redirect / https://www.example.com </VirtualHost> # asked customer to remove this whole block since https:// already works since they have godaddy cert. <VirtualHost _default_:443> ServerName www.example.com DocumentRoot /usr/local/apache2/htdocs SSLEngine On </VirtualHost>
More on Virtual host and hosting multiple websites w/ multiple IPs: https://httpd.apache.org/docs/2.4/vhosts/examples.html
Missing ssl.conf file
In other types of configurations, you may not be using certbot/Let's encrypt and instead need to configure and install the SSL cert manually. In such cases, you may need to use the SSL configuration file located in /etc/httpd/conf.d/ssl.conf.
However, that default SSL configuration file will not get created by default. You will need to install mod_ssl which will create the file /etc/httpd/conf.d/ssl.conf.
sudo yum install mod_ssl
If you noticed that you already have mod_ssl but you are still missing the ssl.conf file, simply re-install mod_ssl:
sudo yum -y reinstall mod_ssl
Ubuntu Specifics
apache2 is the name of the service.
Configuration file: /etc/apache2/apache2.conf
Configuring Secure Response Headers
To beef up the security of your website you can implement various HTTP headers. This will protect your website from getting hacked, Clickjacking, code injection, MIME types, XSS, etc. attacks due to misconfiguration or lack of protection.
The ones you should always have are:
- X-Frame-Options
- X-XSS-Protection
- X-Content-Type-Options
First you must ensure the headers_module is loaded.
LoadModule headers_module modules/mod_headers.so
On my CentOS system, the module is included in "Include conf.modules.d/*.conf" (>> /etc/httpd/conf.modules.d/00-base.conf).
Add the following lines to Apache configuration file.
- In dikapedia.com /etc/httpd/conf/httpd.conf, I added the lines below in the <Directory "/var/www">...</Directory> block
- In soundchiro /etc/httpd/conf/httpd.conf, I added the lines below in the <Directory "/var/www/html">...</Directory> block:
Header set X-Frame-Options SAMEORIGIN Header set X-XSS-Protection 1;mode=block Header set X-Content-Type-Options nosniff # I already have this apparently in Dikapedia.com
Restart Apache.
More info:
https://geekflare.com/http-header-implementation/
https://blog.insiderattack.net/apache-security-configuring-secure-response-headers-e8a83b72ce5e
Check Apache child processes and memory consumption
$ watch -n 1 "echo -n 'Apache Processes: ' && ps -C httpd --no-headers | wc -l && free -m"
You can run the below command to see how much memory each child process is consuming:
$ ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | grep httpd
Issues with Apache after rebooting (No route to host)
From personal experience, after rebooting my system I was unable to reach my site. Apache was running, MariaDB was running, php-fpm was running. But when I did '$ curl -I dikapedia.com', I get "No route to host: 80". This was strange because this never happened before, and I have not made any changes to my configuration file. My steps to troubleshoot were:
1) Run netsat and lsof:
# netstat -tulpna | grep :80 tcp6 0 0 :::80 :::* LISTEN 4848/httpd # sudo lsof -i :80 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 4848 root 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4849 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4851 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4853 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4874 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4879 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4913 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4926 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN) httpd 4927 apache 4u IPv6 29298 0t0 TCP *:http (LISTEN)
It was strange because httpd was listening on port 80. The netstat command is indicative that it is also listening on IPv4, even though lsof shows type: IPv6. (This is by default, AF_INET6 sockets will actually work for both IPv4 and IPv6..reference)
The solution was pointed out by this link. The issue was due to my OS firewall (FirewallD/Iptables). Firewalld was enabled, which was configuring firewalld upon bootup. If I shut off either firewalld or flush iptables, my site was back up. Not sure when this started to come about...
I found I had some weird IPtable rules that I never configured. Must've have been restarted by default after updating my system and rebooting it. I tested by stopping firewalld, my site worked. I enabled it again and flushed iptables, my site worked.
Performance Tuning
How to Adjust MaxClients
- https://www.jeffgeerling.com/blog/3-small-tweaks-make-apache-fly (I like this one)
- https://httpd.apache.org/docs/trunk/misc/perf-scaling.html#sizing-maxClients
There's a really simple way you can know exactly how high to set MaxClients:
(Total RAM - RAM used for Linux, MySQL, etc.) / Average httpd process size.
To get Total Ram and ram used:
$ free -h
To get Mysql ram used:
$ ps aux | grep 'mysql' | awk '{print $6/1024 " MB";}'
To get the average httpd process size:
$ ps aux | grep 'httpd' | awk '{print $6/1024;}' | awk '{avg += ($1 - avg) / NR;} END {print avg " MB";}'
How to disable directory browsing
https://stackoverflow.com/questions/2530372/how-do-i-disable-directory-browsing
In order to prevent users from accessing https://soundchiropractic.co/wp-content/uploads/2020/10/
vim /etc/httpd/conf/httpd.conf
Then find the line:
Options Indexes FollowSymLinks
Change that line to:
Options FollowSymLinks
Lastly save and exit the file, and restart apache server with this command:
sudo systemctl restart httpd
Apachectl
apachectl - Apache HTTP Server Control Interface
apachectl / apache2ctl (ubuntu) - Apache HTTP server control interface. Very handy tool. Can use this test Apache configuration files and see where config files/parameters are:
- Check Apache configuration files/syntax (be sure to run as sudo as some files maybe owned by root user):
sudo apachectl -t Syntax OK
- To view the Apache configs locations and what not:
$ sudo apachectl -S VirtualHost configuration: *:80 ip-172-31-10-144.ec2.internal (/etc/apache2/sites-enabled/000-default.conf:1) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex watchdog-callback: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 not_used Group: name="www-data" id=33 not_used
- Other commands:
sudo apachectl stop/start/restart/status/configtest
- How to list all the enabled modules in Apache web server.
# apachectl -M Loaded Modules: core_module (static) so_module (static) http_module (static) access_compat_module (shared) actions_module (shared) alias_module (shared) allowmethods_module (shared) auth_basic_module (shared) auth_digest_module (shared) authn_anon_module (shared) authn_core_module (shared) authn_dbd_module (shared) authn_dbm_module (shared) authn_file_module (shared) authn_socache_module (shared) authz_core_module (shared) authz_dbd_module (shared) authz_dbm_module (shared) . . http2_module (shared) proxy_http2_module (shared) # apachectl -M | grep expires expires_module (shared)
Expire Headers (for Caching)
1. Confirm mod_expires is already loaded and enabled on the Apache web server.
# apachectl -M | grep expires expires_module (shared) # grep -irl "mod_expires.so" /etc/httpd/ /etc/httpd/conf.modules.d/00-base.conf
# grep -i "mod_expires" /etc/httpd/conf.modules.d/00-base.conf LoadModule expires_module modules/mod_expires.so
2. Next, all you have to do is edit the .htaccess (/var/www/html/.htaccess) file with the following
## EXPIRES HEADER CACHING ## <IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType image/svg "access 1 year" ExpiresByType text/css "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType application/javascript "access 1 month" ExpiresByType application/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 3 days" </IfModule> ## EXPIRES HEADER CACHING ##
These values should work fine for most sites, but you can adjust the time periods if your needs are different.
Notice that the code sets different cache expiration dates based on the type of file. Images are cached longer than HTML, CSS, Javascript, and other file types because they usually stay the same.