[AEWS] #6์ฃผ์ฐจ x.509 ์ธ์ฆ์„œ ๊ตฌ์กฐ ๋ฐ ๊ฒ€์ฆ ์‹ค์Šต (1)

25๋…„๋„ AWS EKS Hands-on Study ์Šคํ„ฐ๋”” ์ •๋ฆฌ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค x.509 ์ธ์ฆ์„œ ์‹ค์Šต

docker exec -it myk8s-control-plane ls -l /etc/kubernetes/pki
total 56
-rw-r--r-- 1 root root 1123 Mar 15 17:33 apiserver-etcd-client.crt
-rw------- 1 root root 1679 Mar 15 17:33 apiserver-etcd-client.key
-rw-r--r-- 1 root root 1176 Mar 15 17:33 apiserver-kubelet-client.crt
-rw------- 1 root root 1679 Mar 15 17:33 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1326 Mar 15 17:33 apiserver.crt
-rw------- 1 root root 1675 Mar 15 17:33 apiserver.key
-rw-r--r-- 1 root root 1107 Mar 15 17:33 ca.crt
-rw------- 1 root root 1679 Mar 15 17:33 ca.key
drwxr-xr-x 2 root root  162 Mar 15 17:33 etcd
-rw-r--r-- 1 root root 1123 Mar 15 17:33 front-proxy-ca.crt
-rw------- 1 root root 1675 Mar 15 17:33 front-proxy-ca.key
-rw-r--r-- 1 root root 1119 Mar 15 17:33 front-proxy-client.crt
-rw------- 1 root root 1675 Mar 15 17:33 front-proxy-client.key
-rw------- 1 root root 1675 Mar 15 17:33 sa.key
-rw------- 1 root root  451 Mar 15 17:33 sa.pub

 

CA ์ธ์ฆ์„œ ๋‚ด์šฉ ํ™•์ธ

docker exec -it myk8s-control-plane openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text

 

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 5754887193385032258 (0x4fdd77696428da42)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: Mar 15 17:28:12 2025 GMT
            Not After : Mar 13 17:33:12 2035 GMT
        Subject: CN = kubernetes
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)

 

X.509 v3๋Š” ํ™•์žฅ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด CA ์ธ์ฆ์„œ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, CA์—์„œ ๋ฐœ๊ธ‰ํ•˜๋Š” ๊ฐ ์ธ์ฆ์„œ๋Š” ๊ณ ์œ ํ•œ ์‹œ๋ฆฌ์–ผ ๋„˜๋ฒ„๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

์ด ์ธ์ฆ์„œ๋Š” SHA-256 + RSA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ช…๋˜์—ˆ์Œ์œผ๋ฉฐ, ์ž๊ธฐ ์ž์‹ ์„ ๋ฐœ๊ธ‰์ž(Issuer)๋กœ ์„ค์ •(CN = kubernetes)ํ•˜๋Š” Self-Signed ์ธ์ฆ์„œ์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ์ธ์ฆ์„œ๋Š” 2025๋…„ 3์›” 15์ผ๋ถ€ํ„ฐ 2035๋…„ 3์›” 13์ผ๊นŒ์ง€ ์œ ํšจํ•˜๋ฉฐ, CA ์ธ์ฆ์„œ๋Š” ์žฅ๊ธฐ๊ฐ„ ์œ ํšจํ•˜๋„๋ก ์„ค์ •๋˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ๋…ธ๋“œ ์ธ์ฆ์„œ๋Š” ๋” ์งง์€ ์œ ํšจ ๊ธฐ๊ฐ„์„ ๊ฐ€์ง„๋‹ค.

์ธ์ฆ์„œ์˜ ๋Œ€์ƒ(Subject)์œผ๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๊ฐ€ ์„ค์ •๋˜๊ณ  ์ด ์ธ์ฆ์„œ๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ ์ธ์ฆ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

RSA 2048-bit ๊ณต๊ฐœ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ธ์ฆ์„œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

 

        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Certificate Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                5B:71:6E:8E:5E:0B:63:0D:42:F8:A1:37:B8:2B:A1:54:60:74:60:8A
            X509v3 Subject Alternative Name:
                DNS:kubernetes
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        xx:yy:zz..~~

 

ํ™•์žฅ ํ•„๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

