LoginSignup
9
5

More than 5 years have passed since last update.

Azure Kubernetes ServiceのNGINX Ingress Controllerでアクセス元IPアドレスを制限する

Posted at

公式の以下手順で、Let's Encryptを使ったTLS証明書付きのIngress Controllerを作成しました。
Azure Kubernetes Service (AKS) の静的パブリック IP アドレスを使用してイングレス コントローラーを作成する

バックエンドのWebサーバコンテナにインターネットからアクセスする際に、アクセス元IPアドレスを絞りたいと思ったのですが、中々うまくいかずハマったので手順残します。

自分で作ったvNetにデプロイしたAKSを使っています。

Ingress Controller作成

  • Ingress Controllerを作成します。ここがポイントで、「--set controller.service.externalTrafficPolicy=Local」を付与しないと、Ingress Controllerが受信するアクセス元のソースIPが、グローバルアドレスではなくvNetのIPになってしまいうまくIP制御できません。
helm install stable/nginx-ingress \
    --namespace [Your Namespace] \
    --set controller.service.loadBalancerIP="[Public IP]"  \
    --set controller.replicaCount=2
    --set controller.service.externalTrafficPolicy=Local

DNS名を構成する

  • ここは公式通りです。以下のShellを作成して実行します。
#!/bin/bash

# Public IP address of your ingress controller
IP="[Public IP]"

# Name to associate with public IP address
DNSNAME="[Your DNS Name]"

# Get the resource-id of the public ip
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)

# Update public ip address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSNAME

cert-manager をインストールする

  • ここは公式通りです。kube-systemネームスペースに作ります。
helm install stable/cert-manager \
  --namespace kube-system \
  --set ingressShim.defaultIssuerName=letsencrypt-prod \
  --set ingressShim.defaultIssuerKind=ClusterIssuer

CAクラスター発行者を作成する

  • ここは公式通りです。yamlを作ってapplyします。kube-systemネームスペースに作ります。
cluster-issuer.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: user@contoso.com
    privateKeySecretRef:
      name: letsencrypt-prod
    http01: {}
kubectl apply -f cluster-issuer.yaml -n kube-system

証明書オブジェクトを作成する

  • ここは公式通りです。yamlを作ってapplyします。
certificates.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: tls-secret
spec:
  secretName: tls-secret
  dnsNames:
  - [Your DNS Name].japaneast.cloudapp.azure.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - [Your DNS Name].japaneast.cloudapp.azure.com
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
kubectl apply -f certificates.yaml -n [Your Namespace]

アプリケーションを実行する

  • バックエンドのWebアプリケーションを実行します。公式手順にあるデモアプリケーションでもよいです。

Ingressルートを作成する

  • Ingressルートを作成する際のマニフェストで、アノテーション「nginx.ingress.kubernetes.io/whitelist-source-range」を付与して作成します。
application.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/whitelist-source-range: xxx.xxx.xxx.xxx/32,yyy.yyy.yyy.yyy/32
spec:
  tls:
  - hosts:
    - [Your DNS Name].japaneast.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: [Your DNS Name].japaneast.cloudapp.azure.com
    http:
      paths:
      - path: /
        backend:
          serviceName: aks-helloworld
          servicePort: 80
      - path: /hello-world-two
        backend:
          serviceName: ingress-demo
          servicePort: 80
kubectl apply -f application.yaml -n [Your Namespace]

テスト

https://[Your DNS Name].japaneast.cloudapp.azure.com にアクセスして、TLS証明書とIPアドレス制御が動作していることを確認します。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5