요약

  • RFC 1447은 각 액세스 행을 대상 파티, 주체 파티, 리소스 컨텍스트로 색인하고, 허용된 PDU 클래스를 별도로 저장했다.
  • 인증과 알려진 파티 이름은 수신 측 결정에 대한 입력이었을 뿐, 어디서나 읽기·쓰기·알림을 허용하는 휴대 가능한 권한이 아니었다.
  • 이후 VACM은 어휘를 바꿨지만 관계적 규율은 유지했다: 주체, 컨텍스트, 보안 조건, 뷰 유형, 개별 객체 모두가 여전히 중요했다.

도구 앞의 네 개의 서랍

Party MIB는 1993년 4월, 원래 SNMPv2 프레임워크의 한 구성 요소로 등장했다. 그 이름은 주체(principal)의 디렉터리처럼 들리게 할 수 있다. 그러나 그것은 더 야심찬 것이었다. Party MIB는 SNMPv2 엔터티가 관리 통신을 어떻게 처리할지 결정하는 데 사용하는 관리 사실들을 노출했다: 파티, 컨텍스트, 액세스 권한, 그리고 MIB 뷰.

RFC 1445는 파티를, 그 연산들이 엔터티의 가능성 중 행정적으로 선택된 부분 집합으로 제한되는 개념적 실행 환경으로 정의했다. 따라서 파티는 단순히 사람, 회사, 주소가 아니었다. 같은 엔터티가 서로 겹치거나 분리된 권한을 가진 여러 파티를 실현할 수 있었다. 원격 파티는 로컬에서 실현되지 않으면서도 로컬에서 알려질 수 있었다. 이름은 행정 기록을 선택했을 뿐, 보편적인 역할을 담지 않았다.

RFC 1447은 그 절제를aclTable에서 구체적으로 만들었다. 한 행의 키가 "user" 하나뿐인 것은 아니었다. 행의 색인은aclTarget,aclSubject,aclResources로 구성되었다. target은 연산 수행을 요청받는 파티를 식별했다. subject는 요청을 제기하는 파티를 식별했다. resources 값은 요청이 이루어지는 SNMPv2 컨텍스트를 식별했다.

그 트리플이 행을 선택한 뒤에야aclPrivileges가 어떤 관리 통신 클래스가 허용되는지 말해 주었다. 권한은 주어, 수신자, 객체 세계, 동사 클래스를 갖춘 하나의 문장이었다. 항을 하나 제거하면 문장이 달라졌다.

35는 관리자 역할이 아니었다

권한 필드는 0부터 255까지의 정수였지만 계급이 아니었다. 각 PDU 클래스는 컨텍스트별 태그에서 파생된 값을 차지했다: Get은 1, GetNext는 2, Response는 4, Set은 8, GetBulk는 32, Inform은 64, SNMPv2-Trap은 128이었다. 허용된 집합은 합으로 표현되었다. 0은 허용된 클래스가 없음을 뜻했다.

기본값은 35였다: Get + GetNext + GetBulk. 이는 게스트에서 관리자로 이어지는 사다리의 중간 어딘가에 놓인 값이 아니었다. 세 가지 읽기 측 메시지 클래스를 가리키고 Set, Response, Inform, Trap은 제외했다. 43은 같은 조회 집합에 Set을 더한 것이었다. 4는 Response만을 뜻했다. 숫자는 분해한 뒤에야 의미를 가졌다.

이 설계는 압축된 정책이 대시보드 문장이 되는 순간마다 중요하다. 35를 "읽기 권한"으로 렌더링하면 요약은 유용할 수 있지만, 근거는 여전히 정확한 비트 집합이다. "신뢰됨"으로 렌더링하면 요약은 경계를 넘어선 것이다. 신뢰는 대상, 컨텍스트, 요청 방향, 허용된 연산을 드러내지 않는다.

