โ๏ธ ํดํด 5๊ธฐ ์์ฆ 1 ์คํฐ๋ : 90DaysOfDevOps ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ๋ฐํ์ผ๋ก ๊ณต๋ถํฉ๋๋ค!
๐งฉ 82 > Securing your microservices
90DaysOfDevOps/2023/day82.md at main · MichaelCade/90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things Dev...
github.com
Day82. Securing your microservices
์์ฆ ๋ DevSecOps๋ผ๋ ๋ง์ด ๋์ค๋ฉด์ ๋ณด์๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๊ฐ ์ค์ํ๊ฒ ๋ ์ค๋ฅด๊ณ ์๋๋ฐ์?
์ด์ฏค์์ ์ ๊น ๋ค์ ๋ณต์ตํ์๋ฉด, ์๋น์ค ๋ฉ์๋! MSA๊ฐ ๊ตด๋ฆฐ ์ค๋ ธ์ฐ๋ณผ!!
monolithic์ด๋ผ๋ฉด ํ๋ ์์์ ์ง์ง๊ณ ๋ณถ๊ณ ํ๋ฉด ๋ฌธ์ ๊ฐ ์์ง๋ง??
MSA์์๋ ์์ฒ ๊ฐ์ ์๋น์ค๋ค์ด ์๋๋ฐ, ๊ฒฐ๊ตญ ์ด๋ค๋ผ๋ฆฌ๋ '๋คํธ์ํฌ'๋ฅผ ํตํด์ ํต์ ์ ํด์ผ ํฉ๋๋ค!
๊ทธ๊ฑฐ, ๋ฏฟ์ ์ ์์ผ์ธ์????????
์๋น์ค ๋ฉ์์์ ๋ค๋ฃจ๋ ๋ณด์ ๋ฌธ์ ์ข ๋ฅ
- Identity
- Policy
- Authorization
- Authentication
- Encrpytion
- Data Loss Prevention
์๋น์ค ๋ฉ์์์ ๋ณด์ ๋ฌธ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ
- SideCar, Ingress Gateway, ๋ ธ๋ ์์ค proxy, k8s ๊ณ์ธต๊ณผ ์ํธ์์ฉ ํ๋ service mesh control plane
- ์ ์ฑ , ์ธ์ฆ ๊ตฌ์ฑ์ Istio control plane์์ ํ ์ ์๋ค → k8s API์ ์ ๊ณตํด์ ํ๊ณผ ๋ค๋ฅธ ๋ฆฌ์์ค์ ๋ํ ๋ฐํ์ ๊ตฌ์ฑ
- k8s CNI ๋ ์ด์ด → ์ ํ๋ ์์ ๋คํธ์ํฌ ์ ์ฑ ๋ฐ ์ํธํ ์ ๊ณต
- ์๋น์ค ๋ฉ์ ์ํธํ → ์๋น์ค ๊ฐ ํต์ ์ ์ํ mutual-TLS(mTLS)
- SPIFFE(Secure Production Identity Framework For Everyone) ID ํ์์ ๊ฐ๋ ฅํ identity ์ฌ์ฉํ์ฌ ์ธ์ฆ ์ ๊ณต
- Layer 7 Authorization→ ํน์ ์๋น์ค์ ๊ถํ์ ๋ถ์ฌํ์ฌ ๋ค๋ฅธ ์๋น์ค์ ๋ํด ์์ (HTTP) ์ํ
๋ฌด์จ ์๋ฆฌ์ธ์ง ์ ๋ง ๋ชจ๋ฅด๊ฒ ์ผ๋, ์ผ๋จ ์ด๋ฐ ๊ฒ ์๊ตฌ๋~ ํ๊ณ ๋์ด๊ฐ๋ณด์! ๋ค์ ์ค์ต์ ํ๋ฉด ์กฐ๊ธ์ฉ ์ดํด๊ฐ ๊ฐ๋ค..!
๐Istio Peer AuthN and mTLS
- ๋ฉ์์ ๋ฐฐํฌ๋ workload ๋ํ identify๋ฅผ ๋ฐ๊ธํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ ์ค์
- Istio์์๋ ๋ชจ๋ ์๋น์ค์ SideCar๊ฐ ์๊ณ Istiod Control Plane์ผ๋ก๋ถํฐ identify๋ฅผ ๋ฐ๊ธ๋ฐ์๋ค๋ฉด, ์๋น์ค๋ฅผ ์ ๋ขฐํ๊ณ ๊ฒ์ฆํ ๋ฅ๋ ฅ์ด ์๋ค, ์ฆ, Peer AuthN์ด mTLS๋ฅผ ์ฌ์ฉํด์ ๋ฌ์ฑ๋ ์ ์๋ค
- Istio์์ Peer AuthN์ ์๋น์ค์ ๋ํด์ ๊ตฌ์ฑ๋์ด์ผ ํ๊ณ ์ํฌ๋ก๋, ๋ค์์คํ์ด์ค, ์ ์ฒด ๋ฉ์๋ก ๋ฒ์๋ฅผ ์ง์ ํ ์ ์๋ค.
- Peer AuthN์๋ 3๊ฐ์ง ๋ชจ๋๊ฐ ์๋ค
- `PERMISSIVE` (Default) : plain text์ mTLS ๋ ๋ค ๊ฐ๋ฅ
- `STRICT` : mTLS ๊ฐ๋ฅํ ์ํฌ๋ก๋๋ง
- `DISABLE` : mTLS ๋ถ๊ฐ๋ฅ
- End-user Auth๋ฅผ JWT(JSON Web Tokens) ์ฌ์ฉํด์ ํ ์๋ ์๋ค
์ด๋ก ๋ชจ๋ฅด๊ฒ ์ผ๋ ์ผ๋จ ์ง์ ํด๋ณด์!
๐ (2)๋ถํฐ ํ์๋ bookinfo sample ์ค์ต ํ๊ฒฝ์ ๊ณ์ ์ด์ด์ ์งํํฉ๋๋ค!
1. ์ฌ์ด๋์นด๊ฐ ์๋ ๋ค๋ฅธ ์ํ ์ฑ ๋ฐฐํฌ
kubectl create ns sleep
kubectl get ns
- Output : Service Account, Service, Deployment ์์ฑ
2. Sleep pod์ด bookinfo ์ฑ๊ณผ ํต์ ํ ์ ์๋์ง ํ ์คํธ
→ sleep namespace์์ app=sleep ๋ผ๋ฒจ์ด ์๋ sleep pod์์ default namespace์ ์๋ productpage์ curl
kubectl exec "$(kubectl get pod -l app=sleep -n sleep -o jsonpath={.items..metadata.name})" -c sleep -n sleep -- curl productpage.default.svc.cluster.local:9080 -s -o /dev/null -w "%{http_code}\\n"
- Output :
200
→ OK ์ฑ๊ณตํ๋ค๋ ์๋ฏธ (Default๋ `PERMISSIVE` ์ด๊ธฐ ๋๋ฌธ)
3. Peer AuthN ์ ์ฉ
spec ํ๋์ mtls์ `STRICT` mode๋ผ๊ณ ๋ช ์ํด๋์๋ค → mTLS๊ฐ ์๋ ๋ชจ๋ ๊ฒฝ์ฐ ๋นํ์ฉ
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: STRICT
EOF
- Output : `peerauthentication.security.istio.io/default created`
4. ๋ค์ 2๋ฒ ํ ์คํธ ๋ฐ๋ณต
Output : ์คํจ!!
→ STRICT ๋ชจ๋์ Peer AuthN์ด mTLS ์ํฌ๋ก๋์ ํต์ ํ ๋ mTLS๊ฐ ์๋๋ฉด ๋นํ์ฉ ํ๋ค.
๐ Istio Layer 7 AuthZ
- AuthZ → ๋ค๋ฅธ ๋ฆฌ์์ค์ ๋ํด ์ด๋ค ์์ ์ ์ํํ ์ ์๋ ์ฌ๋์ ์ธ๋ถ์ ์ผ๋ก ์ ์ด e.g ) ํ ์๋น์ค๊ฐ ๋ค๋ฅธ ์๋น์ค์ ๋ํด ์ํํ ์ ์๋ HTTP ์์ ์? ( GET์ ํ ์ ์๋์ง, GET์ ๊ฐ๋ฅํ๊ณ DELETE๋ ๋ถ๊ฐ๋ฅํ๊ฒ → zero-trust)
- Kiali(์ ์ ๊ทธ๋ํ ๋ทฐ๋ก ๋ชจ๋ํฐ๋ง ํ๋ ๋๊ตฌ) ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํด์ service mapping์ ๋ง๋ค๊ณ ์๋น์ค ๊ฐ ๋ค์ํ HTTP ์ดํด ๊ฐ๋ฅ
- ์ฌ์ด๋์นด๋ก์ Envoy(Istio์ฉ Proxyv2)๊ฐ ๋ชจ๋ AuthZ ์ ์ฑ
์ ๋ํ ์ ์ฑ
์ ์ฉ ์ง์ ์ด๋ค.
- ์ ์ฑ ์ ๋ฐํ์์ ์์ฒญ ์น์ธ์ ํด์ฃผ๋ AuthZ ์์ง์ ์ํด ํ๊ฐ๋ฐ๋๋ค.
- ๋์์ด ๋๋ ์ฌ์ด๋์นด(=Envoy)๊ฐ ์ด๊ฑธ ํ๊ฐํ ์ฑ ์์ด ์๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ์ผ๋จ ํด๋ณด์
1. ๋ชจ๋ HTTP ๊ธฐ๋ฐ ๋์์ ๋ง๊ธฐ
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
EOF
- Output : `authorizationpolicy.security.istio.io/allow-nothing created`
- ํ์ธ : ์์์์ ๊ฐ์ด sleep Pod์ ์ ๊ทผํด๋ณด์
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl productpage.default.svc.cluster.local:9080 -s -o /dev/null -w "%{http_code}\\n"
- Output : `403` (= Forbidden...or Not Authorized) *์๋ `200`(=OK)์ผ๋ก ๋์์๋ค
2. ์๋น์ค ์ ์ฑ ์ง์
์๋น์ค↔ ์๋น์ค ํต์ ์ ํ์ฉํ๊ธฐ ์ํด์ ๋ฆฌํ์คํธ ๊ฒฝ๋ก์์ ์๋น์ค์ ์ ์ฑ ์ ์ ์ฉํด์ฃผ์
๋ค์ 4๊ฐ์์ AuthZ ์ ์ฑ ์ ์ง์ ํด์ค์ผ ํ๋ค(์์ ๊ทธ๋ฆผ์์ ์๋ฌผ์ ์๋ ํ์ดํ๋ค)
1. User client to product page.
2. From Product Page to Details
3. From product-page to reviews
4. From reviews to ratings
๐๐ป AuthZ ์ ์ฑ ๊ตฌ์ฑ ์์
- `apiVersion` : ์ด๊ฒ Istio ๋ฆฌ์์ค/CRD(CustomResourceDefinitions)์์ ๋ช ์
- `spec` : ์ด๋ ๋ฆฌ์์ค๊ฐ HTTP ์์ฒญ ์ธ๋ฐ์ด๋๋ฅผ ๋ฐ๊ณ , ๋ฉ์๋(e.g GET)๋ ๋ฌด์์ธ์ง
- `action` : ์ ๋ฆฌ์์ค์์ ๋ฐ์ํ ์ ์๋ ๋์ (ALLOW)
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "get-productpage"
namespace: default
spec:
selector:
matchLabels:
app: productpage # product page์ธ ์๋น์ค์ ์ ๊ทผํ๋ ๊ฒ์ ๋ํด์
action: ALLOW # ํ์ฉํ๋ค
rules:
- to:
- operation:
methods: ["GET"] # GET๋ง
EOF
→ ์ธ๋ถ ํด๋ผ์ด์ธํธ๊ฐ Product-page์ ๋ํด HTTP GET๋ง ๊ฐ๋ฅํ๋๋ก ํด์ค๋ค (๋๋จธ์ง๋ ๊ฑฐ์ )
- Output : `authorizationpolicy.security.istio.io/get-productpage created`
์ง์ ์ธ๋ถ์์ `localhost/productpage`๋ก ์ ๊ทผํด์ ํ์ธํด๋ณด์! → curl๋ก ํ๋ฉด 200(=OK)์ผ๋ก ๋์ค๊ฒ ๋๋ค
- BUT ์น ๋ธ๋ผ์ฐ์ ๋ก ์ ์ํด๋ณด๋ฉด ์์ง Details์ Reviews์ ๋ํด์๋ ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ถ๋ฌ์ค์ง ๋ชป ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
์ด์ ์์์ ๋งํ ๋๋จธ์ง 3๊ฐ๋ ์ฐจ๋ก ์ฐจ๋ก ํ์ฉํด๋ณด์
3. Productpage → Reviews Get ํ์ฉ
product-page๊ฐ reviews ์๋น์ค๋ก๋ถํฐ HTTP GET ํ๋ ๊ฑธ ํ์ฉํด๋ณด์
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "get-reviews"
namespace: default
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
to:
- operation:
methods: ["GET"]
EOF
- `rules` : principal์ ํตํด์ ์์ฒญ์ source๋ฅผ ๋ช ์ํด์ค๋ค. → bookinfo-productpage์ service account๋ฅผ ํด์ค๋ค
- output : `authorizationpolicy.security.istio.io/get-reviews created`
4. Reviews → Ratings GET ํ์ฉ
๋ง์ฐฌ๊ฐ์ง๋ก reviews๊ฐ ratings๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ป์ด์ค๋ ๊ฒ์ ํ์ฉํ๋ ์ ์ฑ ์ ์ ์ฉํด๋ณด์
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "get-ratings"
namespace: default
spec:
selector:
matchLabels:
app: ratings
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
to:
- operation:
methods: ["GET"]
EOF
- output : `authorizationpolicy.security.istio.io/get-ratings created`
5. Product → Details GET ํ์ฉ
๋ง์ง๋ง์ผ๋ก productpage๊ฐ details๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ป์ด์ค๋ ๊ฒ์ ํ์ฉํ๋ ์ ์ฑ ์ ์ ์ฉํด๋ณด์
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "get-details"
namespace: default
spec:
selector:
matchLabels:
app: details
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
to:
- operation:
methods: ["GET"]
EOF
- output : `authorizationpolicy.security.istio.io/get-details created`
6. ๊ฒฐ๊ณผ ํ์ธ
localhost/productpage์ ๋ค์ ๋ค์ด๊ฐ๋ฉด, ์ด์ ๋ Details์ Reviews์ Ratings ๋ชจ๋ ์ ๋ณด์ด๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
๐ ์ถ์ฒ ์์
๋ง์ฝ ์ ์ค์ต์ ๋ค ํ๋ค๋ฉด ์ด ์์์ ๋ณด์๋ ๊ฑธ ์ถ์ฒ๋๋ฆฝ๋๋ค! ์๋ ๋ผ๋ฉด 0% ์์ ๋ค์ ๋ด์ฉ์ 20% ์ ๋๋ ์ดํดํ ์ ์๊ฒ ๋ฉ๋๋ค! ์๋ถ๋ถ์ mTLS ๊ด๋ จ ์ค๋ช ๋ ์์ด์ ์ข์ ๊ฒ ๊ฐ์์~
https://youtu.be/4sJd6PIkP_s?si=IWbBRCfBICkkx8WP
'๐ DevOps & Cloud > 90DaysOfDevOps' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Runtime Defense & Monitoring] - (1) Introduction (0) | 2024.06.01 |
---|---|
Service Mesh (6) - Ambient Mesh (1) | 2024.04.27 |
Service Mesh (4) - Observability (0) | 2024.04.26 |
Service Mesh (3) - Traffic Engineering (0) | 2024.04.26 |
Service Mesh (2) - Istio Getting-started (0) | 2024.04.26 |