VPN 프로세스에 필요한 Linux 기능은 무엇인가?
인터페이스 설정, 경로, 장치 접근, 일반 소켓은 각각 별개의 권한입니다. CAP_NET_ADMIN을 부여하기 전에 실패한 작업을 먼저 특정하세요.
VPN 데몬은 특권 네트워크 작업이 필요하지만, 일반 애플리케이션은 아무런 권한 없이 나가는 소켓을 엽니다. 바로 이 틈에서 대부분의 기능 관련 실수가 시작됩니다: 누군가 권한 오류를 보고 전체 집합을 부여하면, 나중에는 아무도 설명할 수 없는 이유로 서비스가 동작합니다. 아래의 절차는 실패한 작업에서 시작해 그것을 하나의 권한에 대응시키고, 그다음 프로세스가 실제로 실행되는 맥락을 확인합니다. 제한 없는 root로 실행하는 것은 일부 배포에서는 타당한 답이지만, 기본값이 아니라 결정이어야 합니다.
실패한 작업에서 시작하세요
튜토리얼을 읽기 전에 오류를 읽으세요. 인터페이스 변경에서의 «작업이 허용되지 않음», 장치 노드를 열려는 요청의 거부, 낮은 포트에서의 바인드 실패는 서로 다른 세 가지 허용이 필요한 세 가지 문제입니다. 프로세스가 시작되고 첫 경로 변경에서만 실패한다면, 인터페이스 생성은 이미 성공했다는 뜻이므로 답이 크게 좁혀집니다.
서비스를 멈춘 상태에서 실패를 재현한 뒤, 구현이 허용한다면 같은 사용자로 포그라운드에서 시작하세요. 눈으로 보는 오류가 짐작해야 하는 로그 한 줄보다 낫고, 기능 문제와 SELinux나 AppArmor의 거부 사이의 차이를 분명히 보여 줍니다.
각 작업을 하나의 권한에 대응시키세요
이 표는 출발점 지도이며 구현 문서를 대신하지 않습니다:
| Operation | Usual authority | Watch for |
|---|---|---|
| Create or configure tun/tap | CAP_NET_ADMIN in the relevant namespace | Creating the device and opening it are separate steps |
| Add routes, rules, firewall entries | CAP_NET_ADMIN | Same capability, different namespace than you think |
| Open /dev/net/tun | Device permissions, not a capability | Group membership or a udev rule may be enough |
| Raw sockets | CAP_NET_RAW | Needed by some user-space tunnel implementations |
| Bind a port below 1024 | CAP_NET_BIND_SERVICE | Irrelevant for most modern tunnel ports |
그 표의 두 행이 바로 사람들이 혼동하는 부분입니다. /dev/net/tun 을 여는 것은 파일 권한의 문제이고, 연 것을 설정해 달라고 커널에 요청하는 것은 기능의 문제입니다. CAP_NET_ADMIN을 부여해도 서비스 사용자가 읽을 수 없는 장치 노드는 고쳐지지 않고, 노드를 고쳐도 경로 권한이 생기지 않습니다. 둘 중 하나를 바꾸기 전에 둘 다 확인하세요.
커널 WireGuard와 사용자 공간 터널 프로그램도 요구 사항이 같지 않습니다. 커널 모듈 경로는 기존 인터페이스를 netlink로 설정하지만, 사용자 공간 구현은 장치가 필요할 수 있고 일부 전송에서는 원시 소켓도 필요합니다.
맥락을 읽으세요: 서비스, 컨테이너, 셸
호스트의 네트워크 네임스페이스에 있는 기능은 의도적으로 격리된 스택 안의 같은 작업보다 훨씬 큰 영향을 줄 수 있습니다. 컨테이너 런타임은 보통 축소된 경계 집합으로 시작하며, 호스트 네트워크를 공유하는 컨테이너에 NET_ADMIN 을 추가하는 것은 자체 네트워크 네임스페이스가 있고 호스트 마운트가 없는 컨테이너에 추가하는 것보다 훨씬 큰 허용입니다.
systemd 유닛에서는 유닛 파일이 말하는 것처럼 보이는 것이 아니라 실제로 적용되는 것을 읽으세요: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities 은 유효 값을 보고하며, 그 값은 잊고 있던 drop-in이 설정했을 수 있습니다. 의도한 값이 아니라 유효 값을 물으세요. ambient 기능이 중요한 이유는 root가 아닌 서비스가 그것 없이는 exec 을 거치면서 기능을 잃기 때문입니다.
패키지나 이미지가 지원하는 설정을 기준으로 삼고, 다른 튜토리얼이 다른 도구용으로 나열했다는 이유로 원시 소켓 권한이나 특권 모드를 추가하지 마세요. 그 추론은 아무것도 옮겨 주지 않고, 지불한 격리를 잃게 만듭니다. 의심스러우면 아무것도 부여하지 말고 필요한 정확한 작업에 대한 구현 노트를 읽으세요.
권한이 떨어진 뒤에 무슨 일이 일어나는지 보세요
많은 데몬이 특권으로 시작해 인터페이스를 설정한 뒤 비특권 사용자로 내려가 터널을 유지합니다. 그 시점부터 프로세스는 경로를 추가하거나 방화벽 규칙을 다시 쓰거나 새 특권 장치를 열 수 없으며, 재연결이 바로 그것을 필요로 하기 전까지는 문제가 없습니다. 이후의 파일 읽기와 훅 실행도 같은 이유로 실패할 수 있습니다.
첫 순간이 아니라 전체 수명 주기를 시험하세요: 시작, 갱신이나 재연결, 중지 시 정리입니다. 인터페이스 생성이 처음 성공했다고 해서 이후의 모든 특권 작업이 계속 동작한다는 증거는 아니며, 실패는 보통 운영 환경에서 몇 시간 뒤에 나타납니다.
사용자 전환을 넘겨 터널을 열어 두는 구현은 보통 터널과 키를 유지하는 옵션과 함께 씁니다. systemd 쪽에서 같은 질문은 유닛의 기능 집합이 설정한 사용자 전환을 견디는지입니다.
부여와 그 이유를 기록하세요
정확한 부여, 그것이 가능하게 하는 작업, 그것이 고친 오류를 적으세요. 배포 노트의 한 줄 — «유닛의 네트워크 네임스페이스에서의 CAP_NET_ADMIN, 재연결 후 경로 변경에 필요» — 이면 다음 사람이 다시 부여를 넓히는 것을 막기에 충분합니다.
그다음 업그레이드마다 유효 집합을 다시 읽으세요. 공급업체는 기능을 추가하고 이미지는 기본값을 바꾸며, 작년에는 불필요했던 기능이 아무도 모르는 사이에 지탱하는 요소가 될 수 있습니다.