SlideShare a Scribd company logo
puerto:22
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
---
- 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 commit
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
WPMU DEV
https://www.youtube.com/watch?v=ell0SiTZyX8
https://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install
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 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:57 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:06:59 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:08 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
91.200.12.56 - - [22/Apr/2015:06:07:15 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-"
POST /wp-login.php HTTP/1.1
puerto:22
A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK
IS A BRUTE-FORCE ATTACK
puerto:22
Apr 21 05:40:03 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:05 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:07 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2
Apr 21 05:40:10 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:12 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:13 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2
Apr 21 05:40:39 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:41 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:44 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2
Apr 21 05:40:47 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:49 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:51 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2
Apr 21 05:40:54 myserver sshd[859]: Failed password for root from 43.255.190.126 port 54151 ssh2
Apr 21 05:47:36 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:36 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:39 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:39 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:41 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2
Apr 21 05:47:41 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2
Apr 21 05:47:44 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:46 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:48 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2
Apr 21 05:47:51 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:52 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:47:53 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:54 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:47:56 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2
Apr 21 05:47:57 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2
Apr 21 05:48:19 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:21 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:22 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2
Apr 21 05:48:25 myserver 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 21 19:09:07 blog wordpress(my.wordpress.install)[9298]: Authentication failure for vubpuhttcp from 110.80.74.204
Apr 21 20:39:45 blog wordpress(my.wordpress.install)[9562]: Authentication failure for vubpglyghg from 110.80.74.204
Apr 21 21:11:31 blog wordpress(my.wordpress.install)[12395]: Authentication failure for mougcersdlcrh from 176.97.116.134
Apr 21 21:11:35 blog wordpress(my.wordpress.install)[8190]: Authentication failure for mougcersdvooi from 176.97.116.134
Apr 21 21:51:34 blog wordpress(my.wordpress.install)[12395]: Authentication failure for zeeidrwz54 from 199.168.141.171
Apr 21 22:05:35 blog wordpress(my.wordpress.install)[9562]: Authentication failure for carteykilolye from 176.97.116.134
Apr 21 22:06:36 blog wordpress(my.wordpress.install)[11573]: Authentication failure for dkbzhydsxlmnvj from 176.97.116.134
Apr 22 02:28:46 blog wordpress(my.wordpress.install)[12028]: Authentication failure for gerberktzksy from 176.97.116.134
Apr 22 02:28:47 blog 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 core update
$ wp core update-db
$ wp plugin update --all
$ wp 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/

More Related Content

Similar to WordPress for SysAdmins (20)

PDF
Real-time data analysis using ELK
Jettro Coenradie
 
DOCX
1 Web Page Foundations Overview This lab walk.docx
honey725342
 
PDF
From Zero to Hero - Centralized Logging with Logstash & Elasticsearch
Sematext Group, Inc.
 
PDF
From zero to hero - Easy log centralization with Logstash and Elasticsearch
Rafał Kuć
 
PPTX
HTTP 2.0 - Web Unleashed 2015
dmethvin
 
PDF
Puppet Camp Berlin 2014 Closing Keynote: Next steps for doing more awesome th...
Puppet
 
PPTX
Developers’ mDay 2019. - Nikola Krgović, Twin Star Systems – Big Data for Dev...
mCloud
 
PDF
LogStash - Yes, logging can be awesome
James Turnbull
 
PPTX
Pivotal Open Source: Using Fluentd to gain insights into your logs
Kiyoto Tamura
 
KEY
The Devil and HTML5
Myles Braithwaite
 
PPTX
Who and What Links to the Internet Archive
Michael Nelson
 
PDF
העתיד כבר כאן - שימוש בטכנולוגיות החדשות כבר היום
Ronny Orbach
 
PPTX
Configurare https mule
Antonio Pellegrino
 
PDF
20190516 web security-basic
MksYi
 
PPTX
Windows Azure Visual Studio "Monaco"", Because it’s mundane
Mike Martin
 
PDF
Smashing the stats for fun (and profit)
Security B-Sides
 
PDF
Introducing OWASP OWTF Workshop BruCon 2012
Abraham Aranguren
 
PDF
Application Performance Troubleshooting 1x1 - Von Schweinen, Schlangen und Pa...
rschuppe
 
PDF
The Web Becomes Graceful
colorhook
 
PPTX
Cloud Device Insecurity
Jeremy Brown
 
Real-time data analysis using ELK
Jettro Coenradie
 
1 Web Page Foundations Overview This lab walk.docx
honey725342
 
From Zero to Hero - Centralized Logging with Logstash & Elasticsearch
Sematext Group, Inc.
 
From zero to hero - Easy log centralization with Logstash and Elasticsearch
Rafał Kuć
 
HTTP 2.0 - Web Unleashed 2015
dmethvin
 
Puppet Camp Berlin 2014 Closing Keynote: Next steps for doing more awesome th...
Puppet
 
Developers’ mDay 2019. - Nikola Krgović, Twin Star Systems – Big Data for Dev...
mCloud
 
LogStash - Yes, logging can be awesome
James Turnbull
 
Pivotal Open Source: Using Fluentd to gain insights into your logs
Kiyoto Tamura
 
The Devil and HTML5
Myles Braithwaite
 
Who and What Links to the Internet Archive
Michael Nelson
 
העתיד כבר כאן - שימוש בטכנולוגיות החדשות כבר היום
Ronny Orbach
 
Configurare https mule
Antonio Pellegrino
 
20190516 web security-basic
MksYi
 
Windows Azure Visual Studio "Monaco"", Because it’s mundane
Mike Martin
 
Smashing the stats for fun (and profit)
Security B-Sides
 
Introducing OWASP OWTF Workshop BruCon 2012
Abraham Aranguren
 
Application Performance Troubleshooting 1x1 - Von Schweinen, Schlangen und Pa...
rschuppe
 
The Web Becomes Graceful
colorhook
 
Cloud Device Insecurity
Jeremy Brown
 

More from Javier Arturo Rodríguez (9)

PDF
Introduction to ansible
Javier Arturo Rodríguez
 
PDF
Minimizing cognitive load
 in Perl source code parsing (a.k.a. Pretty program...
Javier Arturo Rodríguez
 
PDF
WordPress Performance Tuning
Javier Arturo Rodríguez
 
PDF
Easy native wrappers with SWIG
Javier Arturo Rodríguez
 
PDF
Open Data: a view from the trenches
Javier Arturo Rodríguez
 
PDF
Barcelona.pm Curs1211 sess01
Javier Arturo Rodríguez
 
PDF
Build an autoversioning filesystem with Apache2
Javier Arturo Rodríguez
 
PDF
Periodismo de Datos II: Construyendo y explorando conjuntos de datos con las ...
Javier Arturo Rodríguez
 
PDF
DatosEnCrudo.org
Javier Arturo Rodríguez
 
Introduction to ansible
Javier Arturo Rodríguez
 
Minimizing cognitive load
 in Perl source code parsing (a.k.a. Pretty program...
Javier Arturo Rodríguez
 
WordPress Performance Tuning
Javier Arturo Rodríguez
 
Easy native wrappers with SWIG
Javier Arturo Rodríguez
 
Open Data: a view from the trenches
Javier Arturo Rodríguez
 
Barcelona.pm Curs1211 sess01
Javier Arturo Rodríguez
 
Build an autoversioning filesystem with Apache2
Javier Arturo Rodríguez
 
Periodismo de Datos II: Construyendo y explorando conjuntos de datos con las ...
Javier Arturo Rodríguez
 
DatosEnCrudo.org
Javier Arturo Rodríguez
 
Ad

Recently uploaded (20)

PPTX
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
PDF
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
PDF
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
PDF
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
PDF
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
ScyllaDB
 
PDF
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
PPTX
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
DOCX
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
PDF
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
PPTX
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
PDF
Redefining Work in the Age of AI - What to expect? How to prepare? Why it mat...
Malinda Kapuruge
 
PDF
Python Conference Singapore - 19 Jun 2025
ninefyi
 
PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
PDF
ArcGIS Utility Network Migration - The Hunter Water Story
Safe Software
 
PPTX
Paycifi - Programmable Trust_Breakfast_PPTXT
FinTech Belgium
 
PDF
Open Source Milvus Vector Database v 2.6
Zilliz
 
PDF
Kubernetes - Architecture & Components.pdf
geethak285
 
PDF
FME as an Orchestration Tool with Principles From Data Gravity
Safe Software
 
PDF
The Growing Value and Application of FME & GenAI
Safe Software
 
PPTX
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Pitch ...
Michele Kryston
 
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
The Future of Product Management in AI ERA.pdf
Alyona Owens
 
Java 25 and Beyond - A Roadmap of Innovations
Ana-Maria Mihalceanu
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
ScyllaDB
 
“MPU+: A Transformative Solution for Next-Gen AI at the Edge,” a Presentation...
Edge AI and Vision Alliance
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
reInforce 2025 Lightning Talk - Scott Francis.pptx
ScottFrancis51
 
Redefining Work in the Age of AI - What to expect? How to prepare? Why it mat...
Malinda Kapuruge
 
Python Conference Singapore - 19 Jun 2025
ninefyi
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Poster...
Michele Kryston
 
ArcGIS Utility Network Migration - The Hunter Water Story
Safe Software
 
Paycifi - Programmable Trust_Breakfast_PPTXT
FinTech Belgium
 
Open Source Milvus Vector Database v 2.6
Zilliz
 
Kubernetes - Architecture & Components.pdf
geethak285
 
FME as an Orchestration Tool with Principles From Data Gravity
Safe Software
 
The Growing Value and Application of FME & GenAI
Safe Software
 
MARTSIA: A Tool for Confidential Data Exchange via Public Blockchain - Pitch ...
Michele Kryston
 
Ad

WordPress for SysAdmins

  • 3. puerto:22 MYTHS AND MISCONCEPTIONS • WordPress is: • Troublesome to install • Hard to maintain • Impossible to secure
  • 5. puerto:22 IN FACT, • WordPress is: • Troublesome Trivial to install • Hard Easy to maintain • Hard to secure Securable
  • 8. puerto:22 DOWNLOAD WP-CLI $ curl -O https://raw.githubusercontent.com/ wp-cli/builds/gh-pages/phar/wp-cli.phar
  • 10. puerto:22 VERIFY WP-CLI $ md5sum wp-cli.phar 8c9113f5de2a892837771fdacf6f8c16 wp-cli.phar
  • 11. puerto:22 --- - 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 commit Known version Known hash
  • 12. 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
  • 15. puerto:22 INSTALL WITH WP-CLI $ wp core download [{arguments}] $ wp core config {arguments} $ wp core install {arguments}
  • 17. 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]
  • 18. puerto:22 CREATE TABLES wp core install --url=<url> --title=<site-title> --admin_user=<username> --admin_password=<password> --admin_email=<email>
  • 23. 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
  • 25. puerto:22 OTHER WP-CLI COMMANDS $ wp plugin install $ wp theme install
  • 27. puerto:22 RESTORE $ wp db import $ wp import
  • 28. puerto:22 MULTISITE $ wp core multisite-convert $ wp core multisite-install
  • 29. puerto:22 LANGUAGE $ wp core multisite-convert $ wp core multisite-install
  • 30. puerto:22 INTEGRITY CHECK $ wp core verify-checksums
  • 33. puerto:22 91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:36 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:37 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:38 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:39 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:40 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:41 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:42 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:43 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:44 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:45 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:46 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:47 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:48 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:49 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:52 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:53 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:54 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:55 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:56 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:57 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:58 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:06:59 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:08 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:09 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:10 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:11 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:12 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:13 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:14 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" 91.200.12.56 - - [22/Apr/2015:06:07:15 +0000] "POST /wp-login.php HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0" "-" POST /wp-login.php HTTP/1.1
  • 34. puerto:22 A BRUTE-FORCE ATTACK IS A BRUTE-FORCE ATTACK IS A BRUTE-FORCE ATTACK
  • 35. puerto:22 Apr 21 05:40:03 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:05 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:07 myserver sshd[540]: Failed password for root from 43.255.190.187 port 40036 ssh2 Apr 21 05:40:10 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:12 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:13 myserver sshd[572]: Failed password for root from 43.255.190.187 port 57055 ssh2 Apr 21 05:40:39 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:41 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:44 myserver sshd[765]: Failed password for root from 43.255.190.126 port 47241 ssh2 Apr 21 05:40:47 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:49 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:51 myserver sshd[778]: Failed password for root from 43.255.190.126 port 37608 ssh2 Apr 21 05:40:54 myserver sshd[859]: Failed password for root from 43.255.190.126 port 54151 ssh2 Apr 21 05:47:36 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:36 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:39 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:39 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:41 myserver sshd[1937]: Failed password for root from 43.255.190.164 port 60212 ssh2 Apr 21 05:47:41 myserver sshd[1939]: Failed password for root from 43.255.190.164 port 34651 ssh2 Apr 21 05:47:44 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:46 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:48 myserver sshd[1957]: Failed password for root from 43.255.190.144 port 37130 ssh2 Apr 21 05:47:51 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:52 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:47:53 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:54 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:47:56 myserver sshd[1969]: Failed password for root from 43.255.190.144 port 52046 ssh2 Apr 21 05:47:57 myserver sshd[1975]: Failed password for root from 43.255.190.144 port 39578 ssh2 Apr 21 05:48:19 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:21 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:22 myserver sshd[2023]: Failed password for root from 43.255.190.186 port 38812 ssh2 Apr 21 05:48:25 myserver sshd[2026]: Failed password for root from 43.255.190.186 port 52811 ssh2
  • 37. puerto:22 FAIL2BAN $ wp plugin install --activate wp-fail2ban
  • 38. puerto:22 /VAR/LOG/AUTH.LOG Apr 21 19:09:07 blog wordpress(my.wordpress.install)[9298]: Authentication failure for vubpuhttcp from 110.80.74.204 Apr 21 20:39:45 blog wordpress(my.wordpress.install)[9562]: Authentication failure for vubpglyghg from 110.80.74.204 Apr 21 21:11:31 blog wordpress(my.wordpress.install)[12395]: Authentication failure for mougcersdlcrh from 176.97.116.134 Apr 21 21:11:35 blog wordpress(my.wordpress.install)[8190]: Authentication failure for mougcersdvooi from 176.97.116.134 Apr 21 21:51:34 blog wordpress(my.wordpress.install)[12395]: Authentication failure for zeeidrwz54 from 199.168.141.171 Apr 21 22:05:35 blog wordpress(my.wordpress.install)[9562]: Authentication failure for carteykilolye from 176.97.116.134 Apr 21 22:06:36 blog wordpress(my.wordpress.install)[11573]: Authentication failure for dkbzhydsxlmnvj from 176.97.116.134 Apr 22 02:28:46 blog wordpress(my.wordpress.install)[12028]: Authentication failure for gerberktzksy from 176.97.116.134 Apr 22 02:28:47 blog wordpress(my.wordpress.install)[10641]: Authentication failure for carteykilojht from 176.97.116.134
  • 39. 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 =
  • 40. puerto:22 /ETC/FAIL2BAN/JAIL.LOCAL [wordpress] enabled = true filter = wordpress logpath = /var/log/auth.log port = http,https bantime = 3600
  • 41. 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
  • 42. puerto:22 TELNET? $ telnet wordpress Trying 173.194.65.104... Connected to wordpress. Escape character is '^]'. Debian GNU/Linux 7 wordpress login:
  • 43. 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:
  • 47. puerto:22 $ wp plugin install --activate wordpress-https
  • 50. puerto:22 $ wp plugin install --activate google-authenticator
  • 51. puerto:22 $ wp plugin install --activate google-authenticator
  • 59. puerto:22 USER ACCOUNTS Account type Administrative Web daemon uid configmgr www-data Permissions Read/Write Read-only
  • 60. puerto:22 FILE OWNERSHIP Directory Owner htdocs/ configmgr htdocs/wp-content/uploads/ www-data
  • 61. puerto:22 $ chown -R configmgr.wheel htdocs/ $ chown -R www-data.www-data htdocs/wp-content/uploads
  • 62. 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>
  • 64. puerto:22 $ wp core update $ wp core update-db $ wp plugin update --all $ wp theme update --all
  • 65. 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
  • 66. puerto:22 /ETC/CRON.D/WP 0 3 * * * configmgr /usr/local/bin/wp-update
  • 68. puerto:22 SQL INJECTION Comic: Rockin’ Randall Munroe, XKCD 327 (CC)
  • 70. puerto:22 MOD_SECURITY # apt-get install libapache2-modsecurity # a2enmod mod-security
  • 72. puerto:22 BUT I GET FALSE POSITIVES!
  • 73. 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>
  • 74. 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>
  • 75. 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>
  • 79. puerto:22 $ wp plugin install --activate akismet $ wp plugin install --activate google-captcha
  • 82. 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
  • 87. puerto:22 MOD_QOS # apt-get install libapache2-mod-qos # a2enmod qos
  • 88. 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>
  • 89. puerto:22 SEE ALSO • wplib • mod_evasive • Bedrock
  • 90. 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!
  • 92. puerto:22 THANK YOU! Javier Arturo Rodríguez @codehead http://scribd.com/javierrgz/