Pages

Thursday, 20 August 2015

使用nghttpx搭建HTTP2代理服务器,用来翻墙 (我测试成功)

HTTP/1.1,定义于 1999 年,至今仍在流行。纵使人们试图在它上面添加各种黑科技,但它依然有各种各样的不足。终于,在 2015 年 5 月,HTTP/2 发布了。 HTTP/2 基于 SPDY 而建,性能和特性较 HTTP/1.1 有了极大的提升,此外,虽然 HTTP/2 标准本身并没有强制 TLS 加密(HTTPS),但主流实现(Google Chrome, Mozilla Firefox)均要求 HTTP/2 被包裹在 TLS 中,因此,HTTP/2 + TLS(HTTPS)已是事实上的标准
本文中,如无特殊说明,「HTTPS」指代「HTTP + TLS」,其中的 HTTP 可以是 HTTP/1.1, SPDY/3.1 或 HTTP/2;但由于几乎所有的 HTTP/2 实现全部要求 TLS,因此单说「HTTP/2」的话,一般指自带了 TLS 的 HTTP/2。
本文介绍使用 nghttpx 配合 Squid 搭建一个支持 HTTP/2 的 HTTPS 代理的方法。
nghttpx 本身并不是一个代理,它只是一个翻译器,因此如果我们需要一个支持 HTTP/2 的正向 HTTPS 代理,可以用一个 HTTP/1.1 的正向代理(如 Squid)和 nghttpx 接在一起实现。使用这样一个 HTTPS 代理,既可以享受 HTTP/2 对多连接的优化(提高客户端和代理服务器之间的连接流畅度),又可以享受外层 TLS 带来的加密和安全。且由于流量特征是 HTTPS,不仅额外开销小,而且在一些封锁严重的 ISP 里也能应用自如。(如封锁了 DTLS 流量的情况下,OpenConnect / AnyConnect 只能 TCP over TCP,效率很低)

一、需求

需求有两种,一种是客户端原生支持 HTTP/2 的,以下以 Chrome 为例:
+------------+    +------------+    +------------+    +------------+                  
|            |    |            |    |            |    |            |                  
|   Chrome   +----+  nghttpx   +----+   Squid    +----+  Internet  |                  
|            |    |            |    |            |    |            |                  
+------------+    +------------+    +------------+    +------------+                  
如图,nghttpx 与 Squid 部署于服务器上,客户端的 Chrome 与 nghttpx 用 HTTP/2 交流,nghttpx 将请求翻译成 HTTP/1.1 发给 Squid,最后 Squid 抓取了结果返回。

另一种是客户端只支持 HTTP/1.1 的,以下以 Pidgin 为例:

+------------+    +------------+    +------------+    +------------+    +------------+
|            |    |            |    |            |    |            |    |            |
|   Pidgin   +----+  nghttpx   +----+  nghttpx   +----+   Squid    +----+  Internet  |
|            |    |            |    |            |    |            |    |            |
+------------+    +------------+    +------------+    +------------+    +------------+
如图,Pidgin 将 HTTP/1.1 请求发给本机的 nghttpx,本机的 nghttpx 翻译成 HTTP/2 之后发给服务器上的 nghttpx。之后的过程和上一种相同。

二、工具

nghttp2 是一个很优秀的 HTTP/2 的 C 类实现。它的前身是 SPDY 库 spdylay,作者都是 Tatsuhiro Tsujikawa,同时他也是著名下载工具 Aria2 的作者。nghttp2 含有多个组件,其中的 nghttpx 程序,可以进行 HTTP/2 和 HTTP/1.1 之间的翻译,如果编译时链接了 spdylay,它也可以支持 SPDY/3.1。
如果你是 Arch Linux 用户,可以直接使用我维护的 aur/nghttp2 包:
https://github.com/wzyboy/PKGBUILDs/blob/master/nghttp2/PKGBUILD,直接 yaourt -S nghttp2 即可,吃豆人会帮你照料好剩下的一切。
如果你是 Debian / Ubuntu 用户,请按照官方 README 完成编译操作,编译完成后在 contrib 目录里可以找到 Upstart 配置文件。注意:nghttp2 库默认是不带 SPDY/3.1 支持的,如果需要 SPDY 支持,请先编译spdylay 再编译nghttp2,后者会自动检测到 spdylay 的存在并链接。
如果你是 CentOS 用户,祝您今天有个好心情

 下面的粉红色内容系我所写。

使用nghttpx,搭建HTTP2代理服务器如下: 
先安装依赖:
apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev libc-ares-dev libjemalloc-dev cython -y
(如果是centos系统,则
yum -y install gcc gcc-c++ autoconf automake make libtool pkg-config openssl openssl-devel libxml2-devel libev libev-devel
zlib zlib-devel libevent-devel libjansson-devel 
libc-ares-devel libjemalloc-devel)

先编译spdylay

git clone https://github.com/tatsuhiro-t/spdylay
cd spdylay/
autoreconf -i
automake
autoconf
./configure
make
make install
ldconfig 

cd ~

