보안 모델

보안 모델 (Security Model)

이 페이지는 Nomad의 보안 모델에 대한 개념 정보를 제공해요. 이 보안 모델은 mTLS, 네임스페이스, ACL(접근 제어 목록), Sentinel 정책, 리소스 쿼터 같은 메커니즘을 제공해 클러스터 내부와 클러스터 간 세분화된 접근을 가능하게 해요. Nomad 클러스터를 보호하는 방법, 위협 모델, 내부 위협, 외부 위협을 알아봐요. 보안 모델이 사용하는 네트워크 포트도 검토해요.

출처: 문서

본문

Nomad는 Consul과 유사한 경량 가십과 RPC 시스템을 활용해요. 두 시스템 모두 기밀성(confidentiality), 무결성(integrity), 인증(authentication)을 제공하는 데 도움이 되는 보안 메커니즘을 제공하므로 이를 활용해야 해요.

클러스터 보안에는 심층 방어(defense in depth)가 중요하며, 배포 요구 사항은 사용 사례에 따라 크게 달라질 수 있어요. 멀티 테넌트 배포를 위한 추가 보안 기능은 엔터프라이즈 버전에서만 제공돼요. 이 문서는 배포 상황에 맞게 조정해야 할 수 있지만, 안전한 Nomad 배포를 위한 일반적인 메커니즘은 다음과 같이 요약돼요.

  • mTLS — TLS 서버와 클라이언트 x509 인증서를 모두 상호 인증하면, 클러스터 내 네트워크 구성 요소에 대한 비인증 접근을 방지해 내부 남용을 막아요.
  • ACL — ACL 토큰에 기능(capabilities)을 부여해 인증된 연결에 대한 권한 부여를 활성화해요.
  • 네임스페이스 (Namespaces) — 네임스페이스에 대한 읽기·쓰기 접근을 제어해 멀티 테넌트 클러스터에서 관리되는 작업 정보에 대한 세분화된 접근을 허용해요.
  • Sentinel 정책 — Enterprise — Sentinel 정책은 클러스터 내 태스크 드라이버 같은 구성 요소에 대한 세분화된 제어를 허용해요.

페르소나 (Personas)

Nomad를 생각할 때, 클러스터 배포의 보안 요구 사항을 관리할 때 다음 유형의 기본 페르소나를 고려하는 것이 도움이 돼요. 엄격한 역할은 Vault용 Nomad 백엔드 시크릿 엔진을 사용해 정확하게 정의하고 관리할 수 있으므로, 팀의 사용 사례에 따라 세분성이 달라질 수 있어요. 이것은 개발 서버를 사용한 시작 단계와 함께 여기에서 더 설명돼요.

Nomad 자체에는 전통적인 사용자 개념이 없다는 점을 기억하는 것이 중요해요.

  • 시스템 관리자 (System Administrator) — Nomad 클러스터의 기본 인프라에 대한 접근 권한이 있는 사람이에요. 보통 배스천 호스트를 통해 클러스터 내 서버에 SSH나 RDP로 직접 접근할 수 있어요. 궁극적으로 실제 Nomad 바이너리에 대한 읽기·쓰기·실행 권한이 있어요. 이 바이너리는 서로 다른 구성 파일을 사용하는 서버와 클라이언트 노드에 대해 동일해요. 이 사용자는 기본 컴퓨팅 리소스에 sudo, 관리자, 또는 다른 슈퍼유저 접근 권한을 가질 수 있어요. 이와 같은 사용자는 시스템에 대한 관리 권한이 있고 에이전트를 시작·중지할 수 있으므로 기본적으로 Nomad가 완전히 신뢰해요.
  • Nomad 관리자 (Nomad Administrator) — 서버와 클라이언트의 Nomad 에이전트 구성을 정의할 수 있는(아마 같은 시스템 관리자일) 사람으로, Nomad 관리 ACL 토큰을 가져요. 또한 클러스터 내 모든 작업을 시작·중지할 수 있는 능력을 포함해 Nomad 시스템의 모든 부분에 대한 전체 권한이 있어요.
  • Nomad 운영자 (Nomad Operator) — 클러스터 내에서 자신의 네임스페이스에 적용되는 작업을 관리하기 위한 제한된 기능을 가진 선택적 접근 권한이 있는 사람일 가능성이 높아요.
  • 사용자 (User) — 시스템에서 실행 중인 애플리케이션의 사용자예요. 어떤 경우에는 애플리케이션이 웹 서버처럼 공개적으로 노출되고 인터넷에 노출될 수 있어요. Nomad 서버 API에 대한 네트워크 접근 권한이 없어야 하는 사람이에요.

