Service Mesh (5) - Security

โ˜๏ธ ํดํด 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