OpenVPN iroute와 커널 라우트: 어느 쪽이 빠졌나?
서버에 라우트가 있는데도 트래픽이 멈춥니다. 경로 결정 하나는 커널에, 다른 하나는 피어에 속합니다. 무엇이 빠졌고 무엇을 확인해야 하는지 알아보세요.
10.77.20.0/24 행 패킷은 OpenVPN 서버에서 두 가지 별개의 결정을 거칩니다: 운영체제가 이를 VPN 인터페이스로 넘겨야 하고, OpenVPN은 어느 연결 클라이언트가 그 프리픽스를 소유하는지 알아야 합니다. 커널 라우트가 없으면 패킷은 터널 이전에 버려지고, 피어 라우트가 없으면 그 이후에 버려집니다. 두 장애는 원격 LAN에서 똑같이 보이며, 어느 쪽인지 진단하려면 양쪽에서 명령 하나씩이 필요합니다.
고전적인 사용자 공간 데이터 경로에서 커널 라우트는 패킷을 터널 프로세스로 보내고 iroute는 그 프로세스에 어느 피어가 받아야 하는지 알려 줍니다. 어느 것도 다른 것을 대신하지 못하며, 둘 중 하나만 담은 구성은 첫 ping까지는 그럴듯해 보입니다.
두 결정, 하나의 라우트가 아니다
10.77.20.0/24가 단일 클라이언트 뒤에 있는 사이트 간 연결을 상상해 보세요. 서버의 커널 라우트, 예를 들어 ip route add 10.77.20.0/24 dev tun0는 일치하는 패킷을 터널 장치로 보냅니다. 그런 다음 OpenVPN은 클라이언트 구성 디렉터리의 iroute 항목으로 만든 자체 내부 테이블을 조회하여 어느 피어 연결이 이를 받을지 결정합니다. 커널 라우트가 없으면 패킷은 프로세스에 절대 도달하지 못하고, 피어 라우트가 없으면 프로세스에는 도달하지만 어디로도 가지 않습니다.
그 분리는 클라이언트 프로필의 라우트 한 줄이 두 작업을 모두 하는 것처럼 보이기 때문에 잊기 쉽습니다. 그렇지 않고, 라우트를 푸시하는 것은 클라이언트에게 터널로 무엇을 보낼지 알려 주며, iroute는 서버에게 클라이언트 뒤 주소 범위가 누구 것인지 알려 줍니다. 둘은 서로 다른 파일에 살고, 다른 쪽이 읽으며, 반대 방향으로 실패합니다.
iroute가 있는 곳과 말하는 내용
항목은 클라이언트의 common_name을 따라 이름 붙인 클라이언트별 파일에, client-config-dir 아래에 iroute 10.77.20.0/24 형태로 들어갑니다. 파일 이름 일치는 꾸밈이 아니며, OpenVPN은 인증된 신원을 조회하고 정확히 그 이름의 파일을 읽으므로 site-a라는 파일은 공통 이름이 site-a인 클라이언트에만 적용됩니다. 그런 파일이 없는 클라이언트를 아예 거부해야 한다면 모든 클라이언트가 사이트 게이트웨이일 때 맞는 설정인 ccd-exclusive를 추가하세요. 게이트웨이마다 파일 하나를 유지하고 실제로 발급하는 인증서 주체로 이름을 붙이세요.
원격 LAN을 탓하기 전에 서버에서 항목을 시험하세요. 상태 파일은 연결된 클라이언트를 공통 이름과 함께 나열하고, --verb 4로 실행하는 서버는 피어가 연결될 때 iroute가 설치되는 것을 로그로 남깁니다. 연결 시점에 아무것도 나타나지 않으면 파일이 잘못된 디렉터리에 있거나 잘못된 신원을 가리키는 것입니다.
함정: 파일은 있는데 신원이 틀리다
올바로 보이는 iroute가 잘못된 피어에 붙어 있으면 디스크상 모든 것이 맞아 보이므로 파일이 없는 경우보다 시간을 더 낭비합니다. 인증서 이름 변경, 중복된 공통 이름, 실효 신원을 바꾸는 username-as-common-name이 모두 이를 만듭니다. 기대했던 신원이 아니라 서버가 인증한 신원을 확인하세요(상태 출력이 권위 있고, 파일 이름은 조회 키일 뿐입니다).
라우트는 소유자보다 오래 살 수 있습니다. 정적 라우트와 iroute 항목은 가용성 보장이 아니라 프리픽스를 설명하므로, 트래픽은 현재 연결이 끊긴 피어를 향해 계속 라우팅될 수 있습니다.
피어 너머까지 경로를 완성하라
피어 소유는 경로의 중간이지 끝이 아닙니다. 클라이언트는 터널에서 자기 LAN으로 패킷을 전달해야 하며, 이는 그 호스트에서 IP 전달이 켜져 있고 통과를 허용하는 방화벽 규칙이 있어야 한다는 뜻입니다. 원격 LAN의 호스트는 터널 주소로 가는 돌아오는 경로가 필요한데, 게이트웨이를 향하는 라우트이거나 클라이언트 측에서 의도적으로 설계한 NAT입니다. 배포판 기본값을 가정하지 말고 sysctl net.ipv4.ip_forward로 클라이언트의 전달 설정을 확인하세요.
다른 VPN 클라이언트가 그 서브넷에 도달해야 한다면 구성은 다시 커지고, 서버에는 client-to-client가 필요하며 그 클라이언트들은 프리픽스를 터널로 라우팅해야 합니다. 이 중 어느 것도 서버 자체의 라우트 테이블에서 나오지 않습니다.
서버 자체가 아니라 실제 원본에서 목적지 하나를 검증하세요. 무관한 LAN 호스트에서 클라이언트 뒤 호스트로 보내는 ping은 돌아오는 경로, 전달 규칙, 피어 소유를 한 번에 시험하지만 성공한 핸드셰이크는 신원만 증명합니다. 그다음 소유 피어를 끊고 라우트가 어떻게 동작하는지 기록하세요(그 답이 바로 당신의 장애 모드입니다).