Total Pageviews

Tuesday 19 April 2016

GFW.Press-一款基于java的翻墙程序

1、服务器
以 CentOS 为例:
第一步:下载gfw.press
git clone https://github.com/chinashiyu/gfw.press
第二步:安装JDK:
yum install java-1.8.0-openjdk.x86_64 -y 
(如果是debian系统,则apt-get install openjdk-7-jdk -y) 


 第三步:安装代理服务器软件:
yum install tinyproxy -y
(如果是debian系统,则apt-get install tinyproxy -y)
然后,
killall tinyproxy
nano /etc/tinyproxy/tinyproxy.conf ,这是centos系统的情形。如果是debian系统,则nano /etc/tinyproxy.conf
修改默认的8888端口为另外某个端口,比如38081.不要把Allow 127.0.0.1这行注释掉。(意思是仅允许vps上的程序连接这个tinyproxy
然后,运行: 
tinyproxy


 第四步:修改帐号文件user.txt,
每行表示一个帐号,由端口号+空格+密码组成,密码长度至少8位,必需包含大小写字母和数字。
( 其实不必修改帐号文件user.txt)

 第五步:运行程序。
cd gfw.press
chmod 755 server.sh
./server.sh
cat server.sh可看到实际上是运行一条带参数的java命令
 会显示:
[2017-07-09 14:50:44] 服务器已经在运行中
[2017-07-09 14:50:44] 如果确定没有运行,请删除 /root/gfw.press/server.lock文件,重新启动。
为了让/root/gfw.press/server.sh命令能随vps的启动而自动运行,我们可以新建一个启动脚本/etc/init.d/gfw.press,内容为:
#!/bin/bash
### BEGIN INIT INFO
# Provides: gfw.press
# Required-Start: $remote_fs $local_fs
# Required-Stop: $remote_fs $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: use it to cross gfw
# Description: try it
### END INIT INFO
/root/gfw.press/server.sh
exit 0
然后chomd 755 /etc/init.d/gfw.press
然后reboot , 
/etc/init.d/gfw.press命令就会随vps的启动而自动运行。
 
root@AR:~/gfw.press# grep -ri 3128 . (在当前目录下,搜索字符串3128,会显示:)
./client.json{"ServerHost":"your_vps_ip","ServerPort":"","ProxyPort":"3128","Password":""}
 client.json是客户端的文件,在服务器上,无需管它)
./server.json: "ProxyPort":"3128",
./src/press/gfw/Server.java: private int proxyPort = 3128; 
root@AR:~/gfw.press# 



我们需要修改./server.json和./src/press/gfw/Server.java这2个文件里的3128端口为其他端口,比如38081,而38081为服务器上的某个代理服务器程序(比如tinyproxy,mocks/ssocks)所监听的端口号。



后端的代理服务器程序,我建议用这个http代理服务器程序:
https://briteming.blogspot.com/2018/04/gohttpkiss-proxy.html

root@AR:~/gfw.press# ps aux|grep java
(找到server.sh文件里所显示的那条java命令所对应的pid值,kill 该pid值 ,然后运行
./server.sh ,这样服务器端就搭建好了)

 
2. 客户端
请访问 http://gfw.press/GFW.Press.msi 下载客户端安装包. 如果你的客户端机器是mac或者linux桌面系统,则
git clone https://github.com/chinashiyu/gfw.press
cd gfw.press
chmod 755 client.sh 
./client.sh 
注意:运行./client.sh之后,不要关闭该终端
这样, gfw.press的客户端程序就不会退出了
如果你遇到出错提示:java.security.InvalidKeyException: Illegal key size ,解决办法:
去掉这种限制需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.网址如下。
下载包的readme.txt 有安装说明。就是替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar
Most likely you don't have the unlimited strength file installed now.
You may need to download this file:
Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6


