Uso del APISIX Ingress Controller con AWS ACM

Xin Rong

December 30, 2022

Ecosystem

¿Por qué necesitamos AWS ACM?

Problemas causados por la gestión manual

Un certificado contiene información como el titular, el emisor y la fecha de expiración, mientras que un certificado expirado no puede usarse y debe renovarse antes de que expire. Por lo tanto, la información del certificado debe registrarse, por ejemplo, manualmente en una hoja de cálculo, para garantizar que los certificados puedan revocarse y renovarse a tiempo.

Sin embargo, a medida que hay más y más certificados, el método de gestión manual no puede gestionar los certificados de manera correcta y eficiente. La hoja de cálculo no puede enviar una notificación automática, ni automatizará la renovación del certificado cuando expire, lo que trae riesgos innecesarios.

Para evitar el riesgo de interrupción del certificado y mantener actualizaciones automáticas según nueva información y regulaciones, surge la gestión automatizada de certificados, reduciendo los riesgos de expiración de certificados y liberando la carga de los desarrolladores.

ACM gestiona los certificados automáticamente

AWS Certificate Manager (ACM) puede provisionar, gestionar, implementar y renovar fácilmente certificados SSL/TLS. Puedes emitir directamente certificados a través de ACM para proteger tus sitios web y aplicaciones en AWS o importar certificados de terceros al sistema de gestión de ACM.

Con ACM, ya no necesitas pasar por los extensos procesos manuales asociados con el uso y la gestión de certificados SSL/TLS como antes. También puedes exportar certificados de ACM firmados por AWS Private CA para usarlos en cualquier ubicación dentro de tu PKI interna. Además, está integrado con AWS Elastic Load Balancing (ELB).

acm

¿Qué problemas resuelve ACM Private CA?

Los certificados autofirmados se utilizan para implementar aplicaciones internas sin ningún CA privado dentro de una organización. Cuando estas aplicaciones intentan acceder entre sí, pueden rechazar el acceso de las demás porque sus certificados no son de confianza. Confiar ciegamente en fuentes desconocidas de aplicaciones podría traer riesgos de seguridad. En este caso, necesitamos un servicio de CA privado alojado para crear y gestionar una jerarquía de CA que garantice que todas las aplicaciones dentro de la organización sean de confianza.

ACM Private CA es un servicio alojado altamente disponible que crea y mantiene una PKI interna para tu organización, eliminando el costo del mantenimiento continuo. Las claves privadas se almacenan en Módulos de Seguridad de Hardware (HSM) alojados en AWS validados por FIPS 140-2, lo que ofrece una solución más segura para organizaciones emisoras de certificados en comparación con el CA predeterminado en Kubernetes.

pca

¿Cómo usar ACM con Kubernetes?

Hay dos configuraciones diferentes para terminar certificados TLS en Kubernetes:

Configurations

  • Terminar certificados TLS en Ingress: Cuando hay una necesidad de cifrado entre aplicaciones, necesitamos terminar TLS en el controlador de Ingress. Cada aplicación puede gestionar su certificado a través de Ingress sin interferencia entre sí. Este método es más fácil de configurar y gestionar y garantiza que la comunicación entre aplicaciones sea de confianza.
  • Terminar certificados TLS en NLB: Terminar certificados TLS a nivel de NLB es el caso de uso más común para usar certificados de confianza pública. Este método es fácil de configurar y vincular un certificado de confianza pública de ACM al NLB. El acceso a las aplicaciones dentro del clúster todavía usa HTTP sin operaciones adicionales de cifrado y descifrado.

En los siguientes ejemplos, puedes configurar APISIX Ingress directamente en Amazon EKS. Usando estos dos métodos, demostraremos cómo APISIX Ingress funciona con ACM (y ACM Private CA).

Requisitos previos

Antes de comenzar, debemos cumplir con los siguientes requisitos:

  • AWS Una cuenta de AWS y la interfaz de línea de comandos de AWS (AWS CLI)
  • Debes tener permiso para usar el rol de IAM de Amazon EKS y los roles relacionados con el servicio AWS CloudFormation, Amazon Virtual Private Cloud (Amazon VPC) y recursos relacionados. Por favor, revisa este artículo en el manual de usuario de IAM "Operaciones, recursos y claves de condición para Amazon Elastic Container Service for Kubernetes" y usa roles relacionados con el servicio. Además, este principal de seguridad de IAM debe tener adjunta la política gestionada de IAM AWSCertificateManagerPrivateCAFullAccess.
  • Instala y configura las herramientas kubectl y eksctl.

Clúster de Amazon EKS

