본문 바로가기
카테고리 없음

Polaris를 통한 보안 적용하기

by james_janghun 2023. 4. 8.

이번에 쿠버네티스 스터디의 마지막 5장의 내용을 작성해보고자한다.

 

보안에는 다양한 툴들이 등장하고 있는데 특히 이번에 배운 polaris라는 오픈소스를 처음 접하고 많은 관심이 생겨서 이 부분에 대해서 좀 더 자세히 적어보고자 한다.

 

1. Polaris란 무엇인가

polaris는 쿠버네티스 클러스터의 구성 및 보안 설정과 관련된 문제를 자동을 검사하고 보고서를 생성하는 오픈소스 툴이다. 다양한 검사 항목과 보안 권장 사항을 지원해서 운영자가 좀 더 손쉽고 정확하게 보안 진단을 할 수 있다.

- 깃허브 : (https://github.com/FairwindsOps/polaris/tree/v5.0.1)

- DOCS : (https://polaris.docs.fairwinds.com/)

 

 

2. Polaris의 기능

https://github.com/FairwindsOps/polaris/tree/v5.0.1

polaris를 동작시키는 방법은 총 3가지가 있다.

첫째는 대시보드를 통한 방식이다. 가장 가시적이고 가장 간편하기 때문에 초보가 사용하기 좋고 기본적으로 운영자가 운영상태 보고서를 받는 느낌으로 사용할 수 있다.

둘째는 adminssion controller를 활용하는 방식이다. 컨트롤러를 통해 작동하기 때문에 정해진 룰에 따른 자동화가 가능하다.

셋째는 CLI를 활용하는 방식이다. 좀 더 전문가용으로 로컬 YAML 파일과 같은 작업을 좀 더 빠르고 대규모로 적용이 가능하다.

 

 

 

3. Polaris 설치

3.1 대시보드 형

 

3.1.1 설치

helm을 통해서 polaris 대시보드를 설치해보자.

helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm upgrade --install polaris fairwinds-stable/polaris --namespace polaris --create-namespace
kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80

 

3.1.2 Overview 

설치한 대시보드에 접속하면 아래와 같은 페이지가 나오는데, 한눈에 아주 잘 보이고 깔끔한 UI가 등장한다.

현재 페이지는 cluster에 대한 overview로 warning checks와 Dangerous Checks를 기준으로 심각도를 확인할 수 있는데 warning은 경고 수준이지만 Dangerous의 경우는 되도록 조치를 반드시 해야한다.

 

 

 

3.1.3 Categories

Categories 색션에서는 아래 3가지 섹션에 대해서 표시한다.

 

Result by Catagory

- Efficiency (효율성) : 쿠버네티스 클러스터의 워크로드에 대한 리소스 요청 및 제한에 대한 구성으로 CPU나 메모리에 대한 요청이나 제한 값에 대한 부분을 확인한다. 특히 쿠버네티스 클러스터의 경우 많은 자원이 컨테이너로 가상화 동작하기 때문에 적당한 조율이 반드시 필요하다.

https://polaris.docs.fairwinds.com/checks/efficiency/

 

- Reliability (신뢰성) : 워크로드가 항상 사용 가능하고 올바른 이미지를 실행하는지 확인하는 지표이다.

https://polaris.docs.fairwinds.com/checks/reliability/

 

- Security (보안성) : 엑세스 수준 제한 등 기본적인 보안 검토하는 지표이다.

https://polaris.docs.fairwinds.com/checks/security/

3.1.4 filter

대시보드에서는 Namespace 필터를 통해서 조금 더 간편하게 클러스터에 대한 지표를 확인할 수 있다.

대부분 회사에서 네임스페이스를 통해서 서비스 부서 혹은 애플리케이션을 구분하고 있기 때문에 네임스페이스를 통해서 나눠주는 것은 상당히 쉽게 파악할 수 있도록 도와준다.

 

 

3.2 Admission Controller 활용하기

3.2.1 설치

명확한 설치를 위해서는 CA 인증서가 필요하다. helm의 set옵션을 통해서 여러가지 변형이 가능하다.

helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm upgrade --install polaris fairwinds-stable/polaris --namespace polaris --create-namespace \
  --set webhook.enable=true --set dashboard.enable=true

 

3.2.2 특징

취약했던 mario.yaml을 실행하려고 했더니, polaris가 막으면서 Danger의 내용을 표시하였다.

이미지 태그 없음, privilege escalation 없음을 해결하거나 허가하고 싶으면 웹훅을 통해 허가하라는 내용을 이야기한다.

즉, 워크로드에서 취약한 yaml이 발견되면 일단 STOP을 시켜주는 것이다.

다만, 취약의 조건은 현재는 Danger부분만 해당된다.

kubectl apply -f mario.yaml
service/mario created
Error from server (
Polaris prevented this deployment due to configuration problems:
- Container mario: Image tag should be specified
- Container mario: Privilege escalation should not be allowed
): error when creating "mario.yaml": admission webhook "polaris.fairwinds.com" denied the request:
Polaris prevented this deployment due to configuration problems:
- Container mario: Image tag should be specified
- Container mario: Privilege escalation should not be allowed

 

 

3.3 Polaris CLI  활용하기

CLI의 경우 쿠버네티스 매니페스트 파일을 감시하는데 사용된다. CI/CD에서도 적용할 수 있는데 yaml파일에 대한 검사 결과에서 polaris 점수가 설정 값보다 못미치거나 Dangerous Check가 발생하는 경우 CI/CD를 중단시킬 수 있다.

3.3.1 설치(리눅스 기준)

wget https://github.com/FairwindsOps/polaris/releases/download/7.4.1/polaris_linux_amd64.tar.gz
tar -zxvf polaris_linux_amd64.tar.gz
mv polaris /usr/local/bin/

 

3.3.2 audit

이런식의 audit 명령어를 통해서 현재 경로에 있는 yaml 파일을 점검할 수 있다.

polaris audit --audit-path . --format=pretty

예를들어 지금 마리오 게임을 배포하는 yaml이 있는데 이것을 검사해보자.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mario
  labels:
    app: mario
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mario
  template:
    metadata:
      labels:
        app: mario
    spec:
      containers:
      - name: mario
        image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
   name: mario
spec:
  selector:
    app: mario
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  type: LoadBalancer

검사결과를 다음과 같이 정말 예쁘게 표현해준다. 총 점수는 43점인데, Danger 한 것들을 좀 살펴볼 필요가 있다.

Polaris audited Path ./ at 2023-04-09T08:15:43+09:00
    Nodes: 0 | Namespaces: 0 | Controllers: 1
    Final score: 43

Deployment mario
    deploymentMissingReplicas            😬 Warning
        Reliability - Only one replica is scheduled
    hostIPCSet                           🎉 Success
        Security - Host IPC is not configured
    hostNetworkSet                       🎉 Success
        Security - Host network is not configured
    hostPIDSet                           🎉 Success
        Security - Host PID is not configured
    topologySpreadConstraint             😬 Warning
        Reliability - Pod should be configured with a valid topology spread constraint
  Container mario
    linuxHardening                       😬 Warning
        Security - Use one of AppArmor, Seccomp, SELinux, or dropping Linux Capabilities to restrict containers using unwanted privileges
    memoryLimitsMissing                  😬 Warning
        Efficiency - Memory limits should be set
    tagNotSpecified                      ❌ Danger
        Reliability - Image tag should be specified
    pullPolicyNotAlways                  😬 Warning
        Reliability - Image pull policy should be "Always"
    readinessProbeMissing                😬 Warning
        Reliability - Readiness probe should be configured
    sensitiveContainerEnvVar             🎉 Success
        Security - The container does not set potentially sensitive environment variables
    runAsRootAllowed                     ❌ Danger
        Security - Should not be allowed to run as root
    cpuLimitsMissing                     😬 Warning
        Efficiency - CPU limits should be set
    hostPortSet                          🎉 Success
        Security - Host port is not configured
    memoryRequestsMissing                😬 Warning
        Efficiency - Memory requests should be set
    livenessProbeMissing                 😬 Warning
        Reliability - Liveness probe should be configured
    notReadOnlyRootFilesystem            😬 Warning
        Security - Filesystem should be read only
    privilegeEscalationAllowed           ❌ Danger
        Security - Privilege escalation should not be allowed
    runAsPrivileged                      🎉 Success
        Security - Not running as privileged
    cpuRequestsMissing                   😬 Warning
        Efficiency - CPU requests should be set
    dangerousCapabilities                🎉 Success
        Security - Container does not have any dangerous capabilities
    insecureCapabilities                 😬 Warning
        Security - Container should not have insecure capabilities

Service mario

성공한 것을 제외하고 경고,위험만 보고싶다면 아래 명령어도 가능하다.

polaris audit --audit-path . --format=pretty --only-show-failed-tests

여기서 특히 위험한 Danger 부분만 해결해보자.

 

1. tagNotSpecified 

해당 위험은 컨테이너의 이미지의 버전이 명시되지 않은 경우이다. 이 경우 대부분 latest 이미지를 다운받게 되는데, 이 이미지가 취약점이 발견되거나 혹은 잘못 업로드 되는 순간 문제가 발생할 수 있기 때문에 특정 버전을 명시할 것을 권고하고 있다.

따라서 기존의 docker-supermario에서 docker-supermario:v1.2.0 이라는 임의의 버전을 붙였다.

(아쉽지만 이 이미지가 실제로는 latest버전만 존재하기 때문에.. 실습을 위해서 임의의 버전을 적었다.)

    spec:
      containers:
      - name: mario
        image: pengbai/docker-supermario:v1.2.0

 

2. runAsRootAllowed

이 위험은 컨테이너가 루트로 동작하는 것을 말하는데, 대부분의 컨테이너는 정해진 루틴대로만 진행하기 때문에 루트 권한이 필요없다. 루트 권한을 악의적인 사용자가 탈취하여 사용할 경우 해당 컨테이너를 통해 다른 컨테이너에 잘못된 명령을 실행하거나 클러스터 혹은 그 서비스 자체의 장애를 유발할 수 있기 때문에 위험하다. 따라서 spec.containers.securityContext를 추가하여 runAsNonRoot를 true로 설정하여 root 권한으로 동작하지 않도록 제한한다.

 

      securityContext:
        runAsNonRoot: true

 

3. allowPrivilegeEscalation

이 위험은 권한 상승에 대한 내용을 제한하는 것으로 위의 runAsNonRoot 형태와 비슷하게 작성한다.

      securityContext:
        allowPrivilegeEscalation: false

 

이렇게 하면 권한 점수가 일정부분 상승한 것을 확인할 수 있다. 하지만 그렇게 높진 않다. warning이 많다보니.

그래도 Danger부분은 제거됨을 확인할 수 있다.

Polaris audited Path . at 2023-04-09T08:40:00+09:00
    Nodes: 0 | Namespaces: 0 | Controllers: 1
    Final score: 56

Deployment mario
    deploymentMissingReplicas            😬 Warning
        Reliability - Only one replica is scheduled
    topologySpreadConstraint             😬 Warning
        Reliability - Pod should be configured with a valid topology spread constraint
  Container mario
    cpuRequestsMissing                   😬 Warning
        Efficiency - CPU requests should be set
    livenessProbeMissing                 😬 Warning
        Reliability - Liveness probe should be configured
    memoryRequestsMissing                😬 Warning
        Efficiency - Memory requests should be set
    readinessProbeMissing                😬 Warning
        Reliability - Readiness probe should be configured
    linuxHardening                       😬 Warning
        Security - Use one of AppArmor, Seccomp, SELinux, or dropping Linux Capabilities to restrict containers using unwanted privileges
    notReadOnlyRootFilesystem            😬 Warning
        Security - Filesystem should be read only
    insecureCapabilities                 😬 Warning
        Security - Container should not have insecure capabilities
    memoryLimitsMissing                  😬 Warning
        Efficiency - Memory limits should be set
    cpuLimitsMissing                     😬 Warning
        Efficiency - CPU limits should be set
    pullPolicyNotAlways                  😬 Warning
        Reliability - Image pull policy should be "Always"

3.3.3 CLI 커스터마이징

저렇게 모든 정보 출력 필요없이 사내에서 딱 필요한 정보들만 확인하고, 필터를 걸고자 한다면 아래와 같이 checks 에 대한 항목과 그 수준을 나열하면 된다.

checks:
  tagNotSpecified: ignore
  runAsRootAllowed: danger
  pullPolicyNotAlways: warning

 

--config 옵션을 통해서 위의 내용을 적용해보자.

polaris audit --audit-path . --config config.yaml --format pretty

출력값은 다음과 같은데, tag에 대한내용은 ignore되어 표시되지 않고, runAsRootAllowed, pullpolicyNotAlways만 식별해서 표시하였다. 

Polaris audited Path . at 2023-04-09T09:26:41+09:00
    Nodes: 0 | Namespaces: 0 | Controllers: 1
    Final score: 0

Deployment mario
  Container mario
    pullPolicyNotAlways                  😬 Warning
        Reliability - Image pull policy should be "Always"
    runAsRootAllowed                     ❌ Danger
        Security - Should not be allowed to run as root

Service mario

 

이상으로 polaris를 사용해보았는데, 실제로 현업에서 적용하기 좋은 가시적인 부분이 많아서 좋았다.

특히 대시보드를 통해서 전반적인 운영관리를 한눈에 파악하고, CLI를 통해 적용될 yaml에 대한 검사를 수행해 운영에 쉽게 적용가능하고 도움도 많이 될 것으로 생각된다.