Skip to content

Hybrid mTLS Ingress

Yuriy Lesyuk edited this page Sep 9, 2020 · 3 revisions

Apigee Hybrid: mTLS Ingress with Self-Signed Certificates

Status: Draft 1/2

NOTE: Prerequisites: cfssl utility is installed. How to install cfssl

mkdir -p ~/bin
curl https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o ~/bin/cfssljson
curl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o ~/bin/cfssl
sudo chmod +x ~/bin/cfssl ~/bin/cfssljson

export PATH=$PATH:~/bin

Create Certificate Authority home directory

export CA_HOME=$HYBRID_HOME/ca

mkdir $CA_HOME
cd $CA_HOME

Provide CA default configuration

?. Default key and certificate values

cat << EOT > ca.json
{
    "cn": "ca.hybrid-apigee.net",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "UK",
            "L": "London",
            "ST": "London"
        }
    ]
}
EOT

?. default expiry override

cat << EOT > cfssl.json
{
  "signing": {
    "default": {
      "expiry": "87600h",
      "usages": [
        "signing",
        "key encipherment",
        "server auth",
        "client auth"
      ]
    }
  }
}
EOT

?. generate a private CA certificate and key

cfssl gencert -initca ca.json | cfssljson -bare hybrid-demo6-ca

Generate Server and Client Certificates

?. server certificate

echo '{"cn":"mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=hybrid-demo6-ca.pem -ca-key=hybrid-demo6-ca-key.pem -config=cfssl.json \
    -hostname="mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net" - | cfssljson -bare server-demo6

?. client certificate

echo '{"cn":"client-mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -ca=hybrid-demo6-ca.pem -ca-key=hybrid-demo6-ca-key.pem -config=cfssl.json \
    -hostname="localhost,127.0.0.1" - | cfssljson -bare client-demo6

?. Verify Certificate Purpose

openssl x509 -in server-demo6.pem -text -noout -purpose

Certificate purposes:
SSL client : Yes
SSL client CA : No
SSL server : Yes
SSL server CA : No
...

?. Verify Server Certificate Validity on the day

ahr-verify-ctl cert $CA_HOME/server-demo6.pem

CHECK: certificate /home/yuriyl/apigee-hybrid/dual-dc-hybrid-110/ca/server-demo6.pem is valid today

Configure Server Key and Certificate as Kubernetes Secret

kubectl create secret generic apigee-ingressmtls-emea-cs-hybrid-demo6-test-ingressgateway-certs  \
--from-file=key=$CA_HOME/server-demo6-key.pem \
--from-file=cert=$CA_HOME/server-demo6.pem \
--from-file=cacert=$CA_HOME/hybrid-demo6-ca.pem

NOTE: If something goes wrong and you need to delete a secret, use

kubectl delete secret apigee-ingressmtls-emea-cs-hybrid-demo6-test-ingressgateway-certs

Configure mTLS Ingress

Create Gateway

?. Define gateway manifest Populate name, hosts, and port name appropriately

cat  << EOT > $HYBRID_HOME/mtls-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: apigee-ingressmtls-emea-cs-hybrid-demo6-test
 namespace: apigee
 # resourceVersion: "343073"
spec:
 selector:
   app: istio-ingressgateway
 servers:
 - hosts:
   - mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net
   port:
     name: apigee-apigee-ingressmtls-emea-cs-hybrid-demo6-test-HTTPS-443
     number: 443
     protocol: HTTPS
   tls:
     credentialName: apigee-ingressmtls-emea-cs-hybrid-demo6-test-ingressgateway-certs
     mode: MUTUAL
 - hosts:
   - mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net
   port:
     name: apigee-apigee-ingressmtls-emea-cs-hybrid-demo6-test-HTTP-80
     number: 80
     protocol: HTTP
   tls:
     httpsRedirect: true
EOT

?. Apply the gateway manifest

kubectl apply -f $HYBRID_HOME/mtls-gateway.yaml

?. Verify the gateway configuration

kubectl get gw,virtualservices,destinationrules

Create Virtual Service

?. Define Virtual Service manifest. Populate name, gateway, hosts, and routing destinations appropriately

cat  << EOT > $HYBRID_HOME/mtls-virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: apigee-ingressmtls-emea-cs-hybrid-demo6-test
 namespace: apigee
 #resourceVersion: "343074"
spec:
 gateways:
 - apigee-ingressmtls-emea-cs-hybrid-demo6-test
 hosts:
 - mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net
 http:
 - headers:
     request: {}
     response:
       remove:
       - x-apigee-user
       - x-apigee.proxy
       - x-apigee.proxy.basepath
       - x-apigee.fault-flag
       - x-apigee.fault-source
       - x-apigee.fault-code
       - x-apigee.fault-policy
       - x-apigee.fault-flow
       - x-apigee.fault-revision
       - x-apigee.fault-proxy-basepath
   match:
   - uri:
       prefix: /
   route:
   - destination:
       host: apigee-runtime-emea-cs-hybrid-demo6-test.apigee.svc.cluster.local
       subset: blue
       port:
         number: 8443
   timeout: 57s
EOT

?. Apply the virtual service manifest

kubectl apply -f $HYBRID_HOME/mtls-virtualservice.yaml

?. Verify the gateway configuration

kubectl get gw,virtualservices,destinationrules

Ping API proxy Request

Fetch IP address of the service

export MP_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

echo $MP_IP

?. Send curl request

curl https://mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net/ping -v --http1.1 --cert $CA_HOME/client-demo6.pem --key $CA_HOME/client-demo6-key.pem --cacert $CA_HOME/hybrid-demo6-ca.pem --resolve mtls-emea-cs-hybrid-demo6-test.hybrid-apigee.net:443:$MP_IP
Clone this wiki locally