然后编译nghttp2:
git clone https://github.com/nghttp2/nghttp2
cd nghttp2
git submodule update --init
autoreconf -i
automake
autoconf (运行autoconf后,会生成configure文件)
./configure
make
如果make途中遇错:no module named setuptools,
解决办法:apt-get install python-setuptools -y
另外,我在centos vps上,这一步make遇错。不过可以通过运行
yum install -y nghttp2来安装nghttp2,得到的可执行文件为nghttpx:
[root@bwg-vps ~]# which  nghttpx
/usr/bin/nghttpx )
make install 
(最终得到的可执行文件为/usr/local/bin/nghttpx)
ldconfig 
必须运行一下ldconfig, 否则直接运行nghttpx,会遇错
nghttpx: error while loading shared libraries: 
libnghttp2.so.14: cannot open shared object file: 
No such file or directory)
root@localhost:~/nghttp2# nghttpx
2017-08-01T07:47:44.720+01:00 17154 17154 decb370c 
FATAL (shrpx.cc:2902) TLS private key and certificate files 
are required.  Specify them in command-line, 
or in configuration file using private-key-file 
and certificate-file options.
(说明nghttpx需要带参数运行) 
root@localhost:~/nghttp2# cp nghttpx.conf.sample nghttpx.conf
root@localhost:~/nghttp2# cd /root
root@localhost:~# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout private.key -out public.crt
(所有步骤的问题可以一律回车/root/下就会生成private.key和public.crt这2个文件.)
root@localhost:~# cd nghttp2
root@localhost:~/nghttp2# nano nghttpx.conf
(在nghttpx.conf文件的末尾空一行,加上:
frontend=0.0.0.0,4433
backend=127.0.0.1,3128
private-key-file=/root/private.key
certificate-file=/root/public.crt
http2-proxy=yes
workers=2
no-ocsp=yes )
root@localhost:~/nghttp2# nghttpx --conf=/root/nghttp2/nghttpx.conf -s --daemon
回车2次。服务器端就搭建好了。
 
建议修改/etc/rc.local文件,在exit 0的上一行加上:
nghttpx --conf=/root/nghttp2/nghttpx.conf -s --daemon 
 
参考https://github.com/freedocs/docs/blob/master/%E5%AE%89%E8%A3%85nghttp2%20https%E4%BB%A3%E7%90%86.md)  
 

三、服务器配置

无论是哪种需求,服务器上都需要安装spdylay,nghttpx 和 Squid

nghttpx

服务器上 nghttpx,前端接受的是来自客户端的 HTTP/2 请求,后端是 Squid,最小配置是这样:
frontend=0.0.0.0,4433
backend=127.0.0.1,3128
private-key-file=/path/to/private.key
certificate-file=/path/to/public.crt
http2-proxy=yes
workers=2
no-ocsp=yes 
  
其中私钥和证书必须是客户端认可的。你可以选择:
  • NameCheap 之类的网站上买一个商业证书,低至 $9 一年;
  • 自己用 OpenSSL / GnuTLS 等工具签一个,然后在你的客户端里强制设置为信任;
  • 如果你不愿意花钱也不愿意折腾 OpenSSL,那你可以尝试去找家免费的 CA 给你签一个。
需要说明的是,GFW 曾被报道会区分商业证书和野证书并对后者做定点清除。试图使用野证书的同学请将此因素考虑在内。
以上只是最小配置,我个人使用的配置还加上了以下内容,是我在 nghttpx 的文档中挑出来觉得比较有用的选项:
# 使用四个 worker,请根据自己服务器的 CPU 合理调整,太小性能差,太大机器挂
workers=2
(# 开启客户端 TLS 认证
verify-client=yes
verify-client-cacert=/path/to/client/ca)
# 不添加 X-Forwarded-For 头
add-x-forwarded-for=no
# 不添加 Via 头
no-via=yes
# 不查询 OCSP 服务器
no-ocsp=yes
# 指定 NPN / ALPN 的顺序
npn-list=spdy/3.1,h2
# 只使用 TLS 1.2
tls-proto-list=TLSv1.2
(# 开启日志功能
accesslog-file=/var/log/nghttpx/access.log
accesslog-format=$remote_addr [$time_iso8601] "$request" $status $body_bytes_sent $alpn "$http_user_agent")
有关npn-list 选项:前文已经说明了,nghttp2 如其名字所示,是一个 HTTP/2 的库,但是由于 Chromium / Google Chrome 的一个 bug(发 稿时最新的 v45 仍未修复),Cr 对 HTTP/2 代理的支持有点问题(Firefox nightly 没有问题),而 nghttpx 默认的 NPN / ALPN 顺序是 h2 优先的,所以需要在这里把 spdy/3.1 的优先级调成最高,以便让 Cr 能用 SPDY/3.1 协商……
(有关 --verify-client 功能:请看下文「有关鉴权」一节。)

Squid

Squid 是一个久经考验的正向代理。在我们的用例中,它是 nghttpx 的后端,只需监听 localhost:3128即可。我用的最小配置如下:(MODIFY SQUID.CONF AS FOLLOWS:)
http_port 127.0.0.1:3128

# 关闭缓存功能和日志功能
cache deny all
access_log none

# 优先访问 IPv4 站点,有完整 IPv6 支持的机器可以去掉
dns_v4_first on
# 不添加 Via 头
via off
# 删除 X-Forwarded-For 头
forwarded_for delete
(我曾试图让 nghttpx 把源 IP 地址发给 Squid 然后让 Squid 记到日志里,但是未能成功,于是 Squid 始终只能记到一堆来自 127.0.0.1 的请求,干脆就把 Squid 的日志关闭,让 nghttpx 去记日志了。
一个可能会让强迫症不爽的地方是,Squid 默认的错误页面会引用 Squid 官网的图片(一只乌贼),而这个图片资源是 http:// 的,因此页面会带有「混合内容」,强迫症用户可以通过编辑 errorpage.css 把这个去掉:
background: url('http://www.squid-cache.org/Artwork/SN.png') no-repeat left;
或者像我一样把这个图片换成 data:image/png;base64 嵌在 CSS 里……)

然后在LINUX VPS里,运行:

nghttpx -s --daemon --conf=/root/nghttp2/nghttpx.conf

有关鉴权

