NGINX Gateway Fabric – IP Access Control

이번 포스트에서는 NGINX Gateway Fabric(NGF)를 활용하여 Kubernetes Gateway API 환경에서 IP 기반 접근 제어(IP Access Control)를 구현하는 방법을 소개합니다.

NGINX Gateway Fabric은 Gateway API를 기반으로 한 고성능 게이트웨이 솔루션으로, 기본 기능 외에 SnippetsFilter API를 통해 NGINX 구성 스니펫을 삽입할 수 있습니다. 이를 이용하면 IP 화이트리스트(allow/deny)를 쉽게 적용하여 보안을 강화할 수 있습니다. 특히, SnippetsFilter는 고급 NGINX 사용자에게 유용하지만, 복잡성과 보안 위험을 고려해야 합니다. 또한, NGINX Plus 대시보드 접근을 위한 NginxProxy 리소스를 통해 IP 제어를 설정하는 방법도 함께 설명하겠습니다.

목차

1. NGINX Gateway Fabric – NginxProxy와 SnippetsFilter API 개요
2. NGINX Gateway Fabric – NginxProxy

2-1. NGINX Gateway Fabric – NginxProxy로 NGINX Plus ACL
3. NGINX Gateway Fabric – SnippetsFilter

3-1. NGINX Gateway Fabric – SnippetsFilter의 단점
3-2. NGINX Gateway Fabric – SnippetsFilter 베스트 프랙티스
4. IP Access Control 구성 예시

4-1. Gateway 및 HTTPRoute 설정
4-2. 테스트 방법
5. 결론

1. NGINX Gateway Fabric – NginxProxy와 SnippetsFilter API 개요

SnippetsFilter는 NGINX Gateway Fabric에서 생성된 NGINX 구성에 사용자 정의 NGINX 스니펫을 삽입할 수 있는 기능입니다. 이를 통해 기본 Gateway API나 NGINX 확장 정책으로 커버되지 않는 고급 설정을 구현할 수 있습니다.

SnippetsFilter는 HTTPRouteFilter 또는 GRPCRouteFilter로 동작하며, HTTPRoute/GRPCRoute 규칙에 정의되어 해당 라우트에만 적용됩니다. 스니펫은 NGINX 컨텍스트(예: http, server, location, main)별로 삽입 가능하며, rate limiting 같은 기능을 구현할 때 유용합니다.

그러나 SnippetsFilter는 기본적으로 비활성화되어 있으며, 고급 NGINX 사용자만 사용하는 것을 권장합니다. Gateway API 리소스나 기존 NGINX 확장 정책으로 대체 가능한 경우 우선 사용하세요.

또한, NGINX Plus 대시보드는 실시간 메트릭을 제공하는 강력한 모니터링 도구로, 포트 8765에서 접근 가능합니다. 대시보드 접근을 IP로 제한하려면 NginxProxy 리소스를 사용하세요. 이 리소스는 allowedAddresses를 통해 IP 또는 CIDR 기반 접근을 제어합니다.

apiVersion: gateway.nginx.org/v1alpha1
kind: NginxProxy
metadata:
   name: ngf-proxy-config
spec:
   nginxPlus:
      allowedAddresses:
         - type: IPAddress
           value: 192.0.2.8
         - type: IPAddress
           value: 192.0.2.0
         - type: CIDR
           value: 198.51.100.0/24

대시보드에 접근하려면 포트 포워딩을 사용하세요:

kubectl port-forward <nginx-plus-pod> 8765:8765 -n <namespace>

브라우저에서 http://127.0.0.1:8765/dashboard.html에 접속하면 대시보드가 나타납니다.

2. NGINX Gateway Fabric – NginxProxy

2-1. NGINX Gateway Fabric – NginxProxy로 NGINX Plus ACL