Amazon EKS es un servicio alojado que te permite ejecutar Kubernetes en AWS y desplegar y gestionar fácilmente tus clústeres de Kubernetes. Este artículo usará la herramienta de línea de comandos eksctl para gestionar clústeres.

  • Usa la configuración predeterminada de eksctl para crear clústeres (ignora esta parte si ya tienes un clúster de EKS)
eksctl create cluster

Instalar APISIX Ingress

  1. Instala APISIX Ingress en el clúster de EKS y configúralo como tipo LoadBalancer.
helm repo add apisix https://charts.apiseven.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install apisix apisix/apisix \
  --set gateway.type=LoadBalancer \
  --set gateway.tls.enabled=true \
  --set ingress-controller.enabled=true \
  --namespace ingress-apisix \
  --create-namespace

Nota:

Asegúrate de que tu clúster pueda agregar volúmenes persistentes; consulta Amazon EKS Storage para más detalles. Si solo quieres probar este tutorial, configura --set etcd.persistence.enabled=false durante la instalación para declarar que no se usarán volúmenes persistentes.

  1. Ejecuta los siguientes comandos para verificar el estado y asegúrate de que todos los pods estén en estado Running.
$ kubectl get pods -n ingress-apisix
NAME                                         READY   STATUS    RESTARTS   AGE
apisix-78bfc58588-qspmm                      1/1     Running   0          103s
apisix-etcd-0                                1/1     Running   0          103s
apisix-etcd-1                                1/1     Running   0          103s
apisix-etcd-2                                1/1     Running   0          103s
apisix-ingress-controller-6ff56cd4b4-rktr9   1/1     Running   0          103s
  1. Verifica el estado del NLB; presta atención a PORT(S) y EXTERNAL-IP.
$ kubectl get svc apisix-gateway -n ingress-apisix
NAME             TYPE           CLUSTER-IP      EXTERNAL-IP                                                                    PORT(S)                      AGE
apisix-gateway   LoadBalancer   10.100.178.65   a6cffe9f6fc5c47b9929cb758610fc5a-2074689558.ap-northeast-1.elb.amazonaws.com   80:30851/TCP,443:32735/TCP   103s

Terminar certificados TLS en NLB

Preparar el certificado de ACM

  1. Abre la consola de ACM y solicita un certificado público de ACM para tu dominio personalizado o importa un certificado personalizado.

acm

Configurar el certificado en LoadBalancer

  1. Abre la consola de EC2 y selecciona tus load balancers -> listener -> edit

nlb-1

  1. Configura el protocolo del NLB a HTTPS, el puerto a 443, el protocolo de la instancia a HTTP y el puerto a 30851

nlb-2

  1. Adjunta el certificado TLS de ACM al NLB.

nlb-3

Asociar el dominio personalizado con el nombre del balanceador de carga

Puedes usar la consola de tu proveedor de DNS para dirigir el registro DNS de tu aplicación a la URL del NLB a través de CNAME. Por ejemplo, Route53 y configura los registros CNAME que apunten a tu NLB.

httpbin.example-test.org CNAME a6cffe9f6fc5c47b9929cb758610fc5a-2074689558.ap-northeast-1.elb.amazonaws.com

Acceder al dominio de la aplicación

curl https://httpbin.example-test.org

Terminar el certificado TLS en Ingress

Antes de comenzar este ejemplo, asegúrate de que la configuración del AWS NLB esté restaurada, como se muestra en la siguiente imagen.

nls-0

Instalar cert-manager

Cert-manager es un complemento de Kubernetes que puede gestionar y emitir automáticamente certificados TLS desde varias fuentes. Puedes usar una forma común para instalar cert-manager.

Crear ACM Private CA

  1. Abre la consola de ACM PCA, elige "Create a private CA" e instala.

pca-1

  1. Después de que el CA se haya creado con éxito y el estado sea activo. El ARN del PCA se usará con frecuencia en las secciones posteriores.

pca-2

Configurar permisos de nodo de EKS para ACM Private CA

Por defecto, no hay permiso de emisión. Para emitir un certificado desde ACM Private CA, debes agregar una política de IAM al EKS NodeInstanceRole, incluyendo el rol de servicio de iamserviceaccount.

  1. Crea el archivo pca-iam-policy.json y necesitas reemplazar ${PCA_ARN} con tu propio PCA_ARN.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "awspcaissuer",
            "Action": [
                "acm-pca:DescribeCertificateAuthority",
                "acm-pca:GetCertificate",
                "acm-pca:IssueCertificate"
            ],
            "Effect": "Allow",
            "Resource": "${PCA_ARN}"
        }
    ]
}
  1. Crea IAM y iamserviceaccount basado en pca-iam-policy.json, y necesitas reemplazar ${account_id} con tu ID de AWS.
