배경
현재 SharedFS SMB 접근 제어는 로컬 사용자/그룹 또는 AD 사용자/그룹을 valid users, write list, admin users로 렌더링하는 계정 ACL만 지원합니다. 유효한 계정 자격 증명을 가진 클라이언트라면 접속 원본 IP와 관계없이 공유 접근을 시도할 수 있어, 공유별로 허용 네트워크를 제한해야 하는 운영 환경을 충족하지 못합니다.
Samba는 공유 단위 hosts allow/hosts deny 설정을 지원하므로 계정 ACL과 독립적인 IP/CIDR 접근 게이트를 구현할 수 있습니다. 이 정책은 SMB listener가 어떤 서비스 IP에서 대기하는지와도 별개입니다. listener는 서버 측 수신 endpoint이고, 네트워크 ACL은 해당 공유에 접근하는 클라이언트의 원본 IP를 판정합니다.
확인한 현재 구현
CreateStorageSmbAclCmd와 UpdateStorageSmbAclCmd는 LOCAL_USER, LOCAL_GROUP, AD_USER, AD_GROUP만 허용합니다.
StorageServiceManagerImpl.isSmbPrincipalType()도 계정/그룹 네 종류만 SMB desired state에 포함합니다.
- SystemVM
ablestack-storagectl은 SMB 공유마다 valid users, write list, admin users만 렌더링하며 hosts allow 정책은 생성하지 않습니다.
storage_access_rule에는 이미 CIDR, IP_ADDRESS principal type을 저장할 수 있고 컬럼이 문자열이므로 신규 테이블이나 DB 컬럼 없이 확장할 수 있습니다.
- 현재
smb-access.json은 계정 ACL 적용 상태만 기록하므로 네트워크 제한의 desired/runtime 정합성을 표시할 수 없습니다.
목표 동작
정책 의미
- SMB 공유마다 계정 ACL과 네트워크 접근 허용 목록을 독립적으로 관리합니다.
- 네트워크 규칙이 없으면 기존 호환성을 위해 네트워크 계층은
ANY_SOURCE로 동작합니다. 계정 인증과 계정 ACL은 계속 적용됩니다.
- 한 개 이상의 IP/CIDR 규칙이 있으면 해당 원본 주소와 SystemVM 로컬 loopback만 공유 접근이 가능합니다.
- 최종 접근은
네트워크 원본 허용 AND 계정/그룹 ACL 허용이어야 합니다. 네트워크 허용은 사용자 인증이나 파일 권한을 대체하지 않습니다.
- 초기 범위는 allow-list만 지원합니다. allow/deny 우선순위 충돌을 피하기 위해 별도 deny-list는 후속 과제로 분리합니다.
- Samba가 판정하는 실제 접속 원본 주소를 사용하므로 NAT를 경유하는 경우 NAT 이후 주소가 정책 대상이라는 점을 UI와 문서에 안내합니다.
Samba 렌더링
- 허용 규칙이 있는 공유에만 다음과 같이 공유 섹션 내부에 렌더링합니다.
[share-name]
hosts allow = 10.10.0.0/16 192.168.10.25
- 전역
[global]에는 hosts allow를 설정하지 않습니다. 전역 설정은 공유별 정책보다 우선할 수 있으므로 공유별 격리를 깨뜨립니다.
- 규칙이 없으면
hosts allow와 hosts deny를 모두 렌더링하지 않아 기존 동작을 유지합니다.
- IP/CIDR 문자열은 API와 SystemVM 양쪽에서 파싱·정규화하고, hostname·와일드카드·임의 Samba 토큰은 거부합니다.
코드 수준 설계
API 및 서비스 계약
- 계정 ACL과 혼동하지 않도록 다음 API를 추가합니다.
createStorageSmbNetworkAcl
updateStorageSmbNetworkAcl
deleteStorageSmbNetworkAcl
listStorageSmbNetworkAcls
- 입력은
shareid, principaltype=CIDR|IP_ADDRESS, principal 또는 복수 principals입니다.
StorageServiceInstance.Permission에 연결 허용 의미의 CONNECT를 추가합니다. READ_ONLY, READ_WRITE, ADMIN은 계정/파일 권한에만 사용합니다.
- 백엔드는 쉼표 입력을 개별 규칙으로 정규화하고 동일 공유의 중복 IP/CIDR를 idempotent하게 병합합니다.
- IPv4/IPv6 literal과 CIDR만 허용하며 prefix 범위, network address 및 중복을 검증합니다. 현재 Storage Service 네트워크가 IPv4만 제공하는 환경에서는 IPv6 규칙을 capability 검증 후 허용합니다.
- 응답은 기존
StorageAccessRuleResponse를 재사용하되 principaltype, principal, permission=CONNECT, state를 명시합니다.
영속성 및 desired state
storage_access_rule을 그대로 사용합니다.
resource_type=FILE_SHARE
resource_id=<SMB share id>
principal_type=CIDR|IP_ADDRESS
permission=CONNECT
- 신규 DB 컬럼은 추가하지 않습니다. Java enum 및 API schema만 확장합니다.
StorageServiceManagerImpl.applySmbDesiredState()는 규칙을 다음 두 배열로 분리합니다.
acls: 로컬/AD 계정 및 그룹 ACL
networkAcls: IP/CIDR 연결 허용 규칙
- 공유 삭제 시 두 종류의 규칙을 함께 정리하고, 네트워크 규칙 변경 실패 시 #892의 snapshot/rollback 절차로 DB와 runtime을 이전 revision으로 복구합니다.
SystemVM
ablestack-storagectl의 SMB renderer에서 networkAcls를 계정 ACL 루프와 분리해 처리합니다.
- Python
ipaddress로 모든 원본을 다시 검증하고 정규화한 값만 hosts allow에 기록합니다.
- 임시 파일 생성,
testparm -s 검증, 원자적 교체 후 Samba reload/restart 순으로 적용합니다.
smb-access.json에 다음 runtime 정보를 추가합니다.
networkAccessMode: ANY_SOURCE 또는 ALLOW_LIST
allowedSources
configuredNetworkAclCount
effectiveNetworkAclCount
networkAccessState: open, restricted, error
- 모니터링 캐시는 desired와 runtime 목록의 차이를 drift로 표시합니다.
UI
- SMB 탭에 계정 ACL과 별도의
네트워크 접근 허용 목록 섹션을 추가합니다.
- 테이블 컬럼은 공유 이름, 원본 유형, 허용 IP/CIDR, 상태, 작업으로 구성하며 작업 칼럼은 우측 고정/정렬합니다.
- 생성·수정 대화상자는 세로형 tag 입력을 사용하고 여러 IP/CIDR를 쉼표 또는 Enter로 입력할 수 있게 합니다.
- 모든 규칙 삭제 시
모든 원본 네트워크에서 연결을 시도할 수 있으며 계정 ACL은 계속 적용됩니다라는 최종 확인을 표시합니다.
- 공유 목록과 상태 요약에는
모든 원본 또는 허용 CIDR 개수/요약을 표시하고 긴 목록은 tooltip으로 제공합니다.
- 초기 SMB 공유 생성에서도 선택 항목으로 허용 IP/CIDR를 입력할 수 있게 합니다.
- 신규 문구는 i18n을 적용하고 다크모드, NoData, 내부 스크롤 및 고정 작업 칼럼 표준을 준수합니다.
보안 및 운영 제약
- 이 기능은 방화벽이나 강한 사용자 인증을 대체하지 않습니다. 연결 원본 필터와 계정 ACL을 함께 사용해야 합니다.
- SMB 서버 접속 자체와 공유 탐색은 가능하더라도 허용되지 않은 공유의 tree connect는 거부될 수 있음을 안내합니다.
- 여러 endpoint IP를 사용하는 경우에도 클라이언트 원본 allow-list는 공유 단위로 동일하게 적용됩니다.
- NFS와 같은 디렉터리를 교차 공유하더라도 SMB 네트워크 ACL은 NFS export ACL을 변경하지 않습니다.
테스트 게이트
- API unit test: IPv4/IPv6, CIDR prefix, 중복, 쉼표 입력, hostname/와일드카드 거부
- Backend test: 계정 ACL과 네트워크 ACL 분리, idempotent create/update/delete, 공유 삭제 cascade
- SystemVM test: 규칙 없음은 미렌더링, 규칙 존재 시 공유별
hosts allow, testparm 실패 rollback
- 허용 CIDR 클라이언트에서 로컬 사용자 및 AD 사용자 mount/read/write 성공
- 비허용 CIDR 클라이언트에서 동일한 정상 계정으로 tree connect/mount 실패
- 허용 CIDR이지만 계정 ACL이 없는 사용자는 접근 실패
- guest access 공유도 네트워크 allow-list 밖에서는 접근 실패
- 서로 다른 allow-list를 가진 두 공유가 독립적으로 동작
- 다중 SMB endpoint, SystemVM/Samba 재시작 및 재부팅 후 정책 복구
- DB desired, SystemVM
smb.conf, 모니터링 캐시, API, UI 목록 정합성
- NFS/SMB 교차 공유 상태에서 NFS ACL에 영향이 없는지 회귀 테스트
연관 관계
완료 조건
- 공유별 IP/CIDR allow-list와 계정/그룹 ACL을 동시에 적용할 수 있습니다.
- 허용 및 비허용 클라이언트의 실제 연결 결과가 DB, runtime, API, UI 상태와 일치합니다.
- 기존 SMB 공유는 별도 네트워크 규칙이 없을 때 기존 접근 동작을 유지합니다.
- 실패·재부팅·재적용 후에도 네트워크 정책이 유실되거나 다른 공유에 전파되지 않습니다.
배경
현재 SharedFS SMB 접근 제어는 로컬 사용자/그룹 또는 AD 사용자/그룹을
valid users,write list,admin users로 렌더링하는 계정 ACL만 지원합니다. 유효한 계정 자격 증명을 가진 클라이언트라면 접속 원본 IP와 관계없이 공유 접근을 시도할 수 있어, 공유별로 허용 네트워크를 제한해야 하는 운영 환경을 충족하지 못합니다.Samba는 공유 단위
hosts allow/hosts deny설정을 지원하므로 계정 ACL과 독립적인 IP/CIDR 접근 게이트를 구현할 수 있습니다. 이 정책은 SMB listener가 어떤 서비스 IP에서 대기하는지와도 별개입니다. listener는 서버 측 수신 endpoint이고, 네트워크 ACL은 해당 공유에 접근하는 클라이언트의 원본 IP를 판정합니다.확인한 현재 구현
CreateStorageSmbAclCmd와UpdateStorageSmbAclCmd는LOCAL_USER,LOCAL_GROUP,AD_USER,AD_GROUP만 허용합니다.StorageServiceManagerImpl.isSmbPrincipalType()도 계정/그룹 네 종류만 SMB desired state에 포함합니다.ablestack-storagectl은 SMB 공유마다valid users,write list,admin users만 렌더링하며hosts allow정책은 생성하지 않습니다.storage_access_rule에는 이미CIDR,IP_ADDRESSprincipal type을 저장할 수 있고 컬럼이 문자열이므로 신규 테이블이나 DB 컬럼 없이 확장할 수 있습니다.smb-access.json은 계정 ACL 적용 상태만 기록하므로 네트워크 제한의 desired/runtime 정합성을 표시할 수 없습니다.목표 동작
정책 의미
ANY_SOURCE로 동작합니다. 계정 인증과 계정 ACL은 계속 적용됩니다.네트워크 원본 허용 AND 계정/그룹 ACL 허용이어야 합니다. 네트워크 허용은 사용자 인증이나 파일 권한을 대체하지 않습니다.Samba 렌더링
[global]에는hosts allow를 설정하지 않습니다. 전역 설정은 공유별 정책보다 우선할 수 있으므로 공유별 격리를 깨뜨립니다.hosts allow와hosts deny를 모두 렌더링하지 않아 기존 동작을 유지합니다.코드 수준 설계
API 및 서비스 계약
createStorageSmbNetworkAclupdateStorageSmbNetworkAcldeleteStorageSmbNetworkAcllistStorageSmbNetworkAclsshareid,principaltype=CIDR|IP_ADDRESS,principal또는 복수principals입니다.StorageServiceInstance.Permission에 연결 허용 의미의CONNECT를 추가합니다.READ_ONLY,READ_WRITE,ADMIN은 계정/파일 권한에만 사용합니다.StorageAccessRuleResponse를 재사용하되principaltype,principal,permission=CONNECT,state를 명시합니다.영속성 및 desired state
storage_access_rule을 그대로 사용합니다.resource_type=FILE_SHAREresource_id=<SMB share id>principal_type=CIDR|IP_ADDRESSpermission=CONNECTStorageServiceManagerImpl.applySmbDesiredState()는 규칙을 다음 두 배열로 분리합니다.acls: 로컬/AD 계정 및 그룹 ACLnetworkAcls: IP/CIDR 연결 허용 규칙SystemVM
ablestack-storagectl의 SMB renderer에서networkAcls를 계정 ACL 루프와 분리해 처리합니다.ipaddress로 모든 원본을 다시 검증하고 정규화한 값만hosts allow에 기록합니다.testparm -s검증, 원자적 교체 후 Samba reload/restart 순으로 적용합니다.smb-access.json에 다음 runtime 정보를 추가합니다.networkAccessMode:ANY_SOURCE또는ALLOW_LISTallowedSourcesconfiguredNetworkAclCounteffectiveNetworkAclCountnetworkAccessState:open,restricted,errorUI
네트워크 접근 허용 목록섹션을 추가합니다.모든 원본 네트워크에서 연결을 시도할 수 있으며 계정 ACL은 계속 적용됩니다라는 최종 확인을 표시합니다.모든 원본또는 허용 CIDR 개수/요약을 표시하고 긴 목록은 tooltip으로 제공합니다.보안 및 운영 제약
테스트 게이트
hosts allow,testparm실패 rollbacksmb.conf, 모니터링 캐시, API, UI 목록 정합성연관 관계
완료 조건