월루를 꿈꾸는 대학생
PKOS 5주차 보안 본문
‘24단계 실습으로 정복하는 쿠버네티스’ 책을 기준하여 정리하였습니다.
http://www.yes24.com/Product/Goods/115187666
인스턴스 중 1대는 메타데이터 보안을 제거
#
kops edit ig nodes-ap-northeast-2a
---
# 아래 3줄 제거
spec:
instanceMetadata:
httpPutResponseHopLimit: 1
httpTokens: required
---
# 업데이트 적용 : 노드1대 롤링업데이트
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster --yes
# netshoot-pod 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 2
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})
# EC2 메타데이터 정보 확인
kubectl exec -it $PODNAME1 -- curl 169.254.169.254 ;echo
## 1번은 안 나오고 2번은 나옴
## 1번에서는 메타데이터를 받지 못함
kubectl exec -it $PODNAME2 -- curl 169.254.169.254 ;echo
## 2번에는 보안삭제해서 ㅅ보이는 듯
# 파드1에서 EC2 메타데이터 정보 확인
kubectl exec -it $PODNAME1 -- curl 169.254.169.254/latest ;echo
kubectl exec -it $PODNAME1 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/ ;echo
kubectl exec -it $PODNAME1 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/nodes.$KOPS_CLUSTER_NAME | jq
# 파드2에서 EC2 메타데이터 정보 확인
kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest ;echo
kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/ ;echo
kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/nodes.$KOPS_CLUSTER_NAME | jq
(hazu:N/A) [root@kops-ec2 ~]# kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest ;echo
dynamic
meta-data
user-data
(hazu:N/A) [root@kops-ec2 ~]# kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/ ;echo
nodes.hazu.link
(hazu:N/A) [root@kops-ec2 ~]# kubectl exec -it $PODNAME2 -- curl 169.254.169.254/latest/meta-data/iam/security-credentials/nodes.$KOPS_CLUSTER_NAME | jq
{
"Code": "Success",
"LastUpdated": "2023-04-08T16:09:32Z",
"Type": "AWS-HMAC",
"AccessKeyId": "ASIAWEYDAGVRFQM6VDXF",
"SecretAccessKey": "NqHLsYCr0SMWiiOlWzuV1PM04/tULdA4hu1hfmcp",
"Token": "IQoJb3JpZ2luX2VjEHgaDmFwLW5vcnRoZWFzdC0yIkcwRQIhAMRd7ohZb71PfNMItu4XhYb/UWYDdGEYvI3f2N9VuyViAiA+2nEifU6Gb5pNUoSjyix7QHuKNzmgtsuoEj+sCiny9SrMBQhhEAEaDDQyMjUyMzcxMjg2NiIMXDwR3xLazR+ilbLSKqkF/baxb6/VuvxDuCcmDLOXvzCvPyWXJzy0vmsSZqVZYjuekXHMS7GjuN9UnZcLpqIE3XBpK1eV6fAnyXYtJWqd/1+SASAz4G/W9nhKbcFU+kASauwkoWeV2qn4H6lKYA9lzGU+IUOcpKSS2iV5kmD5WlWvot1ZuEHji1+HxvfVrX+BPl0auuI84bD9bjbrYv0IyJ++1/h3QUjsHlPA8YhL++kr+5PEZhI01R9lIJHyrf7vM9K9VPAUugafjgU3PN4sTaRGu1LaggbEEiAGOxo+6g4OHeQ3n5fkRWK0sTztKMkKAzkJ4gz0zmoKv5wdFOSAdKQUKY5ND+618ir7F8lHFIyAeHdq1DSim8ACFVy5YxU5FwwjdQE6slBGgQGWrofrsKoErNgOASTQDEsS+vublOwswHZkvr5DhRoll/D6hWNkiLTf07lPNWnRe6AdYvlTI/vkKesB8yGarzh+NmvBSBCoT1lJqd9zLnYbmH1KyaRKFI2BzhM+uKMGahzZCpxkspSnIuuDalPgP/xx73OHII1AWsCi+5yanjl2vvhByYfij/EDGa0mRs3PBThVbFufNeYKOBOeBRT4nC3a3dNCbJQXhA0mKrOCOcnhrtfSMt2viudu1f1qr+NrwnZyOg64Hkt6YhtilrtftoBTJZiYE15r0CmIC5nTW+V02/hk3LtcrUiMtWCcpQduqpUex6pnwwzADe7ybv9w5lowr/ogGlIkleVZ6sIwxdf/j7r5UP99TOMpWTEZc3FFrJWJyNPa1y7jfYVOXBsQOE3PcCrgALXEB5W++mkP0I0Wbyp4mKnflIXv9lYU/WTYWDjyTk35U2wHSDrqsPl4isrbQhTqA+FoJBgtnAh2vr2WZR7jOUUcb7nVo3OQGbiKCUScBqRpAkDsJpBbPf2YMOCjxqEGOrEBjYW31vcQMDQ1Zya0oIavAhYMvIYZrIBjKHyTmhWKxxpEUUSNKOMyvEsX7+L88a9Y/bwuI2mYzZyVReXFN7x/sCjKPCNnCwroY6xCaWxk5JonYfez6LRBnnNr+iCkhqiuGlyGzphFUnBOQNaMpagh5YRxX/CzifbJvo/vaiXNOUp/B4AkWEDuzrmwFEiNtYyDJVlmmZl+bnnfgNQZQTwmaqArdqAVi9/YWhm9fYH4LBpD",
"Expiration": "2023-04-08T22:45:08Z"
}
저렇게 보이면 탈취되었다고 보고 해당 토큰을 가지고 악용이 가능
# boto3 사용을 위한 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: boto3-pod
spec:
replicas: 2
selector:
matchLabels:
app: boto3
template:
metadata:
labels:
app: boto3
spec:
containers:
- name: boto3
image: jpbarto/boto3
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=boto3 -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=boto3 -o jsonpath={.items[1].metadata.name})
# 파드1에서 boto3 사용
kubectl exec -it $PODNAME1 -- sh
------------
cat <<EOF> ec2.py
import boto3
ec2 = boto3.client('ec2', region_name = 'ap-northeast-2')
response = ec2.describe_instances()
print(response)
EOF
python ec2.py # aws ec2 describe-vpcs
exit
------------
# 파드2에서 boto3 사용
kubectl exec -it $PODNAME2 -- sh
------------
cat <<EOF> ec2.py
import boto3
ec2 = boto3.client('ec2', region_name = 'ap-northeast-2')
response = ec2.describe_instances()
print(response)
EOF
python ec2.py # aws ec2 describe-vpcs
exit
------------
# 실습 완료 후 삭제
kubectl delete deploy boto3-pod
탈취가 되었을 때 악용될 수가 있으므로 IRSA를 사용하기 권장
iam 역할을 공유하는 경우 pod 하나만 탈취되더라도 공유되기때문에 문제
IRSA를 사용하면 pod별 iam 규칙을 사용할 수 있어서 보다 안정적
실제로 취득한 토큰과 키들을 넣고 확인해보면 aws 리소스를 확인하고 사용할 수 있음
이래서 요금폭탄 맞는 경우가 생기는 듯
# awscli 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: awscli-pod
spec:
replicas: 2
selector:
matchLabels:
app: awscli-pod
template:
metadata:
labels:
app: awscli-pod
spec:
containers:
- name: awscli-pod
image: amazon/aws-cli
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 파드 이름 변수 지정
APODNAME1=$(kubectl get pod -l app=awscli-pod -o jsonpath={.items[0].metadata.name})
APODNAME2=$(kubectl get pod -l app=awscli-pod -o jsonpath={.items[1].metadata.name})
---
# 메타데이터 메모해두기 : 단 Expiration 시간이 지나면 Token은 유효하지 않음
{
"Code": "Success",
"LastUpdated": "2023-03-01T14:11:26Z",
"Type": "AWS-HMAC",
"AccessKeyId": "ASIA5ILF2FJIZ3VBD6DB",
"SecretAccessKey": "6fCWhz1eKupIXNl9w/BMcHh1YdSOYcFsGv3r+EX/",
"Token": "IQoJb3JpZ2luX2VjEOb//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIhAJRp7ov3nvS7fErWhNqo7ebeYZSS5UpL/pFP763QGDu7AiB23SvUsLr0J1bU/7gDsVH7KHta9Jm7pNwHyQrXZIMQSSrVBQiP//////////8BEAEaDDkxMTI4MzQ2NDc4NSIMgF5IMoJtct/G4uoYKqkFpUmOepDUb2NyRJ5b4CoeAzfEAReqtndk3EJiodz9RQiR0HTtkjfSHpQpCA5JuKDJR+kU8vkhbB+YHgrcL167k+lnblzJuhqYIAtTVYQ3UmZCfVYiwnA/ZhBxqzEvfQrmXQck990rT0sCHf0+fsWeeZHylsHi4DXINSv8BZbgm3leC/n77bJifeYvskbcWML9yEYAMK/rolnehtz/yuKqdWqN1PcmzL8KfkytBkCIEzezDVPF+9DLXbvOQXn26+41PzvXd+pB+d+IkbP8zCnC5hcbLZwE5z8/KYyqTdj9cJqTzQhSnMFkWFiYh4HddVpOq6oj0hOmIbjH8iAD9oMwEuVd/BgBPm9yadVugDVp6XWkLSaQ0esCoVALKzlbr06Tg7JUSpniuSEApqbAKM1dJlHck76UQwXot1n/D54JNyAq2GXbJz/ndqNsBCdtbVWERjcOyCZOH14uLlrRKZUmTEXpIhGOgpq4AHE+/KdisVDu0aaOvaQUhAzMg+x5ROqHCtJoLByYcez0A6PNqiBRIupKWYyRhZY7WzyH21BYw4pgI6ytjBOAQIknCyf5XzU/r+g6r8Ts9BXF75gPfIsMQQbKXdvjoJAHN3HMcfeiiuu6/LQ+bUkkiWdGepyx8iE+UzT8+AMa0Le3zNVSJCK+qz4gSnD/HW87+JPzzZyHA2yYMyXXAq0mBqxtiqI/maMx2o7Mi+xfsBa8cnvWOV3oAQN+drfkkRWWMZaEGVrCLBUf8KSQKup6hu4m257ytBUR3TH5schErAmksSadBzkiK8QX8ZOWNcuHQNcvPd56oLvKgDb1I5ehe96wgHWa/ZZz4jZZIrXKlVC30hRARARqTQxeo1CPi9P2lZrC+Z7vlHVGtazonB+atbQOFScDLAnBrAW4cpxM3sK9MOK5/Z8GOrEB+xhO3/OVp3bCpZ92G97tUUS07j4DWyCeFs1FXSUgLfwvXh7w0e9KPNW+tq87knudsCimTlsw5b/BFBCk5T386qv12m5CqYfOmTwLovpVUmR1wAoeIMgpBTb5AdpXkeuuMdCAc5nNqv3Zdp84+acyR1V2DmvRcFkQqtrCuc4Wt9FYi2QAcurNK9+HGDtlOstFVr2TiiPHpg1hCB3AhX8gpiiC4p5sK5P0VePWyjvSfirl",
"Expiration": "2023-03-01T20:12:11Z"
}
---
# 파드 bash 실행 : 임시자격증명을 직접 입력하는 거라서 아무곳에서나 해도됨 >> 즉 별도의 ec2 1대를 신규 생성 후 임시자격증명 설정 후 확인해보자
# 실행하는 파드는 메타데이터 사용 시 Token이 필요한 노드에 배치된 파드에서 해볼 것!
kubectl get pod -owide
kubectl exec -it $APODNAME1 -- bash
kubectl exec -it $APODNAME2 -- bash
----------------------------------------------------------
# 위에서 출력된 AccessKeyId , SecretAccessKey , SessionToken 으로 임시자격증명 적용
export AWS_ACCESS_KEY_ID="ASIA5ILF2FJIZ3VBD6DB"
export AWS_SECRET_ACCESS_KEY="6fCWhz1eKupIXNl9w/BMcHh1YdSOYcFsGv3r+EX/"
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2VjEOb//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIhAJRp7ov3nvS7fErWhNqo7ebeYZSS5UpL/pFP763QGDu7AiB23SvUsLr0J1bU/7gDsVH7KHta9Jm7pNwHyQrXZIMQSSrVBQiP//////////8BEAEaDDkxMTI4MzQ2NDc4NSIMgF5IMoJtct/G4uoYKqkFpUmOepDUb2NyRJ5b4CoeAzfEAReqtndk3EJiodz9RQiR0HTtkjfSHpQpCA5JuKDJR+kU8vkhbB+YHgrcL167k+lnblzJuhqYIAtTVYQ3UmZCfVYiwnA/ZhBxqzEvfQrmXQck990rT0sCHf0+fsWeeZHylsHi4DXINSv8BZbgm3leC/n77bJifeYvskbcWML9yEYAMK/rolnehtz/yuKqdWqN1PcmzL8KfkytBkCIEzezDVPF+9DLXbvOQXn26+41PzvXd+pB+d+IkbP8zCnC5hcbLZwE5z8/KYyqTdj9cJqTzQhSnMFkWFiYh4HddVpOq6oj0hOmIbjH8iAD9oMwEuVd/BgBPm9yadVugDVp6XWkLSaQ0esCoVALKzlbr06Tg7JUSpniuSEApqbAKM1dJlHck76UQwXot1n/D54JNyAq2GXbJz/ndqNsBCdtbVWERjcOyCZOH14uLlrRKZUmTEXpIhGOgpq4AHE+/KdisVDu0aaOvaQUhAzMg+x5ROqHCtJoLByYcez0A6PNqiBRIupKWYyRhZY7WzyH21BYw4pgI6ytjBOAQIknCyf5XzU/r+g6r8Ts9BXF75gPfIsMQQbKXdvjoJAHN3HMcfeiiuu6/LQ+bUkkiWdGepyx8iE+UzT8+AMa0Le3zNVSJCK+qz4gSnD/HW87+JPzzZyHA2yYMyXXAq0mBqxtiqI/maMx2o7Mi+xfsBa8cnvWOV3oAQN+drfkkRWWMZaEGVrCLBUf8KSQKup6hu4m257ytBUR3TH5schErAmksSadBzkiK8QX8ZOWNcuHQNcvPd56oLvKgDb1I5ehe96wgHWa/ZZz4jZZIrXKlVC30hRARARqTQxeo1CPi9P2lZrC+Z7vlHVGtazonB+atbQOFScDLAnBrAW4cpxM3sK9MOK5/Z8GOrEB+xhO3/OVp3bCpZ92G97tUUS07j4DWyCeFs1FXSUgLfwvXh7w0e9KPNW+tq87knudsCimTlsw5b/BFBCk5T386qv12m5CqYfOmTwLovpVUmR1wAoeIMgpBTb5AdpXkeuuMdCAc5nNqv3Zdp84+acyR1V2DmvRcFkQqtrCuc4Wt9FYi2QAcurNK9+HGDtlOstFVr2TiiPHpg1hCB3AhX8gpiiC4p5sK5P0VePWyjvSfirl"
# ec2 정보 확인
bash-4.2# aws ec2 describe-instances --region ap-northeast-2 | head
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-0443a21cb1a8f238e",
"InstanceId": "i-0003f6c91590ed72a",
"InstanceType": "t2.micro",
...
# vpc 정보 확인
bash-4.2# aws ec2 describe-vpcs --region ap-northeast-2 | head
...
# 빠져나오기
exit
----------------------------------------------------------
kubescape
- 보안 권고 사항을 체크하고 점검
# 설치
curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash
# Download all artifacts and save them in the default path (~/.kubescape)
kubescape download artifacts
tree ~/.kubescape/
cat ~/.kubescape/attack-tracks.json | jq
# 제공하는 보안 프레임워크 확인
kubescape list frameworks --format json | jq '.[]'
"AllControls"
"ArmoBest"
"DevOpsBest"
"MITRE"
"NSA"
"cis-eks-t1.2.0"
"cis-v1.23-t1.0.1"
# 제공하는 통제 정책 확인
kubescape list controls
# 모니터링
watch kubectl get pod -A
# 클러스터 스캔
# Deploy Kubescape host-sensor daemonset in the scanned cluster. Deleting it right after we collecting the data.
# Required to collect valuable data from cluster nodes for certain controls.
# Yaml file: https://github.com/kubescape/kubescape/blob/master/core/pkg/hostsensorutils/hostsensor.yaml
kubescape scan --help
kubescape scan --enable-host-scan --verbose
보안 컨텍스트 : 컨테이너 , 파드 보안 통제 기법 중 하나 !
#
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: rootfile-readonly
spec:
containers:
- name: netshoot
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
securityContext:
readOnlyRootFilesystem: true
terminationGracePeriodSeconds: 0
EOF
## 컨테이너 레벨에 들어가 있음
## 읽기 전용이라 파일 생성 불가
# 파일 생성 시도
kubectl exec -it rootfile-readonly -- touch /tmp/text.txt
touch: /tmp/text.txt: Read-only file system
command terminated with exit code 1
linux capabiliites
- 유저의 권한으로는 권한 통제 단위가 부족하니까 또 나눔
#
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: sample-capabilities2
spec:
containers:
- name: nginx-container
image: masayaaoyama/nginx:capsh
command: ["tail"]
args: ["-f", "/dev/null"]
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
drop: ["AUDIT_WRITE"]
terminationGracePeriodSeconds: 0
EOF
# 파드의 Linux Capabilities 기본 확인
kubectl exec -it sample-capabilities2 -- capsh --print | grep Current
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_setfcap+ep
cap_chown,
cap_dac_override,
cap_fowner,
cap_fsetid,
cap_kill,
cap_setgid,
cap_setuid,
cap_setpcap,
cap_net_bind_service,
cap_net_admin, # 추가
cap_net_raw,
cap_sys_chroot,
cap_sys_time, # 추가
cap_mknod,
cap_setfcap+ep
# 제거됨 cap_audit_write
# 파드 상세 정보 확인
kubectl get pod sample-capabilities2 -o jsonpath={.spec.containers[0].securityContext} | jq
{
"capabilities": {
"add": [
"NET_ADMIN",
"SYS_TIME"
],
"drop": [
"AUDIT_WRITE"
]
}
}
# proc 에서 확인 : bit 별 Capabilities - 링크
kubectl exec -it sample-capabilities2 -- cat /proc/1/status | egrep 'CapPrm|CapEff'
CapPrm: 000000008a0435fb
CapEff: 000000008a0435fb
# 파드에서 시간 변경 시도 : 시간 동기화하는 다른 우선순위가 있는것 같습니다! 혹신 아시는 분들은 댓글 부탁드립니다!
## 확인해 보니 시간이 변경되었지만 해당 파드가 동작되는 노드의 시간을 sync 하고 있습니다.
## 노드에 접근해서 systemd-timesyncd 종료하면은 노드의 바뀐 시간까지는 따라가는 것을 확인했습니다.
## systemctl stop systemd-timesyncd 그리고 파드에서 시간 변경시 해당 노드의 시간도 바뀌는 것을 확인 했습니다.
kubectl exec -it sample-capabilities2 -- date
kubectl exec -it sample-capabilities2 -- date -s "12:00:00"
kubectl exec -it sample-capabilities2 -- date
시간 권한 변경을 따로 주니까 에러가 안나고 시간 변경이 가능
파드 보안 컨텍스트
- 파드에 포함된 컨테이너가 영향을 받음
- 컨테이너 정책이 우선순위가 높음
#
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: rundefault
spec:
containers:
- name: centos
image: centos:7
command: ["tail"]
args: ["-f", "/dev/null"]
securityContext:
readOnlyRootFilesystem: true
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: runuser
spec:
securityContext:
runAsUser: 65534
runAsGroup: 65534
supplementalGroups:
- 1001
- 1002
containers:
- name: centos
image: centos:7
command: ["tail"]
args: ["-f", "/dev/null"]
securityContext:
readOnlyRootFilesystem: true
terminationGracePeriodSeconds: 0
EOF
#
kubectl get pod rundefault -o jsonpath={.spec.securityContext} | jq
kubectl get pod runuser -o jsonpath={.spec.securityContext} | jq
# 실행 사용자 정보 확인
kubectl exec -it rundefault -- id
uid=0(root) gid=0(root) groups=0(root)
kubectl exec -it runuser -- id
uid=65534 gid=65534 groups=65534,1001,1002
# 프로세스 정보 확인
kubectl exec -it rundefault -- ps -axo uid,user,gid,group,pid,comm
UID USER GID GROUP PID COMMAND
0 root 0 root 1 tail
0 root 0 root 13 ps
kubectl exec -it runuser -- ps -axo uid,user,gid,group,pid,comm
UID USER GID GROUP PID COMMAND
65534 65534 65534 65534 1 tail
65534 65534 65534 65534 19 ps
유저 정보를 바꿨고 확인 해보니 하나는 루트 하나는 지정한 유저
보안을 강화하기 위해 루트 말고 다른 유저로 지정하는 편이 좋다
파일시스템 그룹 지정
- 마운트 하는 볼륨 그룹 변경 가능
#
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: fsgoup1
spec:
volumes:
- name: vol1
emptyDir: {}
containers:
- name: centos
image: centos:7
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: vol1
mountPath: /data/demo
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: fsgoup2
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: vol2
emptyDir: {}
containers:
- name: centos
image: centos:7
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: vol2
mountPath: /data/demo
terminationGracePeriodSeconds: 0
EOF
#
kubectl get pod fsgoup1 -o jsonpath={.spec.securityContext} | jq
kubectl get pod fsgoup2 -o jsonpath={.spec.securityContext} | jq
# 실행 사용자 정보 확인
kubectl exec -it fsgoup1 -- id
uid=0(root) gid=0(root) groups=0(root)
kubectl exec -it fsgoup2 -- id
uid=1000 gid=3000 groups=3000,2000
# 프로세스 정보 확인
kubectl exec -it fsgoup1 -- ps -axo uid,user,gid,group,pid,comm
kubectl exec -it fsgoup2 -- ps -axo uid,user,gid,group,pid,comm
# 디렉터리 정보 확인 : fsgoup2파드의 마운트 볼륨 그룹의 GID가 2000 (fsGroup: 2000)
kubectl exec -it fsgoup1 -- ls -l /data
drwxrwxrwx 2 root root 4096 Apr 1 05:15 demo
kubectl exec -it fsgoup2 -- ls -l /data
drwxrwsrwx 2 root 2000 4096 Apr 1 05:15 demo
Polaris
이미 배포된 워크로드 또는 신규로 배포하게 되는 워크로드가 보안, 신뢰성, 네트워크, 효율성등에 어느정도 적절하게 구성되었는지 검사할 수 있는 도구
# 설치
kubectl create ns polaris
#
cat <<EOT > polaris-values.yaml
dashboard:
replicas: 1
service:
type: LoadBalancer
EOT
# 배포
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install polaris fairwinds-stable/polaris --namespace polaris --version 5.7.2 -f polaris-values.yaml
# CLB에 ExternanDNS 로 도메인 연결
kubectl annotate service polaris-dashboard "external-dns.alpha.kubernetes.io/hostname=polaris.$KOPS_CLUSTER_NAME" -n polaris
# 웹 접속 주소 확인 및 접속
echo -e "Polaris Web URL = http://polaris.$KOPS_CLUSTER_NAME"
# netshoot-pod 1대 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 1
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot:v0.9
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
1개만 돌리고 있어서 권고사항 뜸
kubectl scale deployment netshoot-pod --replicas 2
통과!
#
kubectl krew install neat
kubectl get deploy/polaris-dashboard -n polaris -o yaml | kubectl neat > polaris-pod.yaml
cat polaris-pod.yaml | yh
...
spec:
template:
spec:
containers:
imagePullPolicy: Always # 이미지를 항상 리포지토리에서 가져오게 설정
resources: # 리소스 자원 사용 보장 및 제한
limits:
cpu: 150m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
securityContext: # 컨테이너, 파드의 권한 및 접근 제어
allowPrivilegeEscalation: false # 컨테이너의 하위 프로세스가 상위 프로세스보다 많은 권한을 얻을 수 없게 설정
capabilities: # 호스트 커널 레벨 수정이 필요 시 root 권한으로 전체 커널을 수정하지 않고 특정 커널 권한만 부여 후 사용
drop:
- ALL
privileged: false # true인 경우 호스트의 모든 장치에 접근 권한 가짐, 컨테이너의 root권한이더라도 namespace/cgroup으로 격리되어 호스트의 다른 장치 접근 불가
readOnlyRootFilesystem: true # 컨테이너의 root 파일시스템에 읽기 전용
runAsNonRoot: true # root 권한으로 컨테이너를 실행하지 않음
...
권고사항에 적합하지 않은 부분들을 수정해서 다시 배포
# 삭제
kubectl delete deploy netshoot-pod
# netshoot-pod 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 2
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot:v0.9
command: ["tail"]
args: ["-f", "/dev/null"]
imagePullPolicy: Always
resources:
limits:
cpu: 150m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
#runAsNonRoot: true
terminationGracePeriodSeconds: 0
EOF
kubescape
- 보안 권고 사항 대비 지금 구성된 클러스터의 취약점을 점검하는 도구
보안 점검 결과
'Server&Network > Kubernets_Dokcer' 카테고리의 다른 글
PKOS 4주차 모니터링 (0) | 2023.04.02 |
---|---|
PKOS 3주차 GitOps (0) | 2023.03.26 |
PKOS 2주차 (1) | 2023.03.19 |
PKOS 1주차 (2) | 2023.03.12 |
로컬에서 k8s 구축하기 (1) | 2023.03.04 |