위에서 언급한 것처럼, NGINX Plus의 내장 기능인 NGINX Plus Dashboard와 RESTful API에 대한 IP ACL을 NginxProxy crd에서 구현할 수 있습니다.

만약 위의 예시처럼 port-forward가 아닌 상시로 port를 열어두려면 Gateway 리소스를 아래와 같이 수정합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ho-ngf-gateway
  namespace: ho-ngf
spec:
  gatewayClassName: nginx
  infrastructure:
    parametersRef:
      group: gateway.nginx.org
      kind: NginxProxy
      name: ngf-proxy-nodeport-config  # 참조할 NginxProxy 이름 
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: "hocp-ngf.devopsshin.com"
  - name: nginxplus
    port: 8765
    protocol: TCP

Gateway 리소스에서 참조할 NginxProxy crd를 작성합니다. 구현할 환경은 NodePort로 배포되어 있기 때문에 자신의 환경에 맞도록 수정해야 합니다. 여기서 핵심은 spec.nginxPlus.allowedAddresses 이며 NGINX Plus의 Dashboard, API에 대한 접근을 허용할 IPaddress와 CIDR을 설정할 수 있습니다.

apiVersion: gateway.nginx.org/v1alpha2
kind: NginxProxy
metadata:
  annotations:
    meta.helm.sh/release-name: ngf
    meta.helm.sh/release-namespace: nginx-gateway
  generation: 1
  labels:
    app.kubernetes.io/instance: ngf
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: nginx-gateway-fabric
    app.kubernetes.io/version: 2.3.0
    helm.sh/chart: nginx-gateway-fabric-2.3.0
  name: ngf-proxy-nodeport-config
  namespace: ho-ngf
spec:
  ipFamily: dual
  kubernetes:
    deployment:
      container:
        image:
          pullPolicy: IfNotPresent
          repository: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus
          tag: 2.3.0
      replicas: 1
    service:
      externalTrafficPolicy: Local
      type: NodePort
  nginxPlus:
    allowedAddresses:
      - type: IPAddress
        value: "192.168.40.101"
      - type: IPAddress
        value: "192.168.200.106"
#      - type: CIDR
#        value: "0.0.0.0/0"

그렇게 NginxProxy와 Gateway 리소스를 배포한 뒤, NGINX Gateway Fabric이 배포된 Node IP:Port 로 접근하여 NGINX Plus dashboard, API를 사용할 수 있습니다.

NginxProxy 구성에 정의된 허용된 IP 대역에서 접근시:

허용되지 않은 IP에서 접근 시 403 Forbidden이 발생합니다.

NginxProxy에서 구성한 spec.nginxPlus.allowedAddresses는 전체 서비스에 대한 IP access control이 아닌 NGINX Plus의 dashboard, RESTful API에 대한 access control입니다.

서비스에 대한 IP Access Control은 아래 SnippetsFilter를 참고하세요.

3. NGINX Gateway Fabric – SnippetsFilter

3-1. NGINX Gateway Fabric – SnippetsFilter의 단점

  • 복잡성: 올바른 NGINX 구문을 작성해야 하며, Fabric이 생성한 구성과 충돌하지 않도록 이해 필요.
  • 안정성 저하: 잘못된 스니펫으로 인해 NGINX 리로드 실패 가능. 문제가 해결될 때까지 모든 구성 업데이트가 차단됨.
  • 보안 문제: NGINX 원시 설정에 접근하므로, TLS 키/인증서 같은 민감 정보가 노출될 위험이 있음. Fabric에서 검증되지 않음.

잘못된 스니펫이 포함되면 NGINX는 마지막 유효 구성으로 동작하며, 새 구성 적용이 지연됩니다.

