프로필을 건드리기 전에 OpenVPN 프로세스를 세어 보십시오. 로밍 사용자를 받아들이면서 업스트림 서비스로도 접속하는 Pi는 데몬 두 개를 실행하며, 각 데몬은 입력한 인스턴스 이름으로 선택된 구성 파일을 읽습니다. 패키지 템플릿은 이어서 각 데몬에 전용 작업 디렉터리와 전용 런타임 상태 파일, 전용 터널 장치를 부여합니다. 이 분리를 잘못하면 실행 중인 프로세스가 결코 열지 않는 파일 안의 올바른 설정을 고치며 저녁 하나를 보내게 됩니다.

인스턴스 이름마다 자기 파일을 고른다

OpenVPN 2.6과 함께 배포되는 유닛 파일에서 시작 인수에는 @ 기호 뒤의 텍스트로 채워지는 인스턴스 자리 표시자가 들어 있습니다. 서버 템플릿은 서버 구성 디렉터리에서 실행되며 인수를 그곳의 %i.conf에 대해 해석하고, 클라이언트 템플릿도 클라이언트 디렉터리에서 같은 일을 합니다. 따라서 [email protected]는 서버 디렉터리의 admits.conf를 읽고 [email protected]는 클라이언트 디렉터리의 uplink.conf를 읽으며, 두 이름 중 어느 것도 다른 디렉터리에서는 아무 의미가 없습니다.

패키지가 업스트림 기본값을 유지했다고 가정하지 말고 실제 기기에서 대응을 확인하십시오. 배포판의 drop-in은 작업 디렉터리나 구성 인수를 통째로 바꿀 수 있습니다.

systemctl cat [email protected]
systemctl cat [email protected]

그 출력에서 WorkingDirectory 줄과 구성 인수를 읽으십시오, 어떤 파일이 로드되는지는 활성화된 유닛만이 결정하기 때문입니다. ExecStart에 --config를 덧붙이는 drop-in은 템플릿 경로가 맞아 보여도 템플릿을 이깁니다. 로컬 재정의가 작동 중인지 알고 싶으면 프래그먼트와 drop-in 경로를 물으십시오. 두 역할이 같은 파일로 해석되면 하나의 프로세스가 서버이자 클라이언트가 되려는 것이며, 그 파일에서 뒤에 오는 옵션이 조용히 이깁니다.

로컬 전송과 전달된 페이로드는 서로 다른 훅에 닿는다

서버의 각 로밍 사용자에 대한 암호화 연결은 Pi 자체에서 생성되므로 바깥쪽 응답은 로컬 출력 훅으로 나갑니다. 클라이언트의 업스트림 피어 연결도 원격 네트워크에 닿지만 로컬에서 생성된 출력입니다. 전달되는 페이로드는 세 번째 범주이며, 커널은 패킷의 송출 장치를 이미 고른 뒤에야 그것을 대조합니다.

FlowHook that sees itWhat to inspect
Roaming user handshakes to the serverLocal input and local outputListener socket, bind address, rule admitting the UDP port
User payload leaving through the upstream tunnelForwardIPv4 forwarding switch, selected route, permission rule, any translation
Pi's own connection to the upstream peerLocal outputUnderlay route to the provider endpoint, not the tunnel route

포워드 체인 안에서 송출 인터페이스와 일치하는 규칙은 라우팅이 이미 그 인터페이스에 배정한 패킷을 허용하거나 버릴 수 있지만, 인터페이스를 고르지는 결코 않습니다. 한 호스트가 한 터널을 끝내고 다른 터널을 시작할 때, 사용자 페이로드를 업스트림 터널로 보내는 정책과 Pi 자체의 암호화 응답을 보호하는 정책은 별개의 결정입니다. 둘은 우연히 같은 물리 NIC에 도착하며, 그래서 혼동됩니다.

그 구분이 흔한 절반짜리 실패를 설명합니다. 사용자는 접속하고 핸드셰이크도 끝나지만 트래픽은 여전히 잘못된 방향으로 나갑니다, 핸드셰이크는 로컬이었고 페이로드는 포워드였으며 둘 중 하나만 시험되었기 때문입니다.

가져온 경로가 사용자에게 가는 응답을 삼킬 수 있다

클라이언트 프로필의 보안 설정은 업스트림이 Pi의 라우팅 테이블로 무엇을 push할 수 있는지 결정하며, 넓은 리디렉트는 작동하던 이중 역할 호스트를 망가뜨리는 옵션입니다. push된 경로가 로밍 사용자의 공인 주소를 덮으면, 서버가 그들에게 보내는 응답이 언더레이로 나가지 않고 새 경로를 따라 업스트림 터널로 들어갈 수 있습니다. 사람들은 프로바이더로 가는 터널이 아직 작동한다고 확인하고 거기서 멈추곤 하는데, 그 트래픽은 터널 자체의 전송이라 나머지가 모두 잘못 동작해도 계속 흐르기 때문입니다.

출발지나 mark 기반 정책이 두 스트림을 분리해 두는 방법입니다. OpenVPN의 Linux mark 옵션은 데몬 자체의 암호화 패킷에 방화벽 mark를 찍고, 라우팅 규칙이 그것을 전용 테이블로 보낼 수 있게 합니다. 서버의 바깥쪽 응답이 항상 하나의 언더레이 주소에서 나간다면 출발지 주소도 똑같이 잘 작동합니다. 어느 접근이든 선택한 테이블에 유효한 경로와 프로바이더 엔드포인트에 대한 예외가 필요하며, 그렇지 않으면 터널 자체가 올라오지 않습니다.

규칙을 쓰기 전에 응답이 실제로 지날 경로를 커널에 물으십시오. 아래 주소는 Pi의 언더레이 주소와 로밍 사용자 한 명의 공인 주소를 위한 자리 표시자입니다.

ip rule show
ip route get 198.51.100.7 from 192.0.2.10

분리를 검증한 뒤 역할을 하나씩 멈춘다

세 흐름을 따로 시험하십시오, 핸드셰이크가 되어도 나머지 둘에 대해서는 아무것도 증명하지 못하기 때문입니다. 새 인바운드 연결을 받아들이고, 허용된 애플리케이션 하나를 업스트림 출구로 보내고, 두 프로세스가 여전히 각자의 피어에 닿는지 확인하십시오.

그다음 클라이언트 역할을 멈추고 서버 역할이 무엇을 유지하는지 보십시오. 한 인스턴스를 위한 경로나 mark 규칙이 둘 모두에 적용되었는지 찾는 가장 저렴한 방법입니다.

systemctl stop [email protected]
systemctl status [email protected] --no-pager
ss -lunp | grep openvpn
journalctl -u [email protected] -n 20 --no-pager

보고 싶은 것은 클라이언트 역할이 내려가 있는 동안 리스너가 여전히 바인딩되어 있고, 터널 장치가 여전히 존재하며, 로그에 새 오류가 없는 상태입니다. 클라이언트를 멈추면 기존 사용자에 대한 서버의 응답까지 끊긴다면, 두 역할은 하나에만 국한되었어야 할 무언가를 공유하고 있습니다. 각 변경이 어느 인스턴스, 어느 구성 파일, 어느 흐름 소유자에게 닿았는지 기록하십시오, 그렇지 않으면 이 호스트를 다음에 디버깅할 사람이 같은 발견을 처음부터 되풀이하기 때문입니다.

관련 글