WORDPRESS

FOR SYSADMINS
Javier Arturo Rodríguez
@codehead
javier.rodriguez@puerto22.com
puerto:22

MYTHS AND
MISCONCEPTIONS

puerto:22

MYTHS AND

MISCONCEPTIONS

WordPress is:

Troublesome to install

Hard to maintain

Impossible to secure

puerto:22

NOPE

puerto:22

IN FACT,

WordPress is:

Troublesome Trivial to install

Hard Easy to maintain

Hard to secure Securable

puerto:22

WP-CLI

Image: Petr Kratochvil (PD)

puerto:22

HTTP://WP-CLI.ORG/

puerto:22

DOWNLOAD WP-CLI

$ curl -O https://raw.githubusercontent.com/
wp-cli/builds/gh-pages/phar/wp-cli.phar

puerto:22

VERIFY YOUR
CHECKSUMS!

puerto:22

VERIFY WP-CLI

$ md5sum wp-cli.phar
8c9113f5de2a892837771fdacf6f8c16

wp-cli.phar

puerto:22

Known commit
--- name: wordpress - install wp-cli
get_url: url=https://raw.githubusercontent.com/wp-cli/builds/e94cf3fd57116b84c86a2578a0c66757fa77a592/phar/wp-cli.phar
sha256sum=b4dd0b82df6ffd3ccbedcd9d2789dbc9f26fd21c86fc62b6f9f524d1775c9fd3
dest=/usr/local/bin/wp-0180
owner=root
group=root
mode=0755

Known version

Known hash

puerto:22

INSTALL WP-CLI

$ chmod +x wp-cli.phar
$ sudo mv wp-cli.phar /usr/local/bin/wp
$ wp --info
WP-CLI 0.18.0

puerto:22

$ wp help

puerto:22

INSTALL WITH WP-CLI

puerto:22

INSTALL WITH WP-CLI

$ wp core download [{arguments}]
$ wp core config {arguments}
$ wp core install {arguments}

puerto:22

DOWNLOAD

wp core download
[--path=<path>]
[--locale=<locale>]
[--version=<version>]
[--force]

puerto:22

CREATE WP-CONFIG.PHP
wp core config
--dbname=<dbname>
--dbuser=<dbuser>
[--dbpass=<dbpass>]
[--dbhost=<dbhost>]
[--dbprefix=<dbprefix>]
[--dbcharset=<dbcharset>]
[--dbcollate=<dbcollate>]
[--locale=<locale>]
[--extra-php]
[--skip-salts]
[--skip-check]
puerto:22

CREATE TABLES
wp core install
--url=<url>
--title=<site-title>
--admin_user=<username>
--admin_password=<password>
--admin_email=<email>

puerto:22

https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install

puerto:22

https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install

puerto:22

https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install

WPMU DEV
https://www.youtube.com/watch?v=ell0SiTZyX8

puerto:22

30-SECOND INSTALL

puerto:22

$ time ~/wordpress-install
/home/admin/wordpress.config
Downloading WordPress 4.2 (en_US)...
Using cached file '/home/admin/.wp-cli/cache/core/en_US-4.2.tar.gz'...
Success: WordPress downloaded.
Success: Generated wp-config.php file.
Success: WordPress installed successfully.

!

real 0m2.715s
user 0m0.460s
sys0m0.232s

puerto:22

303-SECOND INSTALL

puerto:22

OTHER WP-CLI
COMMANDS

$ wp plugin install
$ wp theme install

puerto:22

BACKUP

$ wp export
$ wp db export

puerto:22

RESTORE

$ wp db import
$ wp import

puerto:22

MULTISITE

$ wp core multisite-convert
$ wp core multisite-install

puerto:22

LANGUAGE

$ wp core multisite-convert
$ wp core multisite-install

puerto:22

INTEGRITY CHECK

$ wp core verify-checksums

puerto:22

SECURITY

puerto:22

(FROM A SYSADMIN
PERSPECTIVE)

puerto:22

91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56
91.200.12.56

