Tráfico TCP
Esta tarea muestra cómo configurar la política de autorización de Istio para el tráfico TCP en una malla de Istio.
Antes de empezar
Antes de comenzar esta tarea, haga lo siguiente:
Lea los conceptos de autorización de Istio.
Instale Istio utilizando la guía de instalación de Istio.
Despliegue dos workloads llamados
curl
ytcp-echo
juntos en un namespace, por ejemplofoo
. Ambos workloads se ejecutan con un proxy Envoy delante de cada uno. El workloadtcp-echo
escucha en los puertos 9000, 9001 y 9002 y devuelve cualquier tráfico recibido con el prefijohello
. Por ejemplo, si envía “world” atcp-echo
, responderá conhello world
. El objeto service de Kubernetestcp-echo
solo declara los puertos 9000 y 9001, y omite el puerto 9002. Una cadena de filtro de paso directo manejará el tráfico del puerto 9002. Despliegue el namespace y los workloads de ejemplo utilizando el siguiente comando:$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/tcp-echo/tcp-echo.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo
Verifique que
curl
se comunica correctamente contcp-echo
en los puertos 9000 y 9001 utilizando el siguiente comando:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Verifique que
curl
se comunica correctamente contcp-echo
en el puerto 9002. Debe enviar el tráfico directamente a la IP del pod detcp-echo
porque el puerto 9002 no está definido explícitamente en el objeto service de Kubernetes detcp-echo
. Obtenga la dirección IP del pod y envíe la solicitud con el siguiente comando:$ TCP_ECHO_IP=$(kubectl get pod "$(kubectl get pod -l app=tcp-echo -n foo -o jsonpath={.items..metadata.name})" -n foo -o jsonpath="{.status.podIP}") $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9002 connection succeeded
Configurar la política de autorización ALLOW para un workload TCP
Cree la política de autorización
tcp-policy
para el workloadtcp-echo
en el namespacefoo
. Ejecute el siguiente comando para aplicar la política para permitir solicitudes a los puertos 9000 y 9001:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: ports: ["9000", "9001"] EOF
Verifique que las solicitudes al puerto 9000 son permitidas utilizando el siguiente comando:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded
Verifique que las solicitudes al puerto 9001 son permitidas utilizando el siguiente comando:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Verifique que las solicitudes al puerto 9002 son denegadas. Esto es aplicado por la autorización política que también se aplica a la cadena de filtro de paso directo, incluso si el puerto no está declarado explícitamente en el objeto service de Kubernetes
tcp-echo
. Ejecute el siguiente comando y verifique la salida:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Actualice la política para agregar un campo solo HTTP llamado
methods
para el puerto 9000 utilizando el siguiente comando:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
Verifique que las solicitudes al puerto 9000 son denegadas. Esto ocurre porque la regla se vuelve inválida cuando utiliza un campo solo HTTP (
methods
) para el tráfico TCP. Istio ignora la regla ALLOW inválida. El resultado final es que la solicitud es rechazada, porque no coincide con ninguna regla ALLOW. Ejecute el siguiente comando y verifique la salida:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Verifique que las solicitudes al puerto 9001 son denegadas. Esto ocurre porque las solicitudes no coinciden con ninguna regla ALLOW. Ejecute el siguiente comando y verifique la salida:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Configurar la política de autorización DENY para un workload TCP
Agregue una política DENY con campos solo HTTP utilizando el siguiente comando:
$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] EOF
Verifique que las solicitudes al puerto 9000 son denegadas. Esto ocurre porque Istio no entiende los campos solo HTTP al crear una regla DENY para el puerto tcp y debido a su naturaleza restrictiva deniega todo el tráfico a los puertos tcp:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Verifique que las solicitudes al puerto 9001 son denegadas. Misma razón que la anterior.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Agregue una política DENY con campos TCP y HTTP utilizando el siguiente comando:
$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
Verifique que las solicitudes al puerto 9000 son denegadas. Esto ocurre porque la solicitud coincide con los
ports
en la política de denegación mencionada anteriormente.$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Verifique que las solicitudes al puerto 9001 son permitidas. Esto ocurre porque las solicitudes no coinciden con los
ports
en la política DENY:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Limpieza
Elimine el namespace foo:
$ kubectl delete namespace foo