초기 구성 예제는 이 비대칭성을 보여 주었다. 매니저 측 subject는 한 컨텍스트에서 에이전트 측 target을 향해 Get, GetNext, GetBulk를 발행하도록 허용될 수 있었고, 반대 방향의 행은 Response와 Trap을 허용했다. 각 방향은 서로 다른 정책이었다. 묻는 권한이 자동으로 답하는 권한을 부여하지 않았고, 어느 행도 자신의 클래스가 없다면 Set을 승인하지 않았다.

발신이 수신자의 정책을 실행하지는 않았다

RFC 1445는 쉽게 잊히는 타이밍 규칙을 명시했다: 액세스 제어는 관리 통신이 전송될 때가 아니라 수신될 때 적용되었다. 요청 생성자는 원본 파티, 목적지 파티, 컨텍스트, PDU를 조립해 원격 엔터티의 로컬 액세스 정책을 문의하지 않고 메시지를 보냈다.

수신 시 경로는 순차적이 되었다. 수신자는 목적지 파티가 알려져 있고 로컬에서 실현되는지 확인했다. 발신 파티를 찾았다. 파티들의 구성된 프로토콜에 따라 인증을 평가했다. 컨텍스트를 찾았다. 그런 다음 발신–수신–컨텍스트 관계에 대해 로컬 액세스 정책 데이터베이스를 조회하고 PDU 클래스를 결정했다.

이것들은 장식적 반복이 아니었다. 각 조회는 서로 다른 이유로 실패할 수 있었다. 구문상 유효한 메시지가 알려지지 않은 목적지를 가리킬 수 있었다. 알려진 목적지가 알려지지 않은 발신원의 메시지를 받을 수 있었다. 인증된 발신원이 존재하지 않는 컨텍스트를 요청할 수 있었다. 알려진 컨텍스트에 관련 ACL 행이 없을 수 있었다. 일치하는 행이 Set을 누락할 수 있었다.

결정은 강한 의미에서 로컬이었다. 두 수신자가 같은 subject 식별자를 알면서도 서로 다른 대상 파티, 컨텍스트, 행, MIB 뷰를 유지할 수 있었다. 발신자가 자신이 무엇을 요청하려는지 알 수는 있었지만, 잘 형성된 패킷을 전송한다고 수신자의 현재 승인을 만들어 낼 수는 없었다.

컨텍스트는 "무엇"과 "누가"를 분리해 두었다

SNMPv2 컨텍스트는 관리 객체 리소스의 집합을 식별했다. 로컬 리소스에 대해서는 MIB 뷰를 가리켰고, 원격 리소스에 대해서는 프록시 관계를 서술할 수 있었다. 따라서 같은 subject와 target이 컨텍스트에 따라 다른 권한을 가질 수 있었고, 같은 연산 이름이 서로 다른 리소스 표면에 닿을 수 있었다.

이 분리는 주체 레이블이 범위를 몰래 삼키는 것을 막았다. "읽을 수 있다"는 "어떤 컨텍스트에서" 없이는 불완전했고, "설정할 수 있다"는 수신 파티와 PDU 클래스 없이는 불완전했다. 액세스 행이 요청을 수용한 뒤에도 컨텍스트의 뷰가 연산이 실행될 수 있는 객체들을 계속 제한했다.

이는 거부가 증명하는 바도 한정했다. 한 컨텍스트를 통해 객체에 닿지 못했다고 해서 객체가 존재하지 않는다거나, 다른 컨텍스트가 그것을 배제한다거나, 다른 subject가 접근 권한이 없다는 것이 증명되지 않았다. 확립된 것은 하나의 수신자에서, 하나의 행정 상태에서, 하나의 관계가 낸 결과였다.

정책 행은 자체적인 수명을 가졌다

ACL 항목은aclStorageType과aclStatus도 함께 담았다. 스토리지는 휘발성, 비휘발성, 영구적일 수 있었다. Status는 RowStatus를 사용했다. 따라서 정책은 표에 나타났다는 이유만으로 시대를 초월한 것이 아니었다. 행은 휘발성 메모리에 의존할 수도, 안정적 스토리지에 뒷받침될 수도, 수정에 저항할 수도, 그 수명 주기 규칙에 따라 준비되지 않았거나 비활성일 수도 있었다.