只按照最小配置来做的话,配置出来的 HTTP/2 代理是没有任何鉴权的,任何人都可以把这个地址填进 Chrome 里当代理用,也就是说,这是一个开放代理。但实践证明:
  • 如果你在公网上搭一个不带 TLS 的 HTTP/1.1 开放代理的话,分分钟各种爬虫就会把你的地址撸走,教你做人;
  • 如果你在公网上搭一个带 TLS 的 HTTP/1.1 开放代理的话,来光顾你的爬虫就非常非常少了,几个月也遇不到几只;
  • 如果你在公网上搭一个只允许 TLS 1.2 的 HTTP/2 开放代理的话,根本不会有爬虫来光顾你……
所以,如果不想弄鉴权的话,问题也不大,因为目前根本没有 TLS 1.2 + HTTP/2 的爬虫,除非你主动把地址告诉别人,否则不会有人来用你的代理。不过,这样毕竟只是迷宫,而不是门锁,所以为了安全还是可以配置一下鉴权。
在这种 TLS 1.2 + HTTP/2 的结构下,鉴权可以在两个阶段做:TLS 和 HTTP/2(感觉是废话),也就是 nghttpx 和 Squid(好像还是废话)。
在 TLS 层面做鉴权的话,就是用上文所述的 --verify-client 了。你需要自己维护一个 CA,然后把 CA 的根证书放到服务器上,持有该 CA 根证书的私钥签出的证书对应的私钥的用户可以使用该代理,否则根本完成不了 TLS 握手,直接被拒绝。CA 的搭建和管理又是一个巨大的话题了,在此不多做叙述,只是推荐一下两个软件:适用于 GNU/Linux 用户的 XCA,和适用于 OS X 用户的 Keychain。这两个都是能够管理中小型 CA 的 GUI 程序。我个人使用的则是 EasyRSA。当然如果你足够硬核,也可以直接使用命令行的 OpenSSL 去管理 CA。再次强调,这个 CA 只是客户端认证所用的,和你买证书的那种商业 CA 没有也不应该有联系
在 HTTP 层面做鉴权的话,请照着 Squid 官方文档
推荐用 TLS 鉴权,你会爱上它的。而且 TLS 鉴权的话,Chrome 能用 AutoSelectCertificateForUrls 策略自动选证书,不用每次开 Chrome 的时候点一下。

四、客户端配置

客户端配置分为两种。Chrome 和 Firefox 等直接支持 HTTP/2代理的程序,直接填进去就行。
大部分不支持HTTP/2代理的程序,需要在本地再起一个 nghttpx翻译一下,在本地生成一个 HTTP/1.1 的代理,供程序使用。

无需翻译的程序:

Chromium / Google Chrome 理论上支持 HTTPS 代理,但是如上文所述,目前由于一个 bug 的存在,对 HTTP/2 代理的支持有问题,暂时只能用 SPDY/3.1;Firefox 曾经不能正常使用 HTTPS 代理(当年 Chrome 是唯一能使用 HTTPS 代理的浏览器),现在它的 nightly 版本反而是支持 HTTP/2 了而超越了 Cr……
令人郁闷的是,无论是 Cr 还是 Fx,它们都未提供直接配置的 GUI,只能通过命令行或插件的方式来使用 HTTPS 代理。比如这样一个 pac 文件便可以让 Cr 和 Fx 使用 HTTPS 代理了:
function FindProxyForURL(url, host) 
{
 return "HTTPS vps-ip:443";
}
(其实这样的PAC文件只能搭配CHROME使用,不适合FIREFOX使用。)
当然,pac 文件可以写得非常复杂,也可以使用浏览器插件进行更灵活的代理配置。Cr 用户推荐使用 SwitchyOmega

NOTICE: CHROME通过命令行方式使用HTTPS代理,需要加上参数--ignore-certificate-errors!!


使用nghttpx搭建的HTTP2代理,在本地机器无需导入证书文件(PUBLIC.CRT文件)

需要翻译的程序:

如前文所述,目前除了 Cr 和 Fx,大部分软件是不支持 HTTP/2 的,而 nghttpx 是个 HTTP/1.1 和 HTTP/2 的翻译器,因此我们可以在本机起一个 nghttpx 生成一个 HTTP/1.1 的代理供不支持 HTTP/2 的程序使用。这种情况下,nghttpx 的前端接收 HTTP/1.1 的请求,然后翻译成 HTTP/2 发给服务器上的另一个 nghttpx 实例。最小配置如下:
frontend=127.0.0.1,8080
backend=proxy.example.org,443
client-proxy=yes
同样地,这只是最小配置,我个人使用的配置中还有以下选项:
# 认证用证书和私钥,如果你没用 TLS 认证则不需要
client-cert-file=/path/to/certificate
client-private-key-file=/path/to/private/key
# 四个 worker,请根据自己计算机/手机性能调整
workers=4
# 不添加 X-Forwarded-For 头
add-x-forwarded-for=no
# 不添加 Via 头
no-via=yes
# 不查询 OCSP
no-ocsp=yes
# NPN / ALPN 优先使用 h2
npn-list=h2
另外可能有用的选项是 -k。如果你用了野证书,这个选项让 nghttpx 放弃证书校验(不安全!),此外它在手机等慢速网络下也有缩短启次握手时间的效果。另外如果你想看实时请求情况的话,加上 -L INFO 能看到漂亮的彩色输出。这个 nghttpx 跑起来之后,别的程序设置 http://127.0.0.1:8080 为代理即可使用。
刚才提到了手机。是的,手机。Tatsuhiro Tsujikawa 大大的程序都是为 Android 交叉编译优化过的。(什么,您是 iOS 用户?您还是用您的 APN 代理,也就是 HTTP 明文代理吧……)
在 nghttp2 的文档中,提供了两种方便的交叉编译 Android 版 nghttpx 的方法,一种是自己装 Android NDK 和依赖,然后用 android-configandroid-make 脚本自动做。另一种是用 Dockerfile.android 文件,在 Docker 容器里装上乱七八糟的编译环境和依赖,最后产出珍贵的 nghttpx 文件并复制到容器外面来。编译完的二进制文件记得 strip 一下,能从 11 MiB 减到 2 MiB……
在 Android 上运行起 nghttpx 之后(可以用 JuiceSSH 之类的起一个,无需 root),推荐配合 Drony 使用(也无需 root),该应用使用 VpnService() 捕获所有应用流量,然后再按照你定的规则(来源地址、应用名、目标主机名、目标端口号、HTTP 方法等),将这些流量进行分流(直连、截断、传给代理、交给 pac 处理等).

 FROM https://wzyboy.im/post/1052.html


