VPN과 웹을 위한 하나의 공용 호스트: 역할을 나누는 방법
공인 IP 하나로 터널을 종료하고, HTTPS를 제공하고, 두 개의 사설 LAN에 도달할 수 있습니다. 먼저 주소, 각 포트, 전달 정책의 소유자를 정하십시오.
한 대의 머신이 세 가지 요구를 동시에 충족할 수 있습니다. 터널을 종료하고, HTTPS에 응답하고, 두 사설 LAN 사이를 전달합니다. 그것이 합리적인지는 종이 위에서 정할 수 있는 세 가지에 달려 있습니다. 공인 주소의 소유자는 누구인지, 각 포트와 프로토콜 쌍의 소유자는 누구인지, 어느 프로세스에 패킷 전달이 허용되는지입니다. 이 세 가지가 맞으면 공유 호스트는 특별할 것이 없습니다. 틀리면 깔끔하게 시작하고 끝내 응답하지 않는 서비스에 주말을 쏟게 됩니다.
다음은 결정 절차이지 구축 지침서가 아닙니다. 각 단계는 방금 추가한 역할이 정말로 격리되었음을 증명하는 점검으로 끝납니다.
포트보다 먼저 주소의 소유자를 고르십시오
터널 종단점과 웹 서버는 같은 커널을 공유할 수 있습니다; 같은 주소, 포트, 프로토콜을 동시에 공유하는 것이 실패하는 지점입니다. WireGuard는 보통 UDP 51820을 사용하고, OpenVPN 은 UDP 1194 또는 TCP 443을 사용하며, 웹 서버는 TCP 443을 사용합니다. 아픈 조합은 HTTPS 옆에서 TCP 443을 쓰는 OpenVPN입니다. 둘 다 같은 소켓을 원하고 커널은 먼저 바인딩한 쪽에 주기 때문입니다. 앞단의 디멀티플렉서, 예를 들어 sslh나 TLS를 이해하는 프록시만이 그 포트를 공유하게 해 주며, 그 장애는 방화벽 문제와 똑같이 보이는 구성 요소가 하나 늘어납니다.
무엇이든 바꾸기 전에 소유자를 보십시오: ss -lntup 는 수신 중인 각 소켓의 로컬 주소, 포트, 프로세스를 출력합니다. 다음을 보여 주는 두 행은 0.0.0.0:443 이면 두 번째 서비스가 결코 바인딩하지 않았다는 뜻입니다. init 스크립트가 아무리 명랑했어도 마찬가지입니다. 브리징도 소유자를 옮깁니다. eth0 가 br0 에 합류하면 IP는 br0 로 옮겨지고 eth0 을 지목하는 모든 방화벽 규칙은 더 이상 일치하지 않으므로, 서비스를 브리지에 바인딩하고 ip -br addr 로 확인하십시오.
같은 소유권 규칙이 가상 머신에서 나타나는 의외의 현상을 설명합니다. 같은 LAN의 게스트 안에서 도는 터널 서버는 게스트의 주소를 유지하므로, 호스트 자신의 주소로 향한 연결은 호스트에 남고 게스트의 터널은 그것들을 결코 보지 못합니다. 클라이언트 프로필이 무엇이라 하든 마찬가지입니다.
두 LAN 사이를 라우팅하거나 한쪽을 NAT 하십시오
서로를 보지 못하는 두 LAN은 각각 공용 호스트에 접속할 수 있고, 그 호스트가 터널 사이를 전달합니다. 이 라우팅 설계에는 세 가지가 필요합니다. 전달 기능을 켜고, 각 원격 프리픽스로 가는 경로를 두고, 통과 트래픽을 허용하는 전달 정책을 두는 것입니다. sysctl -w net.ipv4.ip_forward=1 은 첫째를, ip route add 10.20.0.0/24 dev wg1 은 둘째를, 다음과 같은 nftables 행은 nft add rule inet filter forward iifname "wg0" oifname "wg1" accept 셋째를 담당합니다.
출발지 NAT는 붙이기 쉽고 디버깅하기 어렵습니다. 매스커레이딩은 클라이언트 주소를 다시 쓰므로 먼 쪽은 실제 호스트가 아니라 허브를 보게 되고, 그 접근 규칙과 로그는 귀속에 쓸모가 없어집니다. 두 네트워크가 모두 당신의 것이면 라우팅하십시오. 한쪽이 반환 경로를 추가하지 않을 제삼자의 것이면 NAT가 이번 주에 내보낼 수 있는 선택입니다. 어느 쪽이든 주소 계획을 적어 두십시오. 겹치는 두 개의 /24는 어떤 구성으로도 라우팅할 수 없습니다.
노트북의 인터넷 출구 역할을 한다고 해서 같은 상자가 들어오는 터널을 종료하지 못하는 것은 아닙니다. 겹치는 주소만이 그것을 막으며, 그래서 주소 계획이 중요한 문서입니다.
두 역할을 멈춘 상태에서 분리를 시험하십시오
유용한 시험은 뺄셈입니다. 두 역할을 멈추고 세 번째가 여전히 응답하는지 확인하십시오. 터널 서비스가 꺼져 있어도 웹 요청은 완료되어야 하고, 웹 서버가 멈춰 있어도 터널 핸드셰이크는 완료되어야 합니다. 둘 다 모든 것이 돌 때만 동작한다면 우연한 의존이 있는 것입니다. 공유 방화벽 테이블, 잘못된 경로, 또는 틀린 주소를 가리키는 이름 같은 것입니다.
세 개의 명령이 그 시험을 구체적으로 만듭니다. curl -sk --resolve example.test:443:203.0.113.10 https://example.test/ 는 외부 DNS 없이 로컬 리스너가 응답함을 증명하고, wg show 는 클라이언트에서 핸드셰이크가 완료되었음을 증명하며, tcpdump -ni any port 51820 는 허브에서 라우팅 문제와 키 문제를 구분합니다. 캡처에 한 번도 나타나지 않는 핸드셰이크는 호스트 이전에 죽은 것입니다. 공급자 방화벽, 잘못된 공인 주소, 또는 경로 상의 NAT 규칙입니다.
전달되는 LAN에 대해서도 뺄셈을 반복하십시오. 피어 하나를 끊으면 허브를 가로지르는 핑은 실패해야 하고, 다시 연결하면 규칙을 건드리지 않고 핑이 회복되어야 합니다. 터널을 다시 시작한 뒤에야 회복되는 핑은 도달 가능성이 아니라 정책을 가리키며, 그것은 다른 수정입니다.
역할을 빼는 동안 규칙 집합을 읽기 쉽게 유지하십시오. nft list ruleset 은 정말 필요한 각 방향마다 허용 규칙 하나를 보여 주어야 하며, 모든 것을 허용하는 전달 체인은 분리가 아니라 동작하는 데모입니다.
IPv6 전용 액세스 회선과 IPv4 서비스
일부 액세스 회선은 IPv6 도달성만 제공하고, 서비스는 여전히 IPv4로 공개해야 합니다. 터널 자체는 아직 트래픽을 통과시키는 패밀리로 흐르고, 공개된 서비스는 터널 안의 주소에 앉습니다. 이것은 통상의 가정을 뒤집고 모니터링을 조용히 깨뜨립니다. IPv4 경로를 위해 작성한 방화벽 규칙이나 가동 시간 점검이 이제 아무것도 나르지 않는 인터페이스를 지켜보게 됩니다.
각 패밀리를 따로 시험하십시오. curl -4 과 curl -6 를 쓰는 이유는 한 번의 성공이 시도하지 않은 경로에 대해 아무것도 말해 주지 않기 때문입니다. 포트 소유권은 패밀리 사이에서 바뀌지 않지만 리스너는 바뀝니다. ss -lntup 는 IPv4와 IPv6 소켓을 별도 행으로 나열하고, 0.0.0.0:443 는 [::]:443 를 프로세스가 듀얼 스택 소켓을 요청하지 않는 한 포함하지 않습니다.
한 패밀리에서 응답하고 다른 패밀리에서 거부하는 서비스는 보통 리스너 문제이지 라우팅 문제가 아닙니다. 설계를 끝났다고 부르기 전에 각 역할이 자기 주소나 포트를 가지는지, 전달이 켜져 있고 허용되는지, 그리고 나머지 둘을 멈춘 상태에서도 각 역할이 응답하는지 확인하십시오.