์ธ์ฆ์„œ๋Š” critical๋กœ ์„ ์–ธ๋œ ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

  • Digital Signature: ๋””์ง€ํ„ธ ์„œ๋ช… ์ƒ์„ฑ ๊ฐ€๋Šฅ
  • Key Encipherment: ํ‚ค ์•”ํ˜ธํ™” ๊ฐ€๋Šฅ
  • Certificate Sign: ์ด ์ธ์ฆ์„œ๋Š” ๋‹ค๋ฅธ ์ธ์ฆ์„œ๋ฅผ ์„œ๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” CA ์—ญํ• 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ด CA๋ฅผ ์‹ ๋ขฐํ•˜๋„๋ก ์„ค์ •๋˜๊ณ , ์ธ์ฆ์„œ์˜ ๊ณ ์œ ํ•œ ํ•ด์‹œ๊ฐ’์„ ํ†ตํ•ด ๋‹ค๋ฅธ ์ธ์ฆ์„œ๋“ค์ด ์ด ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ ๋ขฐํ•  CA์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ API ์„œ๋ฒ„๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, "kubernetes"๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด ์ธ์ฆ์„œ๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด CA๋ฅผ ๊ฒ€์ฆํ•  ๋•Œ ๋ฐœ๊ธ‰์ž์˜ ๊ณต๊ฐœ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ช…์„ ํ™•์ธํ•˜์—ฌ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

CSR ๋‚ด์šฉ ํ™•์ธ

kubectl get certificatesigningrequests
NAME        AGE   SIGNERNAME                                    REQUESTOR                         REQUESTEDDURATION   CONDITION
csr-txkc6   11m   kubernetes.io/kube-apiserver-client-kubelet   system:node:myk8s-control-plane   <none>              Approved,Issued

kubectl describe certificatesigningrequests
Name:               csr-txkc6
Labels:             <none>
Annotations:        <none>
CreationTimestamp:  Sun, 16 Mar 2025 02:33:26 +0900
Requesting User:    system:node:myk8s-control-plane
Signer:             kubernetes.io/kube-apiserver-client-kubelet
Status:             Approved,Issued
Subject:
         Common Name:    system:node:myk8s-control-plane
         Serial Number:
         Organization:   system:nodes
Events:  <none>

 

myk8s-control-plane ๋…ธ๋“œ๊ฐ€ Kubelet ์ธ์ฆ์„œ๋ฅผ ์š”์ฒญํ–ˆ๊ณ  ๊ด€๋ฆฌ์ž๊ฐ€ ์ด๋ฅผ ์Šน์ธํ•˜์—ฌ ๋ฐœ๊ธ‰๋œ ์ƒํƒœ์ด๋‹ค.

 

์ด csr์„ ์ข€ ๋” ์ƒ์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด, "myk8s-control-plane" ๋…ธ๋“œ์˜ Kubelet ์ธ์ฆ์„œ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด๋ฉฐ ๋…ธ๋“œ๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ฐธ์—ฌํ•˜๊ธฐ ์œ„ํ•ด Kube API Server์™€ ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

kubernetes.io/kube-apiserver-client-kubelet์€ API ์„œ๋ฒ„๊ฐ€ Kubelet์˜ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋ฅผ ์Šน์ธํ•˜๋Š” ๊ธฐ๋ณธ Signer์ด๋‹ค.
Kube API Server๊ฐ€ ์ด csr์„ ์Šน์ธํ•˜๋ฉด, Kubelet์ด API Server์™€ ์•ˆ์ „ํ•˜๊ฒŒ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๋Š”๋‹ค.

 

 

์ด ์ธ์ฆ์„œ๋ฅผ ํ†ตํ•ด kubelet์ด api ์„œ๋ฒ„์™€ ์ •์ƒ์ ์œผ๋กœ ํ†ต์‹ ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

kubeconifg ์ธ์ฆ์„œ

echo "LS0tLS1CR..." | base64 -d > myuser.key
cat myuser.key

 

์ด ํ‚ค๋Š” client-certificate-data์— ๋Œ€์‘ํ•˜๋Š” ๊ฐœ์ธ ํ‚ค๋กœ, kubernetes-admin ์‚ฌ์šฉ์ž๊ฐ€ API ์„œ๋ฒ„์— ์ธ์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

openssl x509 -in myuser.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1412884469959843802 (0x139b92f08c9f5fda)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Mar 15 17:28:12 2025 GMT
            Not After : Mar 15 17:33:12 2026 GMT
        Subject: O=kubeadm:cluster-admins, CN=kubernetes-admin
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
          
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                keyid:5B:71:6E:8E:5E:0B:63:0D:42:F8:A1:37:B8:2B:A1:54:60:74:60:8A

    Signature Algorithm: sha256WithRSAEncryption

 

client-certificate-data ๊ฐ’์€ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋กœ, ํŠน์ • ์‚ฌ์šฉ์ž๊ฐ€ Kubernetes API ์„œ๋ฒ„์— ์ธ์ฆํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

- name: kind-myk8s
  user:
    client-certificate-data: LS~
    client-key-data: LS~

 

ํ๋ธŒ์ปจํ”ผ๊ทธ๋ฅผ ๋ณด๋ฉด client-certificate-data์™€ client-key-data๊ฐ€ ์žˆ๋Š”๋ฐ,

client-certificate-data ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋กœ, ํŠน์ • ์‚ฌ์šฉ์ž๊ฐ€ Kubernetes API ์„œ๋ฒ„์— ์ธ์ฆํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ

