Block bad bots on cPanel globally with Apache

A lot of traffic from bad bots, crawling your sites can cause problems such as high server load and unstable server. You should use mod_security on cPanel servers that should do the job, but if you want to block specific bots globally, on apache level, then bellow solution is for you. This syntax is for Apache version 2.4.

On cPanel servers you can’t just edit httpd.conf file, it will be rewrited. You can edit it through whm easily. Just login on your cpanel -> Apache Configuration -> Include Editor -> go to “Pre Main Include” -> select your apache version (or all versions) -> then insert code bellow and click Update and then restart apache.

In Directory section, you should specify right path to location where websites are. On cpanel servers this is /home by default.

Here is my example:

<Directory "/home">
   SetEnvIfNoCase User-Agent "MJ12bot" bad_bots
   SetEnvIfNoCase User-Agent "AhrefsBot" bad_bots
   SetEnvIfNoCase User-Agent "SemrushBot" bad_bots
   SetEnvIfNoCase User-Agent "Baiduspider" bad_bots
     Require all granted
     Require not env bad_bots

Get SSL certificate expiry date quickly and easily with ckcrt script

SSL certificates are daily routine of my work, so there was regular practice to check expiry date of live certificate through Chrome browser -> Developer tools. It is quite time-consuming and annoying work if you have to repeat it. So I made this very simple bash script with which you can check expiry date and some other certificate information quickly, from your terminal. This will work on osx or linux machines. Of corse, you must have OpenSSL installed on your machine in order to use this script.

Continue Reading

Macbook Pro – assign escape to section/paragraph key on OSX Sierra

If I’m honest, this touch bar that new Macbook Pro brings keeps me cold. As system administrator I’m forced to use ESC a lot. This “virtual” escape button on touch bar is annoying as hell. But there is way to make escape button physical again. Sierra brought simple solution to assign escape to caps lock button. Not very good solution in my opinion. I have international keyboard and paragraph/section (§) key is unused – I don’t recall that I ever used section key. So I assigned escape function to section key which is also near to position where escape button used to be, so that makes it even more great.

First I installed this Karabiner-Elements. Then you must create simple rule. I was confused when assigning “From key” because section key wasnt there. It turns out that you have to select non_us_backslash option and then assign “To key” escape.

It should look like this:

I hope that this helps anyone 🙂

Limit xmlrpc.php to only specific web clients

Xmlrpc.php is very common target of attacks. In most cases you don’t need xmlrpc, but if you use third-party apps like WordPress for iPhone or android or other editors, then xmlrpc is the one who communicates between them and your WordPress installation. If you’ll be using it, it can be good idea to limit access to it only from “browsers” that you are using to access it. In case bellow, I’m using iPhone WordPress app.

When access to xmlrpc.php via iphone app, you’ll see that access log looks like this:

[11/Jun/2017:19:45:08 +0200] "POST /xmlrpc.php HTTP/2.0" 200 462 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89 wp-iphone/7.7"

From this you can see that wp-iphone/7.7 is named as client. So this will be our key for nginx configuration. We’ll make rule that will only accept requests to xmlrpc.php from clients containing string “wp-iphone”. Other clients will be denied. This is not bulletproof of as web client can be easily spoofed, but it should block majority of attacks.

