보따리 무역 화물 수출 전문 포워딩 업체
페이지 정보
작성자 Elin 작성일25-05-17 16:47 조회1회 댓글0건관련링크
본문
일단.. 포워딩 이것 때문에 3시간이 날라갔습니다..하지만 iptables에 대한 동작 원리를 이해하는 경험이 참 값진거 같아서 좋네요 ㅎ ^^^^^^^^^^무슨 문제였는가?일단 iptables 구성도 보겠습니다.FORWARD 이후 nat(POSTROUTING) ->mangle ->Client ->iptables ->Server Server는 포트포워딩 (TCP - 3000번) 된 상태입니다. 그러면 Client는 Iptables 의 IP와 3000포트로 패킷을 전달하면, iptables 에서는 -p tcp --dport 3000 -j DNAT --to-destination {Server}:3000-t nat PREROUTING 규칙에 의하여 포트포워딩 됩니다. 사진에서는 iptables의 어느정도 세밀한 구조를 보여주고 있습니다.ens160은 외부망 인터페이스이기에, Client와 같은 망이 될 수 있구요, ens160으로부터 패킷을 받으면 raw 테이블 ->mangle 테이블 ->nat 테이블 ->filter 포워딩 테이블 ( INPUT 또는 FORWARD )로 이동됩니다.filter는 그냥 iptables -L 하면 나오는 Chain들이 있구요, nat 은 iptables -L -t nat 을 하면 출력되는 Chain 을 보여줍니다. 그러면 도대체 뭐가 문제일까요? 제가 이런 포트포워딩이 된 환경에서 Client가 Server에 NMAP Xmas, NULL, 이런 conntrack 기준 INVALID한 패킷을 날려보려고 했었습니다.하지만,,,SYN (NEW) 플래그를 통해서 전송하지 않으면 포트포워딩을 하지 않아버립니다.nat 테이블의 PREROUTING체인 에-m conntrack --ctstate INVALID 추가하면 되지 않아?nat에서 PREROUTING 에서 항상 INPUT으로 이동해버리는 문제가 발생했습니다.MANGLE 테이블의 PREROUTING에 LOGNAT 테이블 PREROUTING에 LOGFILTER 테이블 INPUT에 LOG흐름 LOG 결과raw 포워딩 ->mangle ->filter/ INPUT으로 이동시켜버리더군요원래 정상 동작은 다음과 같아야합니다. mangle ->nat PREROUTING nat PREROUTING ->FORWARDmangle ->INPUT이 아니라,.mangle ->nat 의 PREROUTING ->FORWARD 이 떠야하거든요.. 하지만 이것은 NEW 세션일 때만 통과시킵니다.예상 되는 원인은 conntrack이라고 하는 녀석 때문에, INVALID같은 패킷의 경우 filter 테이블의 INPUT 체인으로항상 이동되어버려, nat 테이블로 가지질 못하는 상황으로 판단됩니다.좀 이와 다르긴 해도, Suricata는 기본적으로 INVALID 트래픽을 받지 않습니다.yes 해줘야 INVALID 수용가능그럼 어떻게 할건가?그래서 NFQUEUE라는 mangle - PREROUTING 에 NFQUEUE 등록NetFilter QUEUE 를 사용할 것입니다!!!!!iptables의 동작은 커널기반입니다. NFQUEUE는 유저모드 프로그램에 패킷을 전달하는 역할을 합니다. 포워딩 NFQUEUE라는 큐에 패킷을 전달하구요, 사용자 모드 프로그램에서는 이 큐를 식별하기 위해 --queue-num 값 (일반 정수형 값) 을 지정해서 바로 실시간 패킷을 큐로부터 가져올 수 있습니다그렇게 된다면, NFQUEUE 유저프로그램으로부터 DNAT 된 패킷을 다시iptables가 받아서, destination을 보고 FORWARD를 하게됩니다. 어떤 유저모드 프로그램?어떻게 구현했어 ?Python의 scapy(패킷 전송 및 분석)모듈과 NFQUEUE 큐로부터 패킷을 가져오기 위한 NetfilterQueue 2가지 모듈이면 충분합니다.사전 설치패키지 설치배포판에 따라 설치해주세요다음 파이썬의 pip 모듈 패키지 설치자 이제 코딩합니다. 모듈 로드QUEUE_NUM 변수는 NFQUEUE 큐 번호입니다.--queue-num 값이 0이다!이는 iptables 에서 -j NFQUEUE --queue-num의 값과 동일해야합니다. 그런 포워딩 다음 NetfilterQueue 인스턴스 하나 만들구요, bind해서 큐 번호와, 패킷을 받아서 처리할 handler 하나 만들어서 바인드 정보 등록 후에run() 메서드 호출하면 됩니다. 패킷 핸들러여기에서는 iptables 커널이 보낸 패킷을 인자로받아서 처리할 수 있는 핸들러입니다. 여기서 무엇을 하든 마음입니다 ㅎㅎDNAT을 구현해야하므로 scapy를 통해서 진행해봅시다.먼저 packet 바이너리를 추출해서 가져와야합니다. pkt.get_payload() ->bytes 반환get_payload()를 사용하여 바이너리를 직접 추출할 수 있습니다.DNAT 스크립트accept() 호출하면 패킷이 다시 mangle쪽으로 복귀한다.그런 다음 scapy에서 이 바이너리를 가져와서 Destination 에 대한 NAT로,목적지 IP를 내부망 HOST IP로 변환해야합니다. 변환 수정 과정을 손쉽게 하고,이젠 패킷 바이너리가 바껴버렸으니, 포워딩 chksum 필드를 지웁니다. 이경우 bytes() 로 변환할 때 체크섬을 다시 새로 채워주기 때문에 괜찮습니다.이제 set_payload() 로 변경사항 적용한 뒤,accept()으로 NFQUEUE 작업을 마무리하고다시 쪽으로 복귀됩니다.이후 로그를 확인해보겠습니다.mangle ->FORWARD 이동됨mangle ->FORWARD 이동되는 것을 확인할 수 있습니다.이런 경우라면,,, 구현한 파이썬이 마치 nat의 PREROUTING 대신 처리한 것과 비슷하다고 볼 수 있겠습니다.이미 파이썬 핸들러 작업을 통하여 destination IP 값이 내부 호스트로 미리 만들어줬으니,NAT의 PREROUTING DNAT 추가규칙을 만들지 않아도 destination ip 필드 값을 내부망 호스트로 바꿔버렸기에,,, iptables가 바로 FORWARD로 이동시킨 것이 됩니다.자 그럼 보내는 건 성공했다면, 응답은??? [왼쪽] 포워딩 칼리[오른쪽] 서버 target 어라? 칼리 리눅스측면에서 source 가 내부 호스트IP 그대로인데?.........결국 응답 가져오는 것도 문제가 있습니다 ( 마스커레이드 - SNAT 적용 안됨 )이 경우, nat테이블의 POSTROUTING 체인에서 감지되지 않아 SNAT적용이 안되었습니다.단, mangle 테이블의 POSTROUTING에서는 감지가 됩니다. 이때에도 똑같이 NFQUEUE로 SNAT을 구현해볼 수 있습니다.그러면 결국 파이썬으로 DNAT , SNAT까지 직접 구현하면 해결된다고 볼 수 있겠습니다. 1) 외부 ->내부 패킷 들어올 땐 DNAT ->mangle 테이블의 PREROUTING 에 NFQUEUE 추가2) 내부 ->외부 나갈 땐 SNAT ->mangle 테이블의 POSTROUTING 에 NFQUEUE 추가상단 ->DNAT을 위한 NFQUEUE 규칙하단 포워딩 ->SNAT을 위한 NFQUEUE 규칙최종 결과물은?칼리리눅스 (스캐너) ------>서버 ( 타겟 ) XMAS 스캔nmap 결과 (closed라는 것은 성공적으로 TCP서버가 닫혀있음을 인지함)왼쪽 와이어샤크 ===>칼리리눅스에서 패킷 확인오른쪽 와이어샤크 ===>스캔 대상 서버에서 확인* (TEST환경) TCP서버가 닫혀있어야 RST+ACK를 받으므로, 따로 서비스를 열지 않음.내부 =>외부 패킷 이동시에도 NFQUEUE 패킷 처리 파이썬 스크립트로 SNAT까지 구현해주니,칼리리눅스가 응답을 정확히 확인하는 것을 확인할 수 있었습니다.하드코딩되었기에, 실제 적용시에는 적절하게 환경에 따라 변경하세요iptables에서 NFQUEUE를 설정하고, 파이썬 스크립트에서 패킷을 처리하는 방법. Contribute to lastime1650/iptables_NFQUEUE_python_handler development by creating an account on GitHub.
댓글목록
등록된 댓글이 없습니다.