VPN에서 CIFS 마운트가 실패하는 이유는 nsswitch 순서입니다
공유는 주소로는 응답하고 이름으로는 멈춰서, SMB가 시작되기도 전에 조회가 죽습니다. getent와 host를 비교한 뒤 hosts 줄을 순서대로 읽으세요.
터널은 올라와 있습니다. 파일 서버는 주소로 ping에 응답합니다. 그런데 mount.cifs를 호스트 이름으로 실행하면 한동안 멈춰 있다가 호스트에 연결할 수 없다고 보고하고, 당신은 애초에 문제가 아니었던 VPN 프로필을 다시 만들기 시작합니다. Linux에서는 SMB 패킷이 생기기도 전에 glibc가 이름을 해석하며, 그 리졸버의 순서가 DNS를 묻기도 전에 조회를 끝낼 수 있습니다. 여기 제가 밟는 순서가 있습니다. 클라이언트가 아니라 실패한 명령에서 시작합니다.
실패를 올바른 자리에서 읽기
두 도구는 같은 이름으로 서로 다른 경로를 가고, 둘을 비교하는 데 명령 하나면 됩니다. getent는 설정된 이름 서비스 스택을 따라가고, host와 dig는 DNS에 직접 질의하며 그 스택을 무시합니다. 직접 질의가 주소를 돌려주는데 getent가 아무것도 돌려주지 않으면 DNS 서버는 닿는 곳에 있고 실패하는 것은 리졸버 설정입니다.
getent hosts fileserver.corp.example
host fileserver.corp.example 10.61.0.1
getent -s dns hosts fileserver.corp.example
세 번째 명령이 결정타입니다. DNS 소스를 강제하고 나머지 스택을 건너뜁니다. 그것이 되고 일반 getent가 안 되면, 원인은 순서이지 터널도 서버도 아니라는 것이 증명됩니다.
hosts 줄은 일찍 멈추는 순서입니다
glibc 리졸버는 /etc/nsswitch.conf를 읽고 hosts: 항목을 왼쪽에서 오른쪽으로 훑습니다. 많은 배포판은 멀티캐스트 조회가 먼저 오고 조기 반환 동작이 붙은 줄을 내놓습니다. 그 동작은 장식이 아닙니다. mDNS가 “not found”라고 답하면 [NOTFOUND=return]가 조회 전체를 끝내므로, 회사 이름은 VPN이 밀어 넣은 리졸버로 전혀 전달되지 않습니다. 아무것도 로그를 남기지 않는데, 리졸버가 거부할 질의가 아예 전송되지 않았기 때문입니다. 그래서 마운트가 멈춘 것처럼 보이다가 호스트에 닿을 수 없다고 보고합니다.
cat /etc/nsswitch.conf | grep '^hosts:'
# illustrative repair: dns before the early-return action
hosts: files myhostname mdns4_minimal dns [NOTFOUND=return] wins mdns4
mDNS를 지우는 대신 DNS를 조기 반환 동작 앞으로 옮기고, 구성 관리로 바꾸십시오. 손으로 고친 것은 다음 이미지 빌드까지 살아남고, 그러면 같은 티켓이 그 수정을 기억하지 못하는 다른 장비에서 다시 옵니다.
리졸버는 검색 도메인이 아닙니다
해석에는 이름이 시도되는 것도 필요합니다. fileserver 같은 비정규 이름은 질의를 나르는 인터페이스에 검색 도메인이 붙어 있을 때만 fileserver.corp.example가 됩니다. 검색 목록 없이 DNS 서버만 밀어 넣는 VPN은 아주 특정한 분할을 만듭니다: 정규화된 이름은 해석되고 모든 짧은 이름은 실패합니다.
프로필을 고치기 전에 두 형태를 모두 시험하십시오. 두 실패가 서로 다른 방향을 가리키기 때문입니다. systemd-resolved 호스트에서 터널 링크는 자기 서버와 라우팅 도메인을 소유하므로, 전역 파일이 아니라 링크를 읽으십시오.
resolvectl status
resolvectl query fileserver.corp.example
resolvectl dns
resolvectl domain
질의가 터널을 나르지 않는 링크에 배정되면 DNS 주소가 있어도 라우팅 도메인이 빠집니다. 그것은 resolved 설정의 정책 문제이지 터널의 라우팅 문제가 아닙니다.
컨테이너는 답의 사본을 따로 지닙니다
일반 이미지로 만든 컨테이너는 보통 고정된 resolv.conf를 함께 가집니다. 호스트에서 한 리졸버 변경은 거기에 닿지 않고 검색 도메인도 마찬가지라서, 터널 너머로 공유를 마운트하는 빌드 작업은 실패하지만 같은 명령이 컨테이너 밖에서는 됩니다. 컨테이너에 자체 DNS와 검색 설정을 compose 파일이나 run 인자에 주십시오. 호스트 프로필에만 두지 마십시오.
이미지를 탓하기 전에 컨테이너 안에서 확인하십시오. 명령 두 개면 진단 전체가 몇 초 만에 재현되고, 두 번째가 어느 리졸버가 실제로 답했는지 증명합니다.
그다음에야 공유와 필터를 봅니다
이름이 해석되면 남는 실패는 평범한 네트워크 문제입니다. SMB는 서버로 가는 TCP 445가 필요하고, 작업 그룹 목록을 훑는 일은 터널이 아마 전달하지 않는 이름 서비스에 달려 있습니다. 목록이 채워지기를 기다리는 대신 호스트 이름으로 매핑하고, 클라이언트가 어느 단계까지 갔는지 말하게 하십시오. 거부된 연결과 조용한 timeout도 구분할 가치가 있습니다. 앞은 보통 무언가 답했다는 뜻이고 뒤는 아무것도 답하지 않았다는 뜻입니다.
getent hosts fileserver.corp.example
nc -vz fileserver.corp.example 445
mount -t cifs //fileserver.corp.example/share /mnt/share \
-o vers=3.1.1,username=svc_mount,uid=1000
해석된 주소에서 445 포트가 거부되거나 시간이 초과되면 저쪽의 방화벽이나 리스너 문제입니다. 해석되지 않은 이름은 리졸버 문제입니다. 그리고 인증은 되지만 권한 오류를 돌려주는 마운트는 둘 다 아니므로, 세션이 맺어진 뒤에 네트워크 질문을 다시 열지 마십시오.
결론은 증거만큼만 좁게 유지하십시오. 주소는 되고 이름이 안 되면 터널은 제 일을 하는 것이고, 고칠 곳은 리졸버 순서, 검색 도메인, 또는 컨테이너 자체 설정입니다.