Samba 공유를 사용자 한 명과 VPN 주소 하나로 제한하기
Samba 의 valid users 와 hosts allow 는 사람과 주소를 짝짓지 않는다. 두 개의 공유 이름이 그 짝을 표현할 수 있고, 교차 쌍 테스트가 이를 증명한다.
이 설계에서는 누가 디렉터리를 사용할 수 있는지와 어떤 주소가 애초에 접속할 수 있는지라는 두 가지 다른 권한이 혼동된다. 계정 목록을 소스 목록 옆에 쓰면 짝을 이루는 것처럼 느껴지지만 Samba 는 두 목록을 독립적인 술어로 평가한다. 둘 다 만족하는 사람은 누구나 허용되며, 이는 대부분의 관리자가 의도하는 것보다 넓은 규칙이다. 해결책은 다른 공유 배치이거나 짝을 표현할 수 있는 정책 계층이다.
신화: 두 목록이 하나의 규칙을 만든다
smb.conf 참조는 valid users 과 hosts allow 을 서로 무관한 두 매개변수로 정의하며, 하나의 공유에 둘 다 설정하는 지점에서 혼란이 시작된다. valid users = mira, tomas 와 hosts allow = 10.77.0.21, 10.77.0.22 를 설정하면 네 가지 조합이 허용되어 Mira 는 두 주소 중 어디서든, Tomas 도 두 주소 중 어디서든 접속할 수 있다. 구성에서 첫 번째 이름을 첫 번째 주소에 묶는 것은 없고, 이름의 순서에는 아무 의미가 없다. 순서를 바꾸거나, 두 번째 hosts allow 줄을 추가하거나, 한 줄에 이름 하나씩 써도 아무것도 달라지지 않는다. 결과는 두 목록의 곱이며, 둘 사이의 대응이 아니다.
대부분의 사람이 실제로 원하는 것은 더 좁아서, Mira 는 한 주소에서만, Tomas 는 다른 주소에서만 접속하는 것이다. 단일 공유 정의에는 그 결속을 위한 문법이 없고, 어떤 교묘한 순서도 그것을 만들어 내지 못한다. 이것은 Samba 가 하나의 공유 안에서 표현하지 않는 정책 형태이며, 바로 거기서 신화가 살아남는다.
Samba 가 평가하는 것과 그 순서
단계는 고정된 순서로 진행되며, 순서를 틀리면 진단도 틀린다. 클라이언트가 연결을 열고, 구성되어 있으면 전역 호스트 검사가 실행되며, 세션 설정이 계정을 인증하고, 그다음 클라이언트가 공유에 접속해 그 공유 자체의 호스트 목록, valid users, 읽기 전용 설정이 적용되며, 파일이 열릴 때에야 인증된 ID 의 파일 시스템 권한이 판단한다. 각 단계는 단독으로 요청을 거부할 수 있고, 하나를 통과해도 다음에 대해 아무것도 말하지 않는다. 중요한 귀결은 공유의 호스트 목록이 평가되는 시점에 계정은 이미 알려져 있으며, 호스트 목록은 여전히 그 계정을 지명할 방법이 없다는 것이다.
그래서 공유는 한 사용자를 한 주소에 결속할 수 없고, hosts allow 과 valid users 은 같은 트리 연결 단계에서 적용되는 별개의 술어이며 각각 자기 질문에 답한다. 호스트 술어는 계정 이름을 입력으로 받지 않으므로 사용자별로 쓸 수 없다. 그 짝을 표현할 수 있는 것은 두 번째 공유나 Samba 외부의 정책 계층뿐이다.
전역 값이 중요한 이유는 상속 방식에 있다. hosts allow 을 생략한 공유는 전역 값을 상속하고, 자기 값을 설정한 공유는 전역 값 대신 그 값을 사용하며 추가가 아니다. 따라서 넓은 전역 목록은 매개변수를 결코 설정하지 않는 공유를 넓히고, 자기 값을 정의한 공유에는 아무것도 하지 않는다. testparm -s 를 실행하고 출력되는 공유별 값을 읽어야 하는데, 그 출력이 실제로 적용되는 정책이며 디스크의 파일이 아니기 때문이다.
하나의 공유를 좁히는 것도 서버의 나머지에는 아무 효과가 없다. 다른 공유, 인쇄 대기열, IPC 연결은 각자의 규칙을 유지하므로, 한 공유의 주소 목록에 의존하는 설계는 하나의 경로를 보호할 뿐 호스트를 보호하지 않는다.
하나의 디렉터리에 두 개의 공유 이름
같은 디렉터리에 두 사람이 두 주소에서 접근할 수 있어야 한다면 서로 다른 이름으로 두 번 노출한다. 각 블록은 하나의 계정과 하나의 소스를 가지며, 이는 짝을 구성이 강제할 수 있는 것으로 바꾼다. 대가는 각 사용자가 같은 파일에 접근하기 위해 다른 공유 이름을 쓴다는 것이며, 이는 클라이언트 측의 의도적인 변경이어야 한다.
[shared-mira]
path = /srv/shared
guest ok = no
read only = yes
valid users = mira
hosts allow = 10.77.0.21
hosts deny = ALL
[shared-tomas]
path = /srv/shared
guest ok = no
read only = yes
valid users = tomas
hosts allow = 10.77.0.22
hosts deny = ALL
공유 게이트는 파일 시스템 권한이 아니다. 두 ID 모두 기반 ACL 을 통해 디렉터리에 접근해야 하며, 읽기 전용 설정은 두 번째 계층이지 유일한 계층이 아니다. 작업 흐름이 요구할 때만 쓰기 권한을 주고, 그다음 한 ID 가 만든 파일이 다른 ID 에게도 쓸 수 있는지 확인한다.
두 블록이 하나의 경로를 가리키므로 디렉터리의 변경은 두 공유에 모두 영향을 준다. 보통 그것이 목적이지만, 권한 실수가 두 사용자에게 동시에 보인다는 뜻이기도 하다.
소스 주소가 증명할 수 있는 것
Samba 가 보는 주소는 서버에 도달한 주소이며, 클라이언트가 가지고 있다고 생각하는 주소가 아니다. 모든 클라이언트를 하나의 소스 주소로 변환하는 VPN 게이트웨이는 그 구분을 없애서 모든 클라이언트가 같은 호스트로 도착하고 소스 목록은 더 이상 이들을 구분할 수 없다. 클라이언트별 안정적인 할당과 소스를 보존하는 게이트웨이가 주소를 정책으로 사용하는 전제 조건이다. 둘 다 없으면 제한은 사용자가 아니라 게이트웨이를 측정한다.
그래도 주소는 장치가 아니다. 하나의 터널 주소 뒤의 노트북 두 대, 재할당된 리스, 공유 워크스테이션은 소스가 사람을 식별한다는 가정을 모두 무너뜨린다. 제한은 네트워크 범위로 다루고 인증된 SMB 계정을 ID 계층으로 유지하라, 장치 승인이 필요하면 인증서 같은 장치 자격 증명과 함께.
설계가 서버가 아니라 공유를 닫는 것도 같은 이유다. 거부된 짝도 세션을 열고, 다른 공유에 도달하고, 서버를 나열할 수 있으며, 이는 접속 시점의 인증 실패와 다른 결과다. 인증 전에 거부하는 것이 요구 사항이라면 Samba 의 공유 매개변수는 잘못된 도구다.
교차 쌍으로 증명하라
구성을 검증한 뒤 재사용한 세션이 아니라 새로운 연결로 네 가지 조합을 시험한다. 의도한 짝은 디렉터리에 도달해야 하고, 두 교차 쌍은 모두 실패해야 한다. 이전 테스트의 캐시된 세션은 잘못된 조합에도 기꺼이 응답하여 깨진 규칙을 올바르게 보이게 만든다.
testparm -s
smbclient //fileserver/shared-mira -U mira -c 'ls'
smbclient //fileserver/shared-tomas -U tomas -c 'ls'
smbstatus --shares
구문 검사는 파일이 파싱된다는 것만 증명한다. 자격 증명, ACL, 호스트 결정은 실제 연결로 시험되므로 테스트하려는 주소에서 클라이언트 명령을 실행하고 어느 단계에서 거부되는지 관찰한다. 교차 쌍이 성공하면 실제로 적용되는 호스트 목록은 블록이 시사하는 것보다 넓으며, testparm -s 이 가장 먼저 읽어야 할 것이다. 교차 쌍이 잘못된 이유로 실패하면 계정이나 ACL 이 의심스럽다.
smbstatus 로 세션을 모니터링하고 종료하는 것은 접근이 시작된 뒤의 대응이며 입장 제어가 아니다. 관찰된 주소 전체를 차단하면 같은 NAT 뒤의 무관한 사용자도 끊길 수 있으므로 판단은 공유 정의에, 모니터링은 대응 프로세스에 속한다. 둘을 분리해 두면 설계는 무엇을 강제하는지에 대해 정직하게 남는다.