안전한 구성 (Secure Configuration)

Nomad의 보안 모델은 시스템의 모든 부분이 안전한 구성으로 실행되는 경우에만 적용돼요. Nomad는 기본적으로 안전하지 않아요(not secure-by-default). Nomad 구성에서 다음 메커니즘이 활성화되지 않으면 클러스터에 대한 접근을 남용하는 것이 가능할 수 있어요. 모든 보안 고려 사항과 마찬가지로, 자신의 환경에 대한 우려 사항을 적절히 결정하고 그에 따라 이러한 보안 권장 사항에 적응해야 해요.

요구 사항 (Requirements)

  • mTLS 활성화 — 상호 TLS(mTLS)는 다음 문제를 방지하는 보안 속성으로 상호 인증을 활성화해요. 비인가 접근: 서버와 클라이언트 모두 클러스터 내에서 통신하려면 같은 유효한 CA가 서명한 유효한 TLS X.509 인증서를 제공해야 하기 때문이에요. 노드 간 통신 관찰·변조: 트래픽이 잘 알려진 네트워크 보안 프로토콜인 TLS 1.2 버전으로 암호화되기 때문에 방지돼요(구성 가능한 최소 버전 사용). 서버와 클라이언트 에이전트 모두 mTLS가 실제로 활성화되도록 서로의 인증서를 검증하도록 구성해야 해요. 이를 위해서는 CLI 사용 같은 것들을 위해 적절한 인증서를 서버, 클라이언트, 머신 또는 운영자에게 배포해야 해요. 노드의 인증서 생성과 회전을 안전하게 관리하려면 Vault를 사용하는 것을 권장해요. X.509 SAN 확장을 사용해 에이전트 역할 오구성을 방지해요. 이것은 기본적으로 노드의 리전과 역할 이름이 예상대로(예: client.us-east.nomad) 구성되어 있는지 식별·검증하는 데 사용되는 도메인 이름이에요. 앞서 언급한 역할 이름을 사용하면 서버나 클라이언트 노드로 악의적으로 위장하는 것을 방지하고, 다른 서비스가 같은 CA로 쉽게 서명되도록 해요. 또한 클러스터 내 노드의 IP 또는 호스트네임을 사용하는 인증서의 잠재적 함정을 피해요. tls.verify_https_client=false를 사용하면 Nomad 에이전트 HTTP 서버가 mTLS 대신 TLS를 사용하도록 다운그레이드돼요. 이것은 ACL이 활성화되어 있으면 안전하며, 클라이언트 인증서를 브라우저에 배포하는 어려움을 피하려면 Nomad 웹 UI를 사용할 때 권장돼요. /v1/metrics와 /v1/status/peers 같은 일부 API 엔드포인트는 ACL 토큰 없이 접근할 수 있으며, tls.verify_https_client=false를 사용할 때 Nomad HTTP 주소에 접근할 수 있는 모든 사람에게 노출될 수 있어요. 리버스 프록시나 다른 외부 수단을 사용해 접근을 제한할 수 있어요.
  • ACL 활성화 — 접근 제어 목록(ACL) 시스템은 Nomad 관리자에게 기능 기반 제어 메커니즘을 제공해, (보통 Vault 내의) 커스텀 역할을 개별 사람 또는 머신 운영자 아이덴티티에 연결할 수 있게 해줘요. 이를 통해 클러스터 내 기능에 대한 접근을 특정 사용자로 제한할 수 있어요.
  • 네임스페이스 (Namespaces) — 이 기능은 클러스터를 회사 내 여러 팀이 공유할 수 있게 해줘요. 이 논리적 분리를 사용하는 것은 멀티 테넌트 클러스터에서 해당 네임스페이스에 접근 권한이 없는 사용자가 서로 충돌하는 것을 방지하는 데 중요해요. 이를 적용하려면 ACL이 활성화되어 있어야 해요.
  • Sentinel 정책 — Enterprise — Sentinel은 운영자에게 추가 제한을 적용하기 위해 policy-as-code를 가능하게 하는 기능이에요. 작업에 대한 세분화된 제어를 위해 내장 ACL 시스템을 보강하는 데 사용돼요.
  • 리소스 쿼터 (Resource Quotas) — Enterprise — 운영자에게 상한선을 설정해 네임스페이스의 클러스터 내 기본 컴퓨팅 리소스 접근을 제한할 수 있어요. 이 리소스 쿼터에 대한 접근은 ACL로 관리해 운영자가 자신의 쿼터를 변경할 수 없도록 읽기 전용 접근을 보장할 수 있어요.

