mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 12:10:53 +03:00
Compare commits
3 Commits
c0cb2c43bf
...
862ae72fd3
Author | SHA1 | Date | |
---|---|---|---|
|
862ae72fd3 | ||
|
954ddb5118 | ||
|
cd9b92e4d9 |
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -53,6 +53,7 @@ NFT_TABLE=blockcheck
|
|||||||
|
|
||||||
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
|
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
|
||||||
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ntc.party rutracker.org www.torproject.org bbc.com}
|
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ntc.party rutracker.org www.torproject.org bbc.com}
|
||||||
|
DOH_SERVERS=${DOH_SERVERS:-"https://cloudflare-dns.com/dns-query https://dns.google/dns-query https://dns.quad9.net/dns-query https://dns.adguard.com/dns-query https://common.dot.dns.yandex.net/dns-query"}
|
||||||
DNSCHECK_DIG1=/tmp/dig1.txt
|
DNSCHECK_DIG1=/tmp/dig1.txt
|
||||||
DNSCHECK_DIG2=/tmp/dig2.txt
|
DNSCHECK_DIG2=/tmp/dig2.txt
|
||||||
DNSCHECK_DIGS=/tmp/digs.txt
|
DNSCHECK_DIGS=/tmp/digs.txt
|
||||||
@ -201,6 +202,35 @@ nft_has_nfq()
|
|||||||
}
|
}
|
||||||
return $res
|
return $res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doh_resolve()
|
||||||
|
{
|
||||||
|
# $1 - ip version 4/6
|
||||||
|
# $2 - hostname
|
||||||
|
# $3 - doh server URL. use $DOH_SERVER if empty
|
||||||
|
$MDIG --family=$1 --dns-make-query=$2 | curl -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
||||||
|
}
|
||||||
|
doh_find_working()
|
||||||
|
{
|
||||||
|
local doh
|
||||||
|
|
||||||
|
[ -n "$DOH_SERVER" ] && return 0
|
||||||
|
echo "* searching working DoH server"
|
||||||
|
DOH_SERVER=
|
||||||
|
for doh in $DOH_SERVERS; do
|
||||||
|
echo -n "$doh : "
|
||||||
|
if doh_resolve 4 iana.org $doh >/dev/null 2>/dev/null; then
|
||||||
|
echo OK
|
||||||
|
DOH_SERVER="$doh"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo FAIL
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo all DoH servers failed
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
mdig_vars()
|
mdig_vars()
|
||||||
{
|
{
|
||||||
# $1 - ip version 4/6
|
# $1 - ip version 4/6
|
||||||
@ -219,7 +249,11 @@ mdig_cache()
|
|||||||
mdig_vars "$@"
|
mdig_vars "$@"
|
||||||
[ -n "$count" ] || {
|
[ -n "$count" ] || {
|
||||||
# windows version of mdig outputs 0D0A line ending. remove 0D.
|
# windows version of mdig outputs 0D0A line ending. remove 0D.
|
||||||
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
|
if [ "$SECURE_DNS" = 1 ]; then
|
||||||
|
ips="$(echo $2 | doh_resolve $1 $2 | tr -d '\r' | xargs)"
|
||||||
|
else
|
||||||
|
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
|
||||||
|
fi
|
||||||
[ -n "$ips" ] || return 1
|
[ -n "$ips" ] || return 1
|
||||||
count=0
|
count=0
|
||||||
for ip in $ips; do
|
for ip in $ips; do
|
||||||
@ -518,7 +552,7 @@ curl_supports_tls13()
|
|||||||
[ $? = 2 ] && return 1
|
[ $? = 2 ] && return 1
|
||||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||||
# this is online test because there's no other way to trigger library incompatibility case
|
# this is online test because there's no other way to trigger library incompatibility case
|
||||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://w3.org 2>/dev/null
|
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://iana.org 2>/dev/null
|
||||||
r=$?
|
r=$?
|
||||||
[ $r != 4 -a $r != 35 ]
|
[ $r != 4 -a $r != 35 ]
|
||||||
}
|
}
|
||||||
@ -1677,7 +1711,7 @@ pingtest()
|
|||||||
dnstest()
|
dnstest()
|
||||||
{
|
{
|
||||||
# $1 - dns server. empty for system resolver
|
# $1 - dns server. empty for system resolver
|
||||||
"$LOOKUP" w3.org $1 >/dev/null 2>/dev/null
|
"$LOOKUP" iana.org $1 >/dev/null 2>/dev/null
|
||||||
}
|
}
|
||||||
find_working_public_dns()
|
find_working_public_dns()
|
||||||
{
|
{
|
||||||
@ -1726,6 +1760,10 @@ check_dns()
|
|||||||
{
|
{
|
||||||
local C1 C2 dom
|
local C1 C2 dom
|
||||||
|
|
||||||
|
DNS_IS_SPOOFED=0
|
||||||
|
|
||||||
|
[ "$SKIP_DNSCHECK" = 1 ] && return 0
|
||||||
|
|
||||||
echo \* checking DNS
|
echo \* checking DNS
|
||||||
|
|
||||||
[ -f "$DNSCHECK_DIGS" ] && rm -f "$DNSCHECK_DIGS"
|
[ -f "$DNSCHECK_DIGS" ] && rm -f "$DNSCHECK_DIGS"
|
||||||
@ -1748,6 +1786,8 @@ check_dns()
|
|||||||
check_dns_cleanup
|
check_dns_cleanup
|
||||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||||
echo -- DNS CHANGE OR DNSCRYPT MAY BE REQUIRED
|
echo -- DNS CHANGE OR DNSCRYPT MAY BE REQUIRED
|
||||||
|
DNS_IS_SPOOFED=1
|
||||||
|
USE_SECURE_DNS=${USE_SECURE_DNS:-1}
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
echo $dom : OK
|
echo $dom : OK
|
||||||
@ -1777,6 +1817,8 @@ check_dns()
|
|||||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||||
echo -- DNSCRYPT MAY BE REQUIRED
|
echo -- DNSCRYPT MAY BE REQUIRED
|
||||||
check_dns_cleanup
|
check_dns_cleanup
|
||||||
|
DNS_IS_SPOOFED=1
|
||||||
|
USE_SECURE_DNS=${USE_SECURE_DNS:-1}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
echo all resolved IPs are unique
|
echo all resolved IPs are unique
|
||||||
@ -1825,7 +1867,8 @@ check_already
|
|||||||
[ "$UNAME" = CYGWIN ] || require_root
|
[ "$UNAME" = CYGWIN ] || require_root
|
||||||
check_prerequisites
|
check_prerequisites
|
||||||
trap sigint_cleanup INT
|
trap sigint_cleanup INT
|
||||||
[ "$SKIP_DNSCHECK" = 1 ] || check_dns
|
check_dns
|
||||||
|
[ "$SECURE_DNS" = 1 ] && doh_find_working
|
||||||
check_virt
|
check_virt
|
||||||
ask_params
|
ask_params
|
||||||
trap - INT
|
trap - INT
|
||||||
|
@ -341,3 +341,8 @@ v66:
|
|||||||
|
|
||||||
init.d: rewrite traffic interception and daemon launch parameters in config file. this break compatibility with old versions.
|
init.d: rewrite traffic interception and daemon launch parameters in config file. this break compatibility with old versions.
|
||||||
init.d: openwrt-minimal : tpws launch for low storage openwrt devices
|
init.d: openwrt-minimal : tpws launch for low storage openwrt devices
|
||||||
|
|
||||||
|
v67:
|
||||||
|
|
||||||
|
mdig: --dns-make-query, --dns-parse-query for side-channel resolving (DoH)
|
||||||
|
blockcheck: use DoH resolvers if DNS spoof is detected
|
||||||
|
@ -1098,6 +1098,26 @@ ip2net фильтрует входные данные, выкидывая неп
|
|||||||
Не надо делать такое : 5000000/10000000. 1/2 - гораздо лучше.
|
Не надо делать такое : 5000000/10000000. 1/2 - гораздо лучше.
|
||||||
|
|
||||||
|
|
||||||
|
mdig
|
||||||
|
----
|
||||||
|
|
||||||
|
Программа предназначена для многопоточного ресолвинга больших листов через системный DNS.
|
||||||
|
Она берет из stdin список доменов и выводит в stdout результат ресолвинга. Ошибки выводятся в stderr.
|
||||||
|
|
||||||
|
--threads=<threads_number> ; количество потоков. по умолчанию 1.
|
||||||
|
--family=<4|6|46> ; выбор семейства IP адресов : ipv4, ipv6, ipv4+ipv6
|
||||||
|
--verbose ; дебаг-лог на консоль
|
||||||
|
--stats=N ; выводить статистику каждые N доменов
|
||||||
|
--log-resolved=<file> ; сохранять успешно отресолвленные домены в файл
|
||||||
|
--log-failed=<file> ; сохранять неудачно отресолвленные домены в файл
|
||||||
|
--dns-make-query=<domain> ; вывести в stdout бинарный DNS запрос по домену. если --family=6, запрос будет AAAA, иначе A.
|
||||||
|
--dns-parse-query ; распарсить бинарный DNS ответ и выдать все ivp4 и ipv6 адреса из него в stdout
|
||||||
|
|
||||||
|
Параметры --dns-make-query и --dns-parse-query позволяют провести ресолвинг одного домена через произвольный канал.
|
||||||
|
Например, следующим образом можно выполнить DoH запрос, используя лишь mdig и curl :
|
||||||
|
mdig --family=6 --dns-make-query=rutracker.org | curl --data-binary @- -H "Content-Type: application/dns-message" https://cloudflare-dns.com/dns-query | mdig --dns-parse-query
|
||||||
|
|
||||||
|
|
||||||
Фильтрация по именам доменов
|
Фильтрация по именам доменов
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
157
mdig/mdig.c
157
mdig/mdig.c
@ -319,15 +319,135 @@ static int run_threads(void)
|
|||||||
return thread ? 0 : 12;
|
return thread ? 0 : 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slightly patched musl code
|
||||||
|
size_t dns_mk_query_blob(uint8_t op, const char *dname, uint8_t class, uint8_t type, uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
uint16_t id;
|
||||||
|
struct timespec ts;
|
||||||
|
size_t l = strnlen(dname, 255);
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (l && dname[l-1]=='.') l--;
|
||||||
|
if (l && dname[l-1]=='.') return 0;
|
||||||
|
n = 17+l+!!l;
|
||||||
|
if (l>253 || buflen<n || op>15u) return 0;
|
||||||
|
|
||||||
|
/* Construct query template - ID will be filled later */
|
||||||
|
memset(buf, 0, n);
|
||||||
|
buf[2] = (op<<3) | 1;
|
||||||
|
buf[5] = 1;
|
||||||
|
memcpy((char *)buf+13, dname, l);
|
||||||
|
for (i=13; buf[i]; i=j+1)
|
||||||
|
{
|
||||||
|
for (j=i; buf[j] && buf[j] != '.'; j++);
|
||||||
|
if (j-i-1u > 62u) return 0;
|
||||||
|
buf[i-1] = j-i;
|
||||||
|
}
|
||||||
|
buf[i+1] = type;
|
||||||
|
buf[i+3] = class;
|
||||||
|
|
||||||
|
/* Make a reasonably unpredictable id */
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
id = (uint16_t)ts.tv_nsec + (uint16_t)(ts.tv_nsec>>16);
|
||||||
|
buf[0] = id>>8;
|
||||||
|
buf[1] = id;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
int dns_make_query(const char *dom, char family)
|
||||||
|
{
|
||||||
|
uint8_t q[280];
|
||||||
|
size_t l = dns_mk_query_blob(0, dom, 1, family == FAMILY6 ? 28 : 1, q, sizeof(q));
|
||||||
|
if (!l)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "could not make DNS query\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (fwrite(q,l,1,stdout)!=1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "could not write DNS query blob to stdout\n");
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dns_parse_print(const uint8_t *a, size_t len)
|
||||||
|
{
|
||||||
|
// check of minimum header length and response flag
|
||||||
|
uint16_t k, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
|
||||||
|
char s_ip[40];
|
||||||
|
|
||||||
|
if (len<12 || !(a[2]&0x80)) return false;
|
||||||
|
a+=12; len-=12;
|
||||||
|
for(k=0;k<qcount;k++)
|
||||||
|
{
|
||||||
|
while (len && *a)
|
||||||
|
{
|
||||||
|
if ((*a+1)>len) return false;
|
||||||
|
// skip to next label
|
||||||
|
len -= *a+1; a += *a+1;
|
||||||
|
}
|
||||||
|
if (len<5) return false;
|
||||||
|
// skip zero length label, type, class
|
||||||
|
a+=5; len-=5;
|
||||||
|
}
|
||||||
|
for(k=0;k<acount;k++)
|
||||||
|
{
|
||||||
|
// 11 higher bits indicate pointer
|
||||||
|
if (len<12 || (*a & 0xC0)!=0xC0) return false;
|
||||||
|
dlen = a[10]<<8 | a[11];
|
||||||
|
if (len<(dlen+12)) return false;
|
||||||
|
if (a[4]==0 && a[5]==1 && a[2]==0) // IN class and higher byte of type = 0
|
||||||
|
{
|
||||||
|
switch(a[3])
|
||||||
|
{
|
||||||
|
case 1: // A
|
||||||
|
if (dlen!=4) break;
|
||||||
|
if (inet_ntop(AF_INET, a+12, s_ip, sizeof(s_ip)))
|
||||||
|
printf("%s\n", s_ip);
|
||||||
|
break;
|
||||||
|
case 28: // AAAA
|
||||||
|
if (dlen!=16) break;
|
||||||
|
if (inet_ntop(AF_INET6, a+12, s_ip, sizeof(s_ip)))
|
||||||
|
printf("%s\n", s_ip);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len -= 12+dlen; a += 12+dlen;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int dns_parse_query()
|
||||||
|
{
|
||||||
|
uint8_t a[1500];
|
||||||
|
size_t l;
|
||||||
|
l = fread(a,1,sizeof(a),stdin);
|
||||||
|
if (!l || !feof(stdin))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "could not read DNS reply blob from stdin\n");
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
if (!dns_parse_print(a,l))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "could not parse DNS reply blob\n");
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void exithelp(void)
|
static void exithelp(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
" --threads=<threads_number>\n"
|
" --threads=<threads_number>\n"
|
||||||
" --family=<4|6|46>\t; ipv4, ipv6, ipv4+ipv6\n"
|
" --family=<4|6|46>\t\t; ipv4, ipv6, ipv4+ipv6\n"
|
||||||
" --verbose\t\t; print query progress to stderr\n"
|
" --verbose\t\t\t; print query progress to stderr\n"
|
||||||
" --stats=N\t\t; print resolve stats to stderr every N domains\n"
|
" --stats=N\t\t\t; print resolve stats to stderr every N domains\n"
|
||||||
" --log-resolved=<file>\t; log successfully resolved domains to a file\n"
|
" --log-resolved=<file>\t\t; log successfully resolved domains to a file\n"
|
||||||
" --log-failed=<file>\t; log failed domains to a file\n"
|
" --log-failed=<file>\t\t; log failed domains to a file\n"
|
||||||
|
" --dns-make-query=<domain>\t; output to stdout binary blob with DNS query. use --family to specify ip version.\n"
|
||||||
|
" --dns-parse-query\t\t; read from stdin binary DNS answer blob and parse it to ipv4/ipv6 addresses\n"
|
||||||
);
|
);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -335,20 +455,23 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int r, v, option_index = 0;
|
int r, v, option_index = 0;
|
||||||
char fn1[256],fn2[256];
|
char fn1[256],fn2[256];
|
||||||
|
char dom[256];
|
||||||
|
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"help",no_argument,0,0}, // optidx=0
|
{"help",no_argument,0,0}, // optidx=0
|
||||||
{"threads",required_argument,0,0}, // optidx=1
|
{"threads",required_argument,0,0}, // optidx=1
|
||||||
{"family",required_argument,0,0}, // optidx=2
|
{"family",required_argument,0,0}, // optidx=2
|
||||||
{"verbose",no_argument,0,0}, // optidx=3
|
{"verbose",no_argument,0,0}, // optidx=3
|
||||||
{"stats",required_argument,0,0}, // optidx=4
|
{"stats",required_argument,0,0}, // optidx=4
|
||||||
{"log-resolved",required_argument,0,0}, // optidx=5
|
{"log-resolved",required_argument,0,0}, // optidx=5
|
||||||
{"log-failed",required_argument,0,0}, // optidx=6
|
{"log-failed",required_argument,0,0}, // optidx=6
|
||||||
|
{"dns-make-query",required_argument,0,0}, // optidx=7
|
||||||
|
{"dns-parse-query",no_argument,0,0}, // optidx=8
|
||||||
{NULL,0,NULL,0}
|
{NULL,0,NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(&glob, 0, sizeof(glob));
|
memset(&glob, 0, sizeof(glob));
|
||||||
*fn1 = *fn2 = 0;
|
*fn1 = *fn2 = *dom = 0;
|
||||||
glob.family = FAMILY4;
|
glob.family = FAMILY4;
|
||||||
glob.threads = 1;
|
glob.threads = 1;
|
||||||
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
||||||
@ -394,6 +517,12 @@ int main(int argc, char **argv)
|
|||||||
strncpy(fn2,optarg,sizeof(fn2));
|
strncpy(fn2,optarg,sizeof(fn2));
|
||||||
fn2[sizeof(fn2)-1] = 0;
|
fn2[sizeof(fn2)-1] = 0;
|
||||||
break;
|
break;
|
||||||
|
case 7: /* dns-make-query */
|
||||||
|
strncpy(dom,optarg,sizeof(dom));
|
||||||
|
dom[sizeof(dom)-1] = 0;
|
||||||
|
break;
|
||||||
|
case 8: /* dns-parse-query */
|
||||||
|
return dns_parse_query();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +535,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (*dom) return dns_make_query(dom, glob.family);
|
||||||
|
|
||||||
if (*fn1)
|
if (*fn1)
|
||||||
{
|
{
|
||||||
glob.F_log_resolved = fopen(fn1,"wt");
|
glob.F_log_resolved = fopen(fn1,"wt");
|
||||||
|
Loading…
Reference in New Issue
Block a user