hostspell, openwrt procd, beeline ISP fix

This commit is contained in:
bolvan 2016-12-08 16:36:49 +03:00
parent 918a088527
commit 3bb71b42a0
15 changed files with 75 additions and 53 deletions

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.

View File

@ -70,3 +70,10 @@ v14
change get_antizapret script to work with https://github.com/zapret-info/z-i/raw/master/dump.csv change get_antizapret script to work with https://github.com/zapret-info/z-i/raw/master/dump.csv
filter out 192.168.*, 127.*, 10.* from blocked ips filter out 192.168.*, 127.*, 10.* from blocked ips
v15
added --hostspell option to nfqws and tpws
ISP support : beeline now catches "host" but other spellings still work
openwrt/LEDE : changed init script to work with procd
tpws, nfqws : minor cosmetic fixes

View File

@ -4,11 +4,15 @@
# CHOOSE ISP HERE. UNCOMMENT ONLY ONE LINE. # CHOOSE ISP HERE. UNCOMMENT ONLY ONE LINE.
#ISP=mns #ISP=mns
#ISP=rt #ISP=rt
#ISP=beeline ISP=beeline
#ISP=domru #ISP=domru
ISP=tiera #ISP=tiera
#ISP=none #ISP=none
USE_PROCD=1
# start betfore firewall - we need ipset populated
START=18
# !!!!! in openwrt you need to add firewall rules manually to /etc/firewall.user # !!!!! in openwrt you need to add firewall rules manually to /etc/firewall.user
QNUM=200 QNUM=200
@ -19,9 +23,6 @@ TPWS=/opt/zapret/tpws/tpws
IPSET_CR=/opt/zapret/ipset/create_ipset.sh IPSET_CR=/opt/zapret/ipset/create_ipset.sh
TPWS_USER=daemon TPWS_USER=daemon
# start betfore firewall - we need ipset populated
START=18
# must execute /etc/firewall.user on every firewall reload # must execute /etc/firewall.user on every firewall reload
set_firewall_user_reload() { set_firewall_user_reload() {
@ -53,7 +54,7 @@ get_daemon() {
DAEMON=$NFQWS DAEMON=$NFQWS
;; ;;
beeline) beeline)
DAEMON_OPTS="--qnum=$QNUM --hostcase" DAEMON_OPTS="--qnum=$QNUM --hostspell=HOST"
DAEMON=$NFQWS DAEMON=$NFQWS
;; ;;
domru) domru)
@ -68,7 +69,7 @@ get_daemon() {
} }
start() { start_service() {
set_firewall_user_reload set_firewall_user_reload
echo "Creating ipset" echo "Creating ipset"
($IPSET_CR) ($IPSET_CR)
@ -76,14 +77,8 @@ start() {
get_daemon get_daemon
[ -n "$DAEMON" ] && { [ -n "$DAEMON" ] && {
echo "Starting $DAEMON" echo "Starting $DAEMON"
service_start $DAEMON --daemon $DAEMON_OPTS procd_open_instance
procd_set_param command $DAEMON $DAEMON_OPTS
procd_close_instance
} }
} }
stop() {
get_daemon
[ -n "$DAEMON" ] && {
service_stop $DAEMON
}
}

View File

@ -45,10 +45,6 @@ pre-start script
iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff164|" --algo bm -j DROP --from 40 --to 300 iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff164|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -C PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300 || iptables -t raw -C PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300 ||
iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300 iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -C PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff16e|" --algo bm -j DROP --from 40 --to 300 ||
iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff16e|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -C PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000110|" --algo bm -j DROP --from 40 --to 300 ||
iptables -t raw -I PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000110|" --algo bm -j DROP --from 40 --to 300
;; ;;
tiera) tiera)
adduser --disabled-login --no-create-home --system --quiet $TPWS_USER adduser --disabled-login --no-create-home --system --quiet $TPWS_USER
@ -73,7 +69,7 @@ script
;; ;;
beeline) beeline)
NFEXE=$NFQWS NFEXE=$NFQWS
NFARG="--qnum $QNUM --hostcase" NFARG="--qnum $QNUM --hostspell=HOST"
;; ;;
domru) domru)
NFEXE=$TPWS NFEXE=$TPWS
@ -102,8 +98,6 @@ pre-stop script
iptables -t nat -D OUTPUT -p tcp --dport 80 -m owner ! --uid-owner $TPWS_USER -m set --match-set zapret dst -j DNAT --to 127.0.0.1:$TPPORT iptables -t nat -D OUTPUT -p tcp --dport 80 -m owner ! --uid-owner $TPWS_USER -m set --match-set zapret dst -j DNAT --to 127.0.0.1:$TPPORT
iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff164|" --algo bm -j DROP --from 40 --to 300 iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff164|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300 iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000064|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|5cfff16e|" --algo bm -j DROP --from 40 --to 300
iptables -t raw -D PREROUTING -p udp --sport 53 -m string --hex-string "|2a022698a00000000000000000000110|" --algo bm -j DROP --from 40 --to 300
;; ;;
tiera) tiera)
sysctl -w net.ipv4.conf.$SLAVE_ETH.route_localnet=0 sysctl -w net.ipv4.conf.$SLAVE_ETH.route_localnet=0