권장 사항 (Recommendations)

다음은 사용 사례에 따라 클러스터 보안을 크게 개선하는 데 도움이 될 수 있는 보안 권장 사항이에요. 환경의 보안 메커니즘을 설계할 때 항상 심층 방어를 실천할 것을 권장해요.

  • 자격 증명 회전 (Rotate credentials) — 우발적으로 유출된 자격 증명의 피해를 줄이기 위해 수명이 짧은 자격 증명을 사용하거나 자주 회전하는 것을 적극 권장해요. Vault를 사용해 동적·회전 자격 증명을 생성·관리해 시크릿이 작업 스펙 자체 내에서 쉽게 노출되는 것을 방지해요(작업 스펙은 버전 관리에 유출되거나 운영자 로컬 머신의 디스크에 우발적으로 저장될 수 있음). Nomad 에이전트가 사용하는 자격 증명을 회전해요. 예를 들어 Vault의 PKI 시크릿 엔진과 통합해 각 Nomad 노드에 대해 짧은 TTL의 동적·고유 X.509 인증서를 자동으로 생성·갱신해요.
  • 루트 없이 실행 (Running without Root) — Nomad 서버는 데이터 디렉터리에 대한 접근만 필요한 권한 없는 사용자로 실행할 수 있어요.
  • 샌드박스 런타임이 있는 컨테이너 (Containers with Sandbox Runtimes) — 신뢰할 수 없는 코드를 서비스로 실행하는 것 같은 일부 상황에서는 gVisor나 Kata Containers 같은 다른 컨테이너 런타임을 고려하는 것이 좋을 수 있어요. 이러한 유형의 런타임은 다른 컨테이너와 Nomad 클라이언트 에이전트 자체에 대해 기본 공유 커널에 대한 원시 접근을 방지하는 데 도움이 되는 샌드박싱 기능을 제공해요. Docker 드라이버는 런타임 커스터마이즈를 허용해요.
  • 사용하지 않는 드라이버 비활성화 (Disable Unused Drivers) — 각 드라이버는 서로 다른 격리 수준을 제공하며, 버그로 인해 의도하지 않은 권한 상승이 발생할 수 있어요. 태스크 드라이버가 필요하지 않으면 위험을 줄이기 위해 비활성화할 수 있어요.
  • Linux 보안 모듈 (Linux Security Modules) — AppArmor, SELinux, Seccomp 같이 운영체제에 직접 통합할 수 있는 보안 모듈을 Nomad 호스트와 컨테이너 모두에 적용해 보안 계층을 추가해요. Seccomp 프로파일은 기본 Docker 드라이버에서 사용할 수 있는 security_opt 매개변수를 사용해 컨테이너에 직접 전달할 수 있어요.
  • 서비스 메시 (Service Mesh) — Consul 같은 서비스 메시 기술 통합은 클러스터 내 네트워크 연결을 제한하고 효율적으로 로드 밸런싱하는 데 매우 유용할 수 있어요.
  • TLS 설정 (TLS Settings) — 사용 가능한 암호 스위트 같은 TLS 설정은 환경의 요구에 맞게 조정해야 해요.
  • HTTP 헤더 (HTTP Headers) — X-XSS-Protection 같은 추가 보안 헤더를 HTTP API 응답에 대해 구성할 수 있어요.