aws iam create-policy \
    --policy-name AWSPCAIssuerIAMPolicy \
    --policy-document file://pca-iam-policy.json
# crear namespace
kubectl create namespace aws-pca-issuer
eksctl create iamserviceaccount \
    --cluster=${cluster_name} \
    --namespace=aws-pca-issuer \
    --name=aws-pca-issuer \
    --attach-policy-arn=arn:aws:iam::${account_id}:policy/AWSPCAIssuerIAMPolicy \
    --override-existing-serviceaccounts \
    --approve

Instalar aws-privateca-issuer

AWS PrivateCA Issuer sirve como un complemento de cert-manager (Emisores Externos para firmar solicitudes de certificados.

  1. Usa Helm para instalar
helm repo add awspca https://cert-manager.github.io/aws-privateca-issuer
helm repo update
helm install aws-pca-issuer awspca/aws-privateca-issuer \
    -n aws-pca-issuer \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-pca-issuer
  1. Verifica el estado
$ kubectl get pods -n aws-pca-issuer
NAME                                                   READY   STATUS    RESTARTS   AGE
aws-pca-issuer-aws-privateca-issuer-5cdd4b4687-z52n7   1/1     Running   0          20s

Crear emisor y solicitar certificado

  1. Reemplaza ${PCA_ARN} en el archivo issuer-cert.yaml con tu configuración y ejecuta el siguiente comando:
  • kubectl apply -f issuer-cert.yaml
# issuer-cert.yaml
apiVersion: awspca.cert-manager.io/v1beta1
kind: AWSPCAClusterIssuer
metadata:
  name: demo-test-root-ca
spec:
  arn: ${PCA_ARN}
---

kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
  name: nlb-lab-tls-cert
spec:
  commonName: httpbin.example-test.org # necesitas reemplazar con tu nombre de dominio personalizado
  dnsNames:
    - httpbin.example-test.org # necesitas reemplazar con tu nombre de dominio personalizado
  duration: 2160h0m0s
  issuerRef:
    group: awspca.cert-manager.io
    kind: AWSPCAClusterIssuer
    name: demo-test-root-ca
  renewBefore: 360h0m0s
  secretName: nlb-tls-app-secret
  usages:
    - server auth
    - client auth
  privateKey:
    algorithm: "RSA"
    size: 2048
  1. Ejecuta el siguiente comando para verificar que el certificado ha sido emitido y el secreto ha sido generado.
$ kubectl get cert
NAME                READY   SECRET                AGE
nlb-lab-tls-cert    True    nlb-tls-app-secret    10s
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
nlb-tls-app-secret    kubernetes.io/tls                     3      8s

Publicar y proteger la aplicación httpbin

Asegúrate de que APISIX Ingress se haya instalado correctamente. Por favor, revisa esta sección

  1. Despliega la aplicación httpbin
kubectl run httpbin --image kennethreitz/httpbin --port 80
kubectl expose pod httpbin --port 80
  1. Crea Ingress para publicar y proteger la aplicación httpbin
kubectl apply -f ingress-httpbin.yaml

```yaml
# ingress-httpbin.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin-demo-apisix
spec:
  ingressClassName: apisix
  tls:
  - hosts:
    - httpbin.example-test.org
    secretName: nlb-tls-app-secret
  rules:
  - host: httpbin.example-test.org
    http:
      paths:
      - backend:
          service:
            name: httpbin
            port:
              number: 80
        path: /
        pathType: Prefix
  1. Accede al nombre de dominio de la aplicación

Asegúrate de que tu nombre de dominio personalizado y el nombre del balanceador de carga estén asociados. Por favor, revisa esta sección

$ curl https://httpbin.example-test.org/headers --cacert acm-pca/cacert.pem
{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.example-test.org",
    "User-Agent": "curl/7.74.0",
    "X-Forwarded-Host": "httpbin.example-test.org"
  }
}

Conclusión

Este artículo demuestra el uso de APISIX Ingress con los componentes de AWS ACM y ACM Private CA a través de ejemplos prácticos e introduce dos configuraciones para terminar certificados TLS en Kubernetes: Terminar certificados TLS en NLB e Ingress. La configuración de ACM + NLB es más adecuada para certificados de confianza pública. Si hay un requisito de cifrado entre aplicaciones, ACM Private CA podría proporcionar un servicio de gestión alojado más seguro.

Esperamos que estos artículos prácticos puedan ayudar a los lectores a configurar y gestionar el tráfico TLS en sus clústeres de AWS EKS de manera más efectiva. Para más información sobre la puerta de enlace de API, visita blogs o Contáctanos.

Tags: