VPN 명령은 당신의 사용자로 실행되고, 비밀번호는 나타나지 않으며, 터널이 올라온다. 이 흐름은 비특권 작업처럼 느껴지지만, 대개 그렇지 않다. 네트워크 변경은 별도 서비스가 수행하며, 흥미로운 질문은 그 서비스가 검증하지 않은 호출자에게 무엇을 해 주는가이다. 비밀번호 요구 횟수를 세는 것은 그 경계에 대해 아무것도 알려주지 않는다.

인터페이스, 메커니즘, 검사

인터페이스는 요청을 받는다: 연결, 연결 해제, 프로필 선택. 메커니즘은 네트워크 작업을 소유한다: 인터페이스 생성, 경로 변경, 필터 적용. 권한 검사는 이 호출자가 이 작업을 요청해도 되는지 결정한다. 이 셋은 바이너리, 도우미, 시스템 서비스에 흩어질 수 있고, 사용자는 첫 번째만 본다.

역할은 하나의 바이너리에, 두 개의 프로세스에, 또는 클라이언트와 시스템 서비스에 살 수 있으며, 사용자가 보는 명령이 어느 쪽인지 드러내는 일은 드물다. 트레이 아이콘과 시스템 데몬은 하나의 애플리케이션처럼 보일 수 있지만 매우 다른 권한으로 실행된다. 설치 시점의 권한과 요청 시점의 권한도 서로 다른 것이다. root로 실행된 설치 프로그램은 패키지 관리자가 끝난 훨씬 뒤에도 이후 요청을 듣는 서비스를 남길 수 있다. 권한을 가진 것은 당신이 입력한 명령이 아니라 그 서비스다.

위임은 정상적인 설계다

특권이 필요한 네트워크 작업을 서비스에 위임하는 것은 합리적인 아키텍처다. 일반 애플리케이션은 비특권으로 두고, 주의가 필요한 작업을 한곳에 모은다. 이 설계는 서비스가 누가 무엇 때문에 요청하는지도 검사할 때만 값을 한다. 그 검사가 없으면 그저 더 넓은 문일 뿐이다.

NetworkManager는 Linux의 구체적인 사례다. 그 구성 안내서는 기본 설정에서 PolicyKit이 root가 아닌 요청을 어떻게 승인하는지 설명한다. 이것은 실제 제품에서 위임된 권한 부여를 보여준다. 모든 상용 클라이언트가 NetworkManager를 쓴다는 증명도 아니고, 특정 공급자의 소켓 경로나 정책을 설명하는 것도 아니다.

패턴은 뒤에 정책이 있는 위임이다. 예시는 그 패턴의 한 구현이며 보편적인 것은 아니다.

경계를 읽어라, 요청이 아니라

서비스와 그 구성의 소유자, 프런트엔드가 쓰는 로컬 인터페이스를 찾아라. 그다음 어떤 사용자가 어떤 작업을 요청할 수 있는지 물어라. 저장된 프로필 하나를 올리고 내리는 것은 운영자가 한 번도 검토하지 않은 구성을 불러오는 것과 같은 권한이 아니다. 그 차이가 보안 문제의 전부다.

서비스 관리자와 클라이언트가 자기 권한을 보는 관점에서 시작하라. 아래 명령은 데몬이 실행 중인지, 호출자가 무엇을 요청할 수 있는지, 데몬이 런타임 디렉터리 아래에서 무엇을 노출하는지 보여준다.

systemctl status NetworkManager
nmcli general permissions
ls -l /run/NetworkManager

그 작업이 무엇에 영향을 주는지도 물어라. 개인적으로 보이는 메뉴 항목이 시스템 전체의 경로와 DNS를 바꿀 수 있으며, 이는 다른 사용자의 세션을 방해할 수 있다는 뜻이다. 영향 범위는 권한과 같은 검토에 속하며, 보통 서비스에 더 좁은 역할이 필요한지 결정한다.

지원되는 방식으로 권한을 고쳐라

보호된 제어 소켓을 누구나 쓸 수 있게 만들거나 계정을 넓은 관리 그룹에 추가하면 권한 오류는 사라지고 더 큰 오류가 생긴다. 그 오류는 경계가 존재한다고 알려주던 유일한 것이었다. 문서화된 멤버십 또는 권한 부여 절차를, 그것이 요구하는 세션 갱신까지 포함해 사용하라. 그룹 멤버십은 흔히 새 로그인 세션에만 적용되므로, 변경이 다음 로그인 전까지 아무것도 하지 않는 것처럼 보일 수 있다.

제품이 그 작업에 더 좁은 역할을 제공한다면, 포괄적 부여보다 그것을 선호하라. 선택한 역할과 그 소유자를 서비스 이름 옆에 적어라.

좋은 분리는 어떻게 보이는가

일반 애플리케이션은 비특권으로 남고, 서비스는 그것이 설계된 설정만 수행하며, 모든 호출자는 누군가 소유한 정책에 대해 검사된다. 그것은 변호할 수 있는 설계다. 정책에 이름이 붙어 있으므로 감사도 가능하다. 그보다 큰 것은 조용한 권한 변경이 아니라 서면 예외를 받을 만하다.

실패 모드는 인터페이스가 편리하다는 이유로 어떤 로컬 사용자의 어떤 요청이든 수행하는 서비스다. 사용자 쪽에서는 똑같아 보이며, 훨씬 큰 권한을 지닌다. 성공한 요청만이 아니라 거부된 요청 하나를 시험하라. 정책에서 비롯된 거부가 정책이 존재한다는 증거다.

관련 글