Summary

K3s 환경을 구축할 때 내부망으로만 서비스를 접속하고 싶을 때 Internal-Only MiddleWare를 적용하는 방법을 기록했습니다.

Why

특정 애플리케이션은 보안을 위해 내부망에서만 접근하고 싶을 수 있습니다. 저에게는 Shlink의 GUI 웹이나 Syncthing의 GUI 웹, CloudBeaver 처럼 불특정 다수가 사용하길 원치 않는 서비스의 경우입니다. 이럴 때 특정 IP를 WhiteList로 설정하여 내부망, 특정 IP에서만 접근할 수 있도록 Internal-Only MiddleWare를 적용할 수 있습니다.

How

yaml

internal-only.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: internal-only
  namespace: <name-space>
spec:
  ipAllowList:
    sourceRange:
      - "127.0.0.1/32"        # 로컬호스트
      - "192.168.0.0/16"      # 일반적인 내부망 대역
      - "100.68.21.100/32"    # Tailscale VPN
  • kubectl apply -f internal-only.yaml

Caution

NameSpace 별로 생성해주는 것이 사용하기 편합니다.

Danger

MiddleWare 기능은 K3s 번들 Traefik 을 비활성화하고 최신 Traefik을 설치해야 사용 가능합니다.

적용

cloudbeaver-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cloudbeaver-ingress
  namespace: core-infra
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-cloudflare"
+   traefik.ingress.kubernetes.io/router.middlewares: "core-infra-internal-only@kubernetescrd"
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - beaver.junbeom.work    # 사용할 서브도메인 (필요시 cloudbeaver.junbeom.work 등으로 수정)
      secretName: cloudbeaver-tls-secret
  rules:
    - host: beaver.junbeom.work
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cloudbeaver-svc
                port:
                  number: 80

예시로 CloudBeaveryamlIngress 부분을 가지고 왔습니다. + 표시가 된 줄을 입력하면 CloudBeaver의 도메인인 beaver.junbeom.work로 접속 시 해당 MiddleWare의 규칙에 따라 접속이 제한됩니다.

Danger

만약 CloudFlare 등의 서비스로 Proxy 기능을 사용하고 있다면 해당 도메인의 Proxy는 비활성화 해야 합니다. 왜냐하면 Proxy 기능으로 인해 요청으로 들어오는 IP 주소가 바뀌어서 내부망에서 접근을 해도 접근 제한됩니다.

Success

핸드폰에서 LTE로 접근할 때 Forbidden이 뜨는 것을 볼 수 있습니다.