GN⁺: Linux가 어떻게 NAT를 통해 ping을 처리하는가?
(devnonsense.com)- 리눅스가 인터넷 제어 메시지 프로토콜(ICMP)을 사용하는 핑 명령어에 대해 네트워크 주소 변환(NAT)을 수행하는 방법에 대한 기사 설명
- 저자가 ICMP 패킷에 대한 NAT 작동 방식을 이해하기 위해 리눅스 네트워킹 코드를 탐구, ICMP 패킷은 포트 필드가 없음
- 저자가 네트워크 네임스페이스를 사용하여 단일 리눅스 기계에서 여러 장치를 시뮬레이션하는 실험 설정, NAT 과정을 테스트하기 위해 핑 명령어 사용
- 실험은 브리지에 연결된 두 클라이언트 생성, NAT 박스와 서버 연결, 라우팅 및 NAT 구성을 포함
- 저자가 클라이언트와 서버 네트워크 네임스페이스에서 ICMP 패킷을 캡처하고 패킷 데이터를 분석
- 각 클라이언트가 다른 "id" 필드를 가지고 있어 NAT 박스가 각 클라이언트에게 전달되는 응답 패킷을 구분할 수 있음을 저자가 발견
- 저자가 리눅스 소스 코드와 ICMP 프로토콜을 정의하는 RFC 792를 탐구하여 ID가 어떻게 선택되는지 이해
- 핑 명령어가 식별자를 무작위로 선택하고, 다른 호스트에서 두 핑 프로세스가 동일한 ID를 선택하면, 리눅스 커널이 무작위로 빈 포트를 선택하고, 이 포트가 ICMP 패킷의 ID로 사용됨을 저자가 발견
- 저자가 커널 함수를 추적하고 netfilter 코드의 이해를 검증하기 위해 bpftrace라는 도구를 사용
- 기사 결론은 리눅스가 각 클라이언트에 대한 연결을 생성하여 핑을 NAT하고, 나가는 패킷에서 소스 IP 주소 및/또는 ICMP id 필드를 재작성하고, 그 후에 응답 패킷에서 이러한 수정을 반전한다는 것
- 기사는 기본 기술 지식을 가진 입문 레벨 소프트웨어 엔지니어에게 접근 가능하도록 과정에 대한 자세한 단계별 설명을 제공
Hacker News 의견
- 리눅스 네트워크 주소 변환(NAT)이 핑 요청을 처리하는 방법에 대한 기사
- 서버는 고정된 주소로 고정된 ICMP 에코 요청 패킷을 보내며, 이는 반환될 것으로 예상되지 않음
- 클라이언트가 연결하려 할 때, 서버가 보내던 "원래"의 고정 패킷을 포함한 ICMP 시간 초과 패킷을 서버로 보냄
- 클라이언트는 인터넷의 홉처럼 행동하여 서버에게 원래 패킷이 전달되지 못했다고 알림
- NAT 장치는 클라이언트의 전체 IP 헤더를 포함하여 ICMP 시간 초과를 NAT 뒤의 서버로 전달, 서버가 클라이언트의 IP 주소를 알 수 있게 함
- 로컬 네트워크에서 인터넷의 장치로 핑이 보내질 때, NAT를 수행하는 라우터는 핑의 소스 주소를 공개 IP 주소로 재작성하고 ICMP 패킷의 ID 필드를 고유한 값으로 재작성
- 라우터는 고유한 ID 값을 사용하여 응답을 로컬 네트워크의 올바른 장치로 전달
- 게시물은 패킷 망가뜨리기, 네트워크 주소 변환, 패킷 필터링에 사용되는 Netfilter라는 도구에 대한 자료도 제공
- 기사는 소스 코드까지 모든 추상화 계층을 깊게 파고들어 분석하는 데 대한 칭찬을 받음
- ICMP에는 포트가 없으므로, NAT는 ICMP 에코 응답을 올바른 포트로 되돌려 보내는 문제를 처리할 필요가 없음
- ICMP 에코 요청에는 ID가 있으며, 이는 소스 포트 번호와 사실상 동일
- ICMP 에코의 NAT 처리는 UDP가 소스 포트를 재매핑하는 것과 유사하게 ID를 양방향으로 재매핑해야 함
- 일부 사용자들은 시간이 지남에 따른 변경으로 인해 블로그 게시물에서 특정 코드 라인에 연결하는 것에 대한 불만을 표현
- 일부 사용자들은 NAT를 나쁜 추상화로 비판하고 IPv4의 종료를 촉구
- 중앙 서버 없이 UDP를 통해 핑을 이용하여 피어 투 피어 네트워킹을 위한 짧은 메시지를 보내는 가능성에 대한 추측
- 기사는 ICMP 패킷에 ID 필드가 있고 Netfilter가 ICMP 패킷을 "특별한 경우"로 처리한다는 것을 설명하는 것으로 요약