FTP->SFTP now!

first things first: ABANDON FTP IT IS INSECURE AND WILL TRANSFER YOUR PASSWORDS AND FILES IN CLEAR TEXT OVER THE INTERNET!

MOVE TO SFTP (FTP OVER SSH) with strong passwords!

if you run your own server – disable FTP/remove ftp service/block it with firewall.

if you ignore this and get hacked it’s all your fault.

Hetzner supports SFTP OUT OF THE BOX!

http -> https now!

again: if you are using http during logins, your username and password is send unencrypted through the internet. not cool.

Snowden recommends using SSL, there are cost free Let’s Encrypt SSL certificates! (ask your hosting provider for it)

now finally: htaccess protecting your WordPress installation against brute-force attacks

bruteforce against your website is like DDoS: it will slow down the site for everyone else and cause unnecessary traffic.

Of course this only protects wp-login.php file and wp-admin directory, fencing off more complex DDoS packages is a science in itself.

there are other files you might consider to disable if not in use: (check the statistics of your wordpress website, to see if there are unusual things going on)

# Hits KBytes URL
1 15891 22.07% 134402 8.47% /xmlrpc.php
2 5434 7.55% 19652 1.24% /wp-login.php
3 1599 2.22% 101 0.01% /robots.txt
4 846 1.17% 0 0.00% /wp-cron.php
  • xmlrpc.php
    • this is if you use the WordPress App to update/upload stuff to your self-hosted WordPress installation, if you are not using the App:
      • disable:
      • # add this lines to .htaccess in root folder, to deny all access
        <Files xmlrpc.php>
        order deny,allow
        deny from all
        </Files>
  • wp-cron.php
    • this runs on every request? and tries to figure out if any task is scheduled, this can be exploited to DDoS your WordPress
    • it is recommended to:
      1. to disable it, by adding the red text to your wp-config.php file in /web/root
        /** The Database Collate type. Don't change this if in doubt. */
        define('DB_COLLATE', '');
        define('DISABLE_WP_CRON', true);
        
        # to speed things up a little bit you can run this command in web root
        # search for wp-config.php files
        find /home/UserName/web -type f -name wp-config.php
        # it will find all wp-config.php files and replace the line in question
        find /home/UserName/web -type f -name wp-config.php -exec sed -i.bak 's/define(\x27DB_COLLATE\x27, \x27\x27);/define(\x27DB_COLLATE\x27, \x27\x27); define(\x27DISABLE_WP_CRON\x27, true);/g' {} \;
        # the result should be like this
        
        # it will also create wp-config.php.bak
        # which you can automatically search and delete like this
        find /home/UserName/web -type f -name wp-config.php.bak -delete
        1. create a real cron job (as the user that the files belong to)
          crontab -e
          0 * * * * /scripts/wp-cron.sh # run every hour
          /usr/bin/php /home/UserName/web/domain.com/public_html/wp-cron.php >/dev/null 2>&1

.htaccess to protect wp-login.php

this goes in the same directory as the wp-login.php file is in.

you can do this with any offline virtualbox vm installed linux and upload the files afterwards via SFTP (NOT FTP!)

# install software
apt install apache2-utils
# create the file with this content
vim /var/www/wordpress.com/.htaccess;
  • protect wordpress logins against bruteforce (also causes loads of useless traffic = CO2)
  • not all webservers support .htaccess but apache2 and nginx do
  • /use/absolute/paths/.htpasswd, relative paths do not work well

# it protects every access to wp-login.php with a password
<FilesMatch "wp-login.php">
AuthName "WordPress Admin"
AuthType Basic
AuthUserFile /home/admin/web/.htpasswd
require valid-user
</FilesMatch>
# if the wordpress app is not used, just deny all access to xmlrpc.php
<Files xmlrpc.php>
order deny,allow
deny from all
</Files>

how to generate .htpasswd

this was tested on DATE: 2019-01-31, hetzner level4 webhosting account.

this stores your password in a file that SHALL NOT BE PUBLICLY ACCESIBLE via http https or ftp!

(either because you have it stored in your /var/www/ web root, that is NOT ACCESIBLE only public_html should be!)

# generate password file
htpasswd -c /var/www/.htpasswd username
htpasswd -c /var/www/.htpasswd AnotherUserName
# -s Use SHA encryption for passwords. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif).
This algorithm is insecure by today's
standards.

hetzner’s has a nice backend/dashboard that let’s you configure/restrict directory access:

.htaccess to protect wp-admin directory

unfortunately some plugins as “ajax live search” (returns results as you type) seem to use files from wp-admin such as https://domain.com/wp-admin/admin-ajax.php

?

which then prevents those functions to work.

You should logout, delete all cookies (Firefox: Shift+Ctrl+Del) check if your site’s functionality is not hindered.

create a file under vim ./wp-admin/.htaccess with this content and modify the path to your .htpasswd to suite your setting, again DOUBLE-CHECK THAT .htpasswd IS NOT BE ACCESIBLE BY PUBLIC/OUTSIDE! (try to open it in your browser try to retrieve it with ftp commands)

this format is what hetzner’s dashboard is generating:

AuthUserFile /usr/www/users/username/wp-admin/.htpasswd
AuthName "Realm"
AuthType Basic
require valid-user

how to protect wp-admin.php at hetzner:

you could use something like, in your .htaccess placed under /usr/www/users/username/ (all the red text, is added to the wordpress-generated .htaccess orange text)

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

<FilesMatch "wp-login.php">
AuthName "WordPress Admin"
AuthType Basic
AuthUserFile /usr/www/users/username/wp-admin/.htpasswd
require valid-user
</FilesMatch>

this is one measure you can take to get back speed and performance to your website (people won’t wait 30seconds for your page to load).

liked this article?

  • only together we can create a truly free world
  • plz support dwaves to keep it up & running!
  • (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
  • really really hate advertisement
  • contribute: whenever a solution was found, blog about it for others to find!
  • talk about, recommend & link to this blog and articles
  • thanks to all who contribute!
admin