mTLS
Mutual TLS
양방향 TLS 인증. 서버와 클라이언트 모두 인증서 검증.
Mutual TLS
양방향 TLS 인증. 서버와 클라이언트 모두 인증서 검증.
mTLS(Mutual TLS, 상호 TLS)는 일반 TLS의 확장으로, 서버뿐만 아니라 클라이언트도 인증서를 제시하여 양방향 인증을 수행합니다. 제로 트러스트 아키텍처의 핵심 구성요소로, 마이크로서비스 간 통신에서 널리 사용됩니다.
일반 TLS에서는 클라이언트가 서버의 인증서만 검증합니다(HTTPS). mTLS에서는 서버도 클라이언트의 인증서를 검증하여, 허가된 클라이언트만 접속할 수 있습니다. API 키나 토큰 없이도 강력한 인증이 가능합니다.
Service Mesh(Istio, Linkerd)에서는 사이드카 프록시가 자동으로 mTLS를 처리합니다. 애플리케이션 코드 수정 없이 모든 서비스 간 트래픽을 암호화하고 인증할 수 있습니다.
인증서 관리가 복잡해지므로, cert-manager나 Vault PKI를 사용해 자동화하는 것이 일반적입니다. SPIFFE/SPIRE는 워크로드 아이덴티티 표준으로, 동적 환경에서 인증서 발급과 로테이션을 자동화합니다.
# Istio: PeerAuthentication으로 mTLS 강제
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT # mTLS 필수
---
# Istio: DestinationRule로 mTLS 설정
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-service
spec:
host: my-service.production.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL # Istio가 발급한 인증서 사용
---
# Nginx: mTLS 설정
server {
listen 443 ssl;
# 서버 인증서
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
# 클라이언트 인증서 검증 (mTLS)
ssl_client_certificate /etc/nginx/certs/ca.crt;
ssl_verify_client on; # 필수
ssl_verify_depth 2;
location / {
# 클라이언트 인증서 정보를 백엔드에 전달
proxy_set_header X-Client-Cert-DN $ssl_client_s_dn;
proxy_pass http://backend;
}
}
---
# Node.js: mTLS 클라이언트
import https from 'https';
import fs from 'fs';
const options = {
hostname: 'api.example.com',
port: 443,
path: '/data',
method: 'GET',
// 클라이언트 인증서 (mTLS)
cert: fs.readFileSync('client.crt'),
key: fs.readFileSync('client.key'),
// 서버 CA 검증
ca: fs.readFileSync('ca.crt'),
};
const req = https.request(options, (res) => {
console.log(`Status: ${res.statusCode}`);
});
---
# cert-manager: 인증서 자동 발급
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-service-cert
namespace: production
spec:
secretName: my-service-tls
duration: 2160h # 90일
renewBefore: 360h # 만료 15일 전 갱신
privateKey:
algorithm: ECDSA
size: 256
usages:
- server auth
- client auth # mTLS용
dnsNames:
- my-service.production.svc.cluster.local
issuerRef:
name: cluster-ca
kind: ClusterIssuer
보안: "서비스 간 통신에 mTLS 적용하면 네트워크 레벨에서 인증이 되니까 API 키 관리 부담이 줄어들어요."
개발: "인증서 만료 관리가 어려울 것 같은데요..."
보안: "cert-manager로 자동 갱신하면 됩니다. 아니면 Istio 쓰면 사이드카가 알아서 처리해요."
면접관: "mTLS와 일반 TLS의 차이점을 설명해주세요."
지원자: "일반 TLS는 클라이언트가 서버 인증서만 검증하는 단방향 인증입니다. mTLS는 서버도 클라이언트의 인증서를 검증하는 양방향 인증으로, 허가된 클라이언트만 통신할 수 있습니다. 마이크로서비스 환경에서 서비스 간 인증에 주로 사용되며, 제로 트러스트 아키텍처의 핵심입니다."
리뷰어: "mTLS 설정에서 인증서 만료일을 확인하는 로직이 없네요. 만료된 인증서로 요청하면 어떻게 되나요?"
작성자: "TLS 핸드셰이크에서 거부됩니다. 근데 만료 임박 알림을 추가하면 좋겠네요."