-

-

[22/Apr/2015:06:06:36
[22/Apr/2015:06:06:36
[22/Apr/2015:06:06:37
[22/Apr/2015:06:06:37
[22/Apr/2015:06:06:38
[22/Apr/2015:06:06:38
[22/Apr/2015:06:06:39
[22/Apr/2015:06:06:39
[22/Apr/2015:06:06:40
[22/Apr/2015:06:06:40
[22/Apr/2015:06:06:40
[22/Apr/2015:06:06:41
[22/Apr/2015:06:06:41
[22/Apr/2015:06:06:42
[22/Apr/2015:06:06:42
[22/Apr/2015:06:06:43
[22/Apr/2015:06:06:43
[22/Apr/2015:06:06:44
[22/Apr/2015:06:06:44
[22/Apr/2015:06:06:45
[22/Apr/2015:06:06:45
[22/Apr/2015:06:06:46
[22/Apr/2015:06:06:46
[22/Apr/2015:06:06:47
[22/Apr/2015:06:06:47
[22/Apr/2015:06:06:48
[22/Apr/2015:06:06:48
[22/Apr/2015:06:06:48
[22/Apr/2015:06:06:49
[22/Apr/2015:06:06:49
[22/Apr/2015:06:06:52
[22/Apr/2015:06:06:52
[22/Apr/2015:06:06:53
[22/Apr/2015:06:06:53
[22/Apr/2015:06:06:54
[22/Apr/2015:06:06:54
[22/Apr/2015:06:06:54
[22/Apr/2015:06:06:55
[22/Apr/2015:06:06:55
[22/Apr/2015:06:06:56
[22/Apr/2015:06:06:56
[22/Apr/2015:06:06:57
[22/Apr/2015:06:06:58
[22/Apr/2015:06:06:58
[22/Apr/2015:06:06:59
[22/Apr/2015:06:07:08
[22/Apr/2015:06:07:09
[22/Apr/2015:06:07:09
[22/Apr/2015:06:07:10
[22/Apr/2015:06:07:10
[22/Apr/2015:06:07:11
[22/Apr/2015:06:07:11
[22/Apr/2015:06:07:11
[22/Apr/2015:06:07:12
[22/Apr/2015:06:07:12
[22/Apr/2015:06:07:13
[22/Apr/2015:06:07:13
[22/Apr/2015:06:07:14
[22/Apr/2015:06:07:14
[22/Apr/2015:06:07:15

+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]
+0000]

"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST
"POST

/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php
/wp-login.php

HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"
HTTP/1.1"

302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302
302

-

"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"

"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0
"Mozilla/5.0

POST /wp-login.php HTTP/1.1

(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows
(Windows

NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT
NT

6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;
6.1;

rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)
rv:5.0)

Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101
Gecko/20100101

Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"
Firefox/5.0"

"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"
"-"

puerto:22

A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK

puerto:22

Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr

21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21

05:40:03
05:40:05
05:40:07
05:40:10
05:40:12
05:40:13
05:40:39
05:40:41
05:40:44
05:40:47
05:40:49
05:40:51
05:40:54
05:47:36
05:47:36
05:47:39
05:47:39
05:47:41
05:47:41
05:47:44
05:47:46
05:47:48
05:47:51
05:47:52
05:47:53
05:47:54
05:47:56
05:47:57
05:48:19
05:48:21
05:48:22
05:48:25

myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver
myserver

sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
sshd[859]: Failed password for root from 43.255.190.126 port 54151 ssh2
sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
sshd[2026]: Failed password for root from 43.255.190.186 port 52811 ssh2

puerto:22

FAIL2BAN

puerto:22

FAIL2BAN

$ wp plugin install --activate wp-fail2ban

puerto:22

/VAR/LOG/AUTH.LOG

Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr
Apr

21
21
21
21
21
21
21
22
22

19:09:07
20:39:45
21:11:31
21:11:35
21:51:34
22:05:35
22:06:36
02:28:46
02:28:47

blog
blog
blog
blog
blog
blog
blog
blog
blog

wordpress(my.wordpress.install)[9298]: Authentication failure for vubpuhttcp from 110.80.74.204
wordpress(my.wordpress.install)[9562]: Authentication failure for vubpglyghg from 110.80.74.204
wordpress(my.wordpress.install)[12395]: Authentication failure for mougcersdlcrh from 176.97.116.134
wordpress(my.wordpress.install)[8190]: Authentication failure for mougcersdvooi from 176.97.116.134
wordpress(my.wordpress.install)[12395]: Authentication failure for zeeidrwz54 from 199.168.141.171
wordpress(my.wordpress.install)[9562]: Authentication failure for carteykilolye from 176.97.116.134
wordpress(my.wordpress.install)[11573]: Authentication failure for dkbzhydsxlmnvj from 176.97.116.134
wordpress(my.wordpress.install)[12028]: Authentication failure for gerberktzksy from 176.97.116.134
wordpress(my.wordpress.install)[10641]: Authentication failure for carteykilojht from 176.97.116.134

puerto:22

/ETC/FAIL2BAN/JAIL.LOCAL
# Fail2Ban configuration file
#
# Author: Charles Lecklider
#

!

[INCLUDES]

!

before = common.conf

!
!

[Definition]
_daemon = wordpress
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>$
^%(__prefix_line)sBlocked authentication attempt for .* from <HOST>$
^%(__prefix_line)sBlocked user enumeration attempt from <HOST>$

!

ignoreregex =

puerto:22

/ETC/FAIL2BAN/JAIL.LOCAL
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
port = http,https
bantime = 3600

puerto:22

# fail2ban-client status wordpress
Status for the jail: wordpress
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 0
| `- Total failed: 1016
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 53

puerto:22

TELNET?
$ telnet wordpress
Trying 173.194.65.104...
Connected to wordpress.
Escape character is '^]'.
Debian GNU/Linux 7
wordpress login:

puerto:22

SSH!
$ ssh wordpress
Host key fingerprint is
e0:84:30:20:97:36:53:f1:69:12:7a:fe:5d:32:8d:30
+--[ RSA 2048]----+
|o.+o+.
|
|..=+ + .
|
| ..o+ E
|
|
o = + o
|
|
. . S o
|
|
. . +
|
|
. .
|
|
|
|
|
+-----------------+
!

javier@wordpress password:

puerto:22

http://my.wordpress.com/wp-login.php

puerto:22

ENABLE HTTPS

puerto:22

$ a2enmod ssl

puerto:22

$ wp plugin install --activate wordpress-https

puerto:22

https://my.wordpress.com/wp-login.php

puerto:22

TWO-FACTOR

AUTHENTICATION

puerto:22

$ wp plugin install --activate google-authenticator

puerto:22

$ wp plugin install --activate google-authenticator

puerto:22

EASY. RIGHT?

puerto:22

puerto:22

SECURITY
IS NOT
AN ADD-ON

puerto:22

CODE INJECTION

puerto:22

puerto:22

puerto:22

FILESYSTEM
PERMISSIONS

puerto:22

USER ACCOUNTS
Account type

Administrative

Web daemon

uid

configmgr

www-data

Permissions

Read/Write

Read-only

puerto:22

FILE OWNERSHIP
Directory

Owner

htdocs/

configmgr

htdocs/wp-content/uploads/

www-data

puerto:22

$ chown -R configmgr.wheel htdocs/
$ chown -R www-data.www-data \
htdocs/wp-content/uploads

puerto:22

NOEXEC
# Prevent malicious scripts in upload dirs
<Directory …/htdocs/wp-content/uploads>
Options -Indexes -ExecCGI
SetHandler None
RemoveHandler .php .php3 .php4 .phps
php_flag engine off
</Directory>

puerto:22

BUT THIS BREAKS
AUTO-UPDATE!

puerto:22

$
$
$
$

wp
wp
wp
wp

core update
core update-db
plugin update --all
theme update --all

puerto:22

/USR/LOCAL/BIN

/WP-UPDATE
#!/bin/sh cd /var/www
wp core update
wp core update-db
wp plugin update --all
wp theme update --all

puerto:22

/ETC/CRON.D/WP

0 3 * * * configmgr /usr/local/bin/wp-update

puerto:22

SQL INJECTION

puerto:22

SQL INJECTION

Comic: Rockin’ Randall Munroe, XKCD 327 (CC)

puerto:22

MOD_SECURITY

puerto:22

MOD_SECURITY

# apt-get install libapache2-modsecurity
# a2enmod mod-security

puerto:22

Image: GirlieMac, http://httpcats.herokuapp.com/403

puerto:22

BUT I GET FALSE
POSITIVES!

puerto:22

APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login\.php)">
SecRuleRemoveById 950901
</LocationMatch>
</IfModule>

puerto:22

APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login\.php)">
SecRuleRemoveById 950901
</LocationMatch>
# Images are (mostly) harmless
<FilesMatch "\.(gif|jpe?g|png)$">
SecRuleEngine Off
</FilesMatch>
</IfModule>

puerto:22

APACHE2.CONF
# Mod_security tweaks
<IfModule mod_security2.c>
# wp-login.php should allow redirects
<LocationMatch "^/(wp-login\.php)">
SecRuleRemoveById 950901
</LocationMatch>
# Images are (mostly) harmless
<FilesMatch "\.(gif|jpe?g|png)$">
SecRuleEngine Off
</FilesMatch>
# wp-admin/ is a protected area
<LocationMatch "^/(wp-admin/)">
SecRuleEngine Off
</LocationMatch>
</IfModule>

!

# Enable Basic Auth on /wp-admin/ to discourage attacks
<Location /wp-admin/>
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/wpadmin.passwd
Require valid-user
</Location>

puerto:22

SPAM

Image: Der Hupe (CC)

puerto:22

Image: Der Hupe (CC)

puerto:22

COMMENT SPAM

puerto:22

$ wp plugin install --activate akismet
$ wp plugin install --activate google-captcha

puerto:22

REFERRER SPAM

puerto:22

SETENVIF*

puerto:22

.HTACCESS
SetEnvIfNoCase Via evil-spam-proxy spammer=yes
SetEnvIfNoCase Referer evil-spam-domain.com spammer=yes
SetEnvIfNoCase Referer evil-spam-keyword spammer=yes
SetEnvIfNoCase Via pinappleproxy spammer=yes
SetEnvIfNoCase Referer semalt.com spammer=yes
SetEnvIfNoCase Referer poker spammer=yes
...
Order allow,deny
Allow from all
Deny from env=spammer

https://wordpress.org/support/topic/how-to-block-semaltcom-from-visiting-your-wordpress-website

puerto:22

CREEPY CRAWLERS

Image: David Featherston (CC)

puerto:22

ROBOTS.TXT

puerto:22

ROBOTS.TXT

User-agent: *
Crawl-delay: 30

puerto:22

MOD_QOS

puerto:22

MOD_QOS

# apt-get install libapache2-mod-qos
# a2enmod qos

puerto:22

<IfModule qos_module>
# minimum request rate (bytes/sec at request reading):
QS_SrvRequestRate 120

!
!
!

# limits the connections for this virtual host:
QS_SrvMaxConn 100
# allows keep-alive support till the server reaches 600 connections:
QS_SrvMaxConnClose 80

# allows max 50 connections from a single ip address:
QS_SrvMaxConnPerIP 10
</IfModule>

puerto:22

SEE ALSO

wplib

mod_evasive

Bedrock

puerto:22

SUMMARY

wp-cli for the win

WordPress can be managed like any other system

WordPress security can be managed at the system level

Automate!

puerto:22

Q&A

puerto:22

THANK YOU!
Javier Arturo Rodríguez
@codehead
http://scribd.com/javierrgz/

puerto:22

Sign up to vote on this title
UsefulNot useful