-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add whitelist functionality (#31) #35
Changes from all commits
324281a
09684fd
fc9f595
b178d19
701c0d7
5d428be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import ( | |
"github.com/caddyserver/caddy/v2/modules/caddyhttp" | ||
"github.com/jasonlovesdoggo/caddy-defender/ranges/data" | ||
"github.com/jasonlovesdoggo/caddy-defender/responders" | ||
"github.com/jasonlovesdoggo/caddy-defender/utils/ip/whitelist" | ||
"net" | ||
"reflect" | ||
"slices" | ||
|
@@ -18,11 +19,13 @@ var responderTypes = []string{"block", "garbage", "custom", "ratelimit"} | |
// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. Syntax: | ||
// | ||
// defender <responder> { | ||
// # IP ranges to block | ||
// ranges | ||
// # Custom message to return to the client when using "custom" middleware (optional) | ||
// message | ||
// } | ||
// # IP ranges to block | ||
// ranges | ||
// # Whitelisted IP addresses to allow to bypass ranges (optional) | ||
// whitelist | ||
// # Custom message to return to the client when using "custom" middleware (optional) | ||
// message | ||
// } | ||
func (m *Defender) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { | ||
d.Next() // consume directive name | ||
|
||
|
@@ -52,6 +55,10 @@ func (m *Defender) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { | |
} | ||
Message := d.Val() | ||
m.Message = Message | ||
case "whitelist": | ||
for d.NextArg() { | ||
m.Whitelist = append(m.Whitelist, d.Val()) | ||
} | ||
default: | ||
return d.Errf("unknown subdirective '%s'", d.Val()) | ||
} | ||
|
@@ -112,10 +119,6 @@ func (m *Defender) Validate() error { | |
if m.responder == nil { | ||
return fmt.Errorf("responder not configured") | ||
} | ||
if len(m.Ranges) == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By using all predefined ranges, wouldn't this include private and essentially block all access for most if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. It's not a perfect solution. If you have any suggestions for an alternative let me know There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. It's not a perfect solution. If you have any suggestions for an alternative let me know There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, because that isn't entirely obvious to me, do the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hmm. This does seem like a better solution. What do you suggest? All services that don't have overlap - private? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that might be a good thing. A list referencing all the default IP ranges that are useful as an out-of-the-box setup. E.g.: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay okay 👌 If you want to add that into your documentation PR, I'll merge that in as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR is ready but includes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by to be correct? Didn't you say it wouldn't be beneficial to have private be in the defaults? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant it includes private, to reflect the current state. After your PR that would have to be changed, if you decided to remove private/local from the default rwnge. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, I removed it from the default range and updated the docs accordingly. You can see plugin.go#L23 for the list |
||
// set the default ranges to be all of the predefined ranges | ||
return fmt.Errorf("no ranges specified, this is required") | ||
} | ||
|
||
for _, ipRange := range m.Ranges { | ||
// Check if the range is a predefined key (e.g., "openai") | ||
|
@@ -131,6 +134,12 @@ func (m *Defender) Validate() error { | |
} | ||
} | ||
|
||
// Check if the whitelist is valid | ||
err := whitelist.ValidateWhitelist(m.Whitelist) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
auto_https off | ||
order defender after header | ||
debug | ||
} | ||
|
||
:80 { | ||
bind 127.0.0.1 ::1 | ||
# Everything in AWS besides my EC2 instance is blocked from accessing this site. | ||
defender block { | ||
ranges aws | ||
whitelist 169.254.169.254 # my ec2's public IP. | ||
} | ||
respond "This is what a human sees" | ||
} | ||
|
||
:81 { | ||
bind 127.0.0.1 ::1 | ||
# My localhost ipv6 is blocked but not my ipv4 | ||
defender block { | ||
ranges private | ||
whitelist 127.0.0.1 | ||
} | ||
respond "This is what a ipv4 human sees" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, the new behavior would be to use all ranges, right?
This should be documented in the README.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always been the behavior you can look at the provision step to see where it's set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make a PR to document that behavior.