REF: https://github.com/phuslu/http2 (https://github.com/bradfitz/http2)

https://github.com/tatsuhiro-t/nghttp2

RELATED POST: 

https://briteming.blogspot.com/2015/09/spdy-ssl-proxy.html
(此文说的几乎是一模一样的实现)

https://briteming.blogspot.com/2015/09/nghttpxnginx.html

(HTTP/2的流控机制

起因是在测试H2的代理,发现裸SSL的速度(4MB/s)和用了H2的速度(500KB/s)相差好远。感觉像是配置问题,于是翻nghttpx的文档,尝试了好几个参数,最后发现

backend-http2-window-bits=20
backend-http2-connection-window-bits=30

能让速度恢复到理想水平。知其然当然要知其所以然,搜了下,大概是HTTP/2的流控机制导致的。

HTTP/2流控机制的详细描述在WINDOW_UPDATE帧的定义里。国内也有两篇文章介绍了:[1] 和 [2]

简单说,就是发送方启动是有个窗口大小(默认64K-1),发送了10K的DATA帧,就要在窗口里扣血(减掉10K),如果扣到0或者负数,就不能再发送;接收方收到后,回复WINDOW_UPDATE帧,里面包含一个窗口大小,数据发送方收到这个窗口大小,就回血,如果回血到正数,就又能发不超过窗口大小的DATA帧。

默认nghttpx的两个window-bits都是16,也就是2^16-1=65535,如果一切顺利不丢包的情况下,RTT为100ms,则每秒最多能发送65535*(1000/100)的数据,大约就是500KB,刚好就是我一开始体验的速度。调到30后2^30-1=1,073,741,823,将近1GB的数据,所以同样100ms RTT时的理论上线就会是10GB/s左右。

感觉H2的这个设计有点保守,记得05年的宽带才512K,10年后的今天100M并不罕见,不知道再过10年,这个理论上限会不会导致很多瓶颈,毕竟上一个HTTP版本用了不止10年。

update: 其实在服务端设置会更好,毕竟很多h2的client是不方便设置window大小的

frontend-http2-window-bits=20 
frontend-http2-connection-window-bits=30 )
--------------------------------

搭建http/2代理服务器


证书

HTTP/2 代理其实也就是HTTPS 代理了,首先需要一个证书,可以自己签,太麻烦了。腾讯云和阿里云都提供了免费的DV 证书。搞一个。
因为域名托管在DNSPOD,在腾讯云申请都无需验证,挺快的,会给一个压缩包,打开里面Nginx 子目录,拿到crt 和key 备用。

nghttpx

nghttpx 可以对外提供HTTP/2 服务,将请求转换成HTTP/1.X 转发给后端,相当于一个中间人。
安装
aptitude install nghttp2
不懂为啥ubuntu 的包名是nghttp2,然后包含三个包:
nghttp2-client
nghttp2-proxy
nghttp2-server
编辑配置文件 /etc/nghttpx/nghttpx.conf
frontend=0.0.0.0,443
backend=127.0.0.1,3128
private-key-file=/root/ssl/2_xxxxx.fangpeishi.com.key
certificate-file=/root/ssl/1_xxxxx.fangpeishi.com_bundle.crt
http2-proxy=yes
errorlog-syslog=yes
workers=1

add-x-forwarded-for=no

no-via=yes
no-ocsp=yes
tls-proto-list=TLSv1.2
ciphers=ECDHE+AES128
我是抄的上文文章中的配置,先跑起来再说。。
systemctl restart nghttpx

squid

squid 作为nghttpx 后端的透明代理,不过记住要让它监听在本地,别暴露在公网上。
apt-get install squid
编辑配置文件/etc/squid/squid.conf:
http_port 127.0.0.1:3128

cache deny all
access_log none

dns_v4_first on

via off

forwarded_for delete

auth_param basic program /usr/lib/squid/basic_ncsa_auth  /etc/squid/passwd
auth_param basic casesensitive off
acl auth_user proxy_auth REQUIRED
http_access allow auth_user
也是抄的教程中的配置。。先跑起来再说。鉴权那段下文说明。
systemctl restart squid

鉴权

暴露在公网被其他人乱跑流量总不太好,在Squid 上加一个简单的HTTP Auth。
安装 htpasswd 工具:
apt-get install apache2-utils
#-c 创建文件
htpasswd  -c  /etc/squid/passwd [用户名]

# 添加其他用户
htpasswd /etc/squid/passwd [用户名]
/etc/squid/squid.conf 添加配置,再重启即可:
auth_param basic program /usr/lib/squid/basic_ncsa_auth  /etc/squid/passwd
auth_param basic casesensitive off
acl auth_user proxy_auth REQUIRED
http_access allow auth_user
更多关于squid 的配置需求,直接参考官方文档,应该没有啥是squid 做不到了。

BBR

再顺便升下内核,开启下 BBR,听说有奇效?不过我没有做对比。。直接开启了。
简明步骤,来着上面这篇文章:
安装内核
apt-get install linux-generic-hwe-16.04
reboot 之后,检查内核是不是> 4.9
uname -a 
加载模块,打开参数:
modprobe tcp_bbr
echo "tcp_bbr" | tee -a /etc/modules-load.d/modules.conf

