클라우드 정책에서 VPN 포트를 허용해도 핸드셰이크는 인스턴스에서 죽을 수 있다. 게스트는 자체 필터와 자체 리스너 바인딩을 돌리고 있고, 둘 중 어느 쪽이든 클라우드가 승인한 것을 버릴 수 있다. 반대도 일어난다. 호스트 규칙이 포트를 허용해도 상위 정책이 먼저 떨어뜨리는 경우다. 소유자가 둘, 규칙 집합이 둘, 패킷 경로는 하나. 가장 의심스러운 계층에서 추측하지 말고 순서대로 따라가자.

가장자리에서 시작해 안쪽으로 들어가기

순서는 정해져 있다. 공용 엔드포인트, 리소스 인터페이스, 연결된 클라우드 정책, 게스트 주소, 프로세스 리스너, 로컬 입력 규칙. 각 단계는 패킷을 통과시키거나 조사를 끝낸다. 그래서 게스트부터 시작하면 시간을 가장 많이 낭비한다.

전달된 클라이언트 트래픽은 별도 단계이며 터널을 역캡슐화한 뒤에 검사한다. 클라우드 계층은 바깥 터널만 보므로 연결을 승인해도 내부 서비스 요청과는 아무 관련이 없을 수 있다. 연결은 되지만 내부 호스트에 닿지 않는 터널은 보통 닫힌 포트가 아니라 전달을 가리킨다.

게스트를 건드리기 전에 클라우드 정책을 읽기

VPN 포트의 인바운드 규칙, 프로토콜, 테스트 클라이언트와 맞는 소스 범위를 확인한다. 서브넷 액세스 제어 목록도 살핀다. 자체 규칙과 기본값을 가진 두 번째 필터다. 패킷이 인스턴스에 도달하기 전에 둘 다 흐름을 허용해야 한다. 한쪽은 허용하고 다른 쪽은 거부하는 것이 이 버그의 흔한 모양이다.

범위는 의미가 있을 때까지 좁힌다. VPN 포트를 인터넷 전체에 여는 것은 입증은 쉽고 방어는 어렵다. 반면 한 주소에 고정한 규칙은 테스트 클라이언트가 네트워크를 옮기면 깨진다. 규칙 식별자와 정책 소유자를 적어 두면 다음 변경을 사람까지 추적할 수 있다.

리스너를 확인하고, 그다음 입력 체인

인스턴스에서 VPN 프로세스가 예상한 주소와 포트에 바인딩되어 있는지 확인한다. 예를 들어 ss -lntp 'sport = :1194' 을 쓴다. 127.0.0.1 에만 바인딩된 데몬은 로컬 클라이언트를 받아들이고 터널로는 아무것도 받지 않는다. 밖에서 보면 이것은 필터된 포트와 똑같이 보인다.

그다음 변경에 쓸 것과 같은 문법으로 로컬 규칙을 읽는다. 예를 들어 iptables -S INPUT 이나 nft list chain inet filter input 이다. 파일에 적혔지만 한 번도 읽히지 않은 규칙, 또는 대응하는 허용이 없는 기본 드롭은 패킷을 조용히 버린다. 전달하는 게이트웨이라면 전달과 역경로 설정도 확인한다. 인스턴스로 향하지 않고 인스턴스를 거쳐 라우팅되는 패킷의 처리를 정하는 것이 이 설정들이다.

한 계층은 상태 유지, 다음 계층은 무상태

보안 그룹은 허용한 흐름을 기억하고 응답을 되돌려 보낸다. 서브넷 액세스 제어 목록과 많은 호스트 방화벽은 그런 상태를 유지하지 않는다. 그래서 나가는 방향만 덮는 규칙은 요청을 통과시키고 응답을 버린다. 두 번째 계층의 규칙을 읽지 않고 계층 사이에 반환 트래픽 가정을 넘기지 말아야 한다(second layer's rule).

계정의 모든 규칙을 읽는 것보다 카운터가 더 빨리 판정한다. 올라가는 카운터는 패킷이 그곳에 도착해 버려졌다는 뜻이고, 영에 멈춘 카운터는 그곳까지 가지 못했다는 뜻이다. 규칙을 카운터와 함께 읽어들였다면 iptables -vnL INPUT 과 nft list ruleset 이 그 수치를 보여 준다.

살아 있는 세션이 아니라 새 세션으로 시험하기

화면을 비교하는 동안 소스 네트워크와 테스트 프로필은 그대로 두고, 변경할 때마다 새 연결을 연다. 443 의 웹 콘솔에 닿는 것은 VPN 데몬이 1194 에 바인딩되어 있는지에 대해 아무것도 말해 주지 않는다. 필요한 포트를 시험해야 한다. 기존 세션은 여기서 최악의 증인이다. 새 로그인이 모두 거부되는 동안에도 그것은 계속 동작한다.

원격 정책을 편집하기 전에 변경하려는 경로에 의존하지 않는 되돌아갈 길을 확보한다. 그다음 VPN 시험과 나란히 두 번째 관리 세션을 연다. 먼저 맺은 세션은 새 연결을 막는 규칙보다 오래 살아남을 수 있다. 두 정책의 소유자를 모두 기록해 재구축이 경로의 절반을 되살리지 않게 한다. 두 계층이 일치하는데도 터널이 실패하면 게스트 인터페이스에서 캡처하고 클라이언트가 실제로 쓰는 주소와 포트를 확인한다.

관련 글