koolproxy插件/固件开发文档1.3
更新日期：2017年7月7日（koolproxy 3.6.1）

================================================================================================
声明：
KoolProxy 是一个免费软件，著作权归属 KoolProxy.com，用户可以非商业性地复制和使用 KoolProxy，但禁止将 KoolProxy 用于商业用途。
KoolProxy 可以对 https 网络数据进行识别代理，使用 https 功能的用户需要自己提供相关证书，本程序提供的证书生成脚本仅供用户参考，证书的保密工作由用户自行负责。
使用本软件的风险由用户自行承担，在适用法律允许的最大范围内，对因使用本产品所产生的损害及风险，包括但不限于直接或间接的个人损害、商业赢利的丧失、贸易中断、商业信息的丢失或任何其它经济损失，KoolProxy.com 不承担任何责任。

================================================================================================
KoolProxy By Xiaobao & Crwnet v3.6.1

USAGE:
  koolproxy [options] [arguments...]

OPTIONS:
  -p value        listen port, default value is 3000
  -l value        log level (0:DEBUG, 1:INFO, 2:AD, 3:WARNING, 4:ERROR), default value is ERROR
  -c value        thread count, default value is the number of cpus
  -b value        data path, default value is './data'
  -d              run as daemon mode
  -v              show version
  -h              show help

ADVANCED:
  --cert          generate ssl cert
  --ipv6          enable ipv6, works for ipv6 nat mode
  --video | -e    video mode, load video rules only
  --mark          mark mode, set the socket mark(src ip) when connect to remote host. requires the CAP_NET_ADMIN capability
  --ttl value     ttl mode, set the socket ttl when connect to remote host. default value is 0 (disable)
  
================================================================================================
交流地址：
1 QQ群1： 595300867
2 QQ群2： 203726739
3 TG群： https://t.me/joinchat/AAAAAD-tO7GPvfOU131_vg
4 更新日志：http://koolshare.cn/thread-64086-1-1.html

================================================================================================
#koolproxy部署文件目录参考1（使用openssl生成证书）
.
├── data
│   ├── gen_ca.sh				#证书生成脚本
│   ├── koolproxy_ipset.conf		#ipset名单
│   ├── openssl.cnf				#证书生成所用配置文件
│   ├── rules					#规则存放文件夹
│   │   ├── kp.dat				#视频规则
│   │   ├── koolproxy.txt		#静态规则
│   │   ├── daily.txt			#每日规则
│   │   └── user.txt			#自定义规则
│   └── version					#插件版本号(merlin)
└── koolproxy					#koolproxy二进制(为了保证二进制顺利更新，请保证目录可写)

1 证书生成使用命令 sh gen_ca.sh，该脚本会调用系统内的openssl来生成证书，运行成功后会自动创建data/private data/cert目录
  私钥和公钥会分别存在data/private data/cert目录下，使用http://110.110.110.110会下载路由器内的证书
  
------------------------------------------------------------------------------------------------
#koolproxy部署文件目录参考2（使用koolproxy生成证书）
.
└── koolproxy					#koolproxy二进制(为了保证二进制顺利更新，请保证目录可写)
1 因为规则文件会由koolproxy自动下载,下载后会自动创建data/rules目录
2 使用koolproxy --cert命令可以生成证书，运行成功后会自动创建data/private data/cert目录
  私钥和公钥会分别存在data/private data/cert目录下，使用http://110.110.110.110会下载路由器内的证书
  因为mbedtls性能原因，在非软路由机器上用koolproxy --cert生成证书需要时间较长，请耐心等待

================================================================================================
说明：
1 koolproxy启动会自动检测规则更新，如果没有./data/rules文件夹，会自己创建并下载规则到此处
2 koolproxy启动后会检测二进制文件更新，如果有更新，会替换./koolproxy，并且由父进程重启koolproxy，以后每20分钟检测一次更新
3 现在不支持规则订阅了，只能识别kp.dat, koolproxy.txt, user.txt,daily.txt，需要自定义规则的可以修改user.txt

# 二进制下载固定地址
https://koolproxy.com/downloads/i386
https://koolproxy.com/downloads/x86_64
https://koolproxy.com/downloads/arm
https://koolproxy.com/downloads/mips
https://koolproxy.com/downloads/mipsel

# 规则下载固定地址
https://kprule.com/koolproxy.txt
https://kprule.com/daily.txt
https://kprule.com/kp.dat
https://kprule.com/user.txt

# 规则下载对应的CDN地址
https://kprules.b0.upaiyun.com/koolproxy.txt
https://kprules.b0.upaiyun.com/daily.txt
https://kprules.b0.upaiyun.com/kp.dat
https://kprules.b0.upaiyun.com/user.txt

