Traefik TLS 옵션
Traefik TLS 옵션 (TLS Options)
본문
TLS Options
TLS 옵션은 TLS 연결의 일부 파라미터를 구성할 수 있게 해 줘요.
'default' TLS 옵션
default 옵션은 특별해요. tls 라우터에 TLS 옵션이 지정되지 않으면 default 옵션이 사용돼요. default 옵션에는 provider namespace가 없으므로 명시적으로 지정할 때는 provider namespace를 지정하지 않도록 주의하세요. 반대로 교차 provider 참조의 경우, 예를 들어 docker 라벨에서 file provider를 참조할 때는 provider namespace를 지정해야 해요, 예: traefik.http.routers.myrouter.tls.options=myoptions@file.
Providers
TLS 옵션은 라벨 또는 태그 기반 provider에서 지원되지 않아요. 다만 KV provider를 사용할 때는 정의할 수 있어요.
Kubernetes의 TLSOption
TLSOption 리소스를 사용하면 default라는 이름의 옵션이 명시적으로 TLSOption을 참조하지 않는 모든 라우터에 적용돼요. defaultTLSResourcesNamespace provider 옵션은 이 클러스터 전역 기본값이 정의될 수 있는 네임스페이스를 제한해요.
Server Name Association (서버 이름 연결)
TLS 옵션은 라우터에 구성되지만, 실제 적용은 라우팅이 일어나기 전의 TLS 핸드셰이크 중에, 서버 이름(SNI)이 유일하게 사용 가능한 정보일 때 이뤄져요. 따라서 TLS 옵션 참조는 항상 라우터 규칙의 Host 부분에 있는 호스트 이름에 매핑되며, 라우터나 그 규칙에는 매핑되지 않아요. 규칙에 Host 부분이 여러 개 있을 수도 있는데, 이 경우 TLS 옵션 참조는 그만큼의 호스트 이름에 매핑돼요.
도메인 프론팅(domain fronting)의 경우, Host 헤더와 연결된 TLS 옵션과 SNI가 다르면 Traefik은 421 Misdirected Request 상태 코드로 응답해요.
Conflicting TLS Options (TLS 옵션 충돌)
TLS 옵션 참조는 호스트 이름에 매핑되므로, 아래 예시처럼 같은 엔트리포인트에서 같은 호스트 이름이 서로 다른 두 TLS 옵션 참조와 매칭되는 상황이 발생하면 충돌이 일어나요:
Structured (YAML)
# Dynamic configuration
http:
routers:
routerfoo:
rule: "Host(`example.com`) && Path(`/foo`)"
tls:
options: foo
routerbar:
rule: "Host(`example.com`) && Path(`/bar`)"
tls:
options: bar
Structured (TOML)
# Dynamic configuration
[http.routers]
[http.routers.routerfoo]
rule = "Host(`example.com`) && Path(`/foo`)"
[http.routers.routerfoo.tls]
options = "foo"
[http.routers.routerbar]
rule = "Host(`example.com`) && Path(`/bar`)"
[http.routers.routerbar.tls]
options = "bar"
이런 경우 두 매핑은 모두 폐기되고, 호스트 이름(이 예시에서는 example.com)은 대신 default TLS 옵션과 연결돼요.
충돌 감지는 단일 provider에 국한되지 않아요: 서로 다른 provider에서 온 라우터, 예를 들어 컨테이너 라벨로 정의된 라우터와 file provider로 정의된 라우터도, 같은 엔트리포인트에서 같은 호스트 이름을 제공하는 순간 서로 충돌해요.
기본 TLS 옵션
default TLS 옵션은 충돌 해결의 폴백이므로, 교체될 수 있는 옵션보다 덜 안전해서는 안 돼요. 예를 들어 상호 TLS 인증(clientAuth)에 의존하는 라우터는, 호스트 이름 충돌로 인해 그것을 요구하지 않는 default TLS 옵션으로 폴백하면 더 이상 인증을 강제하지 않게 돼요.
이를 피하는 가장 확실한 방법은 같은 엔트리포인트에서 같은 호스트 이름을 제공하는 모든 라우터가 동일한 TLS 옵션을 참조하게 하는 거예요.
Strict TLS Options (엄격한 TLS 옵션)
core.strictTLSOptions 인스톨 구성 옵션은 default TLS 옵션으로의 폴백을 비활성화해요. 활성화되면 충돌에 연루된 라우터는 오류로 표시되고 전혀 빌드되지 않으며, 호스트 이름은 더 이상 어떤 TLS 옵션에도 매핑되지 않아요.
비활성화된 라우터
strictTLSOptions를 활성화하면 실패 시 닫히는(fail closed) 방식이에요. 충돌은 해당 엔트리포인트에서 충돌하는 호스트 이름을 제공하는 모든 라우터를, 충돌이 해결될 때까지 비활성화해요.
File (YAML)
## Install configuration
core:
strictTLSOptions: true
File (TOML)
## Install configuration
[core]
strictTLSOptions = true
CLI
## Install configuration
--core.strictTLSOptions=true
Minimum TLS Version (최소 TLS 버전)
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
minVersion: VersionTLS12
mintls13:
minVersion: VersionTLS13
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
minVersion = "VersionTLS12"
[tls.options.mintls13]
minVersion = "VersionTLS13"
Maximum TLS Version (최대 TLS 버전)
TLS 1.3을 비활성화하기 위해 이 설정을 사용하는 것은 권장하지 않아요.
권장하는 방법은 클라이언트가 TLS 1.3을 지원하도록 업데이트하는 거예요.
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
maxVersion: VersionTLS13
maxtls12:
maxVersion: VersionTLS12
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
maxVersion = "VersionTLS13"
[tls.options.maxtls12]
maxVersion = "VersionTLS12"
Cipher Suites (암호화 스위트)
자세한 내용은 cipherSuites를 참고해 주세요.
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
cipherSuites = [
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
TLS 1.3
TLS 1.2 이하를 위해 정의된 암호화 스위트는 TLS 1.3에서 사용할 수 없고, 그 반대도 마찬가지예요. (https://tools.ietf.org/html/rfc8446) TLS 1.3에서는 암호화 스위트를 구성할 수 없어요(이 경우 모든 지원 암호화 스위트가 안전해요). https://golang.org/doc/go1.12#tls_1_3
Curve Preferences (곡선 기본 설정)
이 옵션은 선호하는 타원 곡선(elliptic curves)을 설정할 수 있게 해 줘요.
crypto에서 정의한 곡선 이름(예: CurveP521)과 RFC에서 정의한 이름(예: secp521r1)을 사용할 수 있어요.
자세한 내용은 CurveID를 참고해 주세요.
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
curvePreferences:
- CurveP521
- CurveP384
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
curvePreferences = ["CurveP521", "CurveP384"]
Strict SNI Checking (엄격한 SNI 검사)
엄격한 SNI 검사가 활성화되면, Traefik은 server_name 확장을 지정하지 않거나 구성된 인증서 중 어떤 것과도 일치하지 않는 클라이언트의 연결을 허용하지 않아요. 이 경우 기본 인증서는 관련이 없어요.
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
sniStrict: true
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
sniStrict = true
ALPN Protocols
선택 사항, 기본값="h2, http/1.1, acme-tls/1"
이 옵션은 TLS 핸드셰이크를 위해 지원되는 애플리케이션 레벨 프로토콜 목록을 선호 순서대로 지정할 수 있게 해 줘요. 클라이언트가 ALPN을 지원하면 선택되는 프로토콜은 이 목록 중 하나이며, 상호 지원되는 프로토콜이 없으면 연결이 실패해요.
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
alpnProtocols:
- http/1.1
- h2
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
alpnProtocols = ["http/1.1", "h2"]
Client Authentication (mTLS) (클라이언트 인증)
Traefik은 clientAuth 섹션을 통해 상호 인증(mutual authentication)을 지원해요.
클라이언트 인증서 검증이 필요한 인증 정책의 경우, 인증서의 인증 기관(certificate authority)을 clientAuth.caFiles에 설정해야 해요.
Kubernetes 환경에서는 clientAuth.secretNames에 CA 인증서를 설정할 수 있어요. 자세한 내용은 TLSOption 리소스를 참고해 주세요.
clientAuth.clientAuthType 옵션은 다음과 같이 동작을 결정해요:
| Option | Operation |
| NoClientCert | 클라이언트 인증서를 무시해요. |
| RequestClientCert | 인증서를 요청하지만, 제공되지 않으면 계속 진행해요. |
| RequireAnyClientCert | 인증서를 요구하지만, clientAuth.caFiles나 clientAuth.secretNames에 나열된 CA가 서명했는지는 검증하지 않아요. |
| VerifyClientCertIfGiven | 인증서가 제공되면 clientAuth.caFiles나 clientAuth.secretNames에 나열된 CA가 서명했는지 검증해요. 그렇지 않으면 인증서 없이 진행해요. |
| RequireAndVerifyClientCert | 인증서를 요구하며, 이 인증서는 clientAuth.caFiles나 clientAuth.secretNames에 나열된 CA가 서명해야 해요. |
Structured (YAML)
# Dynamic configuration
tls:
options:
default:
clientAuth:
# in PEM format. each file can contain multiple CAs.
caFiles:
- tests/clientca1.crt
- tests/clientca2.crt
clientAuthType: RequireAndVerifyClientCert
Structured (TOML)
# Dynamic configuration
[tls.options]
[tls.options.default]
[tls.options.default.clientAuth]
# in PEM format. each file can contain multiple CAs.
caFiles = ["tests/clientca1.crt", "tests/clientca2.crt"]
clientAuthType = "RequireAndVerifyClientCert"
Disable Session Tickets (세션 티켓 비활성화)
선택 사항, 기본값="false"
true로 설정하면 Traefik은 세션 티켓 사용을 비활성화해서, 세션을 재개하는 대신 모든 클라이언트가 전체 TLS 핸드셰이크를 수행하도록 강제해요.
Structured (YAML)
# routing configuration
tls:
options:
default:
disableSessionTickets: true
Structured (TOML)
# routing configuration
[tls.options]
[tls.options.default]
disableSessionTickets = true
Kubernetes
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
disableSessionTickets: true
프로덕션에서 Traefik OSS를 사용하시나요?
직장에서 Traefik을 사용하고 있다면, 엔터프라이즈급 API 게이트웨이 기능이나 Traefik OSS에 대한 상용 지원을 고려해 보세요.
-
API 게이트웨이 데모 영상 보기
-
24/7/365 OSS 지원 요청하기
Traefik OSS에 API 게이트웨이 기능을 추가하는 것은 빠르고 자연스러워요. 기존 구성을 갈아엎거나 교체할 필요 없이 모든 설정이 그대로 유지돼요. 이 짧은 영상에서 직접 확인해 보세요.