Descripción general de la política de autorización
A diferencia de una aplicación monolítica que podría ejecutarse en un solo lugar, las apps de microservicios distribuidas en todo el mundo realizan llamadas a través de los límites de red. Esto significa que habrá más puntos de entrada a tus aplicaciones y más oportunidades de ataques maliciosos. Debido a que los Pods de Kubernetes tienen IP transitorias, las reglas de firewall tradicionales basadas en IP no son adecuadas para proteger el acceso entre las cargas de trabajo. En una arquitectura de microservicios, se necesita un nuevo enfoque para la seguridad. Basándose en funciones de seguridad como las cuentas de servicio de Kubernetes y las políticas de seguridad de Istio, Cloud Service Mesh proporciona aún más capacidades que te ayudarán a proteger tus aplicaciones.
En esta página, se proporciona a los operadores de aplicaciones una descripción general del recurso personalizado (CR) de AuthorizationPolicy
. Las políticas de autorización te permiten habilitar el control de acceso en las cargas de trabajo en las capas de la aplicación (L7) y de transporte (L3/4). Configura políticas de autorización para especificar permisos: ¿qué puede hacer este servicio o usuario?
Políticas de autorización
Las solicitudes entre servicios de tu malla (y entre usuarios finales y servicios) se permiten de forma predeterminada. Usa el CR AuthorizationPolicy
a fin de definir políticas detalladas para tus cargas de trabajo. Después de aplicar las políticas de autorización, Cloud Service Mesh las distribuye a los proxies de sidecar. A medida que se ingresan las solicitudes, el proxy de sidecar verifica las políticas de autorización para determinar si se debe permitir o rechazar la solicitud.
Consulta Funciones compatibles para obtener detalles sobre los campos de la CR de AuthorizationPolicy
que son compatibles con la plataforma.
Alcance de la política
Puedes aplicar una política a toda la malla de servicios, a un espacio de nombres o a una carga de trabajo individual.
Para aplicar una política en toda la malla, especifica el espacio de nombres raíz,
istio-system
, en el campometadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...
Para aplicar una política a un espacio de nombres, especifica el espacio de nombres en el campo
metadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...
Para restringir una política a una carga de trabajo específica, incluye un campo
selector
.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
Estructura básica
Una política de autorización incluye el alcance de la política, un action
y una lista de rules
:
Como se describió en la sección anterior, el alcance de la política puede ser la malla completa, un espacio de nombres o una carga de trabajo específica. Si lo incluyes, el campo
selector
especifica el destino de la política.El campo
action
especifica si se debeALLOW
oDENY
la solicitud. Si no especificas una acción, la acción se establecerá de forma predeterminada enALLOW
. Para mayor claridad, te recomendamos que siempre especifiques la acción. (Las políticas de autorización también admiten accionesAUDIT
yCUSTOM
). La acciónAUDIT
solo es compatible con algunas plataformas. Consulta Funciones compatibles para obtener más información.Las
rules
especifican cuándo activar la acción.El campo
from
enrules
especifica las fuentes de la solicitud.El campo
to
enrules
especifica las operaciones de la solicitud.El campo
when
especifica condiciones adicionales necesarias para aplicar la regla.
En el siguiente ejemplo:
La política se aplica a las solicitudes al servicio
frontend
en el espacio de nombresdemo
.Las solicitudes se permiten cuando “hello:world” está en el encabezado de la solicitud; de lo contrario, se rechazan las solicitudes.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
Control de acceso a la operación de solicitud
Puedes controlar el acceso a operaciones de solicitud específicas, como métodos HTTP o puertos TCP, si agregas una sección to
en rules
.
En el siguiente ejemplo, solo los métodos HTTP GET
y POST
se permiten a currencyservice
en el espacio de nombres demo
.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
Control de acceso en la identidad autenticada
En los ejemplos anteriores, las políticas permiten solicitudes de cargas de trabajo no autenticadas. Si tienes habilitada la TLS mutua STRICT
(mTLS), puedes restringir el acceso en función de la identidad de la carga de trabajo o el espacio de nombres al que pertenece la solicitud en la sección source
.
Usa el campo
principals
onotPrincipal
para controlar el acceso a nivel de la carga de trabajo.Usa el campo
namespaces
onotNamespaces
para controlar el acceso a nivel del espacio de nombres.
Todos los campos anteriores requieren que tengas habilitado mTLS STRICT
. Si no puedes configurar STRICT
mTLS, consulta Rechaza solicitudes de texto simple para obtener una solución alternativa.
Carga de trabajo identificada
En el siguiente ejemplo, las solicitudes a currencyservice
solo se permiten desde el servicio frontend
. Se rechazan las solicitudes a currencyservice
desde otras cargas de trabajo.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
Para especificar una cuenta de servicio, el principals
debe tener el siguiente formato:
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
Si usas Cloud Service Mesh en el clúster con la AC de Citadel, entonces
cluster.local
es el dominio de confianza. En todos los demás casos, PROJECT_ID.svc.id.goog
es el dominio de confianza de la malla.
Espacio de nombres identificado
En el siguiente ejemplo, se muestra una política que rechaza solicitudes si la fuente no es el espacio de nombres foo
:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
Coincidencia de valores
La mayoría de los campos de las políticas de autorización son compatibles con los siguientes esquemas de coincidencia:
- Coincidencia exacta: coincidencia exacta de strings.
- Coincidencia de comodines mediante el carácter comodín
"*"
:- Coincidencia de prefijo: una string con un
"*"
final. Por ejemplo,"test.example.*"
coincide con"test.example.com"
o"test.example.com.cn"
. - Coincidencia de sufijo: una string con un
"*"
inicial. Por ejemplo,"*.example.com"
coincide con"eng.example.com"
o"test.eng.example.com"
.
- Coincidencia de prefijo: una string con un
- Coincidencia de presencia: para especificar que un campo debe estar presente y no vacío, usa el formato
fieldname: ["*"]
. Esto es diferente a dejar un campo sin especificar, lo que significa que coincide con todo, incluido el vacío.
Existen algunas excepciones. Por ejemplo, los siguientes campos solo admiten coincidencia exacta:
- El campo
key
en la secciónwhen
- Los
ipBlocks
en la secciónsource
- El campo
ports
en la secciónto
La siguiente política de ejemplo permite el acceso a las rutas de acceso con el prefijo /test/*
o el sufijo */info
:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
Coincidencia de exclusión
Para hacer coincidir condiciones negativas como notValues
en el campo when
, notIpBlocks
en el campo source
, notPorts
en el campo to
, Cloud Service Mesh admite la coincidencia de exclusión. En el siguiente ejemplo, se requiere una solicitud válida principals
, que se deriva de la autenticación JWT, si la ruta de la solicitud no es /healthz
. Por lo tanto, la política excluye las solicitudes a la ruta de acceso /healthz
de la autenticación de JWT:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
Rechazo de solicitudes de texto sin formato
En Cloud Service Mesh, la mTLS automática está habilitada de forma predeterminada. Con la mTLS automática, un proxy de sidecar de cliente detecta automáticamente si el servidor tiene un sidecar. El sidecar del cliente envía mTLS a las cargas de trabajo con sidecars y envía texto sin formato a las cargas de trabajo sin sidecars. Para obtener la mejor seguridad, te recomendamos que habilites STRICT de mTLS.
Si no puedes habilitar mTLS con el modo STRICT
para una carga de trabajo o un espacio de nombres, puedes hacer lo siguiente:
- crear una política de autorización a fin de permitir el tráfico de forma explícita con
namespaces
oprincipals
no vacíos, o - rechazar el tráfico con
namespaces
oprincipals
vacíos.
Debido a que namespaces
y principals
solo se pueden extraer con una solicitud mTLS, estas políticas rechazan de manera efectiva el tráfico de texto simple.
La siguiente política rechaza la solicitud si el principal de la solicitud está vacío (como es el caso de las solicitudes de texto simple). La política permite las solicitudes si la principal no está vacía. El ["*"]
significa una coincidencia no vacía y el uso con notPrincipals
significa la coincidencia con el principal vacío.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
Prioridad de la política de autorización
Puedes configurar políticas de autorización de ALLOW
y DENY
independientes, pero debes comprender la prioridad de la política y el comportamiento predeterminado para asegurarte de que las políticas hagan lo que deseas. En el siguiente diagrama, se describe la prioridad de la política.
En las políticas de ejemplo de las siguientes secciones, se ilustran algunos de los comportamientos predeterminados y las situaciones en las que pueden resultarte útiles.
No permitir nada
En el siguiente ejemplo, se muestra una política ALLOW
que no coincide con nada. De forma predeterminada, si no hay otras políticas ALLOW
, las solicitudes siempre se deniegan.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
Se recomienda comenzar con la política No permitir nada y, luego, agregar más políticas ALLOW
a fin de abrir más acceso a una carga de trabajo.
Rechaza todo el acceso
En el siguiente ejemplo, se muestra una política DENY
que coincide con todo. Debido a que las políticas DENY
se evalúan antes que las políticas ALLOW
, todas las solicitudes se rechazan, incluso si hay una política ALLOW
que coincida con la solicitud.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
Una política de rechazo total es útil si deseas inhabilitar de forma temporal todo el acceso a una carga de trabajo.
Permite todo el acceso
En el siguiente ejemplo, se muestra una política ALLOW
que coincide con todo y permite el acceso completo a una carga de trabajo. La política Permitir todo hace que las otras políticas ALLOW
no sean útiles porque siempre permite la solicitud.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
Una política de permiso completo es útil si deseas exponer de forma temporal el acceso completo a una carga de trabajo. Si hay políticas de DENY
, las solicitudes se podrían rechazar, ya que las políticas de DENY
se evalúan antes que las políticas de ALLOW
.
Prácticas recomendadas
Crea una cuenta de servicio de Kubernetes para cada servicio y especifica la cuenta de servicio en el Deployment. Por ejemplo:
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...
Comienza con una política No permitir nada y agrega de forma incremental más políticas
ALLOW
a fin de obtener más acceso a las cargas de trabajo.Si usas JWT para tu servicio, haz lo siguiente:
Crea una política
DENY
para bloquear las solicitudes no autenticadas, por ejemplo:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
Aplica una política No permitir nada.
Define las políticas
ALLOW
para cada carga de trabajo. Para ver ejemplos, consulta Token JWT.
¿Qué sigue?
Obtén más información sobre las funciones de seguridad de Cloud Service Mesh:
- Configura la autenticación de usuarios de Cloud Service Mesh
- Configura políticas de auditoría para tus servicios
- Configura la seguridad del transporte
- Integra Identity-Aware Proxy en Cloud Service Mesh
- Prácticas recomendadas para usar las puertas de enlace de salida de Cloud Service Mesh en los clústeres de GKE
Obtén más información sobre las políticas de autorización en la documentación de Istio:
- Ejemplos de políticas de autorización
- Solución de problemas relacionados con la política de autorización