# 二进制文件和规则 github备份地址：
二进制：https://github.com/koolproxy/koolproxy-bin (已作废)
规则：https://github.com/koolproxy/koolproxy_rules (已作废)


1 建议从上面的链接获取最新的二进制和基本的规则文件，然后按照上面的目录结构来部署
2 如果不需要https过滤，只需要一个koolproxy程序就足够了，data文件夹和rules文件夹都会自己创建。 
3 koolproxy.txt内有视频规则、静态规则、每日规则的更新日期，可以用于提取并显示到界面

================================================================================================
koolproxy运行：

1 在koolproxy主程序目录运行，例如merlin固件下运行：cd /koolshare/koolproxy && koolproxy -d
2 不在koolproxy主程序目录运行（例如将koolproxy放在环境变量中），例如merlin固件下运行：koolproxy -b /koolshare/koolproxy -d -b为data路径
  其它运行方式可能会造成koolproxy识别不到data目录而无法加载规则
  koolproxy运行后默认会使用端口3000作为透明代理端口，需要利用iptables将数据导到端口3000才能发挥作用。
  
视频模式：
1 使用命令koolproxy -e 即可开启
2 开启后只会加载视频规则kp.dat和user.txt

调试模式：
1 使用命令koolproxy -l0 即可开启，l后面的数字代表不同的日志详细程度
2 需要检查规则命中行数可以需要使用-l2

ttl功能：
1 使用命令koolproxy --ttl 160 即可开启ttl功能，后面的数值代表ttl大小
2 ttl功能开启后，koolproxy会对经过它的所有数据ttl进行调整，可以利用iptables的match ttl功能数据进行匹配

mark功能：
1 使用命令koolproxy --mark 即可开启mark功能
2 mark功能开启后，koolproxy会对经过它的所有数据打上标记，mark值等于该数据的源ip转换为十六进制的值
3 例如局域网内192.168.1.100的数据，将会被打上0xc0a80164的mark（192 = c0, 168 = a8, 1 = 01, 100 = 64 ）
4 开发者可以用此功和SS配合，达到既科学上网，又能过滤这些科学上网的流量，还不影响科学上网访问控制的功能
5 ip转换为mark值参考命令：echo 192.168.1.100 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("%02x\n", $4)}'

================================================================================================
ss + kp过滤方案（2017年7月7日）：

方案1（优先SS，其次KP，不推荐）：
1 在NAT PREROUTING链内，SS在前，KP在后，流量将先走SS，经过SS分流后，国外流量走ss-redir，实现翻墙；
2 而剩下国内流量在PREROUTING链内继续往下匹配到koolrpxy规则，流量最终走koolproxy，实现过滤。
  结果：koolproxy只能过滤国内流量（SS剩下的）。

方案2（优先KP，其次SS，不推荐）;
1 在NAT PREROUTING链内，KP在前，SS在后，流量将先走KP，实现过滤；
2 为了SS能拿到KP过滤后的数据，使用match ttl匹配，在OUTPUT链内将流量全部给SS，实现翻墙；
  结果：因为在OUTPUT链内没有源ip信息，流量给SS后无法匹配到源ip，因此SS失去了acl（访问控制）功能。

方案3 (优先kp，其次SS，推荐)；
  为便于理解，以下iptables配置只展示流量经过顺序，不是iptables的创建顺序，PREROUTING内规则的创建实际上应该在最后
0 koolproxy默认开启ttl和mark功能 KoolProxy --ttl 160 --mark -d（固件不支持ttl的仅开启mark也行: KoolProxy --mark -d）
1 在NAT PREROUTING链内，KP在前，SS在后，KP开启--mark，流量将先走KP（80,443），实现过滤，过滤后每个主机会被打上不同的mark；
  #KP在前，所有tcp流量全部交给KOOLPROXY链
  -A PREROUTING -p tcp -j KOOLPROXY
  #SS在后，在kp开启的时候，只能拿到非80,443的流量，在kp关闭后，可以拿到所有端口的流量
  -A PREROUTING -p tcp -j SHADOWSOCKS
  