client-key-data ๋Š” ํด๋ผ์ด์–ธํŠธ ๊ฐœ์ธ ํ‚ค(Private Key)๋กœ client-certificate-data์— ๋Œ€์‘ํ•˜๋Š” ๊ฐœ์ธ ํ‚ค์ด๋‹ค.

 

cat $HOME/.kube/config
    certificate-authority-data: LS

 

์ด ์ธ์ฆ์„œ๋Š” Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ API ์„œ๋ฒ„๊ฐ€ ์‹ ๋ขฐํ•˜๋Š” Root CA ์ธ์ฆ์„œ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

 

kubernetes-admin ์‚ฌ์šฉ์ž๋Š” client-certificate-data์™€ client-key-data๋ฅผ ์ด์šฉํ•˜์—ฌ API ์„œ๋ฒ„์™€ TLS ์ธ์ฆ์„ ์ˆ˜ํ–‰ํ•˜๊ณ ,

certificate-authority-data๋ฅผ ํ†ตํ•ด API ์„œ๋ฒ„๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

CSR์„ ํ™œ์šฉํ•œ ์‹ ๊ทœ ์‚ฌ์šฉ์ž ์ธ์ฆ

openssl genrsa -out $USER.key 2048
openssl req -new -key $USER.key -out $USER.csr -subj "/O=kubeadm:cluster-admins/CN=$USER-cert"

 

Kubernetes API ์„œ๋ฒ„์— ์ œ์ถœํ•  ์ธ์ฆ์„œ ์„œ๋ช… ์š”์ฒญ(CSR) ์ƒ์„ฑํ•œ๋‹ค.

cat $USER.csr | base64 | tr -d '\n'
๋กœ ๋‚˜์˜ค๋Š” ๊ฐ’ ๋ณต์‚ฌ!

kubectl apply -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: $USER-csr
spec:
  signerName: kubernetes.io/kube-apiserver-client
  groups:
  - system:masters
  - system:authenticated
  request: LS...
  usages:
  - digital signature
  - key encipherment
  - client auth
EOF

 

Kubernetes์— CSR์„ ์ œ์ถœํ•˜์—ฌ ์ธ์ฆ์„œ๋ฅผ ์š”์ฒญํ•œ๋‹ค

 

k get csr
NAME        AGE   SIGNERNAME                                    REQUESTOR                         REQUESTEDDURATION   CONDITION
csr-txkc6   52m   kubernetes.io/kube-apiserver-client-kubelet   system:node:myk8s-control-plane   <none>              Approved,Issued
nana-csr    4s    kubernetes.io/kube-apiserver-client           kubernetes-admin                  <none>              Pending

kubectl certificate approve nana-csr
certificatesigningrequest.certificates.k8s.io/nana-csr approved

kubectl get csr
NAME        AGE     SIGNERNAME                                    REQUESTOR                         REQUESTEDDURATION   CONDITION
csr-txkc6   56m     kubernetes.io/kube-apiserver-client-kubelet   system:node:myk8s-control-plane   <none>              Approved,Issued
nana-csr    4m30s   kubernetes.io/kube-apiserver-client           kubernetes-admin                  <none>              Approved,Issue

 

๊ด€๋ฆฌ์ž๊ฐ€ CSR์„ ์Šน์ธํ•˜์—ฌ ์ธ์ฆ์„œ ๋ฐœ๊ธ‰์„ ์š”์ฒญํ•œ๋‹ค.

 

kubectl get csr nana-csr -o jsonpath='{.status.certificate}' | base64 -d > nana.crt

kubectl get csr nana-csr -o jsonpath='{.status.certificate}' | base64 -d > nana.crt

openssl x509 -in nana.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Mar 15 18:24:42 2025 GMT
            Not After : Mar 15 18:24:42 2026 GMT
        Subject: O=kubeadm:cluster-admins, CN=nana-cert
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                keyid:...
                
cat ~/.kube/config
...
- name: nana
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - --region
      - ap-northeast-2
      - eks
      - get-token
      - --cluster-name
      - myeks
      - --output
      - json
      command: aws
      env: null
      interactiveMode: IfAvailable
      provideClusterInfo: false
- name: nana-user
  user:
    client-certificate: /root/nana.crt
    client-key: /root/nana.key

 

kubectl config set-credentials nana-user --client-certificate=nana.crt --client-key=nana.key
kubectl config set-context kind-nana --cluster=kind-myk8s --user=nana-user
cat ~/.kube/config
kubectl config use-context kind-

kubectl config get-contexts
CURRENT   NAME                                  CLUSTER                                                 AUTHINFO                              NAMESPACE
*         kind-nana                             kind-myk8s                                              nana-user

k get node
NAME                  STATUS   ROLES           AGE   VERSION
myk8s-control-plane   Ready    control-plane   63m   v1.32.2

 

์ด์ œ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋“ฑ๋กํ•˜๊ณ  ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ Kubernetes API ์„œ๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•œ ํ›„,

์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.