Closed skrlance closed 3 years ago
@mholt I'd like to take a shot at this, I have a few ideas of how to implement this.
Any pointers for where such functionality could hook in to the Caddy server?
@sk0g Awesome! Start here: https://caddyserver.com/docs/extending-caddy
You'd probably want an http.handlers.*
module, so like http.handlers.rate_limit
: https://caddyserver.com/docs/extending-caddy/namespaces
After you have it at least basically working, then it should be easy to add Caddyfile support: https://caddyserver.com/docs/extending-caddy/caddyfile
I'll be here to answer questions!
Hey, so I've made changes and have put them up at https://github.com/sk0g/caddy. Changes are in master for now, which I'll fix before making a PR :)
Would you mind having a look? It shows up and all, I've tested the algorithms etc, but now I'm at the part where I have to integrate in. I've done... things, and it shows up as an available module, etc. Not sure if there is a default setup/ caddyfile I could tweak with added values, in order to test this? I was unclear on how logging works as well, since it seems like some set up custom zap
loggers, some just use fmt
, etc.
Currently it will just block after the counter goes over for all request types. Would fragmentation by GET/POST,etc, or failed/ successful requests be required, or would that be out of scope for a more preliminary implementation?
Also, sorry in advance - I haven't contributed to an open source project before!
@sk0g Cool - that's awesome. It's great that you wrote tests too.
There's no need to fork all of Caddy -- just make a new repo containing only your module instead. Then use xcaddy. :) The Extending Caddy docs show you how to do this.
I was unclear on how logging works as well, since it seems like some set up custom zap loggers, some just use fmt, etc.
Use a zap logger, just as the linked docs describe: https://caddyserver.com/docs/extending-caddy#logs
Currently it will just block after the counter goes over for all request types. Would fragmentation by GET/POST,etc, or failed/ successful requests be required, or would that be out of scope for a more preliminary implementation?
You'll have to survey your (potential) user base to find out what features and functionality they need. I don't currently have a specific need so I couldn't tell you, but I do happen to know one potential use case, it's pretty advanced though and probably doesn't need to be supported at a first pass.
I have a number of things to comment on, but first, extract the module code into a separate package/repo and then it'll be easier to do a review.
@sk0g @mholt Guys, can I get example configuration please
@bestpaydeals Any updates regarding completion status will be posted here, but for now there isn't much to go off. I'll have more time to dig into it this weekend, so I'll see how that goes :)
@sk0g what is the status for this module? Have you considered using golang.org/x/time/rate
instead of manual implementation?
@sk0g commented on Jun 17, 2020, 3:33 PM GMT+4:30:
@bestpaydeals Any updates regarding completion status will be posted here, but for now there isn't much to go off. I'll have more time to dig into it this weekend, so I'll see how that goes :)
Can you have basicauth rate-limiting on your radar, too? I use it on webdav and some personal REST APIs, and without rate-limiting it's rather unsafe.
I haven't had much time for this since I messed up by extending the main repo instead of building it out as a separate package. I'll scrap that this weekend and get back to it, but can either of you dump your current Caddyfile, and how you think the setup for this might work?
@NightMachinary keen to hear what you mean, can you show me a practical usage example? Do you mean separate throttling limits if users are receiving 4XX/ 403/ 401 status codes, potentially only to specific routes or resources?
@sk0g commented on Aug 6, 2020, 4:44 AM GMT+4:30:
I haven't had much time for this since I messed up by extending the main repo instead of building it out as a separate package. I'll scrap that this weekend and get back to it, but can either of you dump your current Caddyfile, and how you think the setup for this might work?
https://github.com/NightMachinary/.shells/blob/master/scripts/launchers/Caddyfile
@NightMachinary keen to hear what you mean, can you show me a practical usage example? Do you mean separate throttling limits if users are receiving 4XX/ 403/ 401 status codes, potentially only to specific routes or resources?
Yes, exactly. I personally want to limit 401
on https://garden.lilf.ir/api/*
.
Really looking forward to this! It's really needed for strong security, otherwise basic-auth will fall for most brute-force / passwords-dictionary attacks. There are widely distributed tools for this kind of things... @sk0g and @mholt this is in your good hands 🙏🏻
@mysticaltech if you're looking to prevent brute force attacks against authentication, then rate limiting at Caddy is not the ideal solution. You'd want to use a tool like fail2ban to block requests at the firewall level instead.
For this, please follow the discussion at https://github.com/caddyserver/caddy/issues/3363 and the related PR #3364, which still needs help to test, confirm, and complete.
@francislavoie I see, I always thought that fail2ban was for ssh only, but of course not! I'll look into. Thanks a lot, appreciate that clarification.
Hi guys, I have just implemented a Caddy v2 module for rate-limiting. See caddy-ext/ratelimit.
@RussellLuo Very cool! Thanks for sharing. Please feel free to add it to the Caddy website: https://caddyserver.com/download (just go to your account and Register Package).
I guess that wraps this up.
Hi, Is there something for limiting connections per IP ? Thanks
@KaKi87 Yes, the above module probably can, or this one I know can: https://github.com/mholt/caddy-ratelimit
I'm sorry I might have misunderstood what OP meant by limiting connections per IP, which I found to be different from rate limiting.
Both plugins feature rate limiting, but what I'm looking for, is limiting the amount of connections that a client can establish at the same time (simultaneously), not the amount of requests it can do during a time frame.
Thanks
In that case, you might be looking for a layer 3 firewall / rate limiter. They are often available as hardware devices. Even Caddy's layer4 module has to accept a connection before it knows the remote IP.
No, sorry I didn't mean it like that, I meant return 429 if the user has a certain amount of ongoing requests.
In other words, I want to limit concurrency per IP.
Thanks
@KaKi87
Edit: Not sure why the first part of my comment disappeared (PEBKAC?) but anyway, tracking concurrency with keys could be discussed here:
https://github.com/mholt/caddy-ratelimit
This is a very very old issue, so locking; continue new discussions in the forum
Please consider adding rate limit or limit connection per IP feature on Caddy 2. Thanks!!