Install the file in ${java.home}/jre/lib/security/.
参考自:
http://blog.csdn.net/shangpusp/article/details/7416603
http://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters
然后再次运行bash client.sh ,就不会遇到错误了。
运行bash client.sh后,mac的顶部会出现一个绿色的方形图标,按住control键,然后点击
该绿色方形图标然后松开control键,点击屏幕右下角的java图标,就会弹出一个窗口,在该窗口里:
“节点地址”,填写你的vps的ip,
“节点端口”,可填写10001
“连接密码”,填写本地的gfw.press目录中的user.txt文件中的10001端口(指服务器上的端口)所对应的密码。
(服务器上的user.txt文件和本地机器上的user.txt文件最好都不要修改)
“本地端口”,可以随便填写,比如31281,只要是本地未被占用的端口就行。然后点击“确定”。 
设置浏览器的http代理地址为127.0.0.1 端口:31281,浏览器即可翻墙。
注:如果服务器的后端代理服务器程序是http代理,则本地机器的浏览器的代理相应地设为http代理地址:127.0.0.1 端口:31281;
如果服务器的后端代理服务器程序是socks代理,则本地机器的浏览器的代理相应地设为socks代理地址:127.0.0.1 端口:31281;
项目地址:https://github.com/chinashiyu/gfw.press

https://gfw.press/blog/?p=21
------------------------------------------------
 
GFW.Press的安卓手機客户端



暫時大殺器只有2個安卓客戶端支援,一個是官方客戶端,另一個是@postern_overwal
推油開發的多協議第三方客戶端,支持大殺器,暫時是實驗性功能。
官方客戶端只支援能設置HTTP代理的apps,而Postern是VPN模式,可以使用類似iOS下
A.Big.T/Surge/Shadowrocket的規則,或者全局代理,就像影梳的使用方式。
先說石斑魚大爺官方客戶端,下載後安裝,填入所需資料,如圖
然後前往安卓開源市場,下載客戶端,裡面有些可以設置代理的Apps,其中有Twidere
,這個和Twitter官方客戶端一樣,可以設置代理,在手機安裝好後,開啟大殺器客戶端
如圖
然後打開Twidere,撥開選單,點設定
按地球的圖示,點選高級
開啟『為所有網絡請求使用代理』
選取HTTP代理,選取『代理伺服器主機名』,填入127.0.0.1

選取『代理伺服器埠』,填入3128
正常便可通過官方客戶端連接推特
推特官方客戶端沒有測試,應大致相同,請自行摸索。
只有推特APP遠不足夠,但由於安卓支持設置HTTP代理的apps不多,這樣
有些網站須用瀏覽器訪問網站手機網頁版,在安卓開源市場已知有兩款可
以設置代理的瀏覽器

IceCatMobile + Proxy Mobile插件

安裝好icecatmobile,利用它打開Proxy Mobile插件網址安裝,點擊右上角的按鈕,
點選『工具』
然後選取『附加元件』
選取Proxy Mobile
填入正確的資料
這時可以訪問這個網站,看看IP是否改變了?
不過這個組合有時失靈,瀏覽器會不經代理接上網站,於是找了另一個代替

Lightning Browser

這個也是在安卓開源市場下載,它自帶代理設置,無須使用插件,按右上角
按鈕,找到"setting"
點選"General Setting"
點選『HTTP Proxy』
選擇『Manual』
填入資料
按OK,訪問網站測試一下是否使用代理
以上這些都可以使用大殺器客戶端上網,可能有更多apps能設置代理,就等網友
慢慢找尋了。
不過官方客戶端還是限制多,幸好推油@postern_overwal,他也是商業梯子供應商
開發了PosternAndroid下的系统全局代理Proxifier,這個是用VPN模式,不須要在
客戶端設置代理使用,可以使用規則匹配網址,或者全局代理。
安裝好客戶端後,打開Postern,點選配置代理
選取『大殺器GFW.Press(實驗性支持)』
填入服務器的資訊,保存後點選『配置規則』,這裡選單有四個選項
只測試了直連和通過代理連接的方式,現在使用規則,打開『通過代理連接』
裡面已有一些網址,可自行添加,減少便直接編輯
代理選回已設置好的大殺器,如上圖,編輯不要用中文輸入法去刪除或增加,用
系統自帶的英文輸入法,設置後保存,如用規則型式應是這樣
如果是使用全局的,設置好後是這樣,默認規則和通過代理都是『通過代理』
我因為測試,只在規則加了這個網站測試
然後全局測試,使用HKGolden這個不能設置代理的app連接網站
在VPS上監察是否通過服務器連接
正常連接,由於Postern只支援Connect方式,而Get未有支援,後端服務器必須配置
為可用CONNECT 方式才成,這看安裝的後端代理是那個。
另外建議設置DNS代理,不然會使用ISP的DNS,如圖
然後訪問一下這個網站,測試有沒有使用ISP的DNS服務器
這些測試非常簡陋,錯誤在所難免,另外因為無牆,不能測試它的智能DNS,據作
者說撞牆的網址會加入到代理規則,這得由網友測試了
最後感謝這些推友為抵抗資訊審查,做出各種工具做福人群,無私地分享,暫時iOS
上還未有可用的客戶端,不過相信很快出現了。
由於大殺器開始有點人氣,github上出現其他版本的GFW.Press,有興趣的網友自行
研究。
-----------
成功的用它来翻墙了,不过速度较慢。看不了youtube视频。
-------------

