cirrusidentity / simplesamlphp-module-ratelimit
限制某些操作,如用户名+密码登录
Requires
- php: ^8.1
- ext-openssl: *
- simplesamlphp/assert: ~1.1.3
- simplesamlphp/composer-module-installer: ~1.3.4
- simplesamlphp/simplesamlphp: ^2.2.0
- symfony/http-foundation: ^6.4
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-17 01:03:17 UTC
README
目录 由DocToc生成
概述
此模块提供了对SSP功能进行速率限制的功能
安装
-
SSP 2.2:使用v3(当前为v3.0.0)
-
SSP 2.0或2.1:使用v2(当前为v2.0.0-alpha.1)
-
SSP 1:使用v1(当前为1.10)
composer require cirrusidentity/simplesamlphp-module-ratelimit
速率限制认证源
任何使用用户名和密码(并扩展UserPassBase
)的认证源都可以用RateLimitUserPass
包装来限制攻击者可以进行的认证尝试次数。
限制器
- DeviceCookieLimiter:在成功的认证后设置设备cookie。对于同一设备上同一用户的后续认证尝试将允许继续进行。这可以防止攻击者拒绝服务其他用户。
- IpLimiter:允许通过IP地址限制尝试次数。允许将IP和子网列入白名单以排除。
- PasswordStuffLimiter:限制错误密码使用的次数。用于防止攻击者使用相同的密码但更改用户名的密码填充攻击。
- UsernameLimiter:限制通过用户名进行的尝试次数。
配置
所有包含的限制器都支持这两个设置
- limit:(int)在限制器生效之前失败尝试的数量
- window:(string)用于跟踪限制的时间窗口的ISO8601持续时间字符串。例如:PT5M表示5分钟,P14D表示14天。
应在authsources.php
中完成配置。RateLimitUserPass
认证源包装其他认证源以强制执行速率限制。每个现有的authsource
定义都应该移动到'delegate'
键内部。
limiters
按定义的顺序运行,而不是按键的数字顺序。
示例配置
独立代理/SSP 2风格配置
在SSP v2中,攻击者无法在IdP侧直接调用认证源。这允许您定义速率限制认证源并在配置文件中引用另一个认证源。
$config = [ // Sample authsource prior to using rate limiting 'sample' => [ 'ldap:Ldap', //Other ldap:LDAP options ], // Sample authsource after moving to rate limiting 'sample-ratelimit' => [ // Authsource name stays the same 'ratelimit:RateLimitUserPass', 'delegate' => 'sample', 'ratelimit' => [ 0 => [ 'device', 'window' => 'P28D', 'limit' => 10, ], 1 => [ 'user', 'window' => 'PT5M', 'limit' => 20 ], 2 => [ 'password', 'window' => 'PT5M', 'limit' => 20 ], 3 => [ 'ip', 'window' => 'PT5M', 'limit' => 100, 'whitelist' => [ '1.2.3.4', '5.6.7.0/24', ], ], ], ] ];
嵌入式代理/SSP 1.x风格配置
在SSP 1.x中,没有方法可以隐藏认证源以防止某人直接通过测试认证源功能调用它。这意味着要真正限制认证源,必须将其配置隐藏在速率限制认证源中。
$config = [ // Sample authsource prior to using rate limiting // 'sample' => [ // 'ldap:Ldap', // //Other ldap:LDAP options // ], // Sample authsource after moving to rate limiting 'sample' => [ // Authsource name stays the same 'ratelimit:RateLimitUserPass', 'delegate' => [ // Previous authsource configuration for 'sample' moves here 'ldap:Ldap', //Other ldap:LDAP options ], 'ratelimit' => [ 0 => [ 'device', 'window' => 'P28D', 'limit' => 10, ], 1 => [ 'user', 'window' => 'PT5M', 'limit' => 20 ], 2 => [ 'password', 'window' => 'PT5M', 'limit' => 20 ], 3 => [ 'ip', 'window' => 'PT5M', 'limit' => 100, 'whitelist' => [ '1.2.3.4', '5.6.7.0/24', ], ], ], ] ];
如果没有定义ratelimit
块,则自动启用UsernameLimiter
和DeviceCookieLimiter
。
阻塞行为
当登录尝试被阻止时,认证源抛出WRONGUSERPASS
错误。
登录循环检测
当配置后,将阻止浏览器在与损坏的/配置错误的SP交互时无限循环。
配置
$config['authproc.idp'] = [
...
51 => [
'class' => 'loginloopdetection:LoopDetection',
'secondsSinceLastSso' => 5,
'loopsBeforeWarning' => 15,
'logOnly' => false,
],
...
使用Docker探索
您可以使用Docker探索这些功能。
docker network create --driver bridge ratelimit-net # Ratelimit requires you to define a "store" to store rate limit data. These tests use memcached docker run --network ratelimit-net -p 11211:11211 --name memcache-ratelimit -d memcached docker run -d --name ssp-ratelimit \ --network ratelimit-net \ --mount type=bind,source="$(pwd)",target=/var/simplesamlphp/staging-modules/ratelimit,readonly \ -e STAGINGCOMPOSERREPOS=ratelimit \ -e COMPOSER_REQUIRE="cirrusidentity/simplesamlphp-module-ratelimit:@dev" \ -e SSP_ENABLED_MODULES="ratelimit" \ --mount type=bind,source="$(pwd)/tests/docker/metadata/",target=/var/simplesamlphp/metadata/,readonly \ --mount type=bind,source="$(pwd)/tests/docker/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \ --mount type=bind,source="$(pwd)/tests/docker/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \ --mount type=bind,source="$(pwd)/tests/docker/cert/",target=/var/simplesamlphp/cert/,readonly \ --mount type=bind,source="$(pwd)/tests/docker/public/looping-login.php",target=/var/simplesamlphp/public/looping-login.php,readonly \ -p 443:443 cirrusid/simplesamlphp:v2.2.2
然后以 admin:secret
登录到 https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/ 以确认 SSP 是否正在运行。
尝试事项
阻止登录
要到达 admin
测试登录端点,您必须首先以管理员身份进行验证。以 admin:secret
登录到 https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/admin
示例用户密码认证源 example-userpass 被配置为登录尝试次数较少。尝试使用相同的用户名和错误密码登录 3 或 4 次,你应该会看到类似以下日志行
[Tue Dec 06 22:04:23.114923 2022] [php:notice] [pid 58] [client 172.18.0.1:59924] %date{M j H:i:s} simplesamlphp NOTICE STAT [c854ab328b] User 'testuser' login attempt blocked by SimpleSAML\\Module\\ratelimit\\Limiters\\UsernameLimiter
如果你尝试使用不同的用户名和相同的密码(密码填充攻击),那么在几次尝试之后,你应该会看到
User 'pass2' login attempt blocked by SimpleSAML\\Module\\ratelimit\\Limiters\\PasswordStuffingLimiter
循环检测
访问 循环登录页面 将作为服务提供者发起请求以使用本地身份提供者登录并打印出属性。用户 member
,密码 memberpass
。如果你添加一个 loop
查询参数,你可以模拟一个不断将用户发送到身份提供者的不良服务提供者。身份提供者被配置(见 saml20-idp-hosted.php
)以检测循环,并在循环次数过多后显示一个错误页面。
WARNING [c854ab328b] LoopDetection: Only 0 seconds since last SSO for this user from the SP 'https://ratelimit.local.stack-dev.cirrusidentity.com/simplesaml/module.php/saml/sp/metadata.php/loop-test' LoopDetectionCount 5
开发
运行 phpcs
检查代码风格
./vendor/bin/phpcs
运行 phpunit
进行测试
./vendor/bin/phpunit
你可以自动修正一些 phpcs 的发现。建议你在提交更改后(或甚至提交)这样做,因为它弄乱你代码的机会并不是微不足道的。
./vendor/bin/phpcbf
我总是对 psalm
和它的缓存有麻烦,所以我倾向于不使用缓存运行
./vendor/bin/psalm --no-cache