Wordpress Bouncer
#
How does it work ?This wordpress plugin allows you to apply decisions from crowdsec directly within the wordpress application.
It relies on the associated php library and provides the ability to not only block users, but challenge them with captchas.
#
InstallationThe bouncer itself can be installed from the marketplace in wordpress back-office :
#
ConfigurationYou only need to configure your local API endpoint and API key so the bouncer can get its decisions from crowdsec :
A key point of the bouncer is to allow not only to block users, but as well to present them with captchas :
#
ResourcesFeel free to look at the associated article for more configuration options and tweaks.
#
WordPress MarketplaceYou can find this plugin on the WordPress Plugins Marketplace.
#
Developer resourcesdocker-compose
#
Install with #
Install the wordpress and the plugin locally using docker-composeFollow this guide to get the development stack installed locally.
Prerequises:
- you should have
docker
installeddocker
should berunnable without sudo
.docker-compose
installed locally.- IPv6 should be enable in your docker configuration. Enabled it following this guide. (Note that you'll may have to create the file
/etc/docker/daemon.json
).- If your develop environnment is MacOS, please refer to the MacOS host installation guide.
#
Install the stack for development purposeBefore all, create a .env
file, using:
cp .env.example .env
Note about PHP 8.0: WordPress official docker image does not officially supports PHP 8.0 at this time. However, as the CrowdSec PHP Library does support PHP 8.0, there is a good chance that the plugin will work fine with PHP 8.0, but we can not currently test it.
#
Configure WordPress and the CrowdSec PluginNow there are two options, you can fill the Wordpress installation wizard manually OR use let the e2e tests to do it for you.
#
A) Automatic configurationInstall Wordpress instance and activate plugin launching the e2e tests (limited to the installation steps):
SETUP_ONLY=1 ./run-tests.sh
#
B) Manual comfigurationAlternatively, you can install wordpress and the plugin manually with:
docker-compose up -d wordpress crowdsec mysql redis memcached
Then visit the wordpress instance here: http://localhost and install the wordpress instance.
#
Infos to setup the plugin#
Get a bouncer keydocker-compose exec crowdsec cscli bouncers add wordpress-bouncer
#
LAPI URLhttp://crowdsec:8080
#
Try the plugin behaviorInfo | Value |
---|---|
Public blog URL | http://localhost |
Blog admin URL | http://localhost/wp-admin |
Admin username | admin |
Pasword | my_very_very_secret_admin_password |
#
Demo guide#
Full guideThis guide exposes you the main features of the plugin.
#
Let's get started!We will start using "live" mode. You'll understand what it is after try the stream mode.
First, be sure to get the stack installed using the docker-compose guide.
open a terminal to display LAPI logs in realtime:
docker-compose logs -f crowdsec
- In wp-admin, ensure the bouncer is configured with live mode (stream mode disabled).
#
Discover the cache system- In a tab, visit the public home. You're allowed because LAPI said your IP is clean.
To avoid latencies when the clean IP browse the website, the bouncer will keep this information in cache for 30 seconds (you can change this value in the avdanced settings page). In other words, LAPI will not be requested to check this IP for the next 30 seconds.
You can call the website as many times as you want, the cache system will take relay during the ban period and so LAPI will not be disturbed. The ban decision will stay in cache for the full ban duration. Then the public home should be available again.
#
Try ban remediationIf you want to skip this delay, feel free to clear the cache in the wp-admin.
The DOCKER_HOST_IP
environnement variable is initialized via a call to:
source ./load-env-vars.sh
- In a terminal, ban your own IP for 4 hours:
# Ban your own IP for 4 hours:docker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 4h --type ban
- Immediately, the public home is now locked with a short message to explain you that you are banned.
#
Try "captcha" remediation- Now, request captcha for your own IP for 15m:
# Clear all existing decisionsdocker-compose exec crowdsec cscli decisions delete --all
# Add a captchadocker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 15m --type captcha
The public home now request you to fill a captcha.
Unless you manage to solve the captcha, you'll not be able to access the website.
Note: when you resolve the captcha in your browser, the associated PHP session is considered as sure. If you remove the captcha decision with
cscli
, then you add a new captcha decision for your IP, you'll not be prompted for the current PHP session. To view the captcha page, You can force using a new PHP session opening the front page with incognito mode.
#
Stream mode, for the high traffic websitesWith live mode, as you tried it just before, each time a user arrives to the website for the first time, a call is made to LAPI. If the traffic on your website is high, the bouncer will call LAPI very often.
To avoid this, LAPI offers a "stream" mode. The decisions list is updated at a predefined frequency and kept in cache. Let's try it!
This bouncer uses the WordPress cron system. For demo purposes, we encourage you to install the WP-Control plugin, a plugin to view and control each Wordpress Cron task jobs.
First, clear the previous decisions:
# Clear all existing decisionsdocker-compose exec crowdsec cscli decisions delete --all
Then enable "stream" mode right here and set the resync frequency to 30 seconds. If you installed WP-Control plugin, you can see that a new cron tak has just been added here http://localhost/wp-admin/tools.php?page=crontrol_admin_manage_page.
As the whole blocklist has just been loaded in cache (0 decision!), your IP is allowed. The public home is available.
Now, if you ban your IP for 4h:
docker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 4h --type ban
- In less than 30 seconds your IP will be banned and the public home will be locked.
Conclusion: with the stream mode, LAPI decisions are fetched on a regular basis rather than being called when user arrives for the first time.
#
Try Redis or MemcachedIn order to get better performances, you can switch the cache technology.
The docker-compose file started 2 unused containers, redis and memcached.
Let's try Redis!
- Just go to the advanced settings page
- select the Caching technology named "Redis" and
- type
redis://redis:6379
in the "Redis DSN" field.
Very similar with Memcached!
- Just go to the advanced settings page
- select the Caching technology named "Memcached" and
- type
memcached://memcached:11211
in the "Memcached DSN" field.
#
StatisticsThe bouncer has a stats page indicating each time :
- an IP has been banned by your website, or
- when a captcha has been presented to an IP visiting your website
- when a captcha has been solved or not.
#
How to contribute?#
Contribute to this pluginFirst, be sure to get the stack installed using the docker-compose guide.
#
Play with crowdsec state
#### Add captcha your own IP for 15m:docker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 15m --type captcha
#### Ban your own IP for 15 sec:docker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 15s --type ban
#### Remove all decisions:docker-compose exec crowdsec cscli decisions delete --all
#### View CrowdSec logs:docker-compose logs crowdsec
Note: The
DOCKER_HOST_IP
environnment variable is initialized viasource ./load-env-vars.sh
.
#
WP Scan passdocker-compose run --rm wpscan --url http://wordpress5-6/
composer
dependencies#
Reinstall docker-compose exec wordpress5-6 composer install --working-dir /var/www/html/wp-content/plugins/cs-wordpress-bouncer --prefer-source
In this dev environment, we use
--prefer-source
to be able to develop the bouncer library at the same time. Composer may ask you for your own Github token to download sources instead of using dist packages.
docker-compose
cheet sheet#
Quick docker-compose run wordpress sh # run sh on wordpress containerdocker-compose ps # list running containersdocker-compose stop # stopdocker-compose rm # destroy
#
Try the plugin with another PHP versiondocker-compose downdocker images | grep wordpress-bouncer_wordpress # to get the container iddocker rmi <container-id>
Then, in the .env
file, replace:
CS_WORDPRESS_BOUNCER_PHP_VERSION=7.2
with :
CS_WORDPRESS_BOUNCER_PHP_VERSION=<the-new-php-version>
Then re-run the stack.
#
Try the plugin with another WordPress versionThe plugin is tested under each of these WordPress versions: 5.6
, 5.5
, 5.4
, 5.3
, 5.2
, 5.1
, 5.0
, 4.9
.
(Representing more than 90% of the wordpress websites)
#
Add support for a new WordPress versionThis is a cheat sheet to help testing briefly the support:
# To install a specific versiondocker-compose up -d wordpress<X.X> crowdsec mysql redis memcached && docker-compose exec crowdsec cscli bouncers add wordpress-bouncer
# To display the captcha wall
docker-compose exec crowdsec cscli decisions add --ip ${DOCKER_HOST_IP} --duration 15m --type captcha
# To delete the image in order to rebuild it
docker-compose down && docker rmi wordpress-bouncer_wordpress<X.X>
# To debug inside the container
docker-compose run wordpress<X.X> bash
Note: The
DOCKER_HOST_IP
environnement variable is initialized viasource ./load-env-vars.sh
.
#
Plugin debug mode VS production modeThe debug mode throws verbose errors. The production mode hides every error to let users navigate in every edge cases.
This plugin goes in debug mode when Wordpress debug mode is enabled.
To try the production mode of this plugin, just disable the wordpress debug mode: in docker-compose.yml
, comment the line:
WORDPRESS_DEBUG: 1 # Comment this line the simulate the production mode
#
Display the plugin logstail -f logs/debug-*
#
FAQ#
How to use system CRON instead of wp-cron?Add define('DISABLE_WP_CRON', true);
in wp-config.php
then enter this command line on the wordpress host command line:
(crontab -l && echo "* * * * * wget -q -O - htt://<host>:<port>/wp-cron.php?doing_wp_cron >/dev/null 2>&1") | crontab -
Note: replace [host]:[port] with the local url of your website
More info here.
#
Contribute to this plugin from a MacOS hostYou can test the Linux behavior of this project using Vagrant.
#
One time setup#
Run the VM and initialize itvagrant upvagrant sshsudo usermod -aG docker vagrantsudo systemctl restart docker
You have to log out and log back for permission to be updated:
exitvagrant ssh
#
Enabled Docker IPV6 support inside the Linux VMfollow this guide. (Note that you'll have to create the file /etc/docker/daemon.json
).
#
Install NodeJSFollow this guide/
#
Install YarnFollow this guide.
#
Add deps to run playwrightsudo apt-get install libnss3\ libnspr4\ libatk1.0-0\ libatk-bridge2.0-0\ libxcb1\ libxkbcommon0\ libx11-6\ libxcomposite1\ libxdamage1\ libxext6\ libxfixes3\ libxrandr2\ libgbm1\ libgtk-3-0\ libpango-1.0-0\ libcairo2\ libgdk-pixbuf2.0-0\ libasound2\ libatspi2.0-0
#
Edit you local host file:Type sudo vim /etc/hosts
and add:
# select the one you want to try by uncommenting only ont of the two# 172.16.0.50 wordpress5-6 # Uncomment to use IPV4fde4:8dba:82e1::c4 wordpress5-6 # Uncomment to use IPV6
.env
file#
Configure your cd /vagrantcp .env.example .env
Update the created .env
file with:
DEBUG=0DOCKER_HOST_IP=172.16.238.1 # OR IF YOU WANT TO TEST WITH IPV6 USE: 2001:3200:3200::1
#
Run "plugin auto setup" via e2e tests (limited to setup steps)SETUP_ONLY=1 ./run-tests.sh
#
Browse the WordPress website adminVisit http://wordpress5-6/wp-admin.
#
Run testsSETUP_ONLY=1 ./run-tests.sh
#
Stop the Virtal Machinevagrant stop # vagrant up to start after
#
Clean up environnementTo destroy the vagrant instance:
vagrant destroy