Skip to content

Commit faa0cee

Browse files
committed
add ipv6 support
1 parent f2dcdd8 commit faa0cee

17 files changed

+229
-95
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ WORDPRESS_VERSION=5.6
33
WATCHER_LOGIN=watcherLogin
44
WATCHER_PASSWORD=watcherPassword
55
NETWORK_SUBNET=172.16.238.0/24
6-
DOCKER_HOST_IP=172.16.238.1
6+
DOCKER_HOST_IP=172.16.238.1 # OR IPV6 2001:3200:3200::1
77
BOUNCER_KEY=
88
WORDPRESS_URL=
99
DEBUG=1

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
}
1010
],
1111
"require": {
12-
"crowdsec/bouncer": "^0.9.0"
12+
"crowdsec/bouncer": "^0.10.0"
1313
},
1414
"require-dev": {
1515
"bramus/monolog-colored-line-formatter": "^3.0",

composer.lock

Lines changed: 80 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/macos-host.md

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Contribute to this plugin from a MacOS host
22

3-
You can test the Linux behavior of this project using **Vagrant** (you have to install this on your host to continue).
3+
You can test the Linux behavior of this project using **Vagrant**.
4+
5+
## One time setup
6+
7+
### Run the VM and initialize it
48

59
```bash
610
vagrant up
@@ -10,18 +14,26 @@ sudo systemctl restart docker
1014
```
1115

1216
You have to log out and log back for permission to be updated:
17+
1318
```bash
1419
exit
15-
vagrant shh
20+
vagrant ssh
1621
```
22+
### Enabled Docker IPV6 support inside the Linux VM
23+
24+
follow [this guide](https://docs.docker.com/config/daemon/ipv6/). (Note that you'll have to create the file `/etc/docker/daemon.json`).
25+
26+
27+
### Install NodeJS
1728

18-
Enabled IPV6 support following [this guide](https://docs.docker.com/config/daemon/ipv6/). (Note that you'll have to create the file `/etc/docker/daemon.json`).
29+
Follow [this guide](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions)
30+
### Install Yarn
1931

20-
Add yarn: https://linuxize.com/post/how-to-install-yarn-on-ubuntu-18-04/
32+
Follow [this guide](https://linuxize.com/post/how-to-install-yarn-on-ubuntu-18-04/).
2133

22-
https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions
34+
### Add deps to run playwright
2335

24-
Add deps to run playwright:
36+
```bash
2537
sudo apt-get install libnss3\
2638
libnspr4\
2739
libatk1.0-0\
@@ -41,24 +53,52 @@ sudo apt-get install libnss3\
4153
libgdk-pixbuf2.0-0\
4254
libasound2\
4355
libatspi2.0-0
56+
```
57+
58+
### Edit you local host file:
59+
60+
Type `sudo vim /etc/hosts` and add:
61+
62+
```bash
63+
# select the one you want to try by uncommenting only ont of the two
64+
# 172.16.0.50 wordpress5-6 # Uncomment to use IPV4
65+
fde4:8dba:82e1::c4 wordpress5-6 # Uncomment to use IPV6
66+
```
4467

68+
### Configure your `.env` file
4569

4670
```bash
4771
cd /vagrant
4872
cp .env.example .env
73+
```
74+
75+
Update the created `.env` file with:
4976

50-
# set DEBUG=0 in .env
77+
```bash
78+
DEBUG=0
79+
DOCKER_HOST_IP=172.16.238.1 # OR IF YOU WANT TO TEST WITH IPV6 USE: 2001:3200:3200::1
80+
```
5181

82+
### Run "plugin auto setup" via e2e tests (limited to setup steps)
83+
84+
```bash
5285
SETUP_ONLY=1 ./run-tests.sh
5386
```
5487

55-
sudo vim /etc/hosts
88+
### Browse the WordPress website admin
89+
90+
Visit [http://wordpress5-6/wp-admin](http://wordpress5-6/wp-admin).
5691

57-
#172.16.0.50 wordpress5-6
58-
fde4:8dba:82e1::c4 wordpress5-6
59-
# select the one you want to try
92+
### Run tests
6093

61-
Access with ipv4 : http://wordpress5-6/wp-admin
94+
```bash
95+
SETUP_ONLY=1 ./run-tests.sh
96+
```
97+
98+
### Stop the Virtal Machine
99+
```bash
100+
vagrant stop # vagrant up to start after
101+
```
62102

63103
### Clean up environnement
64104

inc/admin/advanced-settings.php

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use CrowdSecBouncer\BouncerException;
44
use CrowdSecBouncer\Constants;
5+
use IPLib\Factory;
56

67
function adminAdvancedSettings()
78
{
@@ -16,7 +17,7 @@ function adminAdvancedSettings()
1617
addFieldCheckbox('crowdsec_stream_mode', 'Enable the "Stream" mode', 'crowdsec_plugin_advanced_settings', 'crowdsec_advanced_settings', 'crowdsec_admin_advanced_stream_mode', function () {
1718
// Stream mode just activated.
1819
$bouncer = getBouncerInstance();
19-
$result = $bouncer->warmBlocklistCacheUp();
20+
$result = $bouncer->warmBlocklistCacheUp()['count'];
2021
$message = __('As the stream mode is enabled, the cache has just been warmed up, '.($result > 0 ? 'there are now '.$result.' decisions' : 'there is now '.$result.' decision').' in cache.');
2122
AdminNotice::displaySuccess($message);
2223
scheduleBlocklistRefresh();
@@ -43,7 +44,7 @@ function adminAdvancedSettings()
4344
// Update wp-cron schedule.
4445
if ((bool) get_option('crowdsec_stream_mode')) {
4546
$bouncer = getBouncerInstance();
46-
$result = $bouncer->warmBlocklistCacheUp();
47+
$result = $bouncer->warmBlocklistCacheUp()['count'];
4748
$message = __('As the stream mode refresh duration changed, the cache has just been warmed up, '.($result > 0 ? 'there are now '.$result.' decisions' : 'there is now '.$result.' decision').' in cache.');
4849
AdminNotice::displaySuccess($message);
4950
scheduleBlocklistRefresh();
@@ -128,7 +129,8 @@ function adminAdvancedSettings()
128129
if ((bool) get_option('crowdsec_stream_mode')) {
129130
$bouncer = getBouncerInstance($input); // Reload bouncer instance with the new cache system
130131
$result = $bouncer->warmBlocklistCacheUp();
131-
$message = __('As the stream mode is enabled, the cache has just been warmed up, '.($result > 0 ? 'there are now '.$result.' decisions' : 'there is now '.$result.' decision').' in cache.');
132+
$count = $result['count'];
133+
$message = __('As the stream mode is enabled, the cache has just been warmed up, '.($count > 0 ? 'there are now '.$count.' decisions' : 'there is now '.$count.' decision').' in cache.');
132134
AdminNotice::displaySuccess($message);
133135
scheduleBlocklistRefresh();
134136
}
@@ -193,43 +195,30 @@ function adminAdvancedSettings()
193195
return $input;
194196
}, '<p>Which remediation to apply when CrowdSec advises unhandled remediation.</p>', $choice);
195197

196-
function cidrToLongBounds(int $longIp, int $factor): array
198+
function convertInlineIpRangesToComparableIpBounds(string $inlineIpRanges): array
197199
{
198-
$range = [];
199-
$range[0] = (($longIp) & ((-1 << (32 - $factor))));
200-
$range[1] = ((($range[0])) + pow(2, (32 - $factor)) - 1);
201-
202-
return $range;
203-
}
204-
205-
function convertInlineIpRangesToLongArray(string $inlineIpRanges): array
206-
{
207-
$longIpBoundsList = [];
200+
$comparableIpBoundsList = [];
208201
$stringRangeArray = explode(',', $inlineIpRanges);
209202
foreach ($stringRangeArray as $stringRange) {
210203
$stringRange = trim($stringRange);
211204
if (false !== strpos($stringRange, '/')) {
212-
$stringRange = explode('/', $stringRange);
213-
$longIp = ip2long($stringRange[0]);
214-
$factor = (int) $stringRange[1];
215-
if (false === $longIp) {
216-
throw new WordpressCrowdSecBouncerException('Invalid IP List format.');
217-
}
218-
if (0 === (int) $factor) {
205+
$range = Factory::rangeFromString($stringRange);
206+
if (null === $range) {
219207
throw new WordpressCrowdSecBouncerException('Invalid IP List format.');
220208
}
221-
$longBounds = cidrToLongBounds($longIp, $factor);
222-
$longIpBoundsList = array_merge($longIpBoundsList, [$longBounds]);
209+
$bounds = [$range->getComparableStartString(), $range->getComparableEndString()];
210+
$comparableIpBoundsList = array_merge($comparableIpBoundsList, [$bounds]);
223211
} else {
224-
$long = ip2long($stringRange);
225-
if (false === $long) {
212+
$address = Factory::addressFromString($stringRange);
213+
if (null === $address) {
226214
throw new WordpressCrowdSecBouncerException('Invalid IP List format.');
227215
}
228-
$longIpBoundsList = array_merge($longIpBoundsList, [[$long, $long]]);
216+
$comparableString = $address->getComparableString();
217+
$comparableIpBoundsList = array_merge($comparableIpBoundsList, [[$comparableString, $comparableString]]);
229218
}
230219
}
231220

232-
return $longIpBoundsList;
221+
return $comparableIpBoundsList;
233222
}
234223

235224
// Field "crowdsec_trust_ip_forward"
@@ -241,8 +230,8 @@ function convertInlineIpRangesToLongArray(string $inlineIpRanges): array
241230

242231
return $input;
243232
}
244-
$longList = convertInlineIpRangesToLongArray($input);
245-
update_option('crowdsec_trust_ip_forward_array', $longList);
233+
$comparableIpBoundsList = convertInlineIpRangesToComparableIpBounds($input);
234+
update_option('crowdsec_trust_ip_forward_array', $comparableIpBoundsList);
246235
AdminNotice::displaySuccess('Ips with XFF to trust successfully saved.');
247236
} catch (WordpressCrowdSecBouncerException $e) {
248237
update_option('crowdsec_trust_ip_forward_array', []);

inc/admin/init.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function clearBouncerCacheInAdminPage()
2929

3030
// In stream mode, immediatelly warm the cache up.
3131
if (get_option('crowdsec_stream_mode')) {
32-
$result = $bouncer->warmBlocklistCacheUp();
32+
$result = $bouncer->warmBlocklistCacheUp()['count'];
3333
$message .= __(' As the stream mode is enabled, the cache has just been warmed up, '.($result > 0 ? 'there are now '.$result.' decisions' : 'there is now '.$result.' decision').' in cache.');
3434
}
3535

inc/bounce-current-ip.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
use CrowdSecBouncer\Bouncer;
44
use CrowdSecBouncer\Constants;
5+
use IPLib\Factory;
56

67
function bounceCurrentIp()
78
{
89
function shouldTrustXforwardedFor(string $ip): bool
910
{
10-
$longIp = ip2long($ip);
11-
foreach (get_option('crowdsec_trust_ip_forward_array') as $longBounds) {
12-
if ($longIp >= $longBounds[0] && $longIp <= $longBounds[1]) {
11+
$comparableAddress = Factory::addressFromString($ip)->getComparableString();
12+
foreach (get_option('crowdsec_trust_ip_forward_array') as $comparableIpBounds) {
13+
if ($comparableAddress >= $comparableIpBounds[0] && $comparableAddress <= $comparableIpBounds[1]) {
1314
return true;
1415
}
1516
}

inc/templates/advanced-settings.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function updateDsnDisplay () {
4040
submit_button();
4141
?>
4242
</form>
43-
43+
<p style="font-style:italic">For information, the current browser IP detected by PHP is: <span id="detected_ip_address" style="user-select: all;"><?php echo $_SERVER['REMOTE_ADDR']; ?></span></p>
4444
<br/>
4545
<form action="<?php echo admin_url('admin-post.php'); ?>" method="post" id="crowdsec_action_clear_cache">
4646
<input type="hidden" name="action" value="crowdsec_clear_cache">
@@ -55,7 +55,7 @@ function updateDsnDisplay () {
5555
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('crowdsec_prune_cache'); ?>">
5656
</form>
5757
</div>
58-
<p>
58+
<p style="padding-top:15px">
5959
Feel free to ask any questions about this plugin, make your suggestions or raise issues on the <a href="https://wordpress.org/support/plugin/crowdsec/">plugin support page</a> or directly on <a href="https://github.com/crowdsecurity/cs-wordpress-bouncer/issues/new">Github</a>.
6060
</p>
6161
</div>

0 commit comments

Comments
 (0)