-
Notifications
You must be signed in to change notification settings - Fork 289
Add runtime config for blocking outbound connections by CIDR #3150
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
Conversation
This gives more output when debugging test failures. Signed-off-by: Lann Martin <[email protected]>
fb76b61
to
ee902ca
Compare
This functionality is available from the more common rustls-pki-types crate which is already a depedency for other reasons. Signed-off-by: Lann Martin <[email protected]>
This allows a host to block outbound connections by CIDR mask or with the 'private' keyword which blocks non-publicly-routable IPs. Signed-off-by: Lann Martin <[email protected]>
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.
The implementation mostly looks good - just one major question I left in a comment. Overall, I'm super on board with the internal changes.
I'm more unsure about the exact UX of how we're extending the runtime config yaml. I don't have specific feedback, and so I'm not going to block. My FUD mainly extends from the fact that the yaml changes are permanent and must be kept into purpiutiy. I think I'd personally have felt much more comfortable if the internal changes were landed separately from the YAML changes. I understand why they're bundled, but they don't have to be, and I think I'd like to be a bit more careful about introducing changes that directly impact users.
Signed-off-by: Lann Martin <[email protected]>
Signed-off-by: Lann Martin <[email protected]>
The only user-visible changes should be the new |
// Convert IPv4-compatible IPv6 addresses to IPv4 and check again to prevent bypass | ||
if let IpAddr::V6(ipv6) = ip_addr { | ||
if let Some(ipv4_compat) = ipv6.to_ipv4() { | ||
return self.is_blocked(&IpAddr::V4(ipv4_compat)); | ||
} | ||
} |
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 noticed this issue when adding the link to ip_network::Ipv6Network::is_global
to the docs above; annoyingly, its behavior is subtly different from the unstable std::net::Ipv6Addr::is_global
though that does lead to an arguably better solution here.
Indeed. My concern is more of a vibe than anything (which is why I've approved this PR and don't want to block). I don't have concrete suggestions - I'm simply unsure about the API and unsure about introducing such additions to the Spin API in a PR. For example, some random questions I have:
I guess in general, I'm wondering if the user facing changes should be introduced through a SIP instead of a PR. It's a small feature so I understand why that wasn't done initially, but it feels like anything that impacts the public API of Spin should be discussed in a SIP. |
I thought about this a little. It seems somewhat unlikely that an operator that wanted to lock down the network that much wouldn't also have complete control over the apps (and therefor |
You could translate |
First off, this is definitely a reasonable question to ask.
Depending on your interpretation, "anything that impacts the public API" could apply to a lot of things that we haven't covered with SIPs before, but we can certainly adjust our attitudes / policies / guidance on that if we want. I guess it didn't even occur to me to do a SIP here in part because we didn't do one for the even larger More broadly: SIPs are documented as being for "major work items" which...leaves a little room for interpretation 😅 but I think reflects that one of the goals is to avoid putting in "too much" work into an implementation before getting feedback on the design. This is important both to avoid wasting contributor's time and to avoid putting too much pressure on reviewers to accept a design just because there is a lot of code already written for it. On the flip side, there is overhead in the SIP process and every extra bit of friction incrementally raises the bar for contribution - even for maintainers! |
@lann it occurs to me that perhaps one reason I'm nervous about this is that runtime-config.yaml isn't currently versioned. Perhaps if it were, I'd be less worried? |
I prefer to think of it as "version 0"; you always get that one freebie before you have to start writing down explicit schema versions. 🙂 |
Example:
A couple of separate commits with supporting changes:
8f455ee
rustls-pemfile
crate in favor ofrustls-pki-types
which has the functionality we need with a slightly nicer API and is already a dependency for other reasons:a4c2219
Which still leaves a pretty hefty final commit, including some not-entirely-related refactoring (sorry):
BlockedNetworks
runtime config toOutboundNetworkingFactor
OutboundHttpFactor
'sallow_private_ips
config with this new featureoutbound_socket_addr_check
too which coverswasi:sockets
OutboundNetworkingFactor
's runtime config code; this should have been a separate PR but by the time I noticed it was very tangled up with the new featureruntime_config.rs
andtls.rs
. There is a lot of renaming and fussing with structs here but overall the behavior shouldn't have changed significantly.ipnet
crate with similarip_network
; we already had dependencies on both, they cover mostly the same ground, andip_network
has a bit more functionality