2 例如局域网内192.168.1.100主机的数据经过kp过滤后，将会被打上0xc0a80164的mark（192 = c0, 168 = a8, 1 = 01, 100 = 64 ）；
  #创建KOOLPROXY链，用于白名单和访问控制
  -N KOOLPROXY
  #创建KOOLPROXY_HTTP链，用于过滤http流量
  -N KOOLPROXY_HTTP
  #创建KOOLPROXY_HTTPS链，用于过滤https流量
  -N KOOLPROXY_HTTPS
  #局域网和保留地址不走kp
  -A KOOLPROXY -m set --match-set white_kp_list dst -j RETURN
  #主机192.168.1.100需要https过滤
  -A KOOLPROXY -s 192.168.1.100/32 -p tcp -g KOOLPROXY_HTTPS
  #其它主机过滤http流量
  -A KOOLPROXY -p tcp -j KOOLPROXY_HTTP
  
3 为了SS能拿到数据，在NAT OUTPUT链中，使用match ttl匹配，在OUTPUT链内将流量全部给SHADOWSOCKS_EXT链；
  #创建SHADOWSOCKS_EXT链，用于开启kp情况下ss的访问控制实现
  -N SHADOWSOCKS_EXT
  #使用ttl匹配将KP过滤后的数据转到SHADOWSOCKS_EXT链（如果固件不支持ttl匹配，使用下面的命令）
  -A OUTPUT -p tcp -m ttl --ttl-eq 160 -j SHADOWSOCKS_EXT
  #如果固件不支持ttl match，可以用mark匹配ip地址的前三位（用0xffffff00作为掩码的形式），来将KP过滤后的数据转到SHADOWSOCKS_EXT链
  # echo 192.168.1 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("00/0xffffff00\n")}' = 0xc0a80100/0xffffff00
  -A OUTPUT -p tcp -m mark --mark 0xc0a80100/0xffffff00 -j SHADOWSOCKS_EXT
  
4 如果开启了acl，比如需要192.168.1.75不走SS（全端口），192.168.1.246走gfwlist模式（80,443端口），192.168.1.214走大陆白名单模式（22,80,443端口），剩余主机全部走大陆白名单模式（全端口）：
  #主机192.168.1.75（0xc0a8014b），流量经过KP过滤后并打上mark后，通过OUTPUT链进入SHADOWSOCKS_EXT链，而未能翻墙（RETURN）
  -A SHADOWSOCKS_EXT -p tcp -m mark --mark 0xc0a8014b -j RETURN		
  #主机192.168.1.246（0xc0a801f6），流量经过KP过滤后并打上mark后，通过OUTPUT链进入SHADOWSOCKS_EXT链，在此流量被导向了SHADOWSOCKS_GFW链，实现gfwlist模式翻墙（80,443端口）							
  -A SHADOWSOCKS_EXT -p tcp -m multiport --dports 80,443 -m mark --mark 0xc0a801f6 -g SHADOWSOCKS_GFW
  #主机192.168.1.214（0xc0a801f6），流量经过KP过滤后并打上mark后，通过OUTPUT链进入SHADOWSOCKS_EXT链，在此流量被导向了SHADOWSOCKS_CHN链，实现大陆白名单模式翻墙（22,80,443端口）
  -A SHADOWSOCKS_EXT -p tcp -m multiport --dports 22,,80,443 -m mark --mark 0xc0a801d6 -g SHADOWSOCKS_CHN
  #剩余的主机，流量经过KP过滤后并打上mark后，通过OUTPUT链进入SHADOWSOCKS_EXT链，在此流量被导向了SHADOWSOCKS_CHN链，实现大陆白名单模式翻墙（全端口）
  -A SHADOWSOCKS_EXT -p tcp -j SHADOWSOCKS_CHN
  
情形：
1 当SS开启，kp未开启：所有流量走ss PREROUTING过，经过分流后，国内的流量在经过OUTPUT的时候，因为KP没开，数据不会匹配到ttl值（或者没匹配到mark值），所以不会过滤广告，翻墙正常
2 当KP开启，SS未开启，所有流量走kp PREROUTING过，广告过滤正常
3 当SS开启，翻墙和acl工作正常的时候，开启KP：KP在PREROUTING内插入到SS前面，会先得到流量，广告过滤正常
4 当KP开启，过滤广告正常的时候，开启SS：SS从原来的从PREROUTING拿流量变成从OUTPUT内拿流量，翻墙和acl会同样正常
5 当KP和SS都开启，此时关闭SS，kp过滤广告正常
6 当KP和SS都开启，此时关闭KP，ss翻墙和acl正常

总结：
使用 ttl + mark （或者纯mark）的方式，可以实现原先很难实现的过滤经过SS流量的广告
主要的改动在于给SS预置好OUTPUT和SHADOWSOCKS_EXT规则链，当kp启用时，它们就会工作，kp关闭时，不会影响正常数据
次要的改动就是给koolproxy默认开启ttl + mark（或者纯mark）功能
================================================================================================
