VPN 게이트웨이 자체 주소에서 LAN 서비스를 게시하기
클라이언트에서 장치까지 그리고 다시 돌아오는 전달된 포트를 추적합니다. 목적지 변환의 범위를 정한 다음 응답이 라우팅되는지 변환되는지 결정합니다.
게이트웨이 자체 터널 주소 중 하나에 LAN 장치를 노출하는 데는 NAT 한 줄이면 충분합니다. 그래도 연결은 실패합니다, 응답하는 장치가 클라이언트 주소가 그 게이트웨이를 통해 도달 가능하다는 사실을 전혀 모르기 때문입니다. 패킷을 클라이언트에서 안쪽으로 따라가고, 그다음 응답을 바깥으로 되돌아가는 방향으로 따라가면 빠진 절반이 분명해집니다.
클라이언트의 관점에서 시작하기
이 예의 클라이언트는 VPN 풀 10.62.0.0/24에 있고 8080 포트로 10.62.0.1에 연결합니다. 그 주소는 게이트웨이 자체의 것이므로 패킷은 다른 피어가 아니라 게이트웨이 커널에 도착합니다. 게이트웨이 뒤의 LAN은 172.21.4.0/24입니다. 게이트웨이가 172.21.4.10을 가지며 실제로 HTTP를 제공하는 장치는 172.21.4.40입니다.
다른 VPN 피어에 속한 주소는 게이트웨이의 서비스 주소와 바꿔 쓸 수 없습니다. 클라이언트가 피어의 주소에 연결하고 있다면 게이트웨이 규칙은 전혀 관여하지 않으며, 이 전체 설명은 잘못된 사례입니다.
목적지 변환의 범위를 의도적으로 좁히기
좁은 버전은 포트 하나를 노출하고 목적지만 다시 씁니다. 패킷은 프로토콜과 출발지를 유지하며, 바로 그것이 나머지 여정을 흥미롭게 만듭니다.
iptables -t nat -A PREROUTING -i tun0 -s 10.62.0.0/24 -d 10.62.0.1 -p tcp --dport 8080 -j DNAT --to-destination 172.21.4.40:80
프로토콜과 포트 조건이 없는 규칙은 넓은 버전이며, 클라이언트가 고른 포트를 그대로 유지하고 주소만 바꿉니다. 호스트 전체를 노출하려는 경우에는 정당하고, 서비스 하나가 의도였다면 잘못입니다. 규칙을 다시 읽고 인터페이스 이름을 확인하십시오. 잘못된 인터페이스의 DNAT 규칙은 아무것도 일치하지 않아, 규칙이 없을 때와 같은 타임아웃을 만들고 장치를 들여다보며 한 시간을 낭비합니다.
전달 경계도 동의하게 하기
변환은 헤더를 바꾸지만 허가를 주지는 않습니다. 기본 드롭 정책에서는 전달되는 흐름에 자체 허용이 필요하고, 되돌아오는 방향에는 정책에 아마 이미 있는 확립된 연결 규칙이 필요합니다.
iptables -A FORWARD -i tun0 -o lan0 -d 172.21.4.40 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
모든 DNAT 흐름에 대한 무조건 허용은 이 설계보다 넓으며 나중에 다른 사람이 추가한 매핑까지 통과시킵니다.목적지와 포트를 지정하고 나머지는 닫아 두기. 전달 규칙의 카운터가 영에 머무는데 NAT 카운터가 오른다면 패킷은 당신의 규칙보다 먼저 버려지고 있습니다. 두 번째 사본을 추가하는 대신 체인 순서를 읽으십시오.
장치는 어떻게든 응답해야 합니다
변환 후 장치는 10.62.0.0/24 안의 출발지를 봅니다. 그 응답은 VPN 게이트웨이가 아니라 LAN 라우터인 기본 게이트웨이로 가며, 무언가 다른 말을 하지 않는 한 그렇습니다. 이를 고치는 두 가지 배치가 있고, 둘은 동등하지 않습니다. 장치나 LAN 라우터의 경로는 10.62.0.0/24를 172.21.4.10으로 보내며 클라이언트 출발지를 유지합니다. 범위가 좁은 출발지 변환은 대신 클라이언트를 게이트웨이의 LAN 주소 뒤에 숨깁니다.
ip route add 10.62.0.0/24 via 172.21.4.10 dev eth1
iptables -t nat -A POSTROUTING -s 10.62.0.0/24 -d 172.21.4.40 -o lan0 -p tcp --dport 80 -j SNAT --to-source 172.21.4.10
서비스에 무엇이 필요한지로 선택하십시오. 클라이언트별 정책과 의미 있는 로그에는 라우팅된 형태가 맞고, 경로를 줄 수 없는 장치나 반드시 LAN 주소를 봐야 하는 서비스에는 변환된 형태가 맞습니다.응답 하나를 동작시키려고 전역 masquerade 규칙에 손을 뻗지 마십시오. 그것은 모든 클라이언트를 모든 목적지로부터 숨기고 출발지 주소에 의존하는 정책을 조용히 망가뜨립니다.
게이트웨이 자체에서 시험하지 마십시오
게이트웨이에서 10.62.0.1로 만든 요청은 들어오는 PREROUTING이 아니라 OUTPUT 체인으로 나갑니다. 그 실패나 성공은 클라이언트를 향한 규칙에 대해 아무것도 말해 주지 않으며, 사람들은 바로 그렇게 동작하는 규칙이 깨졌다고 결론 내립니다.
conntrack -L | grep 172.21.4.40
tcpdump -ni any 'port 8080 or port 80'
실제 클라이언트 요청을 실행하고 둘 다 읽으십시오. conntrack 항목은 적용된 변환을 보여 주고, 캡처는 요청이 LAN으로 건너갔는지 응답이 터널 쪽으로 돌아왔는지 보여 줍니다. 규칙을 바꾼 뒤에는 새 연결을 사용하십시오, 기존 상태는 이전 매핑을 유지하며 예전 방식으로 계속 실패합니다. 그런 다음 장치 주소, 전달 허가, 응답 경로가 모두 같은 흐름을 설명하는지 대화 전체를 확인하십시오.