하나의 사설 서브넷에서 작동하는 strongSwan 연결이 누군가 한 줄을 편집했다고 해서 인터넷 트래픽을 운반하지는 않습니다. 전체 터널은 child SA가 어떤 주소를 보호하는지에 대한 두 피어 간의 합의이며, 각 피어는 상대를 자기 자신을 기준으로 부릅니다. 한쪽을 맞추고 다른 쪽을 틀리면 child SA는 올라오지 않거나 의도보다 좁게 올라옵니다. 아래 다섯 가지 점검은 그 합의를 클라이언트에서 게이트웨이를 거쳐 인터넷까지 따라갑니다.

먼저 클라이언트의 선택기를 확인하십시오

클라이언트는 반대편에서 보호하려는 것을 remote_ts으로 설명하고, 보내는 모든 것은 자신에게 할당된 주소에서 나옵니다. 인터넷 트래픽의 경우 그 값은 사용자가 실제로 도달할 목적지를 포함해야 하며, 실무적으로는 IPv4 공간 전체를 의미합니다. 여전히 서브넷 하나를 나열하는 클라이언트는 인터페이스에서 프로필 이름이 무엇이든 분할 터널을 요청하는 것입니다. 원본 측은 보통 dynamic이며, 주소가 연결 시점에 할당되기 때문입니다. 거기에 고정 원본을 쓰면 주소 풀이 바뀌는 순간 깨집니다.

children {
    net {
        local_ts  = dynamic
        remote_ts = 0.0.0.0/0
    }
}

이 조각은 완전한 연결 파일이 아니며, 인증, ID, 가상 주소 풀이 이미 구성되어 있다고 가정합니다. 클라이언트의 원본 선택기와 서버가 할당한 주소는 여전히 일치해야 하며, 그렇지 않으면 child SA는 어느 쪽도 예상하지 못한 범위로 올라옵니다. swanctl --load-all으로 로드하고 성공을 가정하기 전에 출력을 읽으십시오. 구문 분석되는 파일도 상대의 제안과 겹치지 않는 선택기 때문에 거부될 수 있습니다.

게이트웨이의 선택기를 그 자신의 측에서 확인하십시오

게이트웨이는 같은 개념을 반대 방향에서 읽습니다. 인터넷 목적지는 게이트웨이에 로컬이므로 local_ts이 넓은 쪽이고 remote_ts은 클라이언트 풀을 설명합니다. 이 반전은 전체 터널 구성에서 가장 흔한 실수이며, 두 줄이 각각 그럴듯해 보이기 때문에 검토를 통과합니다.

children {
    rw {
        local_ts  = 0.0.0.0/0
        remote_ts = 10.77.0.0/24
    }
}

클라이언트 조각을 게이트웨이 파일에 복사하면 두 쪽 모두 같은 역할을 주장하므로 아무 유용한 것도 설명하지 못하는 선택기 쌍이 만들어집니다. strongSwan 포워딩 가이드는 클라이언트와 게이트웨이의 짝을 명시적으로 문서화하며, 실패 후가 아니라 연결 파일 옆에서 읽을 가치가 있습니다. 게이트웨이 파일에는 remote_ts이 참조하는 풀 정의도 필요합니다. 존재하지 않는 풀을 지목하는 선택기는 불평 없이 로드되고 연결 시 실패합니다.

구형 ipsec.conf은 서로 다른 키로 왼쪽과 오른쪽 역할을 사용하며, rightsubnet 줄은 swanctl 값의 직접적인 대체가 아닙니다. 두 구문을 한쪽을 다른 쪽에 붙여 넣지 말고 별도 파일에 두십시오. 한 디렉터리에서 섞는 것이 작동하던 연결이 재부팅 후 조용히 되돌아가는 방식입니다.

파일이 아니라 협상된 child SA를 확인하십시오

저장된 구성은 의도만 증명할 뿐 그 이상은 아닙니다. 상대는 요청된 범위를 좁힐 수 있고, 기존 child SA는 그 아래 파일이 바뀌었다고 해서 교체되지 않습니다. 다른 무엇을 바꾸기 전에 실제로 무엇이 설치되어 있는지 확인하십시오.

swanctl --list-conns
swanctl --list-sas
ip xfrm policy list

