Browse Source

hostspell, openwrt procd, beeline ISP fix

pull/5/head
bolvan 8 years ago
parent
commit
3bb71b42a0
  1. BIN
      binaries/armhf/nfqws
  2. BIN
      binaries/armhf/tpws
  3. BIN
      binaries/mips32r1-lsb/nfqws
  4. BIN
      binaries/mips32r1-lsb/tpws
  5. BIN
      binaries/mips32r1-msb/nfqws
  6. BIN
      binaries/mips32r1-msb/tpws
  7. BIN
      binaries/x86_64/nfqws
  8. BIN
      binaries/x86_64/tpws
  9. 7
      changes.txt
  10. 27
      init.d/openwrt/zapret
  11. 8
      init.d/ubuntu12/zapret.conf
  12. 25
      nfq/nfqws.c
  13. 10
      readme.txt
  14. 42
      tpws/tpws.c
  15. 9
      tpws/tpws_conn.c

BIN
binaries/armhf/nfqws

Binary file not shown.

BIN
binaries/armhf/tpws

Binary file not shown.

BIN
binaries/mips32r1-lsb/nfqws

Binary file not shown.

BIN
binaries/mips32r1-lsb/tpws

Binary file not shown.

BIN
binaries/mips32r1-msb/nfqws

Binary file not shown.

BIN
binaries/mips32r1-msb/tpws

Binary file not shown.

BIN
binaries/x86_64/nfqws

Binary file not shown.

BIN
binaries/x86_64/tpws

Binary file not shown.

7
changes.txt

@ -70,3 +70,10 @@ v14
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
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

27
init.d/openwrt/zapret

@ -4,11 +4,15 @@
# CHOOSE ISP HERE. UNCOMMENT ONLY ONE LINE.
#ISP=mns
#ISP=rt
#ISP=beeline
ISP=beeline
#ISP=domru
ISP=tiera
#ISP=tiera
#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
QNUM=200
@ -19,9 +23,6 @@ TPWS=/opt/zapret/tpws/tpws
IPSET_CR=/opt/zapret/ipset/create_ipset.sh
TPWS_USER=daemon
# start betfore firewall - we need ipset populated
START=18
# must execute /etc/firewall.user on every firewall reload
set_firewall_user_reload() {
@ -53,7 +54,7 @@ get_daemon() {
DAEMON=$NFQWS
;;
beeline)
DAEMON_OPTS="--qnum=$QNUM --hostcase"
DAEMON_OPTS="--qnum=$QNUM --hostspell=HOST"
DAEMON=$NFQWS
;;
domru)
@ -68,7 +69,7 @@ get_daemon() {
}
start() {
start_service() {
set_firewall_user_reload
echo "Creating ipset"
($IPSET_CR)
@ -76,14 +77,8 @@ start() {
get_daemon
[ -n "$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
}
}

8
init.d/ubuntu12/zapret.conf

@ -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 -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 -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)
adduser --disabled-login --no-create-home --system --quiet $TPWS_USER
@ -73,7 +69,7 @@ script
;;
beeline)
NFEXE=$NFQWS
NFARG="--qnum $QNUM --hostcase"
NFARG="--qnum $QNUM --hostspell=HOST"
;;
domru)
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 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 "|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)
sysctl -w net.ipv4.conf.$SLAVE_ETH.route_localnet=0

25
nfq/nfqws.c

