PHP Standalone
π Documentation π Hub π¬ Discourse
Overviewβ
This Remediation Component allows you to protect your PHP application from IPs that have been detected by CrowdSec. Depending on the decision taken by CrowdSec, user will either get denied (403) or have to fill a captcha (401).
It uses the PHP auto_prepend_file
mechanism and
the Crowdsec php remediation library to offer remediation/IPS capability directly in your PHP application.
It supports "ban" and "captcha" remediations, and all decisions of type Ip, Range or Country (geolocation).
Prerequisitesβ
- This is a PHP library, so you must have a working PHP (>= 7.2.5) installation.
- Requires PHP extensions :
ext-curl
,ext-gd
,ext-json
,ext-mbstring
. - Code sources are dealt with via
composer
andgit
. - Have CrowdSec on the same machine, or at least be able to reach LAPI.
Installationβ
Preparationβ
Install composerβ
Please follow this documentation to install composer.
Install GITβ
Please follow this documentation to install GIT.
Install CrowdSecβ
To be able to use this component, the first step is to install CrowdSec v1. CrowdSec is only in charge of the "detection", and won't block anything on its own. You need to deploy a bouncer to "apply" decisions.
Please note that first and foremost a CrowdSec agent must be installed on a server that is accessible by this component.
Server and component setupβ
Once you set up your server as below, every browser access to a PHP script will be remediated by the standalone component.
You will have to :
- retrieve sources of the remediation in some
/path/to/the/crowdsec-standalone-bouncer
folder - give the correct permission for the folder that contains the remediation
- copy the
scripts/settings.php.dist
file to ascripts/settings.php
file and edit it. - set an
auto_prepend_file
directive in your PHP setup. - Optionally, if you want to use the standalone component in stream mode, you will have to set a cron task to refresh cache periodically.
Component sources copyβ
- Create a folder that will contain the project sources:
sudo mkdir -p /var/www/crowdsec-standalone-bouncer
We use here /var/www/crowdsec-standalone-bouncer
but you can choose the path that suits your needs.
- Change permission to allow composer to be run in this folder. As you should run composer with your user, this can be done with:
sudo chown -R $(whoami):$(whoami) /var/www/crowdsec-standalone-bouncer
- Retrieve the last version of the component:
composer create-project crowdsec/standalone-bouncer /var/www/crowdsec-standalone-bouncer --keep-vcs
Note that we have to keep the vcs data as we will use it to update the component when a new version is available.
Files permissionβ
The owner of the /var/www/crowdsec-standalone-bouncer
folder should be your web-server owner (e.g. www-data
) and the group should have the write permission on this folder.
You can achieve it by running commands like:
sudo chown -R www-data /var/www/crowdsec-standalone-bouncer
sudo chmod g+w /var/www/crowdsec-standalone-bouncer
Settings fileβ
Please copy the scripts/settings.php.dist
file to a scripts/settings.php
file and fill the necessary settings in it
(see Configurations settings for more details).
For a quick start, simply search for YOUR_BOUNCER_API_KEY
in the settings.php
file and set the API key.
To obtain a API key, you can run the cscli bouncers add
command:
sudo cscli bouncers add standalone-bouncer
auto_prepend_file
directiveβ
We will now describe how to set an auto_prepend_file
directive in order to call the scripts/bounce.php
for each php access.
Adding an auto_prepend_file
directive can be done in different ways:
.ini
fileβ
You should add this line to a .ini
file :
auto_prepend_file = /var/www/crowdsec-standalone-bouncer/scripts/bounce.php
Nginxβ
If you are using Nginx, you should modify your Nginx configuration file by adding a fastcgi_param
directive. The php block should look like below:
location ~ \.php$ {
...
...
...
fastcgi_param PHP_VALUE "auto_prepend_file=/var/www/crowdsec-standalone-bouncer/scripts/bounce.php";
}
Apacheβ
If you are using Apache, you should add this line to your .htaccess
file:
php_value auto_prepend_file "/var/www/crowdsec-standalone-bouncer/scripts/bounce.php"
or modify your Virtual Host
accordingly:
<VirtualHost ...>
...
...
php_value auto_prepend_file "/var/www/crowdsec-standalone-bouncer/scripts/bounce.php"
</VirtualHost>
Stream mode cron taskβ
To use the stream mode, you first have to set the stream_mode
setting value to true
in your script/settings.php
file.
Then, you could edit the web server user (e.g. www-data
) crontab:
sudo -u www-data crontab -e
and add the following line
*/15 * * * * /usr/bin/php /var/www/crowdsec-standalone-bouncer/scripts/refresh-cache.php
In this example, cache is refreshed every 15 minutes, but you can modify the cron expression depending on your needs.
Cache pruning cron taskβ
If you use the PHP file system as cache, you should prune the cache with a cron job:
sudo -u www-data crontab -e
and add the following line
0 0 * * * /usr/bin/php /var/www/crowdsec-standalone-bouncer/scripts/prune-cache.php
In this example, cache is pruned at midnight every day, but you can modify the cron expression depending on your needs.
Upgradeβ
When a new release of the component is available, you may want to update sources to the last version.
Before upgradingβ
Please look at the CHANGELOG before upgrading in order to see the list of changes that could break your application.
To limit the risk of breaking your web application during upgrade, you can perform the following actions to disable bouncing:
- Remove the
auto_prepend_file
directive that point to thebounce.php
file and restart your web server - Disable any scheduled cron task linked to remediation feature
Alternatively, but a little more risky, you could disable bouncing by editing the scripts/settings.php
file and set the value 'bouncing_disabled'
for the 'bouncing_level'
parameter.
Once the update is done, you can reactivate the bounce. You could look at the /var/www/crowdsec-standalone-bouncer/scripts/.logs
to see if all is working as expected.
Below are the steps to take to upgrade your current component:
Retrieve the last tagβ
As we kept the vcs data during installation (with the --keep-vcs
flag), we can use git to get the last tagged sources:
cd /var/www/crowdsec-standalone-bouncer
git fetch
If you get an error message about "detected dubious ownership", you can run
git config --global --add safe.directory /var/www/crowdsec-standalone-bouncer
You should see a list of tags (vX.Y.Z
format )that have been published after your initial installation.
Checkout to last tag and update sourcesβ
Once you have picked up the vX.Y.Z
tag you want to try, you could switch to it and update composer dependencies:
git checkout vX.Y.Z && composer update
Usageβ
Featuresβ
- CrowdSec Local API Support
- Handle
ip
,range
andcountry
scoped decisions Live mode
orStream mode
- Handle
- Support IpV4 and Ipv6 (Ipv6 range decisions are yet only supported in
Live mode
) - Large PHP matrix compatibility: 7.2, 7.3, 7.4, 8.0, 8.1 and 8.2
- Built-in support for the most known cache systems Redis, Memcached and PhpFiles
- Clear, prune and refresh the cache
- Cap remediation level (ex: for sensitives websites: ban will be capped to captcha)
Ban and captcha wallsβ
When a user is suspected by CrowdSec to be malevolent, the component would either display a captcha to resolve or simply a page notifying that access is denied. If the user is considered as a clean user, he/she will access the page as normal.
By default, the ban wall is displayed as below:
By default, the captcha wall is displayed as below:
Please note that it is possible to customize all the colors of these pages so that they integrate best with your design.
On the other hand, all texts are also fully customizable. This will allow you, for example, to present translated pages in your users' language.
Configurationsβ
Here is the list of available settings that you could define in the scripts/settings.php
file:
Component behaviorβ
-
bouncing_level
: Select frombouncing_disabled
,normal_bouncing
orflex_bouncing
. Choose if you want to apply CrowdSec directives (Normal bouncing) or be more permissive (Flex bouncing). With theFlex mode
, it is impossible to accidentally block access to your site to people who donβt deserve it. This mode makes it possible to never ban an IP but only to offer a captcha, in the worst-case scenario. -
fallback_remediation
: Select frombypass
(minimum remediation),captcha
orban
(maximum remediation). Default to 'captcha'. Handle unknown remediations as. -
trust_ip_forward_array
: If you use a CDN, a reverse proxy or a load balancer, set an array of IPs. For other IPs, the remediation will not trust the X-Forwarded-For header. -
excluded_uris
: array of URIs that will not be bounced. -
stream_mode
: true to enable stream mode, false to enable the live mode. Default to false. By default, thelive mode
is enabled. The first time a user connects to your website, this mode means that the IP will be checked directly by the CrowdSec API. The rest of your userβs browsing will be even more transparent thanks to the fully customizable cache system. But you can also activate thestream mode
. This mode allows you to constantly feed the bouncer with the malicious IP list via a background task (CRON), making it to be even faster when checking the IP of your visitors. Besides, if your site has a lot of unique visitors at the same time, this will not influence the traffic to the API of your CrowdSec instance.
Local API Connectionβ
-
auth_type
: Select fromapi_key
andtls
. Choose if you want to use an API-KEY or a TLS (pki) authentification. TLS authentication is only available if you use CrowdSec agent with a version superior to 1.4.0. -
api_key
: Key generated by the cscli (CrowdSec cli) command likecscli bouncers add standlone-php-bouncer
. Only required if you chooseapi_key
asauth_type
. -
tls_cert_path
: absolute path to the component certificate (e.g. pem file). Only required if you choosetls
asauth_type
. Make sure this path is not publicly accessible. See security note below. -
tls_key_path
: Absolute path to the component key (e.g. pem file). Only required if you choosetls
asauth_type
. Make sure this path is not publicly accessible. See security note below. -
tls_verify_peer
: This option determines whether request handler verifies the authenticity of the peer's certificate. Only required if you choosetls
asauth_type
. When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. Iftls_verify_peer
is set to true, request handler verifies whether the certificate is authentic. This trust is based on a chain of digital signatures, rooted in certification authority (CA) certificates you supply using thetls_ca_cert_path
setting below. -
tls_ca_cert_path
: Absolute path to the CA used to process peer verification. Only required if you choosetls
asauth_type
andtls_verify_peer
is set to true. Make sure this path is not publicly accessible. See security note below. -
api_url
: Define the URL to your Local API server, default tohttp://localhost:8080
. -
api_timeout
: In seconds. The timeout when calling Local API. Default to 120 sec. If set to a negative value, timeout will be unlimited. -
use_curl
: By default, this lib call the REST Local API usingfile_get_contents
method (allow_url_fopen
is required). You can setuse_curl
totrue
in order to usecURL
request instead (ext-curl
is in then required)
Cacheβ
-
cache_system
: Select fromphpfs
(PHP file cache),redis
ormemcached
. -
fs_cache_path
: Will be used only if you choose PHP file cache ascache_system
. Make sure this path is not publicly accessible. See security note below. -
redis_dsn
: Will be used only if you choose Redis cache ascache_system
. -
memcached_dsn
: Will be used only if you choose Memcached ascache_system
. -
clean_ip_cache_duration
: Set the duration we keep in cache the fact that an IP is clean. In seconds. Defaults to 5. -
bad_ip_cache_duration
: Set the duration we keep in cache the fact that an IP is bad. In seconds. Defaults to 20. -
captcha_cache_duration
: Set the duration we keep in cache the captcha flow variables for an IP. In seconds. Defaults to 86400.. In seconds. Defaults to 20.
Geolocationβ
-
geolocation
: Settings for geolocation remediation (i.e. country based remediation).-
geolocation[enabled]
: true to enable remediation based on country. Default to false. -
geolocation[type]
: Geolocation system. Only 'maxmind' is available for the moment. Default tomaxmind
. -
geolocation[cache_duration]
: This setting will be used to set the lifetime (in seconds) of a cached country associated to an IP. The purpose is to avoid multiple call to the geolocation system (e.g. maxmind database). Default to 86400. Set 0 to disable caching. -
geolocation[maxmind]
: MaxMind settings. -
geolocation[maxmind][database_type]
: Select fromcountry
orcity
. Default tocountry
. These are the two available MaxMind database types. -
geolocation[maxmind][database_path]
: Absolute path to the MaxMind database (e.g. mmdb file) Make sure this path is not publicly accessible. See security note below.
-
Captcha and ban wall settingsβ
-
hide_mentions
: true to hide CrowdSec mentions on ban and captcha walls. -
custom_css
: Custom css directives for ban and captcha walls -
color
: Array of settings for ban and captcha walls colors.-
color[text][primary]
-
color[text][secondary]
-
color[text][button]
-
color[text][error_message]
-
color[background][page]
-
color[background][container]
-
color[background][button]
-
color[background][button_hover]
-
-
text
: Array of settings for ban and captcha walls texts.-
text[captcha_wall][tab_title]
-
text[captcha_wall][title]
-
text[captcha_wall][subtitle]
-
text[captcha_wall][refresh_image_link]
-
text[captcha_wall][captcha_placeholder]
-
text[captcha_wall][send_button]
-
text[captcha_wall][error_message]
-
text[captcha_wall][footer]
-
text[ban_wall][tab_title]
-
text[ban_wall][title]
-
text[ban_wall][subtitle]
-
text[ban_wall][footer]
-
Debugβ
-
debug_mode
:true
to enable verbose debug log. Default tofalse
. -
disable_prod_log
:true
to disable prod log. Default tofalse
. -
log_directory_path
: Absolute path to store log files. Make sure this path is not publicly accessible. See security note below. -
display_errors
: true to stop the process and display errors on browser if any. -
forced_test_ip
: Only for test or debug purpose. Default to empty. If not empty, it will be used instead of the real remote ip. -
forced_test_forwarded_ip
: Only for test or debug purpose. Default to empty. If not empty, it will be used instead of the real forwarded ip. If set tono_forward
, the x-forwarded-for mechanism will not be used at all.
Security noteβ
Some files should not be publicly accessible because they may contain sensitive data:
- Log files
- Cache files of the File system cache
- TLS authentication files
- Geolocation database files
If you define publicly accessible folders in the settings, be sure to add rules to deny access to these files.
In the following example, we will suppose that you use a folder crowdsec
with sub-folders logs
, cache
, tls
and geolocation
.
If you are using Nginx, you could use the following snippet to modify your website configuration file:
server {
...
...
...
# Deny all attempts to access some folders of the crowdsec standalone bouncer
location ~ /crowdsec/(logs|cache|tls|geolocation) {
deny all;
}
...
...
}
If you are using Apache, you could add this kind of directive in a .htaccess
file:
Redirectmatch 403 crowdsec/logs/
Redirectmatch 403 crowdsec/cache/
Redirectmatch 403 crowdsec/tls/
Redirectmatch 403 crowdsec/geolocation/
N.B.:
- There is no need to protect the
cache
folder if you are using Redis or Memcached cache systems. - There is no need to protect the
logs
folder if you disable debug and prod logging. - There is no need to protect the
tls
folder if you use API key authentication type. - There is no need to protect the
geolocation
folder if you don't use the geolocation feature.
Testing & Troubleshootingβ
Logsβ
Enable debug_mode
in the (scripts/settings.php
) file to enable debug logging. By default, logs will be
located in the scripts path, i.e. /var/www/crowdsec-standalone-bouncer/scripts/.logs
.
Testing ban remediationβ
To test the ban remediation :
- identify or create simple php file (even a
<?php print("hello") ?>
would do) - add a decision on your crowdsec agent (
sudo cscli decisions add -i <your ip>
) - try to access the php file, and you should see the HTML forbidden ban page
Testing the captcha featureβ
To test the captcha remediation :
- identify or create simple php file (even a
<?php print("hello") ?>
would do) - add a decision on your crowdsec agent (
cscli decisions add -i <your ip> -t captcha
) - try to access the php file, and you should see the captcha page
Testing geolocation remediationβ
The remediation is expecting decisions with a scope of Country
, and 2-letters code value.
To test the geolocation remediation :
- identify or create simple php file (even a
<?php print("hello") ?>
would do) - add a decision on your crowdsec agent (
cscli decisions add --scope Country --value FR -t captcha
) - try to access the php file, and you should see the captcha page
Developer guideβ
See Developer guide