3-2. NGINX Gateway Fabric – SnippetsFilter 베스트 프랙티스

  • 접근 제한: Gateway API의 Roles/Personas에 따라 클러스터 운영자(Cluster Operator)만 SnippetsFilter 생성/수정. 애플리케이션 개발자는 참조만 가능.
  • 중복 방지: 하나의 SnippetsFilter당 컨텍스트별 스니펫 1개만. 여러 SnippetsFilter 참조 시 충돌 피하기.
  • 영향 범위 주의: main/http/http.server 컨텍스트 스니펫은 전체 라우트에 영향. 프로덕션 적용 전 테스트 필수.
  • 책임 분리: 운영자는 SnippetsFilter 생성, 개발자는 HTTPRoute에서 참조 → 역할 분담.

4. IP Access Control 구성 예시

아래는 SnippetsFilter를 활용하여 IP 기반 접근 제어를 구현한 예시입니다. 두 가지 SnippetsFilter를 사용합니다: 하나는 map으로 IP 허용 로직 정의, 다른 하나는 allow/deny 직접 지정.

map 지시문을 사용한 IP ACL:

apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
  name: ip-acl-2
  namespace: ho-ngf
spec:
  snippets:
    - context: http
      value: |
              map $remote_addr $allowed_ip {
                default         0;
                192.168.40.101  1;
                192.168.200.106   1;
                127.0.0.1       1;
              }
    - context: http.server
      value: |
              if ($allowed_ip = 0) {
                return 403;
              }

Allow & Deny를 사용한 IP ACL:

apiVersion: gateway.nginx.org/v1alpha1
kind: SnippetsFilter
metadata:
  name: ip-acl-1
  namespace: ho-ngf
spec:
  snippets:
    - context: http
      value: |
            allow 192.168.40.101;
            allow 192.168.201.0/24;
            allow 192.168.200.0/24;
            deny all;

4-1. Gateway 및 HTTPRoute 설정

SnippetsFilter를 HTTPRoute에 참조하여 적용합니다. 아래는 전체 Gateway와 HTTPRoute 구성입니다.

Gateway:

[root@localhost ocp]# cat gateway/ho-ngf.yaml httproute/ho-ngf.yaml 
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: ho-ngf-gateway
  namespace: ho-ngf
spec:
  gatewayClassName: nginx
  infrastructure:
    parametersRef:
      group: gateway.nginx.org
      kind: NginxProxy
      name: ngf-proxy-nodeport-config  # 참조할 NginxProxy 이름 
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: "hocp-ngf.devopsshin.com"

HTTPRoute:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: ho-ngf-httproute
  namespace: ho-ngf
spec:
  parentRefs:
  - name: ho-ngf-gateway
    sectionName: http
  hostnames:
  - "hocp-ngf.devopsshin.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    filters:
      - type: ExtensionRef
        extensionRef:
          group: gateway.nginx.org
          kind: SnippetsFilter
          name: ip-acl
    backendRefs:
    - name: nginx-example-1
      port: 80

HTTPRoute의 filters에서 SnippetsFilter를 참조하면 해당 라우트에 IP 제어가 적용됩니다.

4-2. 테스트 방법

허용된 IP에서 접근 테스트:

curl -H "Host: hocp-ngf.devopsshin.com" http://<GATEWAY_IP>/  # 성공 시 200 OK

차단된 IP에서 접근 테스트:

curl -H "Host: hocp-ngf.devopsshin.com" http://<GATEWAY_IP>/  # 403 Forbidden

로그 확인(kubectl logs -n ho-ngf <ngf-pod> -c nginx): IP, 상태 코드, 요청 시간 등을 확인하세요.

5. 결론

NGINX Gateway Fabric의 SnippetsFilter를 통해 IP Access Control을 구현하면 Gateway API 환경에서 유연한 보안 정책을 적용할 수 있습니다. 그러나 복잡성과 위험을 고려해 기본 Gateway 기능 우선 사용을 권장합니다.

SnippetsFilter는 클러스터 운영자만 접근하도록 하고, 프로덕션 적용 전 테스트를 철저히 하세요. 더 궁금한 점이 있으시면 문의 주세요!

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required