echo "net.core.default_qdisc=fq" | tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | tee -a /etc/sysctl.conf
sysctl -p
最后验证一下:
sysctl net.ipv4.tcp_congestion_control
返回结果必须是:
net.ipv4.tcp_congestion_control = bbr

使用



搞完之后,验证一下,Chrome 安装SwitchyOmega 插件,新建一份配置,协议选择HTTPS,记得填入HTTP Auth验证信息。然后选中启用,打开 whatismyip 看看IP 是不是变了。在不同的平台上要使用,找不同的客户端支持吧。
--------------

利用nghttpx,使squid3支持HTTP/2


利用nghttpx,使squid3支持HTTP/2,实现加密代理访问。(话只能说到这份上了)

首先,任何SSL连接都需要一个域名,所以需要设法申请一个。
不想花钱的可以申.tk等免费域名,想花钱更安稳些的,godaddy神马的都可以。

步骤:(服务器端,以Debian为例)
1. 下载Let's Encrypt Client:
  1. git clone https://github.com/letsencrypt/letsencrypt
复制代码

2. 为你的域名申请SSL证书(或者可以使用已有的证书):(注意在执行这一步前,确保你申请的域名指向了当前服务器的IP地址)
  1. cd letsencrypt
  2. sudo ./letsencrypt-auto certonly --standalone --email [你的邮箱] -d [你的域名] --agree-tos