GFW.press源码简析

GFW.Press号称新一代军用级高强度加密抗干扰网络数据高速传输软件。作者@chinashiyu在twitter上很高调,该项目的代码简洁易懂,就像作者说的,人人开发翻墙工具的时代。
本篇剖析一下源码,示例代码为了可读性做了精简处理。

原理

  • 客户端监听本地端口,作为浏览器的HTTP代理的目标端口。对每一个连接请求,创建连接至服务器监听端口,建立起双向的数据转发。
  • 服务端监听端口,对每一个TCP连接请求,创建连接至HTTP代理服务器(通常安装在同一VPS上)监听端口,建立起双向的数据转发。
  • 其中客户端到服务端的TCP连接,数据是进行加密和随机字节填充了的。
  • 对于一个正常的HTTP代理,从浏览器到HTTP代理就一个TCP连接,然后在之上发送HTTP代理的数据包。对于GFW.press,从浏览器到GFW.press客户端一个TCP连接,从GFW.press客户端到GFW.press服务器一个数据加密的TCP连接,一个从GFW.press服务端到HTTP代理服务器的TCP连接。也就是说由原来1条TCP连接变成了3条TCP连接作为浏览器到HTTP代理的隧道。

Server

配置文件

目录下的user.txt即是配置文件,很简洁,就用户端口和密码,类似于shadowsocks的配置。
10006 ChangeMe1
10007 ChangeMe2
10008 ChangeMe3
还有server.json,配置HTTP代理
{  
    "ProxyHost": 127.0.0.1,
    "ProxyPort": 3128,
 }

端口监听

