Pi 핫스팟과 Pi-hole·VPN: 서비스마다 역할을 하나씩 배정하기
Pi 한 대에서 세 가지 보조 도구를 켜기 전에 DHCP, DNS, 패킷 포워딩의 소유자를 정하세요. 소유자가 겹치면 경쟁하는 임대와 리졸버 루프가 생깁니다.
휴대폰이 Pi 핫스팟에 접속해 주소를 받았는데도 페이지가 열리지 않습니다. Pi에서는 핫스팟 보조 도구, Pi-hole, VPN 클라이언트가 돌고 있고, 각자 경로의 일부를 자기가 가진다고 생각합니다. 이런 구성이 실패하는 이유는 부품이 고장 나서가 아니라 두 부품이 같은 일을 하기 때문인 경우가 많습니다. 어느 하나를 조정하기 전에 기능마다 소유자를 하나씩 정하세요.
기능마다 소유자를 하나씩 정하세요
여기서는 네 가지 기능이 중요하고, 각각 정확히 소유자 하나가 필요합니다. 아래 표는 기능, 실행 가능한 소유자, 두 서비스가 서로 차지하려 할 때 무엇이 깨지는지를 보여 줍니다.
| Function | Workable owner | Duplicate-owner symptom |
|---|---|---|
| Client addresses | One DHCP server, such as the hotspot helper | Competing offers and changing leases |
| DNS reception | Pi-hole on port 53 | Bind failure or queries answered by the wrong process |
| Forwarding and NAT | One firewall manager | Double translation and broken return paths |
| VPN routing | One client configuration | Route flapping and traffic escaping outside the tunnel |
겹침은 보통 패키지 하나씩 들어옵니다. 핫스팟 보조 도구는 자체 dnsmasq를 설치하고, Pi-hole은 53번 포트를 원하며, VPN 클라이언트는 경로를 추가합니다. 각 단계는 따로 보면 합당하지만, 합치면 나중에 시작한 서비스가 먼저 시작한 서비스의 동작을 조용히 바꾸는 기계가 됩니다.
다른 것을 켜기 전에 소유자를 적어 두세요. 구축 메모에 짧은 표를 하나 두면 나중 설치가 이미 소유자가 있는 기능을 가로채는 일을 막을 수 있습니다.
범위를 하나 고르고 터널에서 멀리 두기
핫스팟 범위, 그 안의 Pi 주소, DHCP 풀, 클라이언트가 받는 리졸버를 고르세요. 그 범위는 겹치는 서브넷이 라우팅 문제를 주소 변환 사업으로 바꿔 버리기 때문에 업스트림 LAN과 VPN 터널 범위 모두와 겹치지 않게 두세요. 터널과 겹치는 범위는 Pi를 두 개의 같은 프리픽스 사이의 의도치 않은 라우터로 만듭니다. 범위와 풀은 기본값에 맡기지 말고 핫스팟 설정에 적으세요.
핫스팟을 NetworkManager의 공유 모드가 맡고 있다면 DHCP 서버를 더하기 전에 실제로 적용되는 연결을 확인하세요. 공유 모드는 자체 보조 도구를 띄우고 포워딩을 켜므로 이미 그 인터페이스의 주소 계획 소유자입니다. 쓸 수 있다는 이유로 서버를 하나 더 추가하면 이중화가 아니라 경쟁하는 배포가 생깁니다.
IPv6는 의식적으로 결정하세요. 많은 구성에서 라우터 광고와 DHCPv6는 DHCPv4와 다른 보조 도구에서 나오므로, VPN 정책이 IPv4만 덮는 상태에서 IPv6를 켜 두면 클라이언트에 터널을 우회하는 경로를 주게 됩니다. IPv6 쪽을 설계하거나, 핫스팟 인터페이스에서 이유를 적어 두고 끄세요.
53번 포트에서 실제로 응답하는 것은 누구인가
설정을 바꾸기 전에 53번 포트를 듣고 있는 프로세스를 모두 나열하세요. 로컬 리졸버 스텁, Pi-hole, 공유 보조 도구가 함께 도는 Pi에서는 듣는 프로세스 목록이 누가 질의에 응답하는지 보여 주는 유일하게 믿을 만한 지도입니다:
sudo ss -lunpt '( sport = :53 )'
ip -4 addr show
ip routePi-hole의 인터페이스 안내서는 인터페이스 하나로 제한한 수신 모드도 와일드카드 소켓을 쓰고 다른 곳으로 온 요청을 버릴 수 있다고 설명합니다. 이것은 선택한 인터페이스에만 바인딩하는 것과 다르며, 다른 DNS 서비스가 같은 기계를 나눠 써야 할 때 의도하는 구성은 후자입니다.
두 프로세스는 보통 같은 주소와 포트에 바인딩할 수 없지만 SO_REUSEPORT로 공유 바인딩이 성공할 수는 있으며, 그때도 와일드카드 리스너가 더 좁은 서비스로 갈 요청을 가져갈 수 있습니다. 원하는 역할에 맞는 문서화된 모드를 고르고 서비스를 의도한 순서로 다시 시작하세요.
Pi-hole 관리 페이지는 핫스팟 네트워크 밖에 두세요. 클라이언트에 필요한 것은 리졸버이고, 리졸버 설정을 바꿀 수 있는 웹 화면이나 API가 아닙니다.
DNS 두 구간, 각각 하나의 정책
클라이언트 질의는 휴대폰에서 Pi로 가고, 별도의 질의는 Pi에서 업스트림 리졸버로 갑니다. 포워딩된 핫스팟 트래픽에 맞는 라우팅 규칙은 그 트래픽을 Pi가 로컬에서 만들기 때문에 두 번째 구간에 자동으로 적용되지 않습니다. VPN이 DNS를 나른다면 로컬 경로에 자체 정책이 필요합니다.
루프를 조심하세요. Pi-hole의 업스트림을 Pi 자신이 제공하는 주소로 향하게 하면, 직접이든 포트 포워딩을 통해서든 시간 초과가 날 때까지 도는 질의가 생깁니다. 실제 업스트림을 주거나, 답할 수 없는 도메인에는 조건부 포워더를 두세요.
터널이 끊겼을 때 무슨 일이 일어날지 정하세요. 로컬 리졸버로 되돌리면 브라우징은 살아 있지만 이름이 VPN 밖으로 새어 나갈 수 있고, 차단하면 정책이 그대로 유지되고 장애가 눈에 보이는 오류가 됩니다. 둘 다 근거가 있지만, 기본값에서 물려받지 말고 골라야 합니다.
경로와 단절 시 동작을 증명하기
계층으로, 클라이언트가 주소를 받고, 클라이언트가 Pi를 거쳐 이름을 풀고, Pi가 의도한 업스트림을 거쳐 풀고, 애플리케이션이 요청을 끝내는 순서로 시험하세요. ping이 통한다고 DNS가 증명되지 않고, 이름 조회가 통한다고 포워딩이 증명되지 않습니다.
dig @192.168.70.1 example.com
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/
ip -4 route get 1.1.1.1그다음 터널을 멈추고 반복하세요. 의도한 동작은 몇 초 안에 나타나야 하고, Pi-hole이나 핫스팟 서비스를 손으로 다시 시작한 뒤여서는 안 됩니다. 장애 중에는 보조 공용 리졸버가 정책이 실패를 기대할 때도 계속 응답하므로 클라이언트의 리졸버 설정을 확인하세요.
포워딩과 NAT는 소유자를 하나로 두고, Pi 자체가 아니라 클라이언트에서 검증하세요. Pi를 정상적으로 떠난 요청도 돌아오는 길에 버려질 수 있고, 경로 전체가 보이는 곳은 클라이언트뿐입니다.