커뮤니티

보따리 무역 화물 수출 전문 포워딩 업체

페이지 정보

작성자 Elin 작성일25-05-17 16:47 조회1회 댓글0건

본문

일단.. 포워딩 이것 때문에 3시간이 날라갔습니다..​​하지만 iptables에 대한 동작 원리를 이해하는 경험이 참 값진거 같아서 좋네요 ㅎ ^^^^^^^^^^​무슨 문제였는가?일단 iptables 구성도 보겠습니다.FORWARD 이후 nat(POSTROUTING) -&gtmangle ->Client -&gtiptables -&gtServer ​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 테이블 -&gtmangle 테이블 -&gtnat 테이블 -&gtfilter 포워딩 테이블 ( 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 포워딩 -&gtmangle -&gtfilter/ INPUT으로 이동시켜버리더군요​원래 정상 동작은 다음과 같아야합니다. ​​mangle -&gtnat PREROUTING nat PREROUTING -&gtFORWARD​mangle -&gtINPUT이 아니라,.​mangle -&gtnat 의 PREROUTING -&gtFORWARD 이 떠야하거든요.. 하지만 이것은 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() -&gtbytes 반환get_payload()를 사용하여 바이너리를 직접 추출할 수 있습니다.​​​DNAT 스크립트​accept() 호출하면 패킷이 다시 mangle쪽으로 복귀한다.그런 다음 scapy에서 이 바이너리를 가져와서 ​Destination 에 대한 NAT로,​목적지 IP를 내부망 HOST IP로 변환해야합니다. ​변환 수정 과정을 손쉽게 하고,​이젠 패킷 바이너리가 바껴버렸으니, 포워딩 chksum 필드를 지웁니다. 이경우 bytes() 로 변환할 때 체크섬을 다시 새로 채워주기 때문에 괜찮습니다.​​이제 set_payload() 로 변경사항 적용한 뒤,​accept()으로 NFQUEUE 작업을 마무리하고다시 쪽으로 복귀됩니다.​이후 로그를 확인해보겠습니다.​mangle -&gtFORWARD 이동됨mangle -&gtFORWARD 이동되는 것을 확인할 수 있습니다.​이런 경우라면,,, 구현한 파이썬이 마치 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) 외부 -&gt내부 패킷 들어올 땐 DNAT -&gtmangle 테이블의 PREROUTING 에 NFQUEUE 추가2) 내부 -&gt외부 나갈 땐 SNAT -&gtmangle 테이블의 POSTROUTING 에 NFQUEUE 추가상단 -&gtDNAT을 위한 NFQUEUE 규칙하단 포워딩 -&gtSNAT을 위한 NFQUEUE 규칙​최종 결과물은?​칼리리눅스 (스캐너) ------&gt서버 ( 타겟 ) XMAS 스캔​nmap 결과 (closed라는 것은 성공적으로 TCP서버가 닫혀있음을 인지함)왼쪽 와이어샤크 ===&gt칼리리눅스에서 패킷 확인​오른쪽 와이어샤크 ===&gt스캔 대상 서버에서 확인​* (TEST환경) TCP서버가 닫혀있어야 RST+ACK를 받으므로, 따로 서비스를 열지 않음.​​내부 =&gt외부 패킷 이동시에도 NFQUEUE 패킷 처리 파이썬 스크립트로 SNAT까지 구현해주니,칼리리눅스가 응답을 정확히 확인하는 것을 확인할 수 있었습니다.​​하드코딩되었기에, 실제 적용시에는 적절하게 환경에 따라 변경하세요​iptables에서 NFQUEUE를 설정하고, 파이썬 스크립트에서 패킷을 처리하는 방법. Contribute to lastime1650/iptables_NFQUEUE_python_handler development by creating an account on GitHub.​

댓글목록

등록된 댓글이 없습니다.