-
Notifications
You must be signed in to change notification settings - Fork 413
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
OCPBUGS-20410: CRI-O: Use 127.0.0.1 for stream server with random port #3853
Conversation
cc @mrunalp @haircommander @rphillips @umohnani8 @harche @QiWang19 What are your thoughts on that change? |
makes sense to me! /lgtm |
assign @sinnykumari for approval |
Had a chat with Mrunal. This will break IPv6 only systems. Instead of defaulting to "" (which in golang is all interfaces), we can listen on 127.0.0.1 and ::1. |
The golang server is already listening on IPv4 or IPv6 per: https://github.com/cri-o/cri-o/blob/5951d4935f00bd1501dc510b68da1aa631c5ed72/vendor/k8s.io/kubelet/pkg/cri/streaming/server.go#L240 Can we just use |
127.0.0.1
for stream server with random portlocalhost
for stream server with random port
9d88052
to
34a6903
Compare
34a6903
to
109fcc2
Compare
/retest |
/test okd-scos-e2e-aws-ovn |
3 similar comments
/test okd-scos-e2e-aws-ovn |
/test okd-scos-e2e-aws-ovn |
/test okd-scos-e2e-aws-ovn |
/retest |
1 similar comment
/retest |
@saschagrunert, do you reckon
Using (as an example) ":8080" or "0.0.0.0:8080" (to denote any interface) would result in a Go listener binding to all available interfaces - let it be IPv4 or IPv6. However, if we make it "localhost:8080" or "127.0.0.1:8080", then only IPv4 will be used. Why do we want to listen on IPv6 on localhost? I don't know how practical this would be. I think leaving it to be just "localhost" or "127.0.0.1" (which is probably better than "localhost" if we want to keep it to IPv4 only) would be fine. |
We have to stay compatible with IPv6-only systems. That's why 127.0.0.1 would not work. The listener in golang would then automatically pick IPv6 if we only specify "localhost". |
You mean it wouldn't? The only cases where IPv6 will be used would be ":1234" or "0.0.0.0:1234" (here to denote any explicitly). See a test below. I wish there were an option to enable dual-stack in Go's listener or use a custom listener type to provide configuration (similarly to what one can do when creating a custom client), but that's not the case. Some systems hardcode the notion of "localhost", but this goes through a normal resolver on most, so it might resolve to something other than 127.0.0.1, albeit unlikely. There is also the "ipv6-localhost" that some systems also offer via the /etc/hosts entry, and that resolves to ::1, but it often does not work - and it would not help here anyway. This is why I suggested 127.0.0.1 for loopback, as it does not depend on any resolvers. Using localhost or 127.0.0.1 does not disable IPv6 support, so we are still compatible with it and support it - as long as the OS supports it (kernel supports it and loopback has ::1 configured). If we ought to be locked down to a local-only listener and connection for security, then it does not matter that we aren't listening on IPv6, does it? Am I missing something? Otherwise, if we insist on this, then if we detect "localhost" or "127.0.0.1" as a value, then we need to have another listener to explicitly listen on ::1, which seems like overkill - more error checking, more code, more tests are needed, etc. Test:
Using: package main
import (
"fmt"
"net"
"os"
"os/exec"
"strings"
)
func main() {
go func() {
_, err := net.Listen("tcp", os.Args[1])
if err != nil {
panic(err)
}
}()
s, err := exec.Command("netstat", "-ntlp").Output()
if err != nil {
panic(err)
}
for _, l := range strings.Split(string(s), "\n") {
if strings.Contains(l, fmt.Sprint(os.Getpid())) {
fmt.Println(l)
}
}
if len(os.Args) > 2 && os.Args[2] != "" {
select {}
}
} |
@kwilczynski im not actually sure how to test that, but how does it behave on systems supporting only IPv6, no IPv4? The listen on Would |
We could reason about two things: disabling OS support and not configuring IPv4. The former, for Linux, is challenging, if not impossible [1][2]. The *BSD (FreeBSD) is the only other OS I know that can disable IPv4 entirely if you wish (very purist of them, isn't it? 😄 ). I can't speak for Windows. For Linux, the CONFIG_NET enables loopback and dummy drivers - this is usually coupled with CONFIG_INET, which enables IPv4 shebang. There is no CONFIG_INET4 or CONFIG_INET6 that can be toggled depending on which stack we would want. Things would also break without some resemblance of IPv4 support - for example, many things use simple TCP (with IPv4) IPC over loopback. The latter, you can choose not to configure IPv4 on loopback (most likely things would break) or on other interfaces (more legitimate case). This would work. To add, there is no sysctl toggle to disable IPv4 support as what is available for IPv6 currently. For reference:
Correct, but which addresses the listener will bind in due process is limited to whether the address portion is empty or set to any or the 0.0.0.0 (like the examples from prior comments). For anything else, depending on the provided address portion (not the port) and what it is or what it resolves to, the listener would bind to specific IPv4 or IPv6 addresses only.
The 127.0.0.1 should probably always work on Linux. Otherwise, there will be issues, I suppose. I think a possible solution would be to make the Using a list in TOML: [[crio.api]]
stream_address = "127.0.0.1"
stream_port = "1234"
[[crio.api]]
stream_address = "::1"
stream_port = "0" Using the [crio.api]
stream_address = ["127.0.0.1", "::1"]
stream_port = "0" This approach also allows people to enable a streaming endpoint to listen on multiple addresses (or interfaces, if you wish), such as the localhost (loopback) or perhaps some internal network address (which might be some dedicated management VLAN, etc.). |
109fcc2
to
7abbec0
Compare
Thanks, excellent explanation by the way!
This would be cool, but a breaking change. We would have to spawn multiple streaming servers because the current one does not support that. Or we modify the existing implementation to support multiple endpoints. I don't know if that's really worth the effort. The CRI-O config would have to go through a deprecation policy as well. |
localhost
for stream server with random port127.0.0.1
for stream server with random port
This should work since it's the default in CRI-O with the merge of cri-o/cri-o#1714. It slightly increases security of the default configuration. Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
7abbec0
to
f6192a2
Compare
/test okd-scos-e2e-aws-ovn |
/lgtm |
/approve |
/assign @sinnykumari |
I don't have much domain specific context here, will go with already review done by the node team. Also required ci tests are passing. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: haircommander, rphillips, saschagrunert, sinnykumari The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/cherry-pick release-4.14 |
@kwilczynski: new pull request created: #3984 In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/cherry-pick release-4.15 |
@kwilczynski: new pull request could not be created: failed to create pull request against openshift/machine-config-operator#release-4.15 from head openshift-cherrypick-robot:cherry-pick-3853-to-release-4.15: status code 422 not one of [201], body: {"message":"Validation Failed","errors":[{"resource":"PullRequest","code":"custom","message":"No commits between openshift:release-4.15 and openshift-cherrypick-robot:cherry-pick-3853-to-release-4.15"}],"documentation_url":"https://docs.github.com/rest/pulls/pulls#create-a-pull-request"} In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/cherry-pick release-4.16 |
@kwilczynski: new pull request could not be created: failed to create pull request against openshift/machine-config-operator#release-4.16 from head openshift-cherrypick-robot:cherry-pick-3853-to-release-4.16: status code 422 not one of [201], body: {"message":"Validation Failed","errors":[{"resource":"PullRequest","code":"custom","message":"No commits between openshift:release-4.16 and openshift-cherrypick-robot:cherry-pick-3853-to-release-4.16"}],"documentation_url":"https://docs.github.com/rest/pulls/pulls#create-a-pull-request"} In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
OK. Change already on release-4.15 and release-4.16 branches. |
127.0.0.1
for stream server with random port
@saschagrunert: Jira Issue OCPBUGS-20410: Some pull requests linked via external trackers have merged: The following pull requests linked via external trackers have not merged: These pull request must merge or be unlinked from the Jira bug in order for it to move to the next state. Once unlinked, request a bug refresh with Jira Issue OCPBUGS-20410 has not been moved to the MODIFIED state. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/jira refresh |
@wking: Jira Issue OCPBUGS-20410: All pull requests linked via external trackers have merged: Jira Issue OCPBUGS-20410 has been moved to the MODIFIED state. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
This should work since it's the default in CRI-O with the merge of cri-o/cri-o#1714. It slightly increases security of the default configuration.
- Description for the changelog
Updated CRI-O streaming server configuration to use 127.0.0.1 and a random port.