IP 테이블을 사용한 URL 필터링

IP 테이블을 사용한 URL 필터링

을 사용하려고 했는데 Iptables두 개의 인터페이스가 설정되어 있습니다. 트래픽은 한 인터페이스에서 들어오고 다른 인터페이스에서 나갑니다.

Iptables제가 구성한 내용은 다음과 같습니다 .

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:TCPFILTER - [0:0]
:URLFILTER - [0:0]
#######################
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT

#BGP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 179 -j ACCEPT

# Pass traffic to filters which have TCP Flags PSH,ACK and DST Port 80

-A FORWARD -p tcp --tcp-flags PSH,ACK PSH,ACK --dport 80 -j TCPFILTER
-A FORWARD -p tcp --dport 80 -j TCPFILTER
-A FORWARD -j ACCEPT

# Further process only packets with HTTP Get Request

-A TCPFILTER -m string --string "GET /" --algo bm --from 1 --to 70 -j URLFILTER
-A TCPFILTER -j ACCEPT
-A URLFILTER -m string --algo bm --to 500 --string "Host: www.tutorialspoint.com" -p tcp -j REJECT --reject-with tcp-reset
-A URLFILTER -j ACCEPT
COMMIT

수신된 패킷을 기반으로 한 Wireshark 출력은 다음과 같습니다.

여기에 이미지 설명을 입력하세요.

나는 그것이 작동할 것이라고 믿지만, 다음과 같이 체인에 어떤 히트도 발생하지 않습니다 URLFILTER.

    # iptables -L -v -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    7   352 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 255
  108  6621 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW,RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:2002
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:179

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   39 34674 TCPFILTER  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80 flags:0x18/0x18
  253 13392 TCPFILTER  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 75 packets, 13141 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain TCPFILTER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 URLFILTER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           STRING match "GET /" ALGO name bm FROM 1 TO 70
  292 48066 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain URLFILTER (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           STRING match "Host: www.tutorialspoint.com" ALGO name bm TO 500 reject-with tcp-reset
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

트래픽이 허용되고 전달되지만 문자열과 일치 TCPFILTER할 수 없습니다 .GET /

어떤 도움이라도 대단히 감사하겠습니다.

답변1

이것이 작동하지 않는 이유를 찾았습니다.

단일 패킷의 전체 HTTP 요청을 검사하기 위해 netfilter에 의존할 수는 없습니다. 페이로드가 여러 패킷에 분산되어 있으므로 동일한 패킷은 "GET /" 및 "Host:*"와 일치하지 않습니다.

다음 규칙 목록을 고려하십시오.

-A OUTPUT -p tcp -m tcp --dport 80 -j URLFILTER # would be FORWARD in your case
-A URLFILTER -m string --string "Host: www.kernel.org" --algo bm --from 1 --to 500 --icase -j LOG --log-prefix UF_MATCHHOST
-A URLFILTER -m string --string "GET /" --algo bm --from 1 --to 500 --icase -j LOG --log-prefix UF_MATCHGET

www.kernel.org에 대한 HTTP 호출은 다음과 같습니다.

GET / HTTP/1.0
Host: www.kernel.org

두 개의 규칙이 역순으로 일치하여 URLFILTER 체인이 여러 패킷에 의해 통과되었음을 증명합니다. 첫 번째 규칙은 GET 문자열을 전달하고 두 번째 규칙은 호스트 문자열을 전달합니다. 따라서 추가 작업 없이는 GET과 Host를 모두 일치시킬 수 없습니다.

[471493.767020] UF_MATCHGETIN= OUT=enp0s31f6 SRC=192.168.20.204 DST=147.75.205.195 LEN=67 TOS=0x00 PREC=0x00 TTL=64 ID=65494 DF PROTO=TCP SPT=51624 DPT=80 WINDOW=229 RES=0x00 ACK PSH URGP=0 
[471499.761216] UF_MATCHHOSTIN= OUT=enp0s31f6 SRC=192.168.20.204 DST=147.75.205.195 LEN=73 TOS=0x00 PREC=0x00 TTL=64 ID=65495 DF PROTO=TCP SPT=51624 DPT=80 WINDOW=229 RES=0x00 ACK PSH URGP=0 

아마도 GET /와 일치하고 다음 패킷과 일치하는 모든 연결을 추적할 수 있을 것입니다. 가능하다고 생각합니다.

Netfilter가 이 작업을 수행할 수 있지만 해당 작업에 가장 적합한 도구는 아닙니다.

원래 답변:

당신의

-A TCPFILTER -m 문자열 --string "GET /" --algo bm --1부터 70까지 -j URLFILTER

항목이 일치하지 않습니다. 문자열을 원시 HTTP 트래픽과 일치시킬 수 있습니까? tcpdump -vv를 사용하여 이 문자열을 볼 수 있습니까? 더 간단한 일치를 시도해보고 작동하는지 확인할 수 있습니까?

표시되는 Wireshark 출력은 iptables가 보는 것이 아니라 구문 분석된 패킷입니다. 다시 확인하기 위해 패킷의 16진수/ASCII 페이로드를 보고 싶습니다.

관련 정보