I recently ran into a problem that had two root causes :
- I had grown lazy about backing up my .htaccess file (relying instead on a WordPress backup plugin while forgetting that it doesn’t touch this file).
- A WordPress Update to 6.4.3 (the specific version may not be important).
While I don’t do a lot of redirects on a site, they do show up from time to time. For years (in WordPress) I handled them using a plugin, but that practice went away for several reasons :
- Security : I discovered a vulnerability in one of the redirection plugins I used.
- The fewer plugins on the site the better, both for performance and for security.
- Performance issues – moving the redirects to the .htaccess was faster than using a plugin
How I would handle it within .htaccess would look something like this :
<IfModule mod_write.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Redirect 301 /paypal https://www.paypal.com/donate/?hosted_button_id=FD8KG2WK3Q6TE
</IfModule>
This approach has been working, and continues to work, fine on other sites. But on this newer site, for some reason, the update wiped out the .htaccess file and restored it to its defaults.
As far as I can tell, the only difference between the two is that one .htaccess file is owned by root, and the other (the one that was overwritten by the update) is owned by www-data . Now, perhaps that would work, or perhaps not. But if there is any chance at all that the .htaccess file can be edited by WordPress (which also been used as an attack vector for bad actors in the past to introduce their own redirects) then the best next choice is the enabled site’s .conf file.
Apache sites-available .conf file
Since this issue arose on a Debian Buster server, the paths below apply to that distribution. Amend paths according to the OS flavor you are using.
sudo a2enmod alias
sudo apache2ctl configtest
/var/etc/apache2/sites-available/<sitename>-ssl.conf
The ssl part of this deserves special mention. If the site is using https (which it should be) and if the site’s main .conf file contains only the *.80 VirtualHost like the following then be sure to add the Redirect rule into the ssl version of the .conf file. Otherwise, add it to the *:443 (or appropriate port for your server) VirtualHost.
<VirtualHost *:80>
ServerName k-9elite.dog
ServerAlias www.k-9elite.dog
ServerAdmin ally@eclat.tech
DocumentRoot /var/www/k-9elite.dog
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.k-9elite.dog [OR]
RewriteCond %{SERVER_NAME} =k-9elite.dog
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
The Rewrite rule I want to add is as follows :
Redirect permanent /paypal https://www.paypal.com/donate/?hosted_button_id=FD8KG2WK3Q6TE
Note that adding the RewriteRule here doesn’t work.
Instead, it has to appear here :
<VirtualHost *:443>
ServerName k-9elite.dog
ServerAlias www.k-9elite.dog
ServerAdmin ally@eclat.tech
DocumentRoot /var/www/k-9elite.dog
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile
SSLCertificateKeyFile
Redirect permanent /paypal https://www.paypal.com/donate/?hosted_button_id=FD8KG2WK3Q6TE
</VirtualHost>
Remember to reload the apache service after making changes to the .conf file (or unload the site and reload it).
sudo systemctl reload apache2
Why am I posting this?
I was actually quite surprised to see the number of people who reported problems with .htaccess being overwritten by WordPress, but the solutions were largely to change the permissions on the .htaccess file, and then arguments about whether that solved the problem or not. Many suggested using plugins instead. And those few posts mentioning using the Apache .conf file weren’t entirely clear.
Final Notes
Backup, backup, backup. Hey, we’ve ssh’d into the server already, maybe it’s time to go ahead and make a backup of that .htaccess file – just in case.
Good luck with your webserver!!