location = /xmlrpc.php {
if ($http_user_agent !~* "wp-iphone")
return 403;
include fastcgi_params;

WordPress bruteforce protection with NGINX and limit_req / request limitation

WordPress installations are very common targets of brute force attacks. With this attacks, attacker tries countless username and password variations in order to guess login informations. As you can imagine that such abusive behavior on your WordPress can cause collapse of server. Very common are attacks on wp-login.php and xmlrpc.php. There is a simple way to limit allowed number of requests on specific file with limit_req. This module can limit processing rate of requests coming from a single IP address on your web server.

In order to protect your WordPress administration you can do something like this:

# prevent brute force attacks on wp-login.php
 location = /wp-login.php {
        limit_req zone=one burst=5 nodelay;
        include fastcgi_params;

This will allow 5 request in 5 second “window”. When there’ll be more than 5 request in 5 seconds, Nginx will return 503 error until request rate slows down:

$ curl -I 
HTTP/1.1 503 Service Temporarily Unavailable
Server: nginx

Of course, you can use limit_req to protect other systems besides WordPress to.

Directadmin – find all email forwarders on server for specific email account

Here is simple one liner for finding all mail aliases on Directadmin server that are forwarding to your email account – in this example All aliases are saved in files /etc/virtual/<domain_name>/aliases.

[root@directadmin ~]# grep -ri "" /etc/virtual/*/aliases | awk -F '/|:' {'print $4 ": " $6 " ->" $7'} alias1 -> sales ->, chacha ->,,

Bulk TTL change in Directadmin

You may want to change TTL values for all domains and their DNS records on your Directadmin server. This can be done very easily. Here is how.

  • Go to templates directory.
    cd /usr/local/directadmin/data/templates
  • Directadmin’s default TTL value is 14400, so let’s say we want to change it to 300. You will have to edit template file named.db.
    sed -ie 's/14400/300/g' named.db
  • Rewrite all configuration files for each user
    echo "action=rewrite&value=named" >> /usr/local/directadmin/data/task.queue

Wait a minute or two, then check if user configs were rewrited with new values. Go to /etc/namedb and than open .db file of some domain. It should contain new TTL value.

Migrate email to gmail with imapsync – Host2 failure: Error login

So you want to migrate your emails from your hosting to your Gmail and you can’t get it to work with imapsync? You triple checked your login credentials and are correct but transfer still doesnt work. So what is causing error bellow?

Host2 failure: Error login on [] with user [] auth [LOGIN]: 2 NO [ALERT] Please log in via your web browser

You have to login to your Google Apps settings (Security -> Advanced security settings) and change value for Less secure apps to: Enforce access to less secure apps for all users. Than it should work.

Magento – Fatal error: Class Mage not found

Of corse, this can be caused by many different things, but if you’re stuck, without any ideas what could be wrong, than try solution bellow. Compiler stores everything in one file and can cause problems with includes. Just clear compiler and disable it if you don’t need it of corse.

I was getting error like this:

Warning: include(Mage.php): failed to open stream: No such file or directory in /my/web/server/root/public_html/lib/Varien/Autoload.php on line 94 Warning: include(): Failed opening 'Mage.php' for inclusion (include_path='/my/web/server/root/public_html/app/code/local:/my/web/server/root/public_html/app/code/community:/my/web/server/root/public_html/app/code/core:/my/web/server/root/public_html/lib:.:/usr/local/share/pear') in /my/web/server/root/public_html/lib/Varien/Autoload.php on line 94 Fatal error: Class 'Mage' not found in /my/web/server/root/public_html/app/code/core/Mage/Core/functions.php on line 244

Just login into your shell and then execute commands bellow (without comments):

//clear compiler
php compiler.php clear
//disable compiler
php compiler.php disable

It is most likely that this will fix your problem. If not, keep digging 🙂

Hope it helps.

Alpine PhotoTile for Instagram not showing images

If you’re using this WordPress plugin to show Instagram images gallery on your site, and you noticed that images don’t show anymore, chances are, that this is due to deprecated PHP function ereg_replace. recently I upgraded my PHP version to 7.1 and this plugin stopped working. So, if you upgraded your PHP, this is almost certain the cause of problem. There is how to fix this.

Error log was showing this:

2017/02/11 11:31:40 [error] 18865#18865: *4616 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function ereg_replace() in /path/to/site/public_html/wp-content/plugins/alpine-photo-tile-for-instagram/gears/alpinebot-display.php:58

So, open alpinebot-display.php with your favorite text editor and go to line where error is – in this case 58. Just replace ereg_replace with preg_replace and it should work again.

Hope it hepls.

© 2017
Hosted by Hosterdam

About author