같은 경로를 두고 다투는 두 스크립트는 Linux VPN 문제가 라우팅 버그로 보고될 때의 전형적인 모습입니다. 한 구성 요소가 터널 장치를 만들고, 다른 구성 요소가 기본 경로를 추가하고, 세 번째가 리졸버 구성을 다시 쓰고, 네 번째가 방화벽 규칙을 다시 불러옵니다. 어느 것이든 다른 것의 작업을 되돌릴 수 있고, 승자는 그저 마지막에 실행된 쪽입니다. 답할 가치가 있는 질문은 어떤 패키지를 설치할지가 아니라 상태의 각 부분에 어떤 구성 요소가 권한을 가지는가입니다.

그 지도를 한 번 적으면 대부분의 재연결 실패가 더 이상 미스터리가 아닙니다. 중요한 대상은 넷입니다. 장치와 그 주소, 경로와 정책 규칙, DNS 구성, 그리고 방화벽입니다.

장치와 그 주소

터널 장치는 프로필을 아는 관리자가 만들거나, 누군가 직접 시작한 데몬이 만듭니다. 두 방식 모두 각자 잘 동작하지만 섞으면 안 됩니다. NetworkManager가 프로필을 소유한다면 장치도 소유하게 두고, 같은 터널 이름에 대해 관리되지 않는 OpenVPN 프로세스를 시작하지 마십시오.

세션이 끝날 때 누가 장치를 제거하는지 기록하십시오. 세션보다 오래 사는 장치는 오래된 주소와 그 뒤따르는 혼란의 가장 흔한 원인입니다.

경로와 정책 규칙

바로 경로에서 소유권 충돌이 눈에 보이는 피해를 냅니다. 연결 관리자는 터널용 기본 경로와 원격 네트워크용 더 구체적인 경로를 설치합니다. 그다음 직접 작성한 스크립트가 다른 메트릭으로 자체 기본 경로를 추가하고 타이밍에 따라 조용히 이기거나 집니다. 어떤 항목이 연결에 속하고, 어느 것이 영구 정책이며, 어떤 구성 요소가 재연결 후에 그것들을 갱신하는지 정하십시오. 그다음 다른 구성 요소를 그 테이블에서 배제하십시오.

정책 규칙도 같은 명료함을 받을 자격이 있습니다. 아무도 채우지 않는 테이블을 가리키는 규칙은 죽은 터널과 똑같이 보이는 블랙홀을 만듭니다. 트래픽을 어딘가로 밀어 넣기 위한 규칙이라면, 그것이 선택하는 테이블을 같은 소유자가 유지해야 합니다.

DNS는 항상 별도의 소유자입니다

리졸버 데몬은 자기 정체성으로 자기 프로세스로서 실행되므로 터널의 라우팅 결정을 우연히 상속하지 않습니다. VPN이 DNS 서버를 밀어 넣을 때, 무언가가 그것을 리졸버가 존중하는 링크별 구성으로 번역해야 하고, 나중에 무언가가 그것을 제거해야 합니다.

여기서 오해는 프로필에 네임서버를 적는 것이 쿼리가 가는 곳을 바꾼다는 것입니다. 그것은 리졸버에게 하는 말을 바꿀 뿐, 리졸버가 업스트림에서 어떤 소켓을 쓰는지는 바꾸지 않습니다. 파일을 믿는 대신 쿼리와 경로 조회로 시험하십시오.

방화벽 상태, 그리고 그것을 누가 복원하는가

방화벽 규칙은 VPN 호스트에서 가장 자주 덮어쓰이는 대상입니다. 관리자는 연결마다 NAT나 포워딩 규칙을 추가할 수 있지만, 부팅 시의 방화벽 서비스가 저장된 규칙 집합을 다시 불러와 그것들을 지웁니다. 정책의 권한을 하나 고르고 다른 쪽을 그 소비자로 만들거나, 재부팅이 동작을 조용히 바꾼다는 것을 받아들이십시오. 연결에 속한 예외는 같은 소유자가 불러오는 파일에 있어야 하며, 문제 해결 중에 입력한 iptables 명령이 아닙니다.

규칙이 재연결을 견뎌야 한다면 분명히 말하십시오. 견디지 않아도 된다면 그것도 말하십시오. 다음 엔지니어는 더 편한 답을 전제할 것이기 때문입니다.

수명 주기: 부팅, 재연결, 해체

그 세 순간 각각에 소유자를 주십시오. 부팅에서는 무엇이 전제 조건을 준비하는지, 어떤 순서인지 정하십시오. 소프트 재시작에서는 장치는 살아남아도 세션 상태는 아닐 수 있으므로 생성자가 아니라 검증자가 실행되어야 합니다. 해체에서는 이 연결이 만든 것만 제거하십시오. 모든 경로를 재설정하거나 방화벽 전체를 비우는 것은 터널 하나를 퇴역시키는 것과 같지 않습니다.

관찰을 위해 ip monitor link address route는 커널 변경을 일어나는 대로 보여 주지만, 의도가 아니라 사건을 보고합니다. 삭제된 경로는 어느 프로세스가 삭제했는지 말해 주지 않습니다. 소유권 지도와 짝지으면 혼란스러운 종료가 짧은 후보 목록이 됩니다.

예외에도 비용이 있습니다. 충돌을 피하려고 장치 클래스 전체를 관리 대상 밖으로 표시하는 것은 그 상태를 아무에게도 넘기지 않는 것이며, 이는 수정이 아니라 결정입니다.

관련 글