复制代码
(如果服务器同时正在运行网站的话,则需要用webroot方式验证,
这种情况请参阅Let's Encrypt文档:https://letsencrypt.readthedocs.org/en/latest/
证书颁发后,客户端会显示证书保存的位置,记下文件夹的路径。

3. 安装squid3与nghttp2:
  1. sudo apt-get install squid3 nghttp2
复制代码
(如果debian源未收录nghttp2的话,则需要从https://nghttp2.org/下载安装包)

4. 配置squid3(即编辑/etc/squid3/squid.conf),这个是我个人的配置:
  1. # [HTTP2 Proxy Backend]
  2. http_access allow localhost
  3. http_port 127.0.0.1:8000
  4. # No cache and log
  5. cache deny all
  6. access_log none
  7. # Prefer IPv4 sites
  8. dns_v4_first on
  9. # No via header
  10. via off
  11. # No x-forwarded-for header
  12. forwarded_for delete
复制代码
5. 建立文件/etc/nghttpx/nghttpx.conf,写入配置如下:
  1. frontend=*,1443(需要在其它端口上运行的请自行修改)
  2. backend=127.0.0.1,8000
  3. private-key-file=[证书文件夹路径]/privkey.pem
  4. certificate-file=[证书文件夹路径]/fullchain.pem
  5. http2-proxy=yes
  6. tls-proto-list=TLSv1.2
复制代码
6. 运行squid3,启动squid服务。
7. 运行nohup nghttpx >/dev/null 2>&1 &,启动nghttpx服务。

(客户端,需要使用Chrome或Opera访问该代理服务)
1. 下载Proxy SwitchyOmega:https://github.com/FelisCatus/Sw ... 17/SwitchyOmega.crx
2. 打开chrome://extensions或者opera://extensions,将下载的插件拖进去。(注意不能直接双击安装,这是Chrome等的限制)
3. 点击SwitchyOmega图标,进入选项页面,编辑代理设置。
新建一个代理,代理方式为HTTPS,服务器地址为你的域名,端口为你指定的端口(这里是1443),然后注意保存设置。
4. 点击SwitchyOmega图标,切换到刚才创建的代理,即可使用指定代理上网。

注意:
1. 每三个月需要更新一次Let's Encrypt的证书,不然Chrome可能提示证书无效。
2. Chrome 45(或者使用45版Chrome内核的浏览器)无法使用此方法,这是45版内核的bug所致。这种情况下请更新或更换浏览器。

from https://bbs.deepin.org/forum.php?mod=viewthread&tid=38084
---------------------

使用Nghttpx搭建HTTP2代理



nghttpx 是一个 HTTP2 代理,HTTP2 是新一代的 HTTP 协议,但一些老牌的 HTTP 代理比如 squid 并不支持 HTTP2 协议,就需要 nghttpx 来将 HTTP2 协议翻译成 HTTP1.x 的协议,所以要搭建一个HTTP2 代理你需要一个 HTTP 代理来配合使用。
具体请求流程是:
国内网络VPS自由网络目标网站
你的浏览器→ (加密)HTTP2 →nghttpx → squid→ HTTP(S) →目标网站

服务器安装和配置

配置 squid

在商店中选择 squid 并创建,无需填写任何选项(端口也不用填)安装即可。
**注意,如果 Squid 无法启动,日志中显示 FATAL xcalloc: Uable to allocate *** 时,这是内存不足引起的错误。你可以尝试添加交互分区来解决。
sudo su
fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "vm.swappiness = 10" >> /etc/sysctl.conf
sysctl -p
注意重启后swap会取消挂载.请根据相应系统查询写入fstab的命令.这里给出Ubuntu和Centos的
Ubuntu:echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Centos:echo "/swapfile swap swap defaults 0 0" | sudo tee -a /etc/fstab
然后卸载重装 Squid 即可。

配置 nghttpx

SSL 证书的获取你可以参考 '如何自动生成可信的SSL证书':
https://github.com/briteming/HyperApp-Guide/blob/master/zh/SSL.md,
如果使用自签名证书你需要在客户端导入CA。
  • Port: 代理端口
  • Disable TLS: 是否禁用 TLS,不禁用的话就必须填写 SSL 参数以及提供 SSL 证书。
  • Domain: SSL 证书的域名
  • Backend: 后端 HTTP 代理,如果你下面link 了一个 backend,这里就填 backend,端口号,如果你使用其它远程代理,这里就填代理地址就行,格式 地址,端口
  • Access Log: 是否在日志中显示访问记录
  • Volumes - certs: SSL 证书的存放目录,应该包含上面所填写的 Domain 的两个文件: Domain.key 和 Domain.crt
  • Link Containers - backend: 这儿可以选择上面创建的 squid
安装即可,然后你就有一个非常安全的 HTTPS 代理了。开始配置客户端吧。

客户端

Chrome

Chrome 支持HTTP2,可以使用 Proxy SwitchyOmega 来使用

Surge

nghttpx = https, DOMAIN, 端口,from https://github.com/briteming/HyperApp-Guide/blob/master/zh/nghttpx.md
---------------------------------

基于 HTTP/2的一个代理程序(仅适用64位的LINUX VPS)



Reported by phu...@hotmail.com, Aug 19 

vps 第一版在此. https://github.com/phuslu/goproxy/releases/download/goproxy/vps_linux_amd64.tar.bz2
(须翻墙下载)
1. 使用的是 http2 模式, https://github.com/phuslu/http2
2. 并且用了打过补丁的 go, https://github.com/phuslu/go
目前这个只是服务端, 客户端还未实现. 所以
他目前只是一个普通的 https 代理, 只有 chrome 能用.
现在发出来征集测试.
使用方法:
1. 把压缩包解压到 vps 目录, sudo ./vps, 目前只在 443 端口监听.
2. chrome 启动参数加上--ignore-certificate-errors, 然后使用 switchomega 插件
添加一个 HTTPS 代理, 就可以了.

说明:
1.--ignore-certificate-errors 这个必须,还要等 letencrypt 出来才可能去掉。
2. vps.go 是原代码, 可以自己修改, 编译请务必使用 https://github.com/phuslu/go 编译,
否则性能会大有折扣。
3. 如有问题, 请反馈.

Aug 19 (41 hours ago)
Aug 19 (41 hours ago)
#2 phu...@hotmail.com
本质上这个东东和 nghttpx 是一样的,但是现在用 golang 重新实现了一下, 
以期带来更多潜在的好处:性能,反探测,抗干扰等等。
Aug 19 (41 hours ago)
#3 redfrog...@gmail.com
终于来了,看看测试结果如何。
Aug 19 (41 hours ago)
#4 kingtope...@gmail.com
本地代理设定的目标ip是vpsIP? 代理端口也是443?
Aug 19 (41 hours ago)
Project Member #5 phuslu.bot
#4 是的。红杏和以前的地下铁路的核心原理就是这个,只不过他们用的是 switchysharp修改版 + nghttpx
Aug 19 (41 hours ago)
Project Member #6 phuslu.bot
附上原理解说, 理论上这种方式是目前诸多手段中最先进的之一。
https://wzyboy.im/post/1052.html
Aug 19 (41 hours ago)
#7 kingtope...@gmail.com
好的,我先在我的破搬瓦工上试试,就算泄露了IP也不怕。我的vultr就不敢试了,免得泄露IP了,嘿嘿。话说回来,有了证书的话,是不是就不用担心认证的事情了。
Aug 19 (41 hours ago)
Project Member #8 phuslu.bot
#7 泄露的可能不大,毕竟是 https 代理。启动时候会随即声称一个证书,目前测试阶段是尽量搞定性能问题,保密性呆会再搞。
Aug 19 (41 hours ago)
#9 Kisesy
好顶赞,又有新东西了
Aug 19 (41 hours ago)
#10 yun36041...@gmail.com
大神努力,俺们菜鸟都得靠你哇..没vps,没法参与测试了..
Yesterday (40 hours ago)
#11 hjbhug...@gmail.com
 #8 没vps没法测试,不过想反映一下goproxy的index.php是不是有问题,上传了没有用,goagent的同名文件就可以
Yesterday (40 hours ago)
#13 warmingf...@gmail.com
没有 vps 的基友不用怕,可免费用 Koding 部署 GoProxy 的服务端。
Koding ( https://koding.com ) 可以和 vps 一样使用,独立 IP ,没有 vps 的基友可用它做 vps 。
Koding 的独立 IP 相较 Cloud9 IDE 能干更多事,如在上面可部署 Shadowsocks, gost 的 tls 隧道,当然也能部署 GoProxy 的 vps 服务端。

另对此事: https://code.google.com/p/goagent/issues/detail?id=22357 向作者表示道歉。
Yesterday (40 hours ago)
#14 i.me0...@gmail.com
搬瓦工亲测成功,就是chrome加参数后,每次打开提示不安全
Yesterday (40 hours ago)
#15 warmingf...@gmail.com
Koding 的使用方法(如查看分配的独立 IP )可参考这篇在上面部署 Shadowsocks 服务端的教程: http://www.138vps.com/freeot/161.html
Yesterday (40 hours ago)
#16 warmingf...@gmail.com
Koding 上部署的简单步骤:
1. 进入 IDE 环境
2. 依次输入如下命令
wget https://github.com/phuslu/goproxy/releases/download/goproxy/vps_linux_amd64.tar.bz2
tar -xjvf vps_linux_amd64.tar.bz2
sudo ./vps

美化版:
$ wget https://github.com/phuslu/goproxy/releases/download/goproxy/vps_linux_amd64.tar.bz2
$ tar -xjvf vps_linux_amd64.tar.bz2
$ sudo ./vps
用chrome浏览器,一直开着IDE那个终端网页,然后加一个自动刷新页面的插件(我用auto refresh),几分钟刷新一次即可使koding持续开机。。。
Yesterday (39 hours ago)
#17 kingtope...@gmail.com
汇报一下测试结果:可能是因为普通https的原因,速度上没有优势,基本跟SS的速度持平。
但是有个严重的bug,就是会突然卡死,浏览器无法跟服务端连接了,
VPS的putty窗口也会死掉,无法退出,只能关掉putty,
重新登录VPS,再运行vps服务端才能恢复正常, 貌似TLS连接不是太稳定。 
重新运行vps服务端的命令如下:
ps aux|grep vps.
kill vps的pid.
./vps
Yesterday (39 hours ago)
#18 kingtope...@gmail.com
我感觉目前的vps go还没有达到可用的程度。
Yesterday (39 hours ago)
Project Member #19 phuslu.bot
#17 速度上可以继续优化。
这个 bug 看起来不是 vps go 的本身的问题, 貌似是墙在有意干扰 https 的出境连接。
我在墙外测试一切正常。我继续看下
Yesterday (39 hours ago)
#20 warmingf...@gmail.com
#18 我在 Koding 上部署的 vps 服务端未卡死过,不知是不是 vps 性能不同的问题。
在客户端看视频和浏览网页也未发现问题。
Yesterday (39 hours ago)
Project Member #21 phuslu.bot
#20 是因为墙对某些 ip 端比较感兴趣,会短时间黑洞。导致ssh的连接也会受影响。
Anyway, 这就是我要重新实现一个 http2 proxy 的意义所在,有了这一出版,
我们接下来看看如何来规避探测。
一个想法是在 80 端口使用 h2c 协议
Yesterday (39 hours ago)
Project Member #22 phuslu.bot
#20 http2 这类协议对视频没啥优势,真正能提高视频的还得靠客户端自己实现 autorange.
不过 http2 对于网页这种频繁打开和关闭的场景,非常适合。胜过 socks 类应用。
Yesterday (38 hours ago)
#23 warmingf...@gmail.com
#22 茅塞顿开!刚刚还在惊奇为啥用 vps go 打开 http://zhibo8.cc 实现了秒开,
在这以前是难以想象的——在亚马逊的服务器 ( Koding, OpenShift, Heroku ) 部署 gost, 
GoProxy php 代理后,访问 zhibo8.cc 这个大陆的网站要等很久才能加载出来。
正想找原因,就看到您的话,非常感谢!

为了证实 http2 的这种优势,于是同时在 Koding 部署了 gost 和 goproxy vps go , 
对比发现确实加载时间差异确实特别大。强烈建议 php go 和 gost 也能加持 http2 。

虽然对 h2c 协议不明觉厉,但是对“不过 http2 对于网页这种频繁打开和关闭的场景,非常适合。”
这句话深有体会。
Yesterday (38 hours ago)
Project Member #24 phuslu.bot
在 heroku/openshift 的确可以实现各种 http/socks/http2 代理,比如 gsnova/socksocks-heroku, 
但是在我看来有点越界,我再权衡一下。
Yesterday (38 hours ago)
#25 kingtope...@gmail.com
PaaS平台毕竟是中看不中用,花拳绣腿的,没有太大意义,毕竟不是翻墙的主流,只是看网页的话,
甚至赛风,自由门,无界都可以。 我们的目的是希望能提高连接的抗扰度和速度,流畅看视频,
建议phuslu不要在这花费太多精力。

对于VPS,才是你应该投入的主力,免探测或增强抗扰能力是核心,希望能比SS做的更好。

Yesterday (38 hours ago)
Project Member #26 phuslu.bot
#25 优化视频的确很重要,但是平常人上网更多的是看网页,
目前针对网页类场景 http2 算是做到了极致。
这也是我为什么花了相当一部分精力去完善 golang 的 http2 库
https://github.com/phuslu/http2/commits/master
Yesterday (38 hours ago)
Project Member #27 phuslu.bot
接下来优化视频,规避探测等等,是我比较有经验的部分,这块应该比较容易做稳定,
测试工作量不大。
Yesterday (37 hours ago)
#28 agrochem...@gmail.com
太好了!又有新玩具了…
Yesterday (37 hours ago)
#29 SelenaRi...@gmail.com
PaaS中看不中用?!哥表示1080p完全無壓力!!!
http://i.imgur.com/HG65FYI.png
Yesterday (37 hours ago)
#30 kingtope...@gmail.com
别告诉我,你用C9。用C9看高清视频,让人鄙视
Yesterday (37 hours ago)
#31 kingtope...@gmail.com
如果你能用CDN,那还能证明你有两把刷子
Yesterday (37 hours ago)
#32 SelenaRi...@gmail.com
shadowsocks-heroku
Yesterday (36 hours ago)
#33 warmingf...@gmail.com
PaaS 如 Heroku, OpenShift, Bluemix 中国移动宽带用户确实 1080P 无压力  
https://github.com/phuslu/fetchserver/tree/golang 。不过俺不好意思,
所以只用它们看网页,看视频用的是赛风。
Yesterday (36 hours ago)
#34 uuu...@gmail.com
这个很给力,先顶再试
Yesterday (36 hours ago)
#35 hjbhug...@gmail.com
#33 电信用户看网页还可以,视频是完全没法看,100k都没有
Yesterday (36 hours ago)
#36 qiaogao...@gmail.com
日本东京Linode
nico、youtube正常加载、播放,nico生放送明显比SS顺畅。
打开网页的速度与SS基本不相上下,网页加载似乎goproxy更快。
很期待接下来的发展。
Yesterday (26 hours ago)
#37 nihilit...@gmail.com
#16
koding搭的连不上
: ~ $ sudo ./vps
I0819 23:44:50.602525    1383 vps.go:82] Generating RootCA for www.ibtkrgurh.com
I0819 23:44:50.653205    1383 vps.go:263] ListenAndServe on [::]:443
2015/08/19 23:46:16 http: TLS handshake error from 125.39.***.***:11303: EOF
Yesterday (25 hours ago)
#38 warmingf...@gmail.com
#37 我这使用最新版的 Chrome (我的是 GoogleChrome 44.0.2403.155 ),
使用 --ignore-certificate-errors 参数启动。安装 SwitchyOmega 扩展,
设置所有代理为 https 代理 IP 地址:443 ,然后保存 SwitchyOmega 设置,能成功。
提示 TLS handshake error 有可能是 Chrome 版本问题。
Yesterday (24 hours ago)
#39 nihilit...@gmail.com
#38
thx.使用 --ignore-certificate-errors 参数启动解决。
感觉速度还是不如goagent,而且不稳定,不知道是koding的问题还是什么问题
Yesterday (24 hours ago)
#40 phu...@hotmail.com
#38 看下是不是丢包导致的。 win m t r
Yesterday (23 hours ago)
#41 lg560...@gmail.com
然而首先,你得有台VPS。。。
Yesterday (23 hours ago)
#42 warmingf...@gmail.com
#40 移动用户用 WinMTR ( http://winmtr.net/download-winmtr )测 Koding 的 IP 全程无丢包,
网络顺畅不拥塞,因此 1080P 无压力。 WinMTR 测试结果如图: https://i.imgur.com/cWcVjoD.jpg
以以往的电信使用经验猜测,中国电信用户那丢包应该很严重。
Yesterday (23 hours ago)
#43 warmingf...@gmail.com
#41 没有 vps 的朋友可用 Koding 玩玩。 #c13
Yesterday (19 hours ago)
#44 yimin...@gmail.com
太好了,又有新工具能玩了。小白等候佳音
Yesterday (18 hours ago)
#45 Kishen...@gmail.com
帮主威武!
Today (15 hours ago)
#46 alex...@gmail.com
sudo ./vps 提示 sudo: unable to execute ./vps: No such file or directory
vps新手求助
Today (15 hours ago)
#47 www.leno...@gmail.com
#46 先给权限
sudo chmod 755 vps
sudo ./vps
Today (14 hours ago)
#48 i.me0...@gmail.com
希望能够自定义端口,443已经别别的服务占用了,
Today (14 hours ago)
#49 warmingf...@gmail.com
#48 "vps.go 是原代码, 可以自己修改, 编译请务必使用 https://github.com/phuslu/go 编译
否则性能会大有折扣。",所以可修改源码里的端口,然后再重新编译。你如果不想亲自动手,
想要什么端口的,我可以代劳。
Today (13 hours ago)
#50 alex...@gmail.com
 #47 www.leno...@gmail.com 
sudo chmod 755 vps
sudo ./vps
依然  No such file or directory
Today (13 hours ago)
#51 phu...@hotmail.com
#50 这个是 64bit 的,可能不适合你的 linux.
 
FROM  https://code.google.com/p/goagent/issues/detail?id=22361#c19
 
我的补充说明
首先64位的linx vps建立go环境:
(在~目录下)
wget  https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
tar zxvf go1.8.linux-amd64.tar.gz
cd go
mkdir gopath
nano /etc/profile 如下:
export GOROOT=~/go
export GOBIN="$GOROOT/bin"
PATH=$PATH:$GOROOT/bin
export PATH=$PATH:$GOROOT/bin
GOPATH=~/go/gopath

export GOPATH=~/go/gopath
 
然后运行:

/etc/profile 


这样,GO环境就搭建好了。

mkdir goproxy-vps_linux_amd64-r54/
mv goproxy-vps_linux_amd64-r54.tar.bz2 goproxy-vps_linux_amd64-r54/  
cd goproxy-vps_linux_amd64-r54/ 
tar jxvf goproxy-vps_linux_amd64-r54.tar.bz2
 
[root@RegalMusty-VM goproxy-vps_linux_amd64-r54]# ls
changelog.txt             goproxy-vps goproxy-vps.service pwauth
goproxy-vps-auth.service  goproxy-vps_linux_amd64-r54.tar.bz2 
[root@RegalMusty-VM goproxy-vps_linux_amd64-r54]# ./goproxy-vps > /dev/null & 

这样服务器端的程序就运行起来了。
 
服务器端程序的下载地址: 
64位的版本goproxy-vps_linux_amd64-r54.tar.bz2下载地址
https://drive.google.com/file/d/0B1CmeJlGMtoLVW9ZQnFyUG1CcGs/view 
 

客户端:
右键点击CHROME.EXE的桌面快捷方式图标-属性,在“目标”栏里的chrome.exe后面,空一格,加上:
--proxy-server=https://your-vps-ip:443 --ignore-certificate-errors
然后点击“确定”,即可用CHROME翻墙。  
 
注意:最好用GOOGLE官方的CHROME程序安装版,
不要用网上的杂七杂八的绿色版。否则可能翻墙失败。
---------------------------------------
 

为了避免原上传者删除文件,我把该文件下载,然后上传到了自己的gdrive帐号。

32位的版本vps_linux_386.tar.gz的下载地址:
https://drive.google.com/file/d/0B1CmeJlGMtoLWlVNVGVLM1ZhcWs/view 
 
64位的版本goproxy-vps_linux_amd64-r54.tar.bz2下载地址
https://drive.google.com/file/d/0B1CmeJlGMtoLVW9ZQnFyUG1CcGs/view 
-------------------------------------------

https://github.com/tatsuhiro-t/spdylay的再造轮子版?

目前该项目还是 spdylay/nghttpx 的复刻。
但是好处就是现在代码比较精简,可以作一些有趣的改动。
比如 h2c+AES 这种,比起 socks 类的应用,还是很有优势的。
---------------------  

nghttpx-tinyproxy

nghttpx : A forward/reverse proxy for HTTP/2, HTTP/1 https://nghttp2.org/
tinyproxy: A light-weight HTTP/HTTPS proxy daemon https://tinyproxy.github.io/

from https://github.com/kirbyzhu/nghttpx-tinyproxy
-------------------


https://github.com/kirbyzhu/nghttpx-squid-with-ns