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:
      • mv -v xmlrpc.php xmlrpc.php.disabled
  • 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;

<FilesMatch "wp-login.php">
    AuthName "WordPress Admin"
    AuthType Basic
    AuthUserFile /var/www/passwd
    require valid-user
</FilesMatch>

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 -cs /var/www/passwd username
htpasswd -s /var/www/passwd AnotherUserName
# -s Use SHA encryption for passwords.

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).

admin