Ingress Gateway без термінації TLS
Завдання Захист Gateways з HTTPS описує, як налаштувати доступ до HTTP-сервісу через HTTPS шлюз входу. У цьому прикладі розглядається, як налаштувати доступ до HTTPS-сервісу через HTTPS шлюз входу, тобто налаштувати шлюз входу для пропуску SNI, замість термінації TLS на вхідних запитах.
Приклад HTTPS-сервісу, що використовується для цього завдання, є простий сервер NGINX. У наступних кроках спочатку розгортаєте сервіс NGINX у вашому кластері Kubernetes. Потім налаштовуєте шлюз для забезпечення доступу до сервісу через хост nginx.example.com
.
Перш ніж почати
Налаштуйте Istio, дотримуючись інструкцій з Посібника з встановлення.
Генерація сертифікатів та ключів для клієнта і сервера
Для цього завдання ви можете використовувати улюблений інструмент для генерації сертифікатів та ключів. Команди нижче використовують openssl:
Створіть кореневий сертифікат і приватний ключ для підпису сертифікатів для ваших сервісів:
$ mkdir example_certs $ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
Створіть сертифікат та приватний ключ для
nginx.example.com
:$ openssl req -out example_certs/nginx.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/nginx.example.com.key -subj "/CN=nginx.example.com/O=some organization" $ openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/nginx.example.com.csr -out example_certs/nginx.example.com.crt
Розгортання сервера NGINX
Створіть Kubernetes Secret для зберігання сертифіката сервера.
$ kubectl create secret tls nginx-server-certs \ --key example_certs/nginx.example.com.key \ --cert example_certs/nginx.example.com.crt
Створіть конфігураційний файл для сервера NGINX:
$ cat <<\EOF > ./nginx.conf events { } http { log_format main '$remote_addr - $remote_user [$time_local] $status ' '"$request" $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log; server { listen 443 ssl; root /usr/share/nginx/html; index index.html; server_name nginx.example.com; ssl_certificate /etc/nginx-server-certs/tls.crt; ssl_certificate_key /etc/nginx-server-certs/tls.key; } } EOF
Створіть Kubernetes ConfigMap для зберігання конфігурації сервера NGINX:
$ kubectl create configmap nginx-configmap --from-file=nginx.conf=./nginx.conf
Розгорніть сервер NGINX:
$ cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - port: 443 protocol: TCP selector: run: my-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx sidecar.istio.io/inject: "true" spec: containers: - name: my-nginx image: nginx ports: - containerPort: 443 volumeMounts: - name: nginx-config mountPath: /etc/nginx readOnly: true - name: nginx-server-certs mountPath: /etc/nginx-server-certs readOnly: true volumes: - name: nginx-config configMap: name: nginx-configmap - name: nginx-server-certs secret: secretName: nginx-server-certs EOF
Щоб перевірити, що сервер NGINX був успішно розгорнутий, надішліть запит до сервера з його sidecar-проксі без перевірки сертифіката сервера (використовуйте параметр
-k
дляcurl
). Переконайтеся, що сертифікат сервера виводиться правильно, тобтоcommon name (CN)
дорівнюєnginx.example.com
.$ kubectl exec "$(kubectl get pod -l run=my-nginx -o jsonpath={.items..metadata.name})" -c istio-proxy -- curl -sS -v -k --resolve nginx.example.com:443:127.0.0.1 https://nginx.example.com ... SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 ALPN, server accepted to use http/1.1 Server certificate: subject: CN=nginx.example.com; O=some organization start date: May 27 14:18:47 2020 GMT expire date: May 27 14:18:47 2021 GMT issuer: O=example Inc.; CN=example.com SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. > GET / HTTP/1.1 > User-Agent: curl/7.58.0 > Host: nginx.example.com ... < HTTP/1.1 200 OK < Server: nginx/1.17.10 ... <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...
Налаштуйте ingress gateway
- Визначте
Gateway
, що відкриває порт 443 з прохідним режимом TLS. Це вказує шлюзу пропускати вхідний трафік “as is”, не перериваючи TLS:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: mygateway
spec:
selector:
istio: ingressgateway # використовуємо стандартний istio ingress gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: PASSTHROUGH
hosts:
- nginx.example.com
EOF
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mygateway
spec:
gatewayClassName: istio
listeners:
- name: https
hostname: "nginx.example.com"
port: 443
protocol: TLS
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: All
EOF
- Налаштуйте маршрути для трафіку, що надходить через
Gateway
:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- nginx.example.com
gateways:
- mygateway
tls:
- match:
- port: 443
sniHosts:
- nginx.example.com
route:
- destination:
host: my-nginx
port:
number: 443
EOF
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: nginx
spec:
parentRefs:
- name: mygateway
hostnames:
- "nginx.example.com"
rules:
- backendRefs:
- name: my-nginx
port: 443
EOF
- Визначте вхідний IP і порт:
SECURE_INGRESS_PORT
та INGRESS_HOST
.Використовуйте наступні команди для встановлення змінних оточення SECURE_INGRESS_PORT
та INGRESS_HOST
:
$ kubectl wait --for=condition=programmed gtw mygateway
$ export INGRESS_HOST=$(kubectl get gtw mygateway -o jsonpath='{.status.addresses[0].value}')
$ export SECURE_INGRESS_PORT=$(kubectl get gtw mygateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')
Доступ до служби NGINX ззовні кластера. Зверніть увагу, що сервер повертає правильний сертифікат і його успішно перевірено (надруковано SSL certificate verify ok).
$ curl -v --resolve "nginx.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" --cacert example_certs/example.com.crt "https://nginx.example.com:$SECURE_INGRESS_PORT" Server certificate: subject: CN=nginx.example.com; O=some organization start date: Wed, 15 Aug 2018 07:29:07 GMT expire date: Sun, 25 Aug 2019 07:29:07 GMT issuer: O=example Inc.; CN=example.com SSL certificate verify ok. < HTTP/1.1 200 OK < Server: nginx/1.15.2 ... <html> <head> <title>Welcome to nginx!</title>
Очищення
- Видаліть конфігурацію шлюзу та маршрут:
$ kubectl delete gateway mygateway
$ kubectl delete virtualservice nginx
$ kubectl delete gtw mygateway
$ kubectl delete tlsroute nginx
Видаліть ресурси NGINX і файл конфігурації:
$ kubectl delete secret nginx-server-certs $ kubectl delete configmap nginx-configmap $ kubectl delete service my-nginx $ kubectl delete deployment my-nginx $ rm ./nginx.conf
Видаліть сертифікати та ключі:
$ rm -rf ./example_certs