Skip to content

Commit 6eba74f

Browse files
Merge pull request #104 from julienloizelet/feat/tls-auth
Feat/tls auth
2 parents 5abadcb + 176bb79 commit 6eba74f

23 files changed

+583
-178
lines changed

.github/workflows/test-suite.yml

+36-8
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333

3434
- name: Install DDEV
3535
env:
36-
DDEV_VERSION: v1.19.3
36+
DDEV_VERSION: v1.20.0
3737
run: |
3838
# @see https://ddev.readthedocs.io/en/stable/#installationupgrade-script-linux-and-macos-armarm64-and-amd64-architectures
3939
sudo apt-get -qq update
@@ -55,6 +55,9 @@ jobs:
5555
cp .ddev/config_overrides/config.${{ env.PHP_VERSION_CODE }}.yaml .ddev/config.${{ env.PHP_VERSION_CODE }}.yaml
5656
cp .ddev/additional_docker_compose/docker-compose.crowdsec.yaml .ddev/docker-compose.crowdsec.yaml
5757
cp .ddev/additional_docker_compose/docker-compose.playwright.yaml .ddev/docker-compose.playwright.yaml
58+
mkdir ${{ github.workspace }}/cfssl
59+
cp -r .ddev/custom_files/crowdsec/cfssl/* ${{ github.workspace }}/cfssl
60+
ls -l ${{ github.workspace }}/cfssl
5861
ddev start
5962
6063
- name: Set BOUNCER_KEY and PROXY_IP env
@@ -83,7 +86,6 @@ jobs:
8386
8487
- name: Prepare PHP UNIT tests
8588
run: |
86-
ddev create-watcher PhpUnitTestMachine PhpUnitTestMachinePassword
8789
ddev maxmind-download DEFAULT GeoLite2-City /var/www/html/${{env.EXTENSION_PATH}}/tests
8890
ddev maxmind-download DEFAULT GeoLite2-Country /var/www/html/${{env.EXTENSION_PATH}}/tests
8991
cd ${{env.EXTENSION_PATH}}/tests
@@ -95,23 +97,26 @@ jobs:
9597
9698
- name: Run "IP verification with file_get_contents" test
9799
run: |
98-
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} LAPI_URL=http://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/IpVerificationTest.php
100+
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} AGENT_TLS_PATH=/var/www/html/cfssl LAPI_URL=https://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/IpVerificationTest.php
99101
100102
- name: Run "IP verification with cURL" test
101103
run: |
102-
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} USE_CURL=1 LAPI_URL=http://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/IpVerificationTest.php
104+
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} AGENT_TLS_PATH=/var/www/html/cfssl USE_CURL=1 LAPI_URL=https://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/IpVerificationTest.php
105+
106+
- name: Run "IP verification with TLS" test
107+
run: |
108+
ddev exec AGENT_TLS_PATH=/var/www/html/cfssl BOUNCER_TLS_PATH=/var/www/html/cfssl LAPI_URL=https://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/IpVerificationTest.php
103109
104110
- name: Run "Geolocation with file_get_contents" test
105111
run: |
106-
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} LAPI_URL=http://crowdsec:8080 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/GeolocationTest.php
112+
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} AGENT_TLS_PATH=/var/www/html/cfssl LAPI_URL=https://crowdsec:8080 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/GeolocationTest.php
107113
108114
- name: Run "Geolocation with cURL" test
109115
run: |
110-
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} USE_CURL=1 LAPI_URL=http://crowdsec:8080 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/GeolocationTest.php
116+
ddev exec BOUNCER_KEY=${{ env.BOUNCER_KEY }} AGENT_TLS_PATH=/var/www/html/cfssl USE_CURL=1 LAPI_URL=https://crowdsec:8080 /usr/bin/php ./${{env.EXTENSION_PATH}}/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./${{env.EXTENSION_PATH}}/tests/Integration/GeolocationTest.php
111117
112118
- name: Prepare Standalone Bouncer end-to-end tests
113119
run: |
114-
ddev create-watcher
115120
cd ${{ github.workspace }}/.ddev
116121
ddev nginx-config custom_files/crowdsec-prepend-nginx-site.conf
117122
cd ${{ github.workspace }}
@@ -215,4 +220,27 @@ jobs:
215220
sed -i 's/\x27stream_mode\x27 => true/\x27stream_mode\x27 => false/g' scripts/auto-prepend/settings.php
216221
cat scripts/auto-prepend/settings.php
217222
cd ${{ github.workspace }}/${{env.EXTENSION_PATH}}/tests/end-to-end/__scripts__
218-
./run-tests.sh ci "./__tests__/1-live-mode.js"
223+
./run-tests.sh ci "./__tests__/1-live-mode.js"
224+
225+
- name: Run "live mode with TLS auth" test
226+
run: |
227+
cd ${{ github.workspace }}/${{env.EXTENSION_PATH}}
228+
sed -i 's/\x27auth_type\x27 => \x27api_key\x27/\x27auth_type\x27 => \x27tls\x27/g' scripts/auto-prepend/settings.php
229+
sed -i 's/\x27api_key\x27 => \x27${{env.BOUNCER_KEY}}\x27/\x27api_key\x27 => \x27\x27/g' scripts/auto-prepend/settings.php
230+
sed -i 's/\x27tls_cert_path\x27 => \x27\x27/\x27tls_cert_path\x27 => \x27\/var\/www\/html\/cfssl\/bouncer.pem\x27/g' scripts/auto-prepend/settings.php
231+
sed -i 's/\x27tls_key_path\x27 => \x27\x27/\x27tls_key_path\x27 => \x27\/var\/www\/html\/cfssl\/bouncer-key.pem\x27/g' scripts/auto-prepend/settings.php
232+
sed -i 's/\x27tls_ca_cert_path\x27 => \x27\x27/\x27tls_ca_cert_path\x27 => \x27\/var\/www\/html\/cfssl\/ca-chain.pem\x27/g' scripts/auto-prepend/settings.php
233+
cat scripts/auto-prepend/settings.php
234+
cd ${{ github.workspace }}/${{env.EXTENSION_PATH}}/tests/end-to-end/__scripts__
235+
./run-tests.sh ci "./__tests__/1-live-mode.js"
236+
237+
238+
- name: Run "stream mode with TLS auth and cURL" test
239+
run: |
240+
cd ${{ github.workspace }}/${{env.EXTENSION_PATH}}
241+
sed -i 's/\x27stream_mode\x27 => false/\x27stream_mode\x27 => true/g' scripts/auto-prepend/settings.php
242+
sed -i 's/\x27forced_test_forwarded_ip\x27 => \x27${{env.IPV6_TEST_IP}}\x27/\x27forced_test_forwarded_ip\x27 => \x27\x27/g' scripts/auto-prepend/settings.php
243+
sed -i 's/\x27use_curl\x27 => false/\x27use_curl\x27 => true/g' scripts/auto-prepend/settings.php
244+
cat scripts/auto-prepend/settings.php
245+
cd ${{ github.workspace }}/${{env.EXTENSION_PATH}}/tests/end-to-end/__scripts__
246+
./run-tests.sh ci "./__tests__/3-stream-mode.js"

CHANGELOG.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77

8+
## [0.29.0] - 2022-08-11
9+
10+
### Added
11+
- Add TLS connection feature
12+
13+
814
## [0.28.0] - 2022-08-04
915

1016
### Changed
1117
- *Breaking change*: Rename `ClientAbstract` class to `AbstractClient`
12-
- Hide `api_key` in log.
18+
- Hide `api_key` in log
1319

1420
### Added
1521
- Add `disable_prod_log` configuration

docs/DEVELOPER.md

+22-7
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ For a quick start, follow the below steps.
7272

7373
#### DDEV installation
7474

75-
This project is fully compatible with DDEV 1.19.3, and it is recommended to use this specific version.
75+
This project is fully compatible with DDEV 1.20.0, and it is recommended to use this specific version.
7676
For the DDEV installation, please follow the [official instructions](https://ddev.readthedocs.io/en/stable/#installation).
7777
On a Linux distribution, you can run:
7878
```
7979
sudo apt-get -qq update
8080
sudo apt-get -qq -y install libnss3-tools
8181
curl -LO https://raw.githubusercontent.com/drud/ddev/master/scripts/install_ddev.sh
82-
bash install_ddev.sh v1.19.3
82+
bash install_ddev.sh v1.20.0
8383
rm install_ddev.sh
8484
```
8585

@@ -167,6 +167,8 @@ It will return the bouncer key.
167167
ddev create-watcher [name] [password]
168168
```
169169

170+
N.B : Since we are using TLS authentification for agent, you should avoid to create a watcher with this method.
171+
170172

171173
#### Use composer to update or install the lib
172174

@@ -205,17 +207,20 @@ First, create a bouncer and keep the result key.
205207
ddev create-bouncer
206208
```
207209

208-
Then, create a specific watcher for unit test:
209-
210+
Then, as we use a TLS ready CrowdSec container, you have to copy some certificates and key:
211+
210212
```bash
211-
ddev create-watcher PhpUnitTestMachine PhpUnitTestMachinePassword
213+
cd php-project-sources
214+
mkdir cfssl
215+
cp -r ../.ddev/custom_files/crowdsec/cfssl/* cfssl
212216
```
213217

214218
Finally, run
215219

216220

217221
```bash
218-
ddev exec BOUNCER_KEY=your-bouncer-key LAPI_URL=http://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./my-own-modules/crowdsec-php-lib/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./my-own-modules/crowdsec-php-lib/tests/Integration/IpVerificationTest.php
222+
ddev exec BOUNCER_KEY=your-bouncer-key AGENT_TLS_PATH=/var/www/html/cfssl LAPI_URL=http://crowdsec:8080
223+
MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./my-own-modules/crowdsec-php-lib/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./my-own-modules/crowdsec-php-lib/tests/Integration/IpVerificationTest.php
219224
```
220225

221226
For geolocation Unit Test, you should first put 2 free MaxMind databases in the `tests` folder : `GeoLite2-City.mmdb`
@@ -225,8 +230,18 @@ and`GeoLite2-Country.mmdb`. You can download these databases by creating a maxmi
225230
Then, you can run:
226231

227232
```bash
228-
ddev exec BOUNCER_KEY=your-bouncer-key LAPI_URL=http://crowdsec:8080 /usr/bin/php ./my-own-modules/crowdsec-php-lib/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./my-own-modules/crowdsec-php-lib/tests/Integration/GeolocationTest.php
233+
ddev exec BOUNCER_KEY=your-bouncer-key AGENT_TLS_PATH=/var/www/html/cfssl LAPI_URL=http://crowdsec:8080
234+
/usr/bin/php ./my-own-modules/crowdsec-php-lib/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./my-own-modules/crowdsec-php-lib/tests/Integration/GeolocationTest.php
235+
```
229236

237+
**N.B**: If you want to test with `curl` instead of `file_get_contents` calls to LAPI, you have to add `USE_CURL=1` in
238+
the previous commands.
239+
240+
**N.B**: If you want to test with `tls` authentification, you have to add `BOUNCER_TLS_PATH` environment varibale
241+
and specify the path where you store certificates and keys. For example:
242+
243+
```bash
244+
ddev exec USE_CURL=1 AGENT_TLS_PATH=/var/www/html/cfssl BOUNCER_TLS_PATH=/var/www/html/cfssl LAPI_URL=https://crowdsec:8080 MEMCACHED_DSN=memcached://memcached:11211 REDIS_DSN=redis://redis:6379 /usr/bin/php ./my-own-modules/crowdsec-php-lib/vendor/bin/phpunit --testdox --colors --exclude-group ignore ./my-own-modules/crowdsec-php-lib/tests/Integration/IpVerificationTest.php
230245
```
231246

232247

docs/USER_GUIDE.md

+63-9
Original file line numberDiff line numberDiff line change
@@ -119,82 +119,136 @@ Here is the list of available settings:
119119

120120
##### LAPI Connection
121121

122-
- `api_key`: Key generated by the cscli (CrowdSec cli) command like `cscli bouncers add bouncer-php-library`
122+
- `auth_type`: Select from `api_key` and `tls`. Choose if you want to use an API-KEY or a TLS (pki) authentification.
123+
TLS authentication is only available if you use CrowdSec agent with a version superior to 1.4.0.
124+
125+
126+
- `api_key`: Key generated by the cscli (CrowdSec cli) command like `cscli bouncers add bouncer-php-library`.
127+
Only required if you choose `api_key` as `auth_type`.
128+
129+
130+
- `tls_cert_path`: absolute path to the bouncer certificate (e.g. pem file).
131+
Only required if you choose `tls` as `auth_type`.
132+
133+
134+
- `tls_key_path`: Absolute path to the bouncer key (e.g. pem file).
135+
Only required if you choose `tls` as `auth_type`.
136+
137+
138+
- `tls_verify_peer`: This option determines whether request handler verifies the authenticity of the peer's certificate.
139+
Only required if you choose `tls` as `auth_type`.
140+
When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity.
141+
If `tls_verify_peer` is set to true, request handler verifies whether the certificate is authentic.
142+
This trust is based on a chain of digital signatures,
143+
rooted in certification authority (CA) certificates you supply using the `tls_ca_cert_path` setting below.
144+
145+
146+
- `tls_ca_cert_path`: Absolute path to the CA used to process peer verification.
147+
Only required if you choose `tls` as `auth_type` and `tls_verify_peer` is set to true.
148+
123149

124150
- `api_url`: Define the URL to your LAPI server, default to `http://localhost:8080`.
125151

152+
126153
- `api_timeout`: In seconds. The timeout when calling LAPI. Must be greater or equal than 1. Default to 1 sec.
127154

155+
128156
- `use_curl`: By default, this lib call the REST LAPI using `file_get_contents` method (`allow_url_fopen` is required).
129157
You can set `use_curl` to `true` in order to use `cURL` request instead (`curl` is in then required)
130158

159+
131160
##### Debug
132161
- `debug_mode`: `true` to enable verbose debug log. Default to `false`.
133162

163+
134164
- `disable_prod_log`: `true` to disable prod log. Default to `false`.
135165

136-
- `log_directory_path`: Absolute path to store log files. Important note: be sur this path won't be publicly accessible
166+
167+
- `log_directory_path`: Absolute path to store log files. Important note: be sur this path won't be publicly
168+
accessible.
169+
137170

138171
- `display_errors`: true to stop the process and display errors on browser if any.
139172

173+
140174
- `forced_test_ip`: Only for test or debug purpose. Default to empty. If not empty, it will be used instead of the
141175
real remote ip.
142176

177+
143178
- `forced_test_forwarded_ip`: Only for test or debug purpose. Default to empty. If not empty, it will be used
144179
instead of the real forwarded ip. If set to `no_forward`, the x-forwarded-for mechanism will not be used at all.
145180

146181
##### Bouncer behavior
147182

148183
- `bouncing_level`: Select from `bouncing_disabled`, `normal_bouncing` or `flex_bouncing`. Choose if you want to apply CrowdSec directives (Normal bouncing) or be more permissive (Flex bouncing). With the `Flex 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.
149184

185+
150186
- `fallback_remediation`: Select from `bypass` (minimum remediation), `captcha` or `ban` (maximum remediation). Default to 'captcha'. Handle unknown remediations as.
151187

188+
152189
- `max_remediation_level`: Select from `bypass`,`captcha` or `ban`. Default to 'ban'. Cap the
153190
remediation to the selected one.
154191

192+
155193
- `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 bouncer will not trust the X-Forwarded-For header.
156194

157-
- `excluded_uris`: array of URIs that will not be bounced
195+
196+
- `excluded_uris`: array of URIs that will not be bounced.
158197

159198
##### Cache
160199

161200
- `cache_system`: Select from `phpfs` (File system cache), `redis` or `memcached`.
162201

202+
163203
- `fs_cache_path`: Will be used only if you choose File system as cache_system. Important note: be sur this path
164204
won't be publicly accessible.
165205

166-
- `redis_dsn`: Will be used only if you choose Redis cache as cache_system
167206

168-
- `memcached_dsn`: Will be used only if you choose Memcached as cache_system
207+
- `redis_dsn`: Will be used only if you choose Redis cache as cache_system.
208+
209+
210+
- `memcached_dsn`: Will be used only if you choose Memcached as cache_system.
211+
169212

170213
- `clean_ip_cache_duration`: Set the duration we keep in cache the fact that an IP is clean. In seconds. Defaults to 5.
171214

215+
172216
- `bad_ip_cache_duration`: Set the duration we keep in cache the fact that an IP is bad. In seconds. Defaults to 20.
173217

218+
174219
- `captcha_cache_duration`: Set the duration we keep in cache the captcha flow variables for an IP. In seconds.
175220
Defaults to 86400.. In seconds. Defaults to 20.
176221

222+
177223
- `geolocation_cache_duration`: Set the duration we keep in cache a geolocation result for an IP . In seconds.
178224
Defaults to 86400. Depends on the below `geolocation[save_result]` configuration.
179225

226+
180227
- `stream_mode`: true to enable stream mode, false to enable the live mode. Default to false. By default, the `live mode` is enabled. The first time a stranger 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 the `stream 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.
181228

182229
##### Geolocation
183230

184231
- `geolocation`: Settings for geolocation remediation (i.e. country based remediation).
232+
185233
- `geolocation[enabled]`: true to enable remediation based on country. Default to false.
186-
- `geolocation[type]`: Geolocation system. Only 'maxmind' is available for the moment. Default to `maxmind`
234+
235+
- `geolocation[type]`: Geolocation system. Only 'maxmind' is available for the moment. Default to `maxmind`.
236+
187237

188238
- `geolocation[save_result]`: true to store the geolocalized country in cache. Default to true. Setting true
189-
will avoid multiple call to the geolocalized system (e.g. maxmind database)
190-
- `geolocation[maxmind]`: MaxMind settings
239+
will avoid multiple call to the geolocalized system (e.g. maxmind database).
240+
241+
- `geolocation[maxmind]`: MaxMind settings.
242+
191243
- `geolocation[maxmind][database_type]`: Select from `country` or `city`. Default to `country`. These are the two available MaxMind database types.
192-
- `geolocation[maxmind][database_path]`: Absolute path to the MaxMind database (mmdb
244+
245+
- `geolocation[maxmind][database_path]`: Absolute path to the MaxMind database (e.g. mmdb file)
193246

194247

195248
##### Captcha and ban wall settings
196249

197250
- `hide_mentions`: true to hide CrowdSec mentions on ban and captcha walls.
251+
198252
- Wording and css settings:
199253

200254
`theme_color_text_primary`

scripts/auto-prepend/bounce.php

-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,4 @@
1616
}elseif($crowdSecStandaloneBouncerConfig['bouncing_level'] === 'flex_boucing'){
1717
$crowdSecStandaloneBouncerConfig['bouncing_level'] = 'flex_bouncing';
1818
}
19-
2019
$bounce->safelyBounce($crowdSecStandaloneBouncerConfig);

0 commit comments

Comments
 (0)