-
Notifications
You must be signed in to change notification settings - Fork 369
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
Provide CipherSuites option between Clients and Servers #1784
Conversation
This pull request introduces 1 alert when merging 48a597c into c2c24d4 - view on LGTM.com new alerts:
|
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.
cmd/antrea-agent/config.go
Outdated
@@ -127,4 +127,10 @@ type AgentConfig struct { | |||
// Provide the address of Kubernetes apiserver, to override any value provided in kubeconfig or InClusterConfig. | |||
// Defaults to "". It must be a host string, a host:port pair, or a URL to the base of the apiserver. | |||
KubeAPIServerOverride string `yaml:"kubeAPIServerOverride,omitempty"` | |||
// Cipher suites to use on Client side. |
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.
Do you use the upper case for "Client" on purpose?
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.
Yes.
pkg/util/cipher/cipher.go
Outdated
"VersionTLS13": tls.VersionTLS13, | ||
} | ||
|
||
// NewTLSConfig generates a *tls.Config with cipher suites string, TLS min version and TLS max version. |
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.
Probably remove "*" of "*tls.Config".
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.
Updated.
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.
some minor comments, otherwise LGTM
I am just curious about why we are adding these parameters on the Agent / client side, and not adding them to the Controller to configure the apiserver?
@@ -120,3 +120,12 @@ featureGates: | |||
# Provide the address of Kubernetes apiserver, to override any value provided in kubeconfig or InClusterConfig. | |||
# Defaults to "". It must be a host string, a host:port pair, or a URL to the base of the apiserver. | |||
#kubeAPIServerOverride: "" | |||
|
|||
# Comma-separated list of cipher suites. |
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.
Maybe we could match the K8s documentation here and add "If omitted, the default Go cipher suites will be used." And even add this link: https://golang.org/pkg/crypto/tls/#CipherSuites
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.
Updated. But I prefer this link since this one includes possible cipher suite value: https://golang.org/pkg/crypto/tls/#pkg-constants
pkg/util/cipher/cipher.go
Outdated
"VersionTLS13": tls.VersionTLS13, | ||
} | ||
|
||
// NewTLSConfig generates a *tls.Config with cipher suites string, TLS min version and TLS max version. |
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.
s/with/given
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.
Updated to tls.Config with given cipher suites ...
Not sure if this is your intention or tls.Config given cipher suite ...
but it sounds better for me.
pkg/util/cipher/cipher.go
Outdated
}, nil | ||
} | ||
|
||
// AppendTLSConfig appends TLS config (Cipher Suites, caBundle, serverName) into *rest.Config. |
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.
s/appends into/appends to
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.
Updated.
1b8b5eb
to
50e3d3c
Compare
@antoninbas Yes, I only configured client side. The reason is that I added |
I think I was surprised because I thought we would add these flags for the servers, and not the clients. Similar to how these flags are available for kube-apiserver. But my concern is also for APIServices. Don't you want a way to configure the TLS config for communications between kube-apiserver and the Antrea Controller apiserver? Or is this something you configure in K8s already? |
This pull request introduces 1 alert when merging 50e3d3c into ba703c0 - view on LGTM.com new alerts:
|
24
In my mind, if someone wants to configure cipher suite, both k8s setup and this cipher suite option in Antrea will be configured. Then communication: "k8s apiserver - antrea apiserver" and "antrea apiserver - antrea client" will be ok. As for antctl, I did try to add cipher suite option but it turned out that "insecure: true" cannot be set at the same time. I think maybe it is not needed by design. I am not so familiar with TLS cipher suite. So discussion on the design is highly welcomed. :) |
Codecov Report
@@ Coverage Diff @@
## main #1784 +/- ##
=======================================
Coverage ? 42.91%
=======================================
Files ? 111
Lines ? 13651
Branches ? 0
=======================================
Hits ? 5858
Misses ? 7298
Partials ? 495
Flags with carried forward coverage won't be shown. Click here to find out more. |
pkg/util/cipher/cipher.go
Outdated
if err != nil { | ||
return nil, err | ||
} | ||
// #nosec G402: ignore MinVersion and MaxVersion options in test code |
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.
what does the comment mean? why is it needed?
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.
To ignore error for golangci-int. It says there's error on TLS MinVersion and MaxVersion.
cmd/antrea-agent/config.go
Outdated
@@ -127,4 +127,10 @@ type AgentConfig struct { | |||
// Provide the address of Kubernetes apiserver, to override any value provided in kubeconfig or InClusterConfig. | |||
// Defaults to "". It must be a host string, a host:port pair, or a URL to the base of the apiserver. | |||
KubeAPIServerOverride string `yaml:"kubeAPIServerOverride,omitempty"` | |||
// Cipher suites to use on Client side. | |||
CipherSuites string `yaml:"cipherSuites,omitempty"` |
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.
Name it TLSCipherSuites to be more specific and keep align with kubelet? https://github.com/kubernetes/kubernetes/blob/9d16b194840ee765b73c444054ca7666821f6991/staging/src/k8s.io/kubelet/config/v1beta1/types.go#L177
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.
Updated.
pkg/agent/client.go
Outdated
if err != nil { | ||
return err | ||
} | ||
tr := &http.Transport{TLSClientConfig: p.tlsConfig} |
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.
Why does it construct the Transport .TLSClientConfig
in a different way from inClusterConfig?
I think it won't verify server cert and name any more as they are not specified in TLSClientConfig
, or it cannot even pass the verification as kubeConfig.TLSClientConfig
and kubeConfig .Transport
are both set.
pkg/util/cipher/cipher.go
Outdated
|
||
// AppendTLSConfig appends TLS config (Cipher Suites, TLSVersion, PreferServerCipherSuites, caBundle, serverName) to | ||
// *rest.Config. | ||
func AppendTLSConfig(c *rest.Config, cipherTLSConfig *tls.Config, caBundle []byte, serverName string) error { |
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 parameter c *rest.Config
seems unnecessary. It's not used in the function and we just need to create a tlsConfig for it. That's why the unit test needs to have some unnecessary setup code.
I think it could be moved to pkg/agent/client.go
and be part of inClusterConfig
.
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(caBundle) {
return fmt.Errorf("...")
}
tlsConfig.ServerName = cert.GetAntreaServerNames()[0]
tlsConfig.RootCAs = certPool
return &rest.Config{
Host: "https://" + net.JoinHostPort(host, port),
Transport: &http.Transport{TLSClientConfig: tlsConfig},
BearerToken: string(token),
BearerTokenFile: tokenFile,
}, nil
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.
Actually not, c.Transport
is set at L65 with all those options (CipherSuites, TLSVersion).
@@ -0,0 +1,51 @@ | |||
package e2e |
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.
license header
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.
Updated.
test/e2e/tls_test.go
Outdated
respCS := resp.TLS.CipherSuite | ||
defer resp.Body.Close() | ||
|
||
assert.Equal(t, cs, respCS, "Cipher Suite used by Server should be %s", tls.CipherSuiteName(cs)) |
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.
Not sure if the test really cover any antrea logic. The PR doesn't change anything on server side but it's testing server response. Should it test agent can connect to controller when CipherSuites/ MinVersion/ MaxVersion is 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 use this test to mock the behavior on client side, with ciphersuite, tlsversion, PreferServerCipherSuites.
cmd/antrea-agent/agent.go
Outdated
|
||
// Create Antrea Clientset for the given config. | ||
antreaClientProvider := agent.NewAntreaClientProvider(o.config.AntreaClientConnection, k8sClient) | ||
antreaClientProvider := agent.NewAntreaClientProvider(o.config.AntreaClientConnection, k8sClient, tlsConfig) |
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.
Don't it need to set same TLS config for agent-apiserver communication?
I also have same question as @antoninbas. Even
|
And for maxVersion, is it really useful? I see typically only minVersion is configurable. |
I think usually TLS1.2 and TLS1.3 are used so minVersion can be configured to TLS1.2. But maybe someone prefers TLS1.2 then maxVersion can be set to TLS1.2. |
For someone comes across this PR when configuring Cipher Suites for K8s, please pay attention that choose a proper one like "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". |
bfe673e
to
90cb9b5
Compare
This PR is refactored to configure on apiserver side. PTAL. |
/test-e2e |
/test-ipv6-only-e2e |
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.
some nits
test/e2e/tls_test.go
Outdated
{"TestControllerSideApiserver", controllerPodName, controllerContainerName, apis.AntreaControllerAPIPort, "Controller"}, | ||
{"TestAgentSideApiserver", agentPodName, agentContainerName, apis.AntreaAgentAPIPort, "Agent"}, |
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.
maybe names of subtests should simply be "ControllerApiserver" and "AgentApiserver". The name of the parent test ("TestTLSCipherSuites") will be used as a prefix in log outputs
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.
Updated.
test/e2e/tls_test.go
Outdated
// TestTLSCipherSuites tests Cipher Suite and TLSVersion config on Antrea Apiserver, Controller side or Agent side. | ||
func TestTLSCipherSuites(t *testing.T) { |
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.
what about "TestAntreaApiserverTLSConfig"?
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.
Updated.
test/e2e/tls_test.go
Outdated
break | ||
} | ||
} | ||
assert.Equal(t, true, oneTLS13CS, |
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.
there is an assert.True
assertion
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.
Thank you. Updated.
test/e2e/tls_test.go
Outdated
// 2. Set TLSMaxVersion to TLS1.2, then TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 should be used | ||
stdouts = data.openssl(t, podName, containerName, true, apiserver) | ||
for _, stdout := range stdouts { | ||
assert.Equal(t, true, strings.Contains(stdout, fmt.Sprintf("New, TLSv1.2, Cipher is %s", cipherSuiteStr)), |
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.
same as above
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.
Updated.
test/e2e/tls_test.go
Outdated
opensslTLS13CipherSuites = []string{"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"} | ||
) | ||
|
||
// TestTLSCipherSuites tests Cipher Suite and TLSVersion config on Antrea Apiserver, Controller side or Agent side. |
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 don't think we usually capitalize "apiserver"
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.
Used "apiserver"
test/e2e/tls_test.go
Outdated
|
||
func (data *TestData) openssl(t *testing.T, pod string, container string, tls12 bool, port int) []string { | ||
var stdouts []string | ||
tests := []struct { |
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.
suggest renaming tests
to something else here, such as opensslConnectCommands
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.
Updated.
test/e2e/tls_test.go
Outdated
if tls12 { | ||
cmd = append(cmd, "-tls1_2") | ||
} | ||
stdout, _, _ := data.runCommandFromPod(antreaNamespace, pod, container, cmd) |
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.
ignoring errors on purpose?
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.
Yes, since we just need to the check Cipher Suite used.
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.
still it may be better to fail earlier if the command cannot be run for any reason (e.g. the Pod has crashed)
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.
Got it. Better to be prepared for anything possible. Updated.
35a60c5
to
9ce0eee
Compare
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
test/e2e/tls_test.go
Outdated
for _, tc := range opensslConnectCommands { | ||
if !tc.enabled { | ||
continue | ||
} | ||
cmd := []string{"timeout", "1", "openssl", "s_client", "-connect", net.JoinHostPort(tc.ip, fmt.Sprint(port)), tc.option} | ||
if tls12 { |
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.
s/tc/c
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.
Updated.
test/e2e/tls_test.go
Outdated
if tls12 { | ||
cmd = append(cmd, "-tls1_2") | ||
} | ||
stdout, _, _ := data.runCommandFromPod(antreaNamespace, pod, container, cmd) |
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.
still it may be better to fail earlier if the command cannot be run for any reason (e.g. the Pod has crashed)
build/yamls/antrea.yml
Outdated
|
||
# Comma-separated list of cipher suites. If omitted, the default Go cipher suites will be used. | ||
# https://golang.org/pkg/crypto/tls/#pkg-constants | ||
# Note that Antrea is using an old version of k8s.io/component-base, so TLS1.3 cipher suites cannot be explicitly listed here. |
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 personally feel no need to explain the long reasons in yaml, but just describe the facts. We can move detailed explanation to comments on code. Up to you to decide.
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 feel that everything is needed, except for the k8s.io/component-base
mention and the github link
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.
Yes, I meant "Antrea is using an old version of k8s.io/component-base" and "by default Antrea uses the Go "crypto" libraries".
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.
Sounds good. I had suggested using "by default Antrea uses the Go "crypto" libraries" because I was thinking of user which may have their own FIPS compliant builds of Antrea by using a different crypto implementation. But in that case, it's not really our responsibility to document the behavior.
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.
Removed component-base and the link.
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.
Also "Go crypto libraries"
build/yamls/antrea.yml
Outdated
# https://golang.org/pkg/crypto/tls/#pkg-constants | ||
# Note that Antrea is using an old version of k8s.io/component-base, so TLS1.3 cipher suites cannot be explicitly listed here. | ||
# Additionally, by default Antrea uses the Go "crypto" libraries, which do not support configuring Cipher Suites for TLS1.3. | ||
# In other words, the apiserver will always prefer TLS1.3 Cipher Suites whenever possible. |
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 do not understand this sentence - why "in other words", "the apiserver will always prefer TLS1.3 Cipher Suites whenever possible"? I cannot see the previous sentences are relevant to "the apiserver will always prefer TLS1.3 Cipher Suites whenever possible".
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.
You cannot disable TLS1.3 Cipher Suites and they will always be preferred to the cipher suites you explicitly provide. So if you set tlsCipherSuites
to <some TLS1.2 suite>
, your choice will be ignored if the client supports TLS 1.3
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.
Should we just explicitly declare the two points: TLS1.3 cipher suites cannot be listed; but apiserver will always prefer TLS1.3 when it is supported by the client?
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 think @jianjuns 's concern is that "in other words" isn't proper here. I changed it to "actually". Do you think it is better?
9906400
to
88617e8
Compare
build/yamls/antrea-aks.yml
Outdated
|
||
# Comma-separated list of Cipher Suites. If omitted, the default Go Cipher Suites will be used. | ||
# https://golang.org/pkg/crypto/tls/#pkg-constants | ||
# Note that TLS1.3 Cipher Suites cannot be explicitly listed here. Actually, the apiserver will |
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.
How about:
Note that TLS1.3 Cipher Suites cannot be added to the list. But the apiserver will always prefer TLS1.3 Cipher Suites whenever possible.
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.
Updated.
* Add options TLSCipherSuites, TLSMinVersion on Apiserver side of controller and agent. * Add a util module cipher to support functionality and related UT. * Add tls e2e tests to verify Apiserver of Antrea and Antrea agent. Signed-off-by: Zhecheng Li <[email protected]>
/test-all |
/test-e2e |
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
ipv6-only-e2e is successful according to Jenkins output. |
/test-ipv6-only-networkpolicy |
All tests are successful. |
and agent.
Signed-off-by: Zhecheng [email protected]