첫 번째 명령은 데몬이 로드한 내용을, 두 번째는 설정된 child SA를, 세 번째는 커널이 적용할 정책을 보여줍니다. 파일이 0.0.0.0/0이라고 하는데 목록이 서브넷 하나를 보여 준다면 협상이 범위를 좁힌 것이며 파일을 다시 읽어도 설명되지 않습니다. child를 종료하고 다시 시작한 뒤 세 출력을 다시 비교하십시오. 같은 좁은 범위로 돌아오는 child는 로컬 파일이 아니라 상대에 의해 좁혀진 것이며, 그것은 로컬 편집이 아니라 다른 관리자와의 대화입니다.

정책 목록에서 양방향을 읽으십시오 — 한 방향만 설치하고 다른 방향은 설치하지 않는 터널은 구성 옷을 입은 라우팅 문제입니다. 정방향과 역방향 정책은 같은 선택기 쌍을 거울상으로 지목해야 하며, 빠진 거울은 선택기 텍스트가 아니라 데몬이나 제안의 결함입니다.

포워딩과 반환 경로를 확인하십시오

선택기는 트래픽을 게이트웨이로 허용하지만, 게이트웨이가 그 트래픽을 더 라우팅하도록 만들지는 않습니다. 포워딩이 활성화되어야 하고, 방화벽이 흐름을 허용해야 하며, 응답이 클라이언트 풀로 돌아갈 길을 찾아야 합니다. 이는 세 가지 별개의 요구 사항이며 각각 다른 증상으로 실패합니다. 빠진 포워딩 규칙은 블랙홀처럼 행동하고, 빠진 반환 경로는 단방향 터널처럼 행동합니다.

sysctl net.ipv4.ip_forward
iptables -t nat -S | grep -i masq
ip route get 1.1.1.1

사설 클라이언트 주소는 보통 공용 인터페이스를 떠나기 전에 의도적인 원본 변환이 필요하며, 명시적으로 라우팅된 할당은 다른 처리가 필요합니다. NAT가 관련되면 구현이 지원하는 예외를 유지하여 보안 정책이 검사해야 할 트래픽이 그것을 우회해 변환되지 않도록 하십시오. 다른 게이트웨이에서 복사한 광범위한 masquerade 규칙은 작성자가 의도한 것보다 훨씬 많은 흐름을 바꿉니다. 규칙은 클라이언트 풀에만 작성하고 왜 존재하는지 주석을 남기십시오.

클라이언트에서는 가정한 경로가 아니라 백엔드가 설치한 경로를 확인하십시오. 경로 설치가 비활성화된 관리자는 수동으로 유지되는 라우팅 설계가 필요하며, 그 설계는 터널이 바뀔 때마다 갱신해야 합니다. 라우팅 테이블은 새로 부팅한 후뿐 아니라 다시 연결한 후에도 확인하십시오.

터널이 여전히 다루지 않는 것을 확인하십시오

선택기 쌍은 IPv4만 다루고 그 외에는 아무것도 다루지 않습니다. IPv6, DNS, 모든 애플리케이션 수준 정책은 별개의 결정이며 넓은 IPv4 선택기는 이를 조용히 무시합니다. 모든 IPv4 패킷을 운반하는 터널도 모든 이름 조회를 유출할 수 있습니다.

로컬 리졸버로 이름을 계속 확인하는 전체 터널은 쿼리를 터널 밖으로 유출하고 사설 이름을 깨뜨리므로 의도한 DNS 경로를 명시하십시오. 클라이언트에 IPv6 주소가 할당되면 그 주소 체계에도 같은 처리가 필요하며, 그렇지 않으면 호스트는 터널이 보호하지 않는 경로를 선호합니다. 사설 측만 답할 수 있는 이름으로 테스트하고, 공용 응답은 유출로 취급하십시오.

resolvectl query intranet.example.internal
traceroute -n 1.1.1.1

위 목록에서 협상된 선택기와 함께 이 두 명령으로 체인을 확인하십시오. traceroute가 로컬 라우터를 첫 홉으로 보여 준다면 선택기가 무엇을 주장하든 트래픽은 터널을 쓰지 않습니다. 인터넷 접근은 선택된 트래픽이 설계된 게이트웨이를 통해 허용되고, 포워딩되고, 반환될 때만 완전합니다. 프로필에서 0.0.0.0/0을 찾는 것은 그 체인의 증거가 아니라 시작입니다.

관련 글