RFC 1447은 행을 읽는 것이 모든 의존성이 활성 상태임을 증명한다거나, 병행 관리자가 경합하지 않았다거나, 성공한 Set이 재시작 후에도 살아남을 것이라고 약속하지 않았다. 그런 질문들은 행 상태, 스토리지 실현, 응답, 그 이후의 관찰에 속했다. 일반 RowStatus 메커니즘은 자체적인 역사를 갖는다; 여기서 그 중요성은 더 좁다. 액세스 관계 자체가 관리되는 상태였다.

이것은 감추기보다 보존할 가치가 있는 재귀를 만든다. 관리 트래픽은 이후의 관리 트래픽을 지배하는 행정 사실을 바꿀 수 있었다. 정책 객체에 대한 성공한 쓰기가 의도한 관계 아래 미래의 요청이 수용될 것이라는 증거는 아니었다. 운영자는 기록된 값, 반환된 상태, 활성 의존성, 그리고 새로운 수신 측 검증이 필요했다.

VACM은 지도를 바꿨을 뿐, 좌표의 필요성을 바꾸지 않았다

원래의 파티 기반 프레임워크는 지속되지 못했다. RFC 2575와 그 후속 대체물인 RFC 3415는 모듈형 SNMP 아키텍처를 위한 뷰 기반 액세스 제어 모델(View-based Access Control Model)을 정의했다. 표현은 바뀌었다: 보안 모델과 보안 이름이 그룹에 매핑되고; 그룹, 컨텍스트 이름, 보안 모델, 보안 수준이 액세스 항목을 선택하며; 읽기, 쓰기 또는 알림이 뷰를 선택하고; 개별 변수 이름이 그 뷰에 대해 검증되었다.

VACM은 조인별 실패까지 이름 붙였다: 그런 컨텍스트 없음, 그룹 이름 없음, 액세스 항목 없음, 그런 뷰 없음, 뷰에 없음. 이 결과들이 전부 "잘못된 자격 증명"을 뜻하지는 않았다. 그것들은 결정의 서로 다른 부분에서 누락되거나 배제하는 상태의 위치를 짚어 주었다.

이 계보는 동등함이 아니다. Party MIB의 ACL 행과 VACM 테이블은 서로 다른 아키텍처를 가진 서로 다른 시스템이다. 살아남은 것은 주체를 무제한 권한과 동등하게 보지 않는 태도였다. "누가?"에 대한 답은 여전히 입력 중 하나일 뿐이었다. "어디에서?", "어떤 보안 모델과 수준에서?", "어떤 연산에 대해?", "어떤 객체에 대해?"가 여전히 결과를 제약했다.

정책 사실은 운영 효과가 아니었다

Lu Heng의 running-code 원리는 명세, 구현, 검증, 배포, 사용을 구분한다. 그의 현실 계층에 대한 서술은 상징적 권위와 실행 가능한 효과를 구분한다. RFC 1447은 이 두 아이디어 모두의 작은 역사적 사례를 제공한다.

파티 식별자는 상징 계층에 속했다. ACL 행은 로컬 정책을 표현했다. 수신 측 처리가 그 정책을 실행했다. 프로토콜 응답은 한 가지 결과를 기록했다. 바뀐 카운터, 인터페이스 상태, 라우팅 행동은 또다시 다른 관찰에 속했다.

그 어떤 기록도 무가치하지 않다. 오류는 하나가 다른 모두를 대표하도록 승격될 때 시작된다. 알려진 파티가 승인을 증명하지 않는다. 일치하는 ACL 행이 활성 상태임을 증명하지 않는다. 수용된 Set이 영구적 변경을 증명하지 않는다. 반환된 값이 의미적 정확성을 증명하지 않는다.

Party MIB의 관리 모델은 Historic이다. 그 증거 규율은 아니다. 권위는 신원에 붙은 흥빈한 형용사로 남는 것보다, 재구성할 수 있는 관계로 남을 때 감사하기가 쉽다.

출처