mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-29 21:40:52 +03:00
nfqws: fix posnat initial packet handling
This commit is contained in:
parent
f94703a866
commit
99c6014adb
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
60
nfq/desync.c
60
nfq/desync.c
@ -321,6 +321,35 @@ static void reasm_orig_fin(t_ctrack *ctrack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static packet_process_result ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, packet_process_result res)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
// if used in postnat chain, dropping initial packet will cause conntrack connection teardown
|
||||||
|
// so we need to workaround this.
|
||||||
|
// we can't use low ttl for UDP because TCP/IP stack listens to ttl expired ICMPs and notify socket
|
||||||
|
// we also can't use TCP fooling because DPI would accept fooled packets
|
||||||
|
if (ip && ctrack && ctrack->pcounter_orig==1)
|
||||||
|
{
|
||||||
|
// routers will drop IP frames with invalid checksum
|
||||||
|
if (ip->ip_p==IPPROTO_TCP)
|
||||||
|
{
|
||||||
|
// linux recalc ip checksum in tcp
|
||||||
|
// need another limiter
|
||||||
|
ip->ip_ttl=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ip->ip_sum ^= htons(0xBEAF);
|
||||||
|
|
||||||
|
return res==frag ? modfrag : modify;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
// ipv6 does not have checksum
|
||||||
|
// consider we are free of NAT in ipv6 case. just drop
|
||||||
|
// BSDs also do not need this
|
||||||
|
return drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// result : true - drop original packet, false = dont drop
|
// result : true - drop original packet, false = dont drop
|
||||||
packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload)
|
packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload)
|
||||||
@ -479,26 +508,11 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
#ifdef __linux__
|
res = ct_new_postnat_fix(ctrack, ip, drop);
|
||||||
// if used in postnat chain, dropping SYN will cause conntrack connection teardown
|
|
||||||
// so we need to workaround this.
|
|
||||||
// we can't use low ttl because TCP/IP stack listens to ttl expired ICMPs in response to SYN and reset connection
|
|
||||||
// we also can't use TCP fooling because DPI would accept fooled packets
|
|
||||||
if (ip)
|
|
||||||
{
|
|
||||||
// routers will drop IP frames with invalid checksum
|
|
||||||
ip->ip_sum ^= htons(0xBEAF);
|
|
||||||
res=modify;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// ipv6 does not have checksum
|
|
||||||
// consider we are free of NAT in ipv6 case. just drop
|
|
||||||
res=drop;
|
|
||||||
#else
|
|
||||||
res=drop;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// can do nothing else with SYN packet
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.desync_cutoff)
|
if (params.desync_cutoff)
|
||||||
@ -1142,7 +1156,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return res;
|
return res;
|
||||||
// this mode is final, no other options available
|
// this mode is final, no other options available
|
||||||
return drop;
|
return ct_new_postnat_fix(ctrack, ip, drop);
|
||||||
}
|
}
|
||||||
desync_mode = params.desync_mode2;
|
desync_mode = params.desync_mode2;
|
||||||
break;
|
break;
|
||||||
@ -1163,7 +1177,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
udp_fix_checksum(udphdr,sizeof(struct udphdr)+len_payload,ip,ip6hdr);
|
udp_fix_checksum(udphdr,sizeof(struct udphdr)+len_payload,ip,ip6hdr);
|
||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, len_pkt))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, len_pkt))
|
||||||
return res;
|
return res;
|
||||||
return drop;
|
return ct_new_postnat_fix(ctrack, ip, drop);
|
||||||
}
|
}
|
||||||
desync_mode = params.desync_mode2;
|
desync_mode = params.desync_mode2;
|
||||||
}
|
}
|
||||||
@ -1180,7 +1194,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
DLOG("resending original packet with increased by %d length\n", params.udplen_increment);
|
DLOG("resending original packet with increased by %d length\n", params.udplen_increment);
|
||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return res;
|
return res;
|
||||||
return drop;
|
return ct_new_postnat_fix(ctrack, ip, drop);
|
||||||
case DESYNC_TAMPER:
|
case DESYNC_TAMPER:
|
||||||
if (IsDhtD1(data_payload,len_payload))
|
if (IsDhtD1(data_payload,len_payload))
|
||||||
{
|
{
|
||||||
@ -1205,7 +1219,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
DLOG("resending tampered DHT\n");
|
DLOG("resending tampered DHT\n");
|
||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return res;
|
return res;
|
||||||
return drop;
|
return ct_new_postnat_fix(ctrack, ip, drop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1261,7 +1275,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
return frag;
|
return ct_new_postnat_fix(ctrack, ip, frag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ static packet_process_result processPacketData(uint32_t *mark, const char *ifout
|
|||||||
// ipv6 packets were with incorrect checksum
|
// ipv6 packets were with incorrect checksum
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
// FreeBSD tend to pass ipv6 frames with wrong checksum
|
// FreeBSD tend to pass ipv6 frames with wrong checksum
|
||||||
if (res==modify || res!=frag && ip6hdr)
|
if (res==modify || res!=frag && res!=modfrag && ip6hdr)
|
||||||
#else
|
#else
|
||||||
if (res==modify)
|
if (res==modify)
|
||||||
#endif
|
#endif
|
||||||
@ -169,7 +169,7 @@ static packet_process_result processPacketData(uint32_t *mark, const char *ifout
|
|||||||
res = dpi_desync_udp_packet(*mark, ifout, data_pkt, len_pkt, ip, ip6hdr, udphdr, data, len);
|
res = dpi_desync_udp_packet(*mark, ifout, data_pkt, len_pkt, ip, ip6hdr, udphdr, data, len);
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
// FreeBSD tend to pass ipv6 frames with wrong checksum
|
// FreeBSD tend to pass ipv6 frames with wrong checksum
|
||||||
if (res==modify || res!=frag && ip6hdr)
|
if (res==modify || res!=frag && res!=modfrag && ip6hdr)
|
||||||
#else
|
#else
|
||||||
if (res==modify)
|
if (res==modify)
|
||||||
#endif
|
#endif
|
||||||
@ -216,6 +216,7 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
|||||||
switch (processPacketData(&mark, ifout, data, len))
|
switch (processPacketData(&mark, ifout, data, len))
|
||||||
{
|
{
|
||||||
case modify:
|
case modify:
|
||||||
|
case modfrag:
|
||||||
DLOG("packet: id=%d pass modified\n", id);
|
DLOG("packet: id=%d pass modified\n", id);
|
||||||
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, len, data);
|
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, len, data);
|
||||||
case drop:
|
case drop:
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
// frag=drop but do not fix checksum
|
// frag=drop but do not fix checksum
|
||||||
pass = 0, modify, drop, frag
|
pass = 0, modify, drop, frag, modfrag
|
||||||
} packet_process_result;
|
} packet_process_result;
|
||||||
|
Loading…
Reference in New Issue
Block a user