VPN을 통해 내 컴퓨터의 특정 사용자로부터 모든 트래픽을 라우팅하려고 합니다. 사용자의 패킷에 태그를 지정하기 위해 "-mowner --uid-owner"를 사용하여 iptables 규칙을 만든 다음 해당 패킷의 라우팅 테이블을 사용하여 이 작업을 수행했습니다. 모든 것이 리디렉션되도록 하기 위해 "-m Owner ! --uid-owner 0-99999 -j DROP"을 사용하여 만일의 경우에 대비해 모든 "익명" 네트워크 패킷을 삭제합니다.
대부분의 경우 잘 작동하지만 사용자로부터 오는 것이 분명함에도 불구하고 일부 SSL 연결에서는 이러한 현상이 거의 발생하지 않는 것으로 관찰되었습니다. 내가 "wget"을 하고 있다는 뜻이야https://google.comGoogle IP로 전송된 패킷이 uid 없이 전송되었기 때문에 삭제된 것을 로그에서 확인했습니다.
내가 이해하는 바는 커널이 때때로 어떤 이유로 요청을 "대기열"에 넣은 다음 패킷의 uid를 설정하지 않고 비동기식으로 처리할 수 있다는 것입니다. 이 경우 이 패킷의 실제 소스를 추적하는 것이 가능합니까? VPN을 통해 모든 "익명" 패킷을 전달할 수는 없습니다. 다른 사용자에게도 이런 일이 발생한다고 생각하기 때문입니다.
감사해요.
답변1
일부 패킷은 실제로 어떤 사용자에게도 속하지 않고 커널에만 속합니다.
- 패킷 라우팅
- 외부 이벤트에 대한 응답으로 커널에서 생성된 패킷입니다. 예를 들어 icmp echo-request가 수신되면 커널은 icmp echo-reply로 응답합니다.
- 아마도 모든 iptable에 대해 -j REJECT 패킷이 있을 것입니다.
- ...
이제 당신이 말하는 패킷에 대해: 소유자가 있는 패킷과 소유자가 없는 패킷으로 테스트한 결과, ACK
통신 종료 협상이 종료되고 FIN
연결 이 갑자기 끊어질 때 RST
최종 패킷 에 포함되는 것으로 보입니다. 내 생각에는 두 경우 모두 커널이 사용자에게 속한 연결을 분리하기 때문에 고려를 중단한 것 같습니다. 하지만 이것이 항상 발생하는 것은 아닙니다 ACK
(PSH 및 최종 데이터와 혼합될 때?).
업데이트: 답변"Iptables: 나가는 트래픽을 conntrack 및 소유자와 일치시킵니다. 이상한 삭제에 적합합니다."이 문제에 대한 자세한 정보를 제공하십시오.
이러한 패킷을 잃고 싶지 않고 여전히 의사 결정에 MARK를 사용하려는 경우에는 계속해서 MARK를 사용할 수 있습니다.넷필터 CONNMARK마지막 패킷은 소유자가 없더라도 여전히 동일한 연결의 일부이기 때문입니다. 예를 들어, 링크의 예에서 적용한 규칙으로 테스트해 보세요.
#!/bin/sh
iptables -t mangle -N connmark_test
iptables -t mangle -N connmark_log
iptables -t mangle -A connmark_test -j CONNMARK --restore-mark
iptables -t mangle -A connmark_test -m mark ! --mark 0 -j RETURN
iptables -t mangle -A connmark_test -m mark --mark 0 -m owner --uid-owner 0-99999 -p tcp -j MARK --set-mark 1
iptables -t mangle -A connmark_test -m mark --mark 0 -m owner --uid-owner 0-99999 -j MARK --set-mark 2
iptables -t mangle -A connmark_test -m mark --mark 0 -p tcp -j MARK --set-mark 3
iptables -t mangle -A connmark_test -m mark --mark 0 -j MARK --set-mark 4
iptables -t mangle -A connmark_test -j CONNMARK --save-mark
iptables -t mangle -A connmark_log -m owner --uid-owner 0-99999 -j LOG --log-prefix "with_owner "
iptables -t mangle -A connmark_log -m owner ! --uid-owner 0-99999 -j LOG --log-prefix " NO_owner "
iptables -t mangle -A POSTROUTING -j connmark_test
iptables -t mangle -A POSTROUTING -m mark ! --mark 0 -j connmark_log
curl -s -L https://google.com/ >/dev/null
(두 개의 연결 설정) 소유자가 일치할 때 최종 연결의 ACK 또는 RST가 일반적으로 실패하지만 다음과 같은 이유로 여전히 connmark가 있음을 알 수 있습니다 MARK=0x1
.
[14668.179780] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=83 TOS=0x00 PREC=0x00 TTL=64 ID=53193 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK PSH URGP=0 MARK=0x1
[14668.181740] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53194 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK FIN URGP=0 MARK=0x1
[14668.181914] NO_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.209.238 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=53195 DF PROTO=TCP SPT=33472 DPT=443 WINDOW=339 RES=0x00 ACK URGP=0 MARK=0x1
[14668.182667] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=83 TOS=0x00 PREC=0x00 TTL=64 ID=58460 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=520 RES=0x00 ACK PSH URGP=0 MARK=0x1
[14668.184588] with_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=58461 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=520 RES=0x00 ACK RST URGP=0 MARK=0x1
[14668.201316] NO_owner IN= OUT=eth0 SRC=10.0.3.66 DST=216.58.198.67 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=20784 DF PROTO=TCP SPT=33210 DPT=443 WINDOW=0 RES=0x00 RST URGP=0 MARK=0x1
최종 참고 사항: 사용자의 활동이 다른 사용자의 패킷을 트리거할 수 있다는 점을 잊지 마십시오. 예를 들어 로컬 DNS 서버에 DNS 요청이 이루어지면 로컬 DNS 서버는 실행 중인 사용자가 소유한 패킷을 사용하여 DNS 요청을 합니다. DNS 서버.