노트북은 이더넷으로 사무실 /24에 연결되어 있고, 같은 /24에 있는 OpenVPN 서버에도 함께 접속합니다. 동료가 터널 주소로 ping을 보내면 요청은 분명히 도착하지만 아무것도 돌아오지 않습니다. 터널 로그는 깨끗하고 브라우징은 여전히 되므로, 터널은 잘못된 용의자입니다. 수신하는 컴퓨터의 IPv4 소스 검증이 패킷을 읽기 전에 버립니다.

패킷을 읽기 전에 버려진다

소스 검증은 들어오는 모든 패킷에 대해, 이 호스트가 그 소스에 응답한다면 응답이 패킷이 방금 도착한 인터페이스로 나갈까라는 한 가지 질문을 합니다. 답이 아니오라면 커널은 도착 즉시 패킷을 버립니다. 어떤 소켓도 어떤 포워딩 경로도 그것을 보지 못하므로, 터널에서의 캡처는 애플리케이션이 결코 받지 못하는 요청을 여전히 기록합니다.

여기 클라이언트는 터널에 10.66.0.9를 두고 있고, OpenVPN 서버는 사무실 프리픽스 안의 192.168.80.10에서 응답합니다. 192.168.80.25의 동료가 터널 주소로 ping을 보내므로, 요청은 LAN을 지나 서버가 터널로 보내고, 사무실 소스 주소를 지닌 채 클라이언트의 터널 인터페이스로 도착합니다. 그 컴퓨터의 라우팅 테이블에서 사무실 프리픽스는 이더넷 장치에 속하며 터널에는 속하지 않습니다. 검증은 도착 인터페이스를 경로와 비교해 불일치를 찾고 패킷을 버리므로, 양쪽 끝이 건강한 터널을 보고하는 동안 동료는 완전한 손실을 봅니다.

거울 방향도 같은 모양으로, 클라이언트가 사무실 쪽으로 시작하면 같은 이유로 사무실 쪽에서 응답이 버려질 수 있습니다. 한 방향에서만 확인한 수정은 보통 두 번째 티켓으로 돌아옵니다.

어떤 sysctl도 만지기 전에 유효한 모드를 증명하라

인터페이스별 설정은 결정의 절반일 뿐이므로 배포판 기본값을 믿는 대신 실제 값을 읽으세요. 유효한 모드는 인터페이스 값과 all 값 중 높은 쪽이므로, all이 하나인 동안 터널 인터페이스의 영은 아무 의미가 없습니다. 엄격 모드의 결정은 라우팅 결정이므로, 커널이 실행하는 조회를 실행하고 그 답을 패킷이 실제로 도착한 인터페이스와 비교하세요.

tcpdump -ni tun0 icmp and host 192.168.80.25
ip route get 192.168.80.25
sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.tun0.rp_filter

그다음 오류 카운터를 보면서 ping을 반복합니다. 캡처가 이미 보여 주는 요청 옆에서 올라가는 수치는 이 버림의 서명이며, 빠진 경로의 것이 아닙니다. 그곳에 있는 동안 화성 패킷 로깅을 켜서 커널이 거부한 소스와 인터페이스를 지목하게 하세요. 함께 보면 암호, 방화벽, 빠진 iroute를 설명에서 배제합니다.

무엇이든 바꾸기 전에 두 값, 조회가 고른 장치, 지켜본 카운터를 기준선으로 적어 두세요. 그 기록이 나중에 변경이 생각한 대로 되었는지 알려 줍니다.

각 rp_filter 모드가 실제로 받아들이는 것

커널은 인터페이스마다 세 가지 값을 보여 주며, 그것들은 한 규칙의 세 가지 농도가 아닙니다. 영은 검사를 끕니다. 하나는 엄격해서 소스가 도착 인터페이스로 되돌아 라우팅되기를 요구합니다. 둘은 느슨해서 테이블에 소스로 가는 어떤 경로든 존재하기만을 요구합니다, 어디를 가리키든.

ValueNameAcceptsStill rejects
0offany source at allnothing on this check
1stricta source routed back out the arrival interfacea source whose route points elsewhere
2loosea source with any route in the tablea source with no route at all

여기서 중요한 행은 느슨한 쪽이며, 그것이 계속 거부하는 것입니다. 테이블 어디로든 라우팅되는 위조 소스는 통과하지만, 경로가 전혀 없는 소스는 여전히 거부됩니다. 노트북에서는 좁은 양보이고, 다른 사람의 트래픽을 전달하는 라우터에서는 넓은 양보입니다. 모드는 호스트에 속하므로 같은 숫자가 두 곳에서 다른 무게를 가집니다.

이 토폴로지에 어느 행이 필요한지는 습관이 아니라 테이블에서 나옵니다. 패킷은 정당하고 소스가 라우팅 가능하므로 느슨한 쪽은 받아들이고 엄격한 쪽은 받아들이지 않습니다. 이 사안에서 영을 요구하는 것은 없고, 영을 고르면 여기서 아무 비용도 들지 않는 검사를 없애게 됩니다.

모호함을 없애는 가장 작은 변경을 고르세요

느슨한 모드는 맞는 가장 작은 변경이며, 무해한 스위치가 아니라 엄격함의 실제 감소입니다. 토폴로지가 허락할 때마다 더 나은 선택이 있는데, 겹침을 없애면 모호함도 사라집니다.

사무실 프리픽스가 이더넷으로만 필요하다면, 프로필이 가져오는 경로에서 빼면 주소는 한 경로로 도달할 수 있게 됩니다. 두 경로가 정말 함께 존재해야 한다면, 모든 인터페이스에서 검증을 느슨하게 하는 대신 정책 규칙으로 소스와 장치를 고정하세요. 그러면 컴퓨터의 나머지 전부에 엄격한 필터링이 유지되고, 예외는 다음 엔지니어가 찾을 곳에 문서화됩니다.

어느 경로를 고르든 살아 있는 명령이 아니라 sysctl drop-in에 기록하세요. all과 default 키를 함께 설정해, 재접속이 엄격 모드를 조용히 되돌리지 못하게 하세요.

# /etc/sysctl.d/99-rp-filter.conf
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
sysctl --system

느슨한 모드가 포기하는 것, 그리고 그 장소

느슨한 모드는 어떤 경로도 닿지 못할 소스를 여전히 거부하고, 우연히 라우팅 가능한 위조 소스를 거부하는 것을 멈춥니다. 노트북에서는 좁은 양보입니다. 자기 것이 아닌 트래픽을 전달하는 장치에서는 같은 선택이 훨씬 넓습니다. 그래서 같은 설정이 어디에서 도는지에 따라 두 가지 매우 다른 의미를 가집니다.

다른 사람을 위해 트래픽을 전달하는 호스트에서 검사를 완전히 끄는 것이 피해야 할 유일한 수리입니다. 영은 느슨한 모드가 조심스럽게 지키는 검증을 버립니다. 호스트가 다른 이를 위해 전달한다면, 대신 앞 절의 정책 규칙 선택지를 주장하세요.

두 인터페이스, 겹치는 프리픽스, 그리고 이제 성공하는 정확한 검사를 지목한 메모를 남기세요. 필터링을 조정했다는 한 줄보다 다음 엔지니어에게 더 유용합니다.

관련 글