对每个用户端口,都开启一个新的服务线程(Server类实现)进行对该端口的端口监听,监听并处理用户连接
    # Server.java:Server.service():

    Enumeration<String> userPorts = users.keys();
    while (userPorts.hasMoreElements()) { // 新用户
            String userPort = userPorts.nextElement();
            Server thread = new Server(proxyHost, proxyPort, userPort, users.get(userPort));
            thread.start();
每个服务线程监听一个端口,为一个用户服务。线程对监听端口的每个连接,创建一个转发线程(ServerThread类实现),将一条连接的数据转发到代理上
    # Server.java:Server.run()
    # the listenPort is the userPort in user.txt config

    serverSocket = new ServerSocket(listenPort);
    while(True){
            clientSocket = serverSocket.accept();
            ServerThread serverThread = new ServerThread(clientSocket, proxyHost, proxyPort, key);
            serverThread.start();
    }
每个转发线程(ServerThread)完成一条从GFW.press客户端到GFW.press服务端、GFW.press服务到HTTP代理的TCP连接。转发线程创建一条连接至代理服务器,然后对客户端的连接进行读取数据、解密、转发解密后的明文数据到代理,然后对代理返回的数据,加密后返回给客户端。
    # ServerThread.java:ServerThread.run()

    // 连接代理服务器
    proxySocket = new Socket(proxyHost, proxyPort);

    // 获取输入输出流
    clientIn = clientSocket.getInputStream();
    clientOut = clientSocket.getOutputStream();

    proxyIn = proxySocket.getInputStream();
    proxyOut = proxySocket.getOutputStream();

    DecryptForwardThread forwardProxy = new DecryptForwardThread(clientIn, proxyOut, key);
    forwardProxy.start();

    EncryptForwardThread forwardClient = new EncryptForwardThread(proxyIn, clientOut, key);
    forwardClient.start();
如上,转发线程又开了两个线程,以分别处理上行转发流和下行转发流

Client

Windows.java实现了一个UI界面。最终会创建一个本地服务线程,并监听本地端口作为浏览器的HTTP代理目标端口。最终调用的代码如下
client = new Client(serverHost, serverPort, password, proxyPort);
client.start();
Client线程,创建本地监听端口,接受每一个TCP连接,并创建到服务器的转发线程(ClientThread)。
    # Client.java:Client.run()
    listenSocket = new ServerSocket(proxyPort);
    while(true){
        agentSocket = listenSocket.accept();
        ClientThread clientThread = new ClientThread(agentSocket, serverHost, serverPort, key);
        clientThread.start();
    }
客户端的转发线程(ClientThread)跟服务端的转发线程(ServerThread)都差不多,唯一不一样的就是上行流是先加密后转发,下行流是先解密后转发。而服务端的转发线程恰好相反,上行流是先解密后转发,下行流是先加密后转发。客户端的转发线程的转发目标是服务端的监听端口,而服务端的转发线程是HTTP代理服务器。
    # ClientThread.java:ClientThread.run()
    serverSocket = new Socket(serverHost, serverPort);
    // 获取输入输出流
    agentIn = agentSocket.getInputStream();
    agentOut = agentSocket.getOutputStream();
    serverIn = serverSocket.getInputStream();
    serverOut = serverSocket.getOutputStream();

    EncryptForwardThread forwardServer = new EncryptForwardThread(this, agentIn, serverOut, key);
    forwardServer.start();

    DecryptForwardThread forwardAgent = new DecryptForwardThread(this, serverIn, agentOut, key);
    forwardAgent.start();

转发数据流的加密

代码在Encrypt.java:encrypNet(),对每一块data,使用随机IV(16位)和key(password通过算法生成的16位key)加密,生成随机长度的噪音数据。加密后的数据长度/噪音数据长度值填在前面的30字节
+-----+----+--------+--------------+-------------+
|IV1  |size|  IV2   |   data       | noise bytes | 
+-----+----+--------+--------------+-------------+
| 16  | 14 |   16   |      1+      |     0+      | 
+-----+----+--------+--------------+-------------+
size是用IV1和key加密的,data是用IV2和key加密的。噪音随机字节是当data小于2K时会填充0–4K的字节,否则噪音数据是0字节。
public static final int NOISE_MAX = 1024 * 4; // 噪音数据最大长度,4K

byte[] noise_bytes = (cipher_bytes.length < NOISE_MAX / 2) ? getSecureRandom(secureRandom.nextInt(NOISE_MAX)) : new byte[0];
size那14个字节的存储格式如下,是把长度值写成字符串,而不是用整数值直接存储的。
String.format("%08d,%05d", data_size, noise_size).getBytes(CHARSET);
from https://medium.com/@FWTO_O/gfw-press%E6%BA%90%E7%A0%81%E7%AE%80%E6%9E%90-61a2714eb99f#.1txkv7mzp
------------

https://victor-notes.blogspot.com/2016/06/gfwpress.html
---------

翻墙软件大杀器技术分析

之前我提醒过大杀器可能存在的问题,现在我就进行一下技术分析。小白不用怕,我的技术分析只是简单分析,我个人也做不到卡巴斯基那种行为分析水平,同时我也不会叙述过多细节,请耐心点。

大部分翻墙软件都是不需安装的绿色软件,例如自由门,无界,shadowsocks,ssr,赛风三,goagent及其衍生软件,萤火虫代理。但所有的VPN,lantern,和tor browser是例外的,还有就是这个大杀器了。

从安全性来看,绿色软件做小动作的可能性比安装版软件要小很多,但也不是所有软件都能做绿色版:例如VPN,其原理为在操作系统中安装虚拟网卡,所以必须在管理员权限下安装才能正常工作;如果想要自动生成快捷方式,那么这也是一个安装的理由。

但是,评估翻墙软件的安全性,关键在于服务器端,所以诸位没必要过于看重客户端,因为服务器提供者才是真正掌握你所有上网信息的人,他根本就没必要在客户端设置后门。不过,接下来我还是先从客户端分析起,毕竟这也是很多大杀器粉丝最强调的东西,呵呵。

我监控了大杀器的安装过程,监控环境:vmware虚拟机内,纯净XP系统,监控软件为PChunter,监控内容为进程建立状况,进程联网状况(这点很关键),进程是否向驱动或内核写入文件,进程在注册表中干了什么。

结果如下:大杀器安装文件只建立了一个安装进程,并且未发现隐藏进程;在安装过程中,安装程序未发起任何联网请求;也未发现向驱动或内核内写入文件;向注册表中写入了信息,但只是正常的安装信息。看起来,安装过程还是比较规矩的。安装完成后,桌面上会自动生成指向大杀器运行程序的快捷方式。

但是,你如何确定安装包没问题?开源?那没用,因为安装包本身很有可能被篡改,特别是通过第三方渠道分享的安装包。对此有两个方案:1,申请数字证书,例如自由门和无界,但大杀器并没有数字证书;2,官网给出hash值,用户下载后自行计算比对。但是,大杀器用的MD5算法几年前就被宣布不安全了,呵呵。

安装好之后,再来看看大杀器到底是个什么东西。对java有点了解的人都能看出来,大杀器很明显是由java编写的程序,而其github上的开源代码也的确是java代码。不过,大爷看来是对程序进行了打包处理,所以不需要用户单独安装java环境,这倒是方便。

大杀器的运行程序是一个bat,内容是运行java包主程序以及日志程序,而日志记录在安装目录下;运行之后,会弹出java标准UI界面(对,默认的UI界面,基本上是初学者拿来练手的,哈哈),界面中需要填写服务器信息,而相关信息需要先去大杀器的网站注册,注册需要邮箱,我是随便google找了个免费匿名邮箱然后完成注册的,注意有些邮箱可能无法收到邮件。填写完毕后点击确定,大杀器就开始运行了。

大爷和他的粉丝都拒绝说明大杀器的工作原理,不过我倒是可以说说:根据官网上的浏览器设置,设置的是HTTP代理,所以很明显大杀器就是个HTTP代理程序;此外还有个证据,大爷提供了服务器端程序给自建服务器的人使用,而程序内文件显示这是个squid proxy,而squid proxy的介绍是:Squid is a caching proxy for the Web supporting HTTP, HTTPS, FTP, and more. 意思是,squid是个为web服务准备的缓存代理,支持http,https和ftp等应用层协议,当然也可以拿来翻墙。但是单纯的HTTP代理是没有加密的,这必然无法对抗GFW,于是大爷就自行加入了AES加密,也就是官网上所谓的军工级别加密。说实在,曾经AES加密的确被当成军火,但如今AES加密早就普及到是个号称注重安全的程序都会去使用的程度,吹这个,呵呵。

总结一下,大杀器的实质就是个自行使用AES加密的HTTP代理,而HTTP作为应用层协议的应用范围非常狭窄,除浏览器之外的程序极少支持,所以基本上大杀器也就能拿来看看网页(而使用socks5协议的ss就能支持多得多的软件翻墙);而在越来越多的软件加入支持局域网代理的功能的背景下,大杀器迄今不支持局域网代理,实属落后。而从抗封锁能力来看,作为单纯的HTTP代理,在无流量混淆的情况下唯一可行的反封锁措施就是经常更换IP,而从推上观察到的事实也的确如此,大杀器经常更换节点,但有时还是会被完全封锁,很显然脑残粉所宣传的长期稳定不符合事实!

最后,我要说最关键的问题了:我前面已经说了,评估翻墙软件的安全,服务器端才是关键。从单纯的安全角度说,squid proxy本身作为单纯的缓存代理没有任何防御攻击的能力,所以即使对于极少数选择自搭服务器的人,他们的服务器安全也只能依赖于第三方软件和服务提供商;而绝大部分人使用的是大爷提供的代理,那请问这位大爷,你能出来说一下服务器的配置情况吗?哈,我可不是要服务器IP,说一下服务器配置情况,安全措施如何?最关键的是,你搭建的服务器上,有没有对那些脑残粉的上网内容进行记录呢?

from https://plus.google.com/109790703964908675921/posts/eofnZxyQtVZ
--------

相关帖子:
https://briteming.blogspot.com/2018/05/gfwpress.html
https://briteming.blogspot.com/2018/05/ios-gfwpress.html