View File

@ -248,6 +248,7 @@ struct cbdata_s
int wsize; int wsize;
int qnum; int qnum;
bool hostcase; bool hostcase;
char hostspell[4];
}; };
// ret: false - not modified, true - modified // ret: false - not modified, true - modified
@ -291,8 +292,8 @@ bool processPacketData(unsigned char *data,int len,const struct cbdata_s *cbdata
} }
if (cbdata->hostcase && (p = find_bin(data,len,"\r\nHost: ",8))) if (cbdata->hostcase && (p = find_bin(data,len,"\r\nHost: ",8)))
{ {
printf("modifying Host: => host:\n"); printf("modifying Host: => %c%c%c%c:\n",cbdata->hostspell[0],cbdata->hostspell[1],cbdata->hostspell[2],cbdata->hostspell[3]);
p[2]='h'; // "Host:" => "host:" memcpy(p+2,cbdata->hostspell,4);
bRet = true; bRet = true;
} }
if (bRet) if (bRet)
@ -349,7 +350,7 @@ bool droproot(uid_t uid, gid_t gid)
void exithelp() void exithelp()
{ {
printf(" --qnum=<nfqueue_number>\n --wsize=<window_size>\t; set window size. 0 = do not modify\n --hostcase\t\t; change Host: => host:\n --daemon\t\t; daemonize\n"); printf(" --qnum=<nfqueue_number>\n --wsize=<window_size>\t; set window size. 0 = do not modify\n --hostcase\t\t; change Host: => host:\n --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n --daemon\t\t; daemonize\n");
exit(1); exit(1);
} }
@ -368,12 +369,15 @@ int main(int argc, char **argv)
gid_t gid; gid_t gid;
memset(&cbdata,0,sizeof(cbdata)); memset(&cbdata,0,sizeof(cbdata));
memcpy(cbdata.hostspell,"host",4); // default hostspell
const struct option long_options[] = { const struct option long_options[] = {
{"qnum",required_argument,0,0}, // optidx=0 {"qnum",required_argument,0,0}, // optidx=0
{"daemon",no_argument,0,0}, // optidx=1 {"daemon",no_argument,0,0}, // optidx=1
{"wsize",required_argument,0,0}, // optidx=2 {"wsize",required_argument,0,0}, // optidx=2
{"hostcase",no_argument,0,0}, // optidx=3 {"hostcase",no_argument,0,0}, // optidx=3
{"user",required_argument,0,0}, // optidx=4 {"hostspell",required_argument,0,0}, // optidx=4
{"user",required_argument,0,0}, // optidx=5
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
if (argc<2) exithelp(); if (argc<2) exithelp();
@ -397,14 +401,23 @@ int main(int argc, char **argv)
cbdata.wsize=atoi(optarg); cbdata.wsize=atoi(optarg);
if (cbdata.wsize<0 || cbdata.wsize>65535) if (cbdata.wsize<0 || cbdata.wsize>65535)
{ {
fprintf(stdout,"bad qnum\n"); fprintf(stdout,"bad wsize\n");
exit(1); exit(1);
} }
break; break;
case 3: /* hostcase */ case 3: /* hostcase */
cbdata.hostcase = true; cbdata.hostcase = true;
break; break;
case 4: /* user */ case 4: /* hostspell */
if (strlen(optarg)!=4)
{
fprintf(stdout,"hostspell must be exactly 4 chars long\n");
exit(1);
}
cbdata.hostcase = true;
memcpy(cbdata.hostspell,optarg,4);
break;
case 5: /* user */
{ {
struct passwd *pwd = getpwnam(optarg); struct passwd *pwd = getpwnam(optarg);
if (!pwd) if (!pwd)

View File

@ -1,4 +1,4 @@
zapret v.14 zapret v.15
Для чего это надо Для чего это надо
----------------- -----------------
@ -99,7 +99,8 @@ nfqws
--daemon ; демонизировать прогу --daemon ; демонизировать прогу
--qnum=200 ; номер очереди --qnum=200 ; номер очереди
--wsize=4 ; менять tcp window size на указанный размер --wsize=4 ; менять tcp window size на указанный размер
--hostcase ; менять регистр заголовка "Host:" --hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
Параметры манипуляции могут сочетаться в любых комбинациях. Параметры манипуляции могут сочетаться в любых комбинациях.
tpws tpws
@ -112,7 +113,8 @@ tpws - это transparent proxy.
--user=<username> ; менять uid процесса --user=<username> ; менять uid процесса
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb. --split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
--hostcase ; замена "Host:" => "host:" --hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv." --hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--methodspace ; добавить пробел после метода : "GET /" => "GET /" --methodspace ; добавить пробел после метода : "GET /" => "GET /"
Параметры манипуляции могут сочетаться в любых комбинациях. Параметры манипуляции могут сочетаться в любых комбинациях.
@ -122,7 +124,7 @@ tpws - это transparent proxy.
---------- ----------
mns.ru : нужна замена window size на 4 mns.ru : нужна замена window size на 4
beeline (corbina) : нужна замена регистра "Host:" на протяжении всей http сессии beeline (corbina) : нужна замена регистра "Host:" на протяжении всей http сессии. С некоторых пор "host" не работает, но работают другие регистры букв.
dom.ru : нужно проксирование HTTP сессий через tpws с заменой регистра "Host:" и разделение TCP сегментов на хедере "Host:". dom.ru : нужно проксирование HTTP сессий через tpws с заменой регистра "Host:" и разделение TCP сегментов на хедере "Host:".
Ахтунг ! Домру блокирует все поддомены заблоченого домена. IP адреса всевозможных поддоменов узнать невозможно из реестра Ахтунг ! Домру блокирует все поддомены заблоченого домена. IP адреса всевозможных поддоменов узнать невозможно из реестра
блокировок, поэтому если вдруг на каком-то сайте вылезает блокировочный баннер, то идите в консоль firefox, вкладка network. блокировок, поэтому если вдруг на каком-то сайте вылезает блокировочный баннер, то идите в консоль firefox, вкладка network.

View File

@ -34,6 +34,7 @@ struct params_s
uint16_t port; uint16_t port;
bool daemon; bool daemon;
bool hostcase,hostdot,methodspace; bool hostcase,hostdot,methodspace;
char hostspell[4];
enum splithttpreq split_http_req; enum splithttpreq split_http_req;
int split_pos; int split_pos;
int maxconn; int maxconn;
@ -123,7 +124,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
if (p=find_bin(buf,bs,*item,l)) if (p=find_bin(buf,bs,*item,l))
{ {
pos = p-buf; pos = p-buf;
printf("Found http method '%s' at pos %d. Adding extra space.\n",*item,(unsigned int)pos); printf("Found http method '%s' at pos %zd. Adding extra space.\n",*item,pos);
p += l-1; p += l-1;
pos += l-1; pos += l-1;
memmove(p+1,p,bs-pos); memmove(p+1,p,bs-pos);
@ -144,7 +145,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
if (p<(buf+bs)) if (p<(buf+bs))
{ {
pos = p-buf; pos = p-buf;
printf("Adding dot to host name at pos %d\n",(unsigned int)pos); printf("Adding dot to host name at pos %zd\n",pos);
memmove(p+1,p,bs-pos); memmove(p+1,p,bs-pos);
*p = '.'; // insert dot *p = '.'; // insert dot
bs++; // block will grow by 1 byte bs++; // block will grow by 1 byte
@ -193,7 +194,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
if (p=find_bin(buf,bs,*split_item,l)) if (p=find_bin(buf,bs,*split_item,l))
{ {
split_pos = p-buf; split_pos = p-buf;
printf("Found split item '%s' at pos %d\n",*split_item,(unsigned int)split_pos); printf("Found split item '%s' at pos %zd\n",*split_item,split_pos);
split_pos += l-1; split_pos += l-1;
break; break;
} }
@ -203,13 +204,13 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
{ {
if (phost || (phost=find_bin(buf,bs,"\r\nHost: ",8))) if (phost || (phost=find_bin(buf,bs,"\r\nHost: ",8)))
{ {
printf("Changing 'Host:' => 'host:' at pos %d\n",(unsigned int)(phost-buf)); printf("Changing 'Host:' => '%c%c%c%c:' at pos %zd\n",params.hostspell[0],params.hostspell[1],params.hostspell[2],params.hostspell[3],phost-buf+2);
phost[2]='h'; memcpy(phost+2,params.hostspell,4);
} }
} }
if (split_pos) if (split_pos)
{ {
printf("Splitting at pos %d\n",(unsigned int)split_pos); printf("Splitting at pos %zd\n",split_pos);
wr=send_with_flush(fd_out,buf,split_pos,0); wr=send_with_flush(fd_out,buf,split_pos,0);
if (wr>=0) if (wr>=0)
wr=send(fd_out,buf+split_pos,bs-split_pos,0); wr=send(fd_out,buf+split_pos,bs-split_pos,0);
@ -393,7 +394,7 @@ int8_t block_sigpipe(){
void exithelp() void exithelp()
{ {
printf(" --bind-addr=<ipv4_addr>|<ipv6_addr>\n --port=<port>\n --maxconn=<max_connections>\n --split-http-req=method|host\n --split-pos=<numeric_offset>\t; split at specified pos. invalidates split-http-req.\n --hostcase\t\t; change Host: => host:\n --hostdot\t\t; add \".\" after Host: name\n --methodspace\t\t; add extra space after method\n --daemon\t\t; daemonize\n --user=<username>\t; drop root privs\n"); printf(" --bind-addr=<ipv4_addr>|<ipv6_addr>\n --port=<port>\n --maxconn=<max_connections>\n --split-http-req=method|host\n --split-pos=<numeric_offset>\t; split at specified pos. invalidates split-http-req.\n --hostcase\t\t; change Host: => host:\n --hostspell\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n --hostdot\t\t; add \".\" after Host: name\n --methodspace\t\t; add extra space after method\n --daemon\t\t; daemonize\n --user=<username>\t; drop root privs\n");
exit(1); exit(1);
} }
@ -403,6 +404,7 @@ void parse_params(int argc, char *argv[])
int v,i; int v,i;
memset(&params,0,sizeof(params)); memset(&params,0,sizeof(params));
memcpy(params.hostspell,"host",4); // default hostspell
params.maxconn = DEFAULT_MAX_CONN; params.maxconn = DEFAULT_MAX_CONN;
const struct option long_options[] = { const struct option long_options[] = {
@ -414,10 +416,11 @@ void parse_params(int argc, char *argv[])
{"user",required_argument,0,0},// optidx=5 {"user",required_argument,0,0},// optidx=5
{"maxconn",required_argument,0,0},// optidx=6 {"maxconn",required_argument,0,0},// optidx=6
{"hostcase",no_argument,0,0},// optidx=7 {"hostcase",no_argument,0,0},// optidx=7
{"hostdot",no_argument,0,0},// optidx=8 {"hostspell",required_argument,0,0},// optidx=8
{"split-http-req",required_argument,0,0},// optidx=9 {"hostdot",no_argument,0,0},// optidx=9
{"split-pos",required_argument,0,0},// optidx=10 {"split-http-req",required_argument,0,0},// optidx=10
{"methodspace",no_argument,0,0},// optidx=11 {"split-pos",required_argument,0,0},// optidx=11
{"methodspace",no_argument,0,0},// optidx=12
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
while ((v=getopt_long_only(argc,argv,"",long_options,&option_index))!=-1) while ((v=getopt_long_only(argc,argv,"",long_options,&option_index))!=-1)
@ -468,10 +471,19 @@ void parse_params(int argc, char *argv[])
case 7: /* hostcase */ case 7: /* hostcase */
params.hostcase = true; params.hostcase = true;
break; break;
case 8: /* hostdot */ case 8: /* hostspell */
if (strlen(optarg)!=4)
{
fprintf(stdout,"hostspell must be exactly 4 chars long\n");
exit(1);
}
params.hostcase = true;
memcpy(params.hostspell,optarg,4);
break;
case 9: /* hostdot */
params.hostdot = true; params.hostdot = true;
break; break;
case 9: /* split-http-req */ case 10: /* split-http-req */
if (!strcmp(optarg,"method")) if (!strcmp(optarg,"method"))
params.split_http_req = split_method; params.split_http_req = split_method;
else if (!strcmp(optarg,"host")) else if (!strcmp(optarg,"host"))
@ -482,7 +494,7 @@ void parse_params(int argc, char *argv[])
exit(1); exit(1);
} }
break; break;
case 10: /* split-pos */ case 11: /* split-pos */
i = atoi(optarg); i = atoi(optarg);
if (i) if (i)
params.split_pos = i; params.split_pos = i;
@ -492,7 +504,7 @@ void parse_params(int argc, char *argv[])
exit(1); exit(1);
} }
break; break;
case 11: /* methodspace */ case 12: /* methodspace */
params.methodspace = true; params.methodspace = true;
break; break;
} }

View File

@ -1,17 +1,16 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <errno.h>
#include <string.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <linux/netfilter_ipv4.h>
#include "linux/netfilter_ipv4.h"
#include <ifaddrs.h> #include <ifaddrs.h>
#include "tpws_conn.h" #include "tpws_conn.h"