@ -248,6 +248,7 @@ struct cbdata_s
int wsize;
int qnum;
bool hostcase;
char hostspell[4];
};
// 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)))
{
printf("modifying Host: => host:\n");
p[2]='h'; // "Host:" => "host:"
printf("modifying Host: => %c%c%c%c:\n",cbdata->hostspell[0],cbdata->hostspell[1],cbdata->hostspell[2],cbdata->hostspell[3]);
memcpy(p+2,cbdata->hostspell,4);
bRet = true;
}
if (bRet)
@ -349,7 +350,7 @@ bool droproot(uid_t uid, gid_t gid)
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);
}
@ -368,12 +369,15 @@ int main(int argc, char **argv)
gid_t gid;
memset(&cbdata,0,sizeof(cbdata));
memcpy(cbdata.hostspell,"host",4); // default hostspell
const struct option long_options[] = {
{"qnum",required_argument,0,0}, // optidx=0
{"daemon",no_argument,0,0}, // optidx=1
{"wsize",required_argument,0,0}, // optidx=2
{"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}
};
if (argc<2) exithelp();
@ -397,14 +401,23 @@ int main(int argc, char **argv)
cbdata.wsize=atoi(optarg);
if (cbdata.wsize<0 || cbdata.wsize>65535)
{
fprintf(stdout,"bad qnum\n");
fprintf(stdout,"bad wsize\n");
exit(1);
}
break;
case 3: /* hostcase */
cbdata.hostcase = true;
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);
if (!pwd)

10
readme.txt

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

42
tpws/tpws.c

@ -34,6 +34,7 @@ struct params_s
uint16_t port;
bool daemon;
bool hostcase,hostdot,methodspace;
char hostspell[4];
enum splithttpreq split_http_req;
int split_pos;
int maxconn;
@ -123,7 +124,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
if (p=find_bin(buf,bs,*item,l))
{
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;
pos += l-1;
memmove(p+1,p,bs-pos);
@ -144,7 +145,7 @@ bool handle_epollin(tproxy_conn_t *conn,int *data_transferred){
if (p<(buf+bs))
{
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);
*p = '.'; // insert dot
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))
{
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;
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)))
{
printf("Changing 'Host:' => 'host:' at pos %d\n",(unsigned int)(phost-buf));
phost[2]='h';
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);
memcpy(phost+2,params.hostspell,4);
}
}
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);
if (wr>=0)
wr=send(fd_out,buf+split_pos,bs-split_pos,0);
@ -393,7 +394,7 @@ int8_t block_sigpipe(){
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);
}
@ -403,6 +404,7 @@ void parse_params(int argc, char *argv[])
int v,i;
memset(&params,0,sizeof(params));
memcpy(params.hostspell,"host",4); // default hostspell
params.maxconn = DEFAULT_MAX_CONN;
const struct option long_options[] = {
@ -414,10 +416,11 @@ void parse_params(int argc, char *argv[])
{"user",required_argument,0,0},// optidx=5
{"maxconn",required_argument,0,0},// optidx=6
{"hostcase",no_argument,0,0},// optidx=7
{"hostdot",no_argument,0,0},// optidx=8
{"split-http-req",required_argument,0,0},// optidx=9
{"split-pos",required_argument,0,0},// optidx=10
{"methodspace",no_argument,0,0},// optidx=11
{"hostspell",required_argument,0,0},// optidx=8
{"hostdot",no_argument,0,0},// optidx=9
{"split-http-req",required_argument,0,0},// optidx=10
{"split-pos",required_argument,0,0},// optidx=11
{"methodspace",no_argument,0,0},// optidx=12
{NULL,0,NULL,0}
};
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 */
params.hostcase = true;
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;
break;
case 9: /* split-http-req */
case 10: /* split-http-req */
if (!strcmp(optarg,"method"))
params.split_http_req = split_method;
else if (!strcmp(optarg,"host"))
@ -482,7 +494,7 @@ void parse_params(int argc, char *argv[])
exit(1);
}
break;
case 10: /* split-pos */
case 11: /* split-pos */
i = atoi(optarg);
if (i)
params.split_pos = i;
@ -492,7 +504,7 @@ void parse_params(int argc, char *argv[])
exit(1);
}
break;
case 11: /* methodspace */
case 12: /* methodspace */
params.methodspace = true;
break;
}

9
tpws/tpws_conn.c

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

Loading…
Cancel
Save