Skip to content

Commit

Permalink
Use aligned flags and secrets for system-internal-tls (#1116)
Browse files Browse the repository at this point in the history
* Use aligned flags and secrets for `knative-internal-tls`

* Fix string conversion

* Change config key to system-internal-tls

* Fix lint warnings and create certificates with new names + SANs
  • Loading branch information
ReToCode authored Oct 3, 2023
1 parent 3fdb548 commit a895a08
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 46 deletions.
37 changes: 23 additions & 14 deletions pkg/generator/ingress_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
// Match the ingress' port with a port on the Service to find the target.
// Also find out if the target supports HTTP2.
var (
externalPort = int32(80)
targetPort = int32(80)
http2 = false
internalEncryption = false
externalPort = int32(80)
targetPort = int32(80)
http2 = false
httpsPortUsed = false
)
for _, port := range service.Spec.Ports {
if port.Port == split.ServicePort.IntVal || port.Name == split.ServicePort.StrVal {
Expand All @@ -165,7 +165,7 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
http2 = true
}
if port.Port == split.ServicePort.IntVal && port.Name == "https" {
internalEncryption = true
httpsPortUsed = true
}
}

Expand Down Expand Up @@ -209,16 +209,16 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
//
// TODO:
// Drop this configmap check - issues/968
// We can determin whether internal-encryption is enabled or disabled via `internalEncryption` only,
// but all conformance tests need to be updated to have the port name so check the configmap as well.
// We could determine whether system-internal-tls is enabled or disabled via the flag only,
// but all conformance tests need to be updated to have the port name so we check the configmap as well.
//
// TODO: Or fetch configmap before the loop as per https://github.com/knative-sandbox/net-kourier/pull/959#discussion_r1048441513
cfg := config.FromContextOrDefaults(ctx)

// As Ingress with RewriteHost points to ExternalService(kourier-internal), we don't enable TLS.
if (cfg.Network.InternalEncryption || internalEncryption) && httpPath.RewriteHost == "" {
if (cfg.Network.SystemInternalTLSEnabled() || httpsPortUsed) && httpPath.RewriteHost == "" {
var err error
transportSocket, err = translator.createUpstreamTransportSocket(http2)
transportSocket, err = translator.createUpstreamTransportSocket(http2, split.ServiceNamespace)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -296,16 +296,16 @@ func (translator *IngressTranslator) translateIngress(ctx context.Context, ingre
}, nil
}

func (translator *IngressTranslator) createUpstreamTransportSocket(http2 bool) (*envoycorev3.TransportSocket, error) {
caSecret, err := translator.secretGetter(pkgconfig.ServingNamespace(), netconfig.ServingInternalCertName)
func (translator *IngressTranslator) createUpstreamTransportSocket(http2 bool, namespace string) (*envoycorev3.TransportSocket, error) {
caSecret, err := translator.secretGetter(pkgconfig.ServingNamespace(), netconfig.ServingRoutingCertName)
if err != nil {
return nil, fmt.Errorf("failed to fetch activator CA secret: %w", err)
}
var alpnProtocols string
if http2 {
alpnProtocols = "h2"
}
tlsAny, err := anypb.New(createUpstreamTLSContext(caSecret.Data[certificates.CaCertName], alpnProtocols))
tlsAny, err := anypb.New(createUpstreamTLSContext(caSecret.Data[certificates.CaCertName], namespace, alpnProtocols))
if err != nil {
return nil, err
}
Expand All @@ -317,7 +317,7 @@ func (translator *IngressTranslator) createUpstreamTransportSocket(http2 bool) (
}, nil
}

func createUpstreamTLSContext(caCertificate []byte, alpnProtocols ...string) *tlsv3.UpstreamTlsContext {
func createUpstreamTLSContext(caCertificate []byte, namespace string, alpnProtocols ...string) *tlsv3.UpstreamTlsContext {
return &tlsv3.UpstreamTlsContext{
CommonTlsContext: &tlsv3.CommonTlsContext{
AlpnProtocols: alpnProtocols,
Expand All @@ -336,7 +336,16 @@ func createUpstreamTLSContext(caCertificate []byte, alpnProtocols ...string) *tl
SanType: tlsv3.SubjectAltNameMatcher_DNS,
Matcher: &envoymatcherv3.StringMatcher{
MatchPattern: &envoymatcherv3.StringMatcher_Exact{
Exact: certificates.FakeDnsName,
// SAN used by Activator
Exact: certificates.DataPlaneRoutingSAN,
},
},
}, {
SanType: tlsv3.SubjectAltNameMatcher_DNS,
Matcher: &envoymatcherv3.StringMatcher{
MatchPattern: &envoymatcherv3.StringMatcher_Exact{
// SAN used by Queue-Proxy in target namespace
Exact: certificates.DataPlaneUserSAN(namespace),
},
},
}},
Expand Down
25 changes: 17 additions & 8 deletions pkg/generator/ingress_translator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,12 +684,12 @@ func (t *testConfigStore) ToContext(ctx context.Context) context.Context {
var (
defaultConfig = &config.Config{
Network: &netconfig.Config{
AutoTLS: false,
ExternalDomainTLS: false,
},
}
upstreamTLSConfig = &config.Config{
Network: &netconfig.Config{
AutoTLS: false,
ExternalDomainTLS: false,
},
}
)
Expand Down Expand Up @@ -937,7 +937,7 @@ func TestIngressTranslatorWithUpstreamTLS(t *testing.T) {
false,
&envoycorev3.TransportSocket{
Name: wellknown.TransportSocketTls,
ConfigType: typedConfig(false /* http2 */),
ConfigType: typedConfig(false),
},
v3.Cluster_STATIC,
),
Expand Down Expand Up @@ -1009,7 +1009,7 @@ func TestIngressTranslatorWithUpstreamTLS(t *testing.T) {
true, /* http2 */
&envoycorev3.TransportSocket{
Name: wellknown.TransportSocketTls,
ConfigType: typedConfig(true /* http2 */),
ConfigType: typedConfig(true),
},
v3.Cluster_STATIC,
),
Expand Down Expand Up @@ -1082,7 +1082,7 @@ func TestIngressTranslatorWithUpstreamTLS(t *testing.T) {
false, /* http2 */
&envoycorev3.TransportSocket{
Name: wellknown.TransportSocketTls,
ConfigType: typedConfig(false /* http2 */),
ConfigType: typedConfig(false),
},
v3.Cluster_STATIC,
),
Expand Down Expand Up @@ -1155,7 +1155,7 @@ func TestIngressTranslatorWithUpstreamTLS(t *testing.T) {
true, /* http2 */
&envoycorev3.TransportSocket{
Name: wellknown.TransportSocketTls,
ConfigType: typedConfig(true /* http2 */),
ConfigType: typedConfig(true),
},
v3.Cluster_STATIC,
),
Expand Down Expand Up @@ -1574,7 +1574,7 @@ var (
caSecret = &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "knative-testing",
Name: netconfig.ServingInternalCertName,
Name: netconfig.ServingRoutingCertName,
},
Data: map[string][]byte{
certificates.CaCertName: cert,
Expand Down Expand Up @@ -1615,7 +1615,16 @@ func typedConfig(http2 bool) *envoycorev3.TransportSocket_TypedConfig {
SanType: auth.SubjectAltNameMatcher_DNS,
Matcher: &envoymatcherv3.StringMatcher{
MatchPattern: &envoymatcherv3.StringMatcher_Exact{
Exact: certificates.FakeDnsName,
// SAN of Activator
Exact: certificates.DataPlaneRoutingSAN,
},
},
}, {
SanType: auth.SubjectAltNameMatcher_DNS,
Matcher: &envoymatcherv3.StringMatcher{
MatchPattern: &envoymatcherv3.StringMatcher_Exact{
// SAN of Queue-Proxy in target namespace
Exact: certificates.DataPlaneUserSAN("servicens"),
},
},
}},
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/ingress/config/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func FromContextOrDefaults(ctx context.Context) *Config {

func defaultConfig() *netconfig.Config {
return &netconfig.Config{
InternalEncryption: false,
SystemInternalTLS: netconfig.EncryptionDisabled,
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/config/tls/config-network.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ metadata:
app.kubernetes.io/component: networking
app.kubernetes.io/version: devel
data:
internal-encryption: "true"
system-internal-tls: "enabled"
8 changes: 4 additions & 4 deletions test/e2e-kind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ $(dirname $0)/upload-test-images.sh
echo ">> Setup test resources"
ko apply -f test/config
if [[ $(kubectl get secret server-certs -n "${TEST_NAMESPACE}" -o name | wc -l) -eq 1 ]]; then
echo ">> Enable tls against upstream"
echo ">> Enabling TLS on kourier gateway (one static certificate) and upstream TLS with system-internal-tls"
ko apply -f test/config/tls
export "UPSTREAM_TLS_CERT=server-certs"
export "UPSTREAM_CA_CERT=server-ca"
# Use OpenSSL subjectAltName/serverName to enable the certificate for various
# application URLs with this pattern: <APP>.<NAMESPACE>.svc.X.X
export "SERVER_NAME=data-plane.knative.dev"
export "SERVER_NAME=kn-user-serving-tests"
fi

IPS=($(kubectl get nodes -lkubernetes.io/hostname!=kind-control-plane -ojsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'))
Expand Down Expand Up @@ -74,8 +74,8 @@ go test -v -tags=e2e ./test/tls/... \

kubectl -n "${KOURIER_CONTROL_NAMESPACE}" patch configmap/config-kourier --type merge -p '{"data":{"cipher-suites":""}}'

echo ">> Setup one certificate"
$(dirname $0)/generate-cert.sh
echo ">> Setup one wildcard certificate"
$(dirname $0)/generate-wildcard-cert.sh
kubectl -n "${KOURIER_CONTROL_NAMESPACE}" set env deployment net-kourier-controller CERTS_SECRET_NAMESPACE="${KOURIER_CONTROL_NAMESPACE}" CERTS_SECRET_NAME=wildcard-certs
kubectl -n "${KOURIER_CONTROL_NAMESPACE}" rollout status deployment/net-kourier-controller --timeout=300s

Expand Down
37 changes: 22 additions & 15 deletions test/generate-upstream-cert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,43 @@
SERVING_SYSTEM_NAMESPACE=knative-serving
TEST_NAMESPACE=serving-tests
out_dir="$(mktemp -d /tmp/certs-XXX)"
san="data-plane.knative.dev"
activatorSAN="kn-routing"
serviceSAN="kn-user-$TEST_NAMESPACE"

kubectl create ns $SERVING_SYSTEM_NAMESPACE
kubectl create ns $TEST_NAMESPACE

# Generate Root key and cert.
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example/CN=Example' -keyout "${out_dir}"/root.key -out "${out_dir}"/root.crt

# Create server key
openssl req -out "${out_dir}"/tls.csr -newkey rsa:2048 -nodes -keyout "${out_dir}"/tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:$san"
# Create activator key + cert
openssl req -out "${out_dir}"/activator-tls.csr -newkey rsa:2048 -nodes -keyout "${out_dir}"/activator-tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:$activatorSAN"
openssl x509 -req -extfile <(printf "subjectAltName=DNS:$activatorSAN") -days 365 -in "${out_dir}"/activator-tls.csr -CA "${out_dir}"/root.crt -CAkey "${out_dir}"/root.key -CAcreateserial -out "${out_dir}"/activator-tls.crt

# Create server certs
openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") -days 365 -in "${out_dir}"/tls.csr -CA "${out_dir}"/root.crt -CAkey "${out_dir}"/root.key -CAcreateserial -out "${out_dir}"/tls.crt
# Create test service key + cert
openssl req -out "${out_dir}"/service-tls.csr -newkey rsa:2048 -nodes -keyout "${out_dir}"/service-tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:$serviceSAN"
openssl x509 -req -extfile <(printf "subjectAltName=DNS:$serviceSAN") -days 365 -in "${out_dir}"/service-tls.csr -CA "${out_dir}"/root.crt -CAkey "${out_dir}"/root.key -CAcreateserial -out "${out_dir}"/service-tls.crt

# Create secret
# TODO: drop ca-cert.pem after v1.9 released. It is used for upgrade e2e test since previous version uses the old file name.
kubectl create -n ${SERVING_SYSTEM_NAMESPACE} secret generic knative-serving-certs \
# Create activator secret for system-internal-tls
kubectl create -n ${SERVING_SYSTEM_NAMESPACE} secret generic routing-serving-certs \
--from-file=ca.crt="${out_dir}"/root.crt \
--from-file=ca-cert.pem="${out_dir}"/root.crt \
--dry-run=client -o yaml | \
sed '/^metadata:/a\ \ labels: {"networking.internal.knative.dev/certificate-uid":"test-id"}' | kubectl apply -f -

kubectl create -n ${TEST_NAMESPACE} secret tls server-certs \
--key="${out_dir}"/tls.key \
--cert="${out_dir}"/tls.crt --dry-run=client -o yaml | kubectl apply -f -
# Create test service secret for system-internal-tls
kubectl create -n ${TEST_NAMESPACE} secret tls serving-certs \
--key="${out_dir}"/service-tls.key \
--cert="${out_dir}"/service-tls.crt --dry-run=client -o yaml | kubectl apply -f -


# Create a certificate for testing kourier encryption with a static certificate
san="example.com"
openssl req -out "${out_dir}"/san-tls.csr -newkey rsa:2048 -nodes -keyout "${out_dir}"/san-tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:$san"
openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") -days 365 -in "${out_dir}"/san-tls.csr -CA "${out_dir}"/root.crt -CAkey "${out_dir}"/root.key -CAcreateserial -out "${out_dir}"/san-tls.crt

# For testing encryption with Kourier local gateway
kubectl create -n ${TEST_NAMESPACE} secret generic server-ca \
--from-file=ca.crt="${out_dir}"/root.crt

kubectl create -n ${SERVING_SYSTEM_NAMESPACE} secret tls server-certs \
--key="${out_dir}"/tls.key \
--cert="${out_dir}"/tls.crt --dry-run=client -o yaml | kubectl apply -f -
--key="${out_dir}"/san-tls.key \
--cert="${out_dir}"/san-tls.crt --dry-run=client -o yaml | kubectl apply -f -
File renamed without changes.
6 changes: 3 additions & 3 deletions test/upgrade/probe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ func TestProbe(t *testing.T) {

portName := networking.ServicePortNameHTTP1

// Set "https" to the port name when internal-encryption is enabled.
// Controller determines the internal-encryption is enabled or not by the port instead of configmap.
// Set "https" to the port name when system-internal-tls is enabled.
// Controller determines the system-internal-tls is enabled or not by the port instead of configmap.
// ConfigMap does not work during the upgrade test - issues/968.
cm, err := clients.KubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, "config-network", metav1.GetOptions{})
if err != nil {
t.Fatal("Failed to fetch configmap:", err)
}
if strings.EqualFold(cm.Data[config.InternalEncryptionKey], "true") {
if strings.EqualFold(cm.Data[config.SystemInternalTLSKey], string(config.EncryptionEnabled)) {
portName = networking.ServicePortNameHTTPS
}

Expand Down

0 comments on commit a895a08

Please sign in to comment.