Tráfico TCP
Esta tarea muestra cómo configurar la política de autorización de Istio para el tráfico TCP en un mesh 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
curlytcp-echojuntos en un namespace, por ejemplofoo. Ambos workloads se ejecutan con un proxy Envoy delante de cada uno. El workloadtcp-echoescucha 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-echosolo 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 fooVerifique que
curlse comunica correctamente contcp-echoen 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 succeededVerifique que
curlse comunica correctamente contcp-echoen el puerto 9002. Debe enviar el tráfico directamente a la IP del pod detcp-echoporque 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-policypara el workloadtcp-echoen 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"] EOFVerifique 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 succeededVerifique 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 succeededVerifique 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 rejectedActualice la política para agregar un campo solo HTTP llamado
methodspara 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"] EOFVerifique 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 rejectedVerifique 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"] EOFVerifique 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 rejectedVerifique 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 rejectedAgregue 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"] EOFVerifique que las solicitudes al puerto 9000 son denegadas. Esto ocurre porque la solicitud coincide con los
portsen 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 rejectedVerifique que las solicitudes al puerto 9001 son permitidas. Esto ocurre porque las solicitudes no coinciden con los
portsen 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