위협 모델 (Threat Model)

다음은 Nomad 위협 모델의 일부예요.

  • Nomad 에이전트 간 통신 — 도청을 방지하려면 에이전트 간 통신에 대한 전송 암호화가 필요해요. Nomad 내 TCP 및 UDP 기반 프로토콜은 대칭(공유 가십 암호화 키) 및 비대칭(TLS) 키를 포함한 암호화 활성화를 위한 서로 다른 메커니즘을 제공해요.
  • 전송 중 데이터 변조 (Tampering of data in transit) — 모든 변조는 mTLS를 통해 감지 가능해야 하며, Nomad가 요청 처리를 피하게 해야 해요.
  • 인증 또는 권한 부여 없이 데이터 접근 — 서버에 대한 요청은 각각 mTLS와 ACL을 사용해 인증되고 권한 부여되어야 해요.
  • 악성 메시지로 인한 상태 수정 또는 손상 — 잘못된 형식의 메시지는 폐기되는 반면, 올바른 형식의 메시지는 인증과 권한 부여가 필요해요.
  • 비서버 멤버의 원시 데이터 접근 — 클러스터에 조인하는 모든 서버는 Raft 참여를 시작하려면 적절한 인증과 권한 부여가 필요해요. Raft의 모든 데이터는 TLS로 암호화되어야 해요.
  • 노드에 대한 서비스 거부 (Denial of Service against a node) — 단일 노드에 대한 DoS 공격은 Nomad의 보안 태세(posture)를 손상시키지 않아야 해요.

다음은 서버 에이전트에 대한 위협 모델의 일부가 아니에요.

  • Nomad 데이터 디렉터리 접근(읽기 또는 쓰기) — Nomad가 관리하는 작업에 대한 정보는 서버의 데이터 디렉터리에 영속화돼요.
  • Nomad 구성 디렉터리 접근(읽기 또는 쓰기) — Nomad 구성 파일 디렉터리에 대한 접근은 클러스터의 기능을 활성화·비활성화할 수 있어요.
  • 실행 중인 Nomad 서버 에이전트에 대한 메모리 접근 — Nomad 서버 에이전트 프로세스의 메모리에 직접 접근하면(보통 다양한 수단으로 시스템에서 셸이 필요함) 인증서와 다른 시크릿 접근을 포함해 에이전트의 거의 모든 측면이 손상돼요.
  • 변수 메타데이터 존재 — 변수 List API에 대한 접근은 ACL 정책으로 제어되지만, 특정 경로나 메타데이터의 존재는 민감한 것으로 간주되지 않아요.

