-
Notifications
You must be signed in to change notification settings - Fork 446
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
Added way to block members using CIDR #196
Added way to block members using CIDR #196
Conversation
ef409b4
to
b4cd6df
Compare
@mkeeler Is it what you had in mind in hashicorp/consul#5916 (comment) ? |
@mkeeler Could you have a look and tell me if it is Ok to achieve hashicorp/consul#5916 ? |
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.
Overall I think this would work. My one concern is all the string parsing and checks that would have to be done for every UDP packet or TCP connection. Would it still work if the CIDR checks were done in these two places instead (rough locations):
Line 896 in e1138a6
state = &nodeState{ |
Line 933 in e1138a6
// If DeadNodeReclaimTime is configured, check if enough time has elapsed since the node died. |
In the first location we are handling an alive event for a new node. In the second location we are handling an alive event for an existing node but already know that either the IP or port has changed. What this doesn't do is CIDR validation when handling an alive event for a node whose IP or port has not been updated (which should be the normal and most prevalent case).
@mkeeler DONE as you suggested |
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.
LGTM
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.
Please take a look at my comments and see if I've misunderstood anything about your intent.
1ff23f4
to
6bb8396
Compare
I fixed issues you mentioned. Are you Ok with the implementation I made to protect |
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.
Apologies for the delay. I was having a hard time figuring out how to describe my remaining reservations with the proposed implementation but I think I've got it now.
Overall the best solution here is to always ensure you are using gossip encryption in your consul clusters which should prevent accidental joins, since the stray agents would lack the necessary keys to formulate valid memberlist messages. But I can see situations where someone may be in a situation where enabling gossip encryption isn't feasible and so something shaped like the proposed solution is beneficial.
I think the pairing of an allow and a deny configuration is offering too much complexity for a likely rarely used subfeature. The allow_write_http_from
consul configuration option has the semantics that if you don't configure it at all it is default-allow, and if you configure anything it switches to default-deny. It does require that you have the ability to enumerate all allowable addresses in CIDR form sanely.
For straightforward behind-the-firewall setups this might be as straightforward as dumping all of the class-C networks (10.0.0.0/8
, 172.16.0.0/12
, 192.168.0.0/16
, and an ipv6 equivalent if being used) into the allow list. If you are incapable of doing this because your IP addresses don't neatly fit into CIDR blocks, my assumption is that you are probably drifting into the territory where you would be better served with the gossip encryption option.
I'd like it if you could reduce the complexity here and only expose a single tunable AllowedCIDRs
setting that defaults to nil
with the semantics that it is default-allow unless configured to a non-empty slice of data.
When the feature is in default-allow mode it would also be nice to avoid incurring any additional operations or allocations that can be avoided (namely we should avoid parsing net.Addr.Network()
into an interim net.IP
when we know the user has not activated this CIDR feature at all.
@rboyer Thank you for the review, I think I addressed all your points! |
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.
Looks good. The only thing missing for me now that you've made the big changes is some test showcasing the feature successfully keeping awareness of a blocked node from making it into the memberlist of a node configured to block it.
@pierresouchay The only thing thats left, seem to be
|
@i0rek yes, I have started to implement test, but I have many things to change, including the shell script to create sub networks for Mac, I'll find some time soon to work on this |
@i0rek DONE |
@rboyer I added the tests as required |
Added 2 new fields in configuration of memberlists to allow/disallow others machines joining memberlist. This will allow protecting some machines from joining a cluster. Will be useful to implement hashicorp/consul#5916 as suggested my @mkeller
OK the last comments I left should be pretty quick to fix and after that we are golden. |
hu... fun, unit tests do not work anymore :( |
Also had to fix unit test blocking all connectivity when AllowedCIDR was set to [] instead of nil
@rboyer Ok, I found the issue with the unit tests, now, Join() by default assert that Name / Addr is set by default, so my unit tests were not working anymore, but last commit fixes that. On another topic, the change you asked to use:
instead of cheking nil also broke another test (I fixed it), that was asserting that AllowedCIDRs = [] was blocking everything. When I wrote it initially, I thought in terms of security that blocking everything is always a nice feature, but for the project itself, it might defeat its own purpose, so I don't think it is a big deal. An finally, the unit tests are not run in the PR, not a big deal, but it might be a good addition I think everything is ok now |
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.
LGTM
We can tag a new version of this after you start using this from serf or consul, in case you discover a need to do any last minute refactor of this feature while attempting to use it. |
@rboyer Thanks, I'll try the integration in Consul soon, but it should be straigforward |
@rboyer I made the PR in Consul some time ago, maybe you could have a look at hashicorp/consul#7628 ? Thank you |
Based on work done in hashicorp/memberlist#196 this allows to restrict the IP ranges that can join a given Serf cluster and be a member of the cluster. Restrictions on IPs can be done separatly using 2 new differents flags and config options to restrict IPs for LAN and WAN Serf.
…7628) Based on work done in hashicorp/memberlist#196 this allows to restrict the IP ranges that can join a given Serf cluster and be a member of the cluster. Restrictions on IPs can be done separatly using 2 new differents flags and config options to restrict IPs for LAN and WAN Serf.
…7628) Based on work done in hashicorp/memberlist#196 this allows to restrict the IP ranges that can join a given Serf cluster and be a member of the cluster. Restrictions on IPs can be done separatly using 2 new differents flags and config options to restrict IPs for LAN and WAN Serf.
Added 2 new fields in configuration of memberlists to allow/disallow
others machines joining memberlist.
This will allow protecting some machines from joining a cluster and will increase security as well.
Will be useful to implement hashicorp/consul#5916
as suggested my @mkeller