EKS 보안 Workshop
https://www.eksworkshop.com/docs/security/
1
EC2 생성
role 생성과 EC2에 적용
eksctl 설치 , kubectl 설치
EKS 생성
aws-com11
hostnamectl --static set-hostname aws-com11
sudo su -
[root@aws-demo3 ~]#
2
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin
eksctl version
3
# kubectl = 쿠버네티스 마스터에 명령을 내릴때 사용한다. 리소스 만들때 사용하는 툴.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version
4
aws-com11
# 기타 - EKS를 만들기위한 명령서버인 Cloud9 생성하기
cloudformation으로 만든다. (콘솔로 만들어도 된다.)
1
디폴트 VPC가 있어야 한다.
2
AWS 콘솔 로그인
오른쪽 위 cloud shell 실행
3
wget -q https://raw.githubusercontent.com/aws-samples/eks-workshop-v2/stable/lab/cfn/eks-workshop-ide-cfn.yaml -O eks-workshop-ide-cfn.yaml
aws cloudformation deploy --stack-name eks-workshop-ide --template-file ./eks-workshop-ide-cfn.yaml --parameter-overrides RepositoryRef=stable EksWorkshopC9InstanceType=t3.medium --capabilities CAPABILITY_NAMED_IAM
Ask before pasting multiline code
체크 해제
(5분 걸림)
wget으로 받은 yaml file
4
aws cloudformation describe-stacks --stack-name eks-workshop-ide --query 'Stacks[0].Outputs[?OutputKey==`Cloud9Url`].OutputValue' --output text
url 확인 웹 접속 (콘솔로 cloud9가서 접속 해도 된다.)
위 명령어들 모음
1
EC2 접속해 eks 클러스터 생성하기
export AWS_REGION=ap-northeast-2
export EKS_CLUSTER_NAME=myeks11-cluster
curl -fsSL https://raw.githubusercontent.com/aws-samples/eks-workshop-v2/stable/cluster/eksctl/cluster.yaml | envsubst | eksctl create cluster -f -
(20분 걸림)
2
타이머
https://vclock.kr/timer/#countdown=00:10:00&enabled=0&seconds=0&sound=xylophone&loop=1
3
# 아래 버전 1.30 이다.
# 최신 버전은 1.31 이다. 1.31로 수정하여 설치하자
cat << EOF > myeks-cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
availabilityZones:
- ${AWS_REGION}a
- ${AWS_REGION}b
- ${AWS_REGION}c
metadata:
name: ${EKS_CLUSTER_NAME}
region: ${AWS_REGION}
version: "1.31"
tags:
karpenter.sh/discovery: ${EKS_CLUSTER_NAME}
created-by: eks-workshop-v2
env: ${EKS_CLUSTER_NAME}
iam:
withOIDC: true
vpc:
cidr: 10.42.0.0/16
clusterEndpoints:
privateAccess: true
publicAccess: true
addons:
- name: vpc-cni
version: 1.16.0
configurationValues: '{"env":{"ENABLE_PREFIX_DELEGATION":"true", "ENABLE_POD_ENI":"true", "POD_SECURITY_GROUP_ENFORCING_MODE":"standard"},"enableNetworkPolicy": "true", "nodeAgent": {"enablePolicyEventLogs": "true"}}'
resolveConflicts: overwrite
managedNodeGroups:
- name: default
desiredCapacity: 3
minSize: 3
maxSize: 6
instanceType: m5.large
privateNetworking: true
releaseVersion: "1.30.0-20240625"
updateConfig:
maxUnavailablePercentage: 50
labels:
workshop-default: "yes"
EOF
eksctl create cluster -f myeks-cluster.yaml
2
결과?
eksctl-eks-workshop-cluster/VPC
eksctl-eks-workshop-cluster pub 3개
eksctl-eks-workshop-cluster pri 3개
클러스터 이름
eks-workshop
클러스터 > Compute > Node groups
default
3
kubectl get nodes
쇼핑카트 마이크로 서비스가 배포되어 있는 상태이다.
https://www.eksworkshop.com/docs/introduction/getting-started/about
https://www.eksworkshop.com/docs/security/
1
파드가 권한이 필요하다. = IRSA 사용한다.
use-cluster $EKS_CLUSTER_NAME
환경 설정을 한다.
2
https://www.eksworkshop.com/docs/security/iam-roles-for-service-accounts/using-dynamo
로컬 다이나모 디비 대신 AWS 다이나모 디비로 변경하려 한다.
확인
kubectl -n carts get -o yaml cm carts
1
디폴트 사용 = ROOT 로 사용 = 보안에 취약
2
ec2-user:~/environment $ kubectl get ns
NAME STATUS AGE
assets Active 30m
carts Active 30m
catalog Active 30m
checkout Active 30m
default Active 42m
kube-node-lease Active 42m
kube-public Active 42m
kube-system Active 42m
orders Active 30m
other Active 12m
rabbitmq Active 30m
ui Active 30m
ec2-user:~/environment $ kubectl -n assets get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
assets 1/1 1 1 30m
ec2-user:~/environment $ kubectl -n assets get deployment assets -o yaml | yq '.spec.template.spec'
containers:
- envFrom:
- configMapRef:
name: assets
image: public.ecr.aws/aws-containers/retail-store-sample-assets:0.4.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /health.html
port: 8080
scheme: HTTP
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 1
name: assets
ports:
- containerPort: 8080
name: http
protocol: TCP
resources:
limits:
memory: 128Mi
requests:
cpu: 128m
memory: 128Mi
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /tmp
name: tmp-volume
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: assets
serviceAccountName: assets
terminationGracePeriodSeconds: 30
volumes:
- emptyDir:
medium: Memory
name: tmp-volume
ec2-user:~/environment $
V
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/privileged-workload
namespace/assets unchanged
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
deployment.apps/assets configured
kubectl -n assets get pod
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-78666574f6-7hft5 1/1 Running 0 10s
ec2-user:~/environment $ kubectl -n assets exec $(kubectl -n assets get pods -o name) -- whoami
root
3
권한으로 제한 사용 = 중간 보안
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/baseline-namespace
namespace/assets unchanged
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
Warning: would violate PodSecurity "baseline:latest": privileged (container "assets" must not set securityContext.privileged=true)
deployment.apps/assets configured
ec2-user:~/environment $
ec2-user:~/environment $
ec2-user:~/environment $ kubectl -n assets delete pod --all
pod "assets-7ccc84cb4d-xvkdv" deleted
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-7ccc84cb4d-zz2wj 1/1 Running 0 6s
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-7ccc84cb4d-zz2wj 1/1 Running 0 13s
ec2-user:~/environment $ kubectl get deployment -n assets assets -o yaml | yq '.status'
availableReplicas: 1
conditions:
- lastTransitionTime: "2023-11-09T02:22:42Z"
lastUpdateTime: "2023-11-09T02:22:42Z"
message: 'pods "assets-78666574f6-6v64m" is forbidden: violates PodSecurity "baseline:latest": privileged (container "assets" must not set securityContext.privileged=true)'
reason: FailedCreate
status: "True"
type: ReplicaFailure
- lastTransitionTime: "2023-11-09T02:23:29Z"
lastUpdateTime: "2023-11-09T02:23:29Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2023-11-09T01:40:32Z"
lastUpdateTime: "2023-11-09T02:23:29Z"
message: ReplicaSet "assets-78666574f6" is progressing.
reason: ReplicaSetUpdated
status: "True"
type: Progressing
observedGeneration: 4
readyReplicas: 1
replicas: 1
unavailableReplicas: 1
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/baseline-workload
namespace/assets unchanged
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
deployment.apps/assets configured
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-7ccc84cb4d-j6cvx 1/1 Running 0 36s
ec2-user:~/environment $ kubectl -n assets exec $(kubectl -n assets get pods -o name) -- whoami
nginx
4
보안이 가장 강하다.
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/baseline-workload
namespace/assets unchanged
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
deployment.apps/assets configured
ec2-user:~/environment $
ec2-user:~/environment $
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-7ccc84cb4d-j6cvx 1/1 Running 0 36s
ec2-user:~/environment $ kubectl -n assets exec $(kubectl -n assets get pods -o name) -- whoami
nginx
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/restricted-namespace
Warning: existing pods in namespace "assets" violate the new PodSecurity enforce level "restricted:latest"
Warning: assets-7ccc84cb4d-j6cvx: allowPrivilegeEscalation != false, runAsNonRoot != true, seccompProfile
namespace/assets configured
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
deployment.apps/assets unchanged
ec2-user:~/environment $ kubectl -n assets delete pod --all
pod "assets-7ccc84cb4d-j6cvx" deleted
ec2-user:~/environment $ kubectl -n assets get pod
No resources found in assets namespace.
ec2-user:~/environment $
ec2-user:~/environment $ kubectl apply -k ~/environment/eks-workshop/modules/security/pss-psa/restricted-workload
namespace/assets unchanged
serviceaccount/assets unchanged
configmap/assets unchanged
service/assets unchanged
deployment.apps/assets configured
ec2-user:~/environment $ kubectl -n assets get pod
NAME READY STATUS RESTARTS AGE
assets-5bb65f9959-pvvm4 1/1 Running 0 4s
ec2-user:~/environment $
시크릿 매니저 사용
쿠버네티스에서 시크릿 매니저 사용해보자.
https://www.eksworkshop.com/docs/security/secrets-management/secrets-manager/
1
ec2-user:~/environment $ export SECRET_SUFFIX=$(openssl rand -hex 4)
ec2-user:~/environment $ export SECRET_NAME="$EKS_CLUSTER_NAME-catalog-secret-${SECRET_SUFFIX}"
ec2-user:~/environment $ aws secretsmanager create-secret --name "$SECRET_NAME" \
> --secret-string '{"username":"catalog_user", "password":"default_password"}' --region $AWS_REGION
{
"ARN": "arn:aws:secretsmanager:ap-northeast-2:319485572629:secret:eks-workshop-catalog-secret-fbf13fe1-uimSoX",
"Name": "eks-workshop-catalog-secret-fbf13fe1",
"VersionId": "be3473c9-c5a4-4092-8e04-dc444b60a51c"
}
ec2-user:~/environment $ aws secretsmanager describe-secret --secret-id "$SECRET_NAME"
{
"ARN": "arn:aws:secretsmanager:ap-northeast-2:319485572629:secret:eks-workshop-catalog-secret-fbf13fe1-uimSoX",
"Name": "eks-workshop-catalog-secret-fbf13fe1",
"LastChangedDate": "2023-11-09T02:31:17.877000+00:00",
"VersionIdsToStages": {
"be3473c9-c5a4-4092-8e04-dc444b60a51c": [
"AWSCURRENT"
]
},
"CreatedDate": "2023-11-09T02:31:17.672000+00:00"
}
ec2-user:~/environment $
2
AWS Secrets and Configuration Provider (ASCP)
볼륨으로 가져오도록 해보자.
https://brunch.co.kr/@topasvga/3519