다음은 클라이언트 에이전트에 대한 위협 모델의 일부가 아니에요.

  • Nomad 데이터 디렉터리 접근(읽기 또는 쓰기) — Nomad 클라이언트에 스케줄링된 할당에 대한 정보는 데이터 디렉터리에 영속화돼요. 여기에는 할당의 파일시스템에 있는 모든 시크릿이 포함돼요.
  • Nomad 구성 디렉터리 접근(읽기 또는 쓰기) — 클라이언트 구성 파일에 대한 접근은 raw_exec 같은 안전하지 않은 드라이버를 포함해 클라이언트의 기능을 활성화·비활성화할 수 있어요.
  • 실행 중인 Nomad 클라이언트 에이전트에 대한 메모리 접근 — Nomad 클라이언트 에이전트 프로세스의 메모리에 직접 접근하면 공격자가 Vault 토큰 같은 시크릿을 클라이언트에서 추출할 수 있어요.
  • 느슨한 클라이언트 드라이버 샌드박스 — 드라이버는 일부 권한 있는 작업(예: 구성 디렉터리에 대한 파일시스템 접근, 호스트 장치에 대한 원시 접근)을 허용할 수 있어요. 이러한 권한은 다른 워크로드를 손상시키거나 서비스 거부 공격을 일으키는 데 사용될 수 있어요.

내부 위협 (Internal Threats)

  • 작업 운영자 (Job Operator) — 유효한 mTLS 인증서와 ACL 토큰을 가진 사람이라도 특정 상황, 특히 멀티 팀 클러스터 배포에서 클러스터에 위협이 될 수 있어요. 우발적으로 또는 의도적으로 악성 작업을 사용해 클러스터에 해를 끼칠 수 있으며, 이는 쿼터, 네임스페이스, Sentinel 정책을 사용해 보호할 수 있어요.
  • 워크로드 (Workload) — 워크로드는 클러스터 내에서 호스트 네트워크 접근을 가질 수 있으며, 이는 Nomad 범위 밖의 애플리케이션 보안 문제로 인한 SSRF로 이어져 클러스터 내부 접근을 유발할 수 있어요. mTLS, ACL, Sentinel 정책을 함께 사용하면 악성 워크로드에 대한 보호 계층을 추가할 수 있어요.
  • RPC / API 접근 — mTLS가 없는 RPC 및 HTTP API 엔드포인트는 클러스터 내 악성 워크로드로부터 클러스터가 남용되도록 노출할 수 있어요.
  • 클라이언트 드라이버 — 드라이버는 클러스터에 대해 다양한 워크로드 유형을 구현하며, 심층 방어를 구현하려면 이러한 드라이버의 백엔드 구성을 고려해야 해요. 예를 들어 호스트 파일시스템 마운트 능력을 제한하는 커스텀 Docker 드라이버는 raw_exec 드라이버 같은 다른 수단을 통해 노출된 Docker 데몬 API에 대한 네트워크 접근으로 전복될 수 있어요.

외부 위협 (External Threats)

Nomad 클러스터에서 외부 위협에 대해 고려할 두 가지 주요 구성 요소가 있어요.

  • 서버 에이전트 — 내부 클러스터 리더 선거와 복제는 서버 에이전트 간 Raft를 통해 관리되며 전송 중 암호화돼요. 그러나 서버에 대한 정보는 에이전트의 데이터 디렉터리에 저장 시 암호화되지 않은 채 저장돼요. 여기에는 ACL 토큰과 TLS 인증서 같은 민감한 정보가 포함될 수 있어요.
  • 클라이언트 에이전트 — 클러스터 내 클라이언트-서버 통신은 mTLS로 암호화되고 인증돼요. 클라이언트 노드의 할당에 대한 정보는 에이전트의 데이터 및 구성 디렉터리에 암호화되지 않은 채 저장돼요.

네트워크 포트 (Network Ports)

포트 / 프로토콜 (Port / Protocol) 에이전트 (Agents) 설명 (Description)
4646 / TCP 전체 (All) 에이전트에 대한 UI와 API 접근을 제공하는 HTTP.
4647 / TCP 전체 (All) 에이전트가 사용하는 RPC 프로토콜.
4648 / TCP + UDP 서버 (Servers) Serf를 사용해 서버 멤버십을 관리하는 가십 프로토콜.

더 알아보기 (Learn more)