[Kubernetes] TLS/SSL Termination with Ingress
🚀 TLS/SSL Termination란 무엇인가 ?
SSL 표준화 → TLS
SSL은 취약점이 발견되어 현재 사용되지 않는다.
첫번째 이미지가 종단간 암호화 방식이며 두번째 이미지가 TLS/SSL Termination 방식이다.
종단간 암호화 방식은 클라이언트부터 서버까지 모든 통신 구간에 암호화를 사용하는 방식을 말한다.
TLS/SSL Termination 방식은Loadblancer
(=Proxy
)가 존재하며 노출되어 있다.
클라이언트와 LB 사이에는 HTTPS
(암호화를 제공)를 사용하며 LB와 실제 서비스를 제공하는 서버 사이에는 HTTP
(암호화를 제공하지 않음, 평문 통신)를 사용한다.
클라이언트부터 LB까지만 암호화하며 종단간 암호화가 아니다.
그렇다면 안전해보이지 않는 이런 구성을 왜 사용하는가 ?
1) 인증서 관리에 용이하다.
2) 개별 서버들이 암/복호화를 하지 않아 리소스 사용량이 낮아진다.
3) 여러가지 보안 장치를 비암호화 구간(HTTP)에 구성할 수 있다.
🚀 TLS/SSL Termination with Ingress 구성하기
vagrant@k8s-node1 ~/deploy kubectl explain ing.spec
tls
- TLS Termination 관련 설정
vagrant@k8s-node1 ~/deploy kubectl explain ing.spec.tls
hosts
- 도메인(www.sohui.com), 기본값은 와일드카드 호스트secretName
- 인증서가 있는 secret
의 이름을 지정
구성에 사용한 파일은 다음과 같다.
자체 서명 인증서와 secret 생성 과정은 다음 글에서 참조할 수 있다.
ingress-tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: nginx-tls-secret
type: kubernetes.io/tls
data:
# base64 x509/nginx-tls.crt -w 0
tls.crt: |
# base64 x509/nginx-tls.key -w 0
tls.key: |
myweb-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
env: dev
template:
metadata:
labels:
app: web
env: dev
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
ports:
- containerPort: 8080
protocol: TCP
myweb-svc-np.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb-svc-np
spec:
type: NodePort
selector:
app: web
ports:
- port: 80
targetPort: 8080
myweb-ing-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myweb-ing-tls
spec:
tls:
- hosts:
- '*.nip.io'
secretName: ingress-tls-secret
rules:
- host: '*.nip.io'
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myweb-svc-np
port:
number: 80
vagrant@k8s-node1 ~/configure/tls-termination kubectl create -f ingress-tls-secret.yaml
secret/ingress-tls-secret created
vagrant@k8s-node1 ~/configure/tls-termination kubectl create -f myweb-rs.yaml
replicaset.apps/myweb-rs created
vagrant@k8s-node1 ~/configure/tls-termination kubectl create -f myweb-svc-np.yaml
service/myweb-svc-np created
vagrant@k8s-node1 ~/configure/tls-termination kubectl create -f myweb-ing-tls.yaml
ingress.networking.k8s.io/myweb-ing-tls created
vagrant@k8s-node1 ~/configure/tls-termination kubectl get po
NAME READY STATUS RESTARTS AGE
myweb-rs-77mlk 1/1 Running 0 27s
myweb-rs-rpsnj 1/1 Running 0 27s
myweb-rs-rql9s 1/1 Running 0 27s
nfs-client-provisioner-758f8cd4d6-wpjbt 1/1 Running 0 20h
구성 파일로 리소스를 생성하고 정상 작동을 확인한다.
vagrant@k8s-node1 ~/configure/tls-termination kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 36h
service/myweb-svc-np NodePort 10.233.42.63 <none> 80:32306/TCP 49s
NAME ENDPOINTS AGE
endpoints/k8s-sigs.io-nfs-subdir-external-provisioner <none> 20h
endpoints/kubernetes 192.168.100.100:6443 36h
endpoints/myweb-svc-np 10.233.90.77:8080,10.233.90.78:8080,10.233.92.118:8080 49s
vagrant@k8s-node1 ~/configure/tls-termination kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
myweb-ing-tls <none> *.nip.io 192.168.100.100,192.168.100.101,192.168.100.102 80, 443 116s
vagrant@k8s-node1 ~/configure/tls-termination curl -k https://192-168-100-100.nip.io
Hello World!
myweb-rs-rpsnj
자체 서명 인증서를 사용했으므로 -k
옵션을 사용해서 접속한다.
vagrant@k8s-node1 ~/configure/tls-termination curl -k https://192-168-100-100.nip.io -v
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
TLS 4-way handshake
과정을 확인할 수 있다.