GCP做梯子流量钱还是太贵了,到大陆的下行流量0.23刀一个G。随便看点油管视频每个月百G根本不是问题。以迁移共享梯子为契机,正好试一下V2Ray新推出的基于http2的传输模式。即使从原理讲反向代理用http2基本无法获得h2带来的性能提升,但是前段伪装站又有基于header分流的需求,还可以测试一下h2和ws在反代情境下的性能区别,何乐而不为呢?
配料一览:
- Ubuntu 18.04 LTS
- 域名 / 一条指向VPS公网IP的DNS A记录
- 服务器将使用Caddy
- 简化本文涉及的内容并缩短篇幅,前端站使用静态网页
- VPS提供商为Linode,初始镜像的配置可能因提供商不同而异
I. Ubuntu初始配置
Linode 上新建虚拟机实例并部署镜像后只提供root访问。因此第一步,以root身份建立个人帐户,并根据终端提示输入密码及相关账户信息。
adduser <username>
赋予新建账户sudo权限
usermod -aG sudo <username>
配置SSH Keys,可以参考Windows教程 或 Mac教程。
为代理服务器优化配置,将以下粘贴到/etc/sysctl.conf末尾
# max open files fs.file-max = 51200 # max read buffer net.core.rmem_max = 67108864 # max write buffer net.core.wmem_max = 67108864 # default read buffer net.core.rmem_default = 65536 # default write buffer net.core.wmem_default = 65536 # max processor input queue net.core.netdev_max_backlog = 4096 # max backlog net.core.somaxconn = 4096 # resist SYN flood attacks net.ipv4.tcp_syncookies = 1 # reuse timewait sockets when safe net.ipv4.tcp_tw_reuse = 1 # turn off fast timewait sockets recycling net.ipv4.tcp_tw_recycle = 0 # short FIN timeout net.ipv4.tcp_fin_timeout = 30 # short keepalive time net.ipv4.tcp_keepalive_time = 1200 # outbound port range net.ipv4.ip_local_port_range = 10000 65000 # max SYN backlog net.ipv4.tcp_max_syn_backlog = 4096 # max timewait sockets held by system simultaneously net.ipv4.tcp_max_tw_buckets = 5000 # turn on TCP Fast Open on both client and server side net.ipv4.tcp_fastopen = 3 # TCP receive buffer net.ipv4.tcp_rmem = 4096 87380 67108864 # TCP write buffer net.ipv4.tcp_wmem = 4096 65536 67108864 # turn on path MTU discovery net.ipv4.tcp_mtu_probing = 1 # for high-latency network net.ipv4.tcp_congestion_control = bbr
以root身份运行以下命令使上述配置生效
sudo sysctl --system
增大最大允许同时打开的文件链接数
sudo nano /etc/profile
最后新加一行,保存退出
ulimit -n 51200
以root身份进行全面系统更新并重启
sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade sudo reboot
II. 安装Caddy
nginx不支持h2反代,遂使用Caddy。
2.1 获取Caddy
Caddy是基于Go实现的服务器后端,首先安装Go,以及版本管理工具Git
sudo apt-get update sudo apt-get install golang git
从GitHub获取最新版本的Caddy。 Caddy的安装可能在后续版本发生改变,具体请参看Caddy的官方wiki
go get github.com/mholt/caddy/caddy go get github.com/caddyserver/builds
Go的安装路径因发行版而异,$GOPATH默认值一般为用户或root主文件夹下的/go。如果安装时未配置,注意根据实际情况手动添加$GOPATH。
禁用数据反馈:Caddy默认启用数据反馈,如需禁用,打开文件
nano $GOPATH/src/github.com/mholt/caddy/caddy/caddymain/run.go
修改最后一行为
const enableTelemetry = false
然后进行编译
cd $GOPATH/src/github.com/mholt/caddy/caddy go run build.go
2.2 将Caddy安装为服务
首先将编译好的二进制文件拷贝到用户的二进制文件夹
sudo cp $GOPATH/bin/caddy /usr/local/bin/
进行一系列配置
#root拥有二进制文件防止其他账户修改 sudo chown root:root /usr/local/bin/caddy #修改权限为755,root可读写执行,其他账户不可写 sudo chmod 755 /usr/local/bin/caddy #Caddy不会由root运行,使用setcap允许caddy作为用户进程绑定低号端口(服务器需要80和443) sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy #创建文件夹存储Caddy的配置文件 sudo mkdir /etc/caddy #创建文件夹存储Caddy所管理的站点证书 sudo mkdir /etc/ssl/caddy #允许root及www-data组访问相关文件,允许Caddy写入站点证书文件夹 sudo chown -R root:www-data /etc/caddy sudo chown -R root:www-data /etc/ssl/caddy sudo chmod 0770 /etc/ssl/caddy #如果默认站点根目录不存在,创建以下文件夹 sudo mkdir /var/www #允许www-data组拥有站点文件夹 sudo chown www-data:www-data /var/www #创建空的Caddy配置文件 sudo touch /etc/caddy/Caddyfile #从源码拷贝systemd服务文件到对应文件夹 sudo cp $GOPATH/src/github.com/mholt/caddy/dist/init/linux-systemd/caddy.service /etc/systemd/system/ #调整权限使其只可被root修改 sudo chmod 644 /etc/systemd/system/caddy.service #重载systemd使其检测到新安装的Caddy服务 sudo systemctl daemon-reload
为验证Caddy作为服务注册成功,运行以下命令
sudo systemctl status caddy
若看到类似以下输出,说明服务注册成功
● caddy.service - Caddy HTTP/2 web server
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: e
Active: inactive (dead)
Docs: https://caddyserver.com/docs
执行下一步之前,如果站点配置了防火墙,注意放行80和443端口的相关流量。
2.3 配置Caddy
开始写配置文件前,首先创建一个测试用的站点文件
sudo touch /var/www/index.html
打开文件进行编辑
sudo nano /var/www/index.html
粘贴以下内容并保存
<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1 style="font-family: sans-serif">This page is being served via Caddy</h1>
</body>
</html>
打开Caddy配置文件
sudo nano /etc/caddy/Caddyfile
粘贴如下配置内容并保存
:80 {
root /var/www
gzip {
ext .html .htm .php
level 6
}
}
启动Caddy
sudo systemctl start caddy
检查Caddy运行状态
sudo systemctl status caddy
如果看到如下输出,证明Caddy配置正确
● caddy.service - Caddy HTTP/2 web server
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: e
Active: active (running) since Thu 2018-06-28 02:11:29 UTC; 4s ago
Docs: https://caddyserver.com/docs
Main PID: 13322 (caddy)
Tasks: 7 (limit: 2321)
CGroup: /system.slice/caddy.service
└─13322 /usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy
接下来打开浏览器,访问配置好的网址。如看到以下页面,说明上述步骤,除了证书相关的步骤,都成功执行了(证书相关下一步验证)

如果确认配置没有问题,将Caddy加入系统启动项
sudo systemctl enable caddy
2.4 配置HTTPS
Caddy内嵌基于Let’s Encrypt的证书自动认证颁发功能。 由于v2ray基于h2的连接必须tls,所以这部分正好可以交给caddy为我们解决。按照下述样本修改caddy配置文件,注意替换尖括号内的内容,服务器域名为你的站点域名,email替换成自己的邮箱。该邮箱用作证书过期通知等
http://<example.com> {
redir https://<example.com>{url}
}
https://<example.com> {
root /var/www/
gzip
tls <user@example.com> {
ciphers ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-CBC-SHA
curves p384
key_type p384
}
header / {
Strict-Transport-Security "max-age=31536000;"
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}
保存退出后,手动切换到配置文件所在的文件夹
cd /etc/caddy
然后结束刚才启动的caddy进程,以命令行方式重新启动caddy
sudo systemctl stop caddy caddy
以这种方式启动是因为需要接受Let’s Encrypt的EULA。按照命令行的提示接受,并确认证书颁发过程没有报错。
之后就可以到SSL Labs检测一下https配置评分。按照上述配置的站点在现在这个时点(2018年6月)可以拿到SSL Labs满分A+的安全评级
配置完成后就可以Ctrl+C终止进程,并通过Systemd重启Caddy
sudo systemctl start caddy

III. 安装V2Ray
终于轮到我们主菜了,其实也是老生常谈,照例一步一步来吧
3.1 获取并安装V2Ray
使用官网的一键安装脚本。首先切换到root,并在root下新建文件夹保存脚本
sudo su cd ~ mkdir scripts cd ./scripts curl -L -s https://install.direct/go.sh > v2ray.sh
更改权限,并执行安装脚本
chmod +x v2ray.sh bash v2ray.sh
使用crontab每周运行该脚本,以定期更新v2ray
crontab -e
如果第一次使用crontab会被问到使用哪个文本编辑器,新手建议1号nano,选择后在末尾追加以下一行
21 10 * * sun /bin/bash /root/scripts/v2ray.sh
意思是每周日上午10点21分,会调用v2ray.sh执行更新。可以根据需求改变更新时间,
3.2 配置V2Ray
恩,这部分实际是重点中的重点。v2ray魅力就在于灵活的配置和丰富的功能,而缺点就是配置文件需要手工写json,缺少图形化的配置界面。本文直接提供配置文件范例,注意根据自己的安装实例修改UUID以及服务器域名/路径。
V2Ray的配置文件保存在/etc/v2ray/config.json。下面的配置会使用Caddy将所有路径为</path>的请求全部分流到v2ray。本段配置涉及的<uuid> <domian.com> </path> 注意与3.4部分客户端配置文件保持统一, <port> <domain.com>注意与3.3部分Caddy配置保持统一
{
"log" : {
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log",
"loglevel": "warning"
},
"inbound": {
"port": <port>,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "<uuid>",
"level": 1,
"alterId": 64
}
]
},
"streamSettings": {
"network": "h2",
"security": "tls",
"httpSettings": {
"path": "</path>",
"host": ["<domain.com>"]
},
"tlsSettings": {
"serverName": "<domain.com>",
"certificates": [
{
"certificateFile": "/etc/v2ray/v2ray.crt",
"keyFile": "/etc/v2ray/v2ray.key"
}
]
}
}
},
"outbound": {
"protocol": "freedom",
"settings": {}
},
"outboundDetour": [
{
"protocol": "blackhole",
"settings": {},
"tag": "blocked"
}
],
"routing": {
"strategy": "rules",
"settings": {
"rules": [
{
"type": "field",
"ip": [
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"::1/128",
"fc00::/7",
"fe80::/10"
],
"outboundTag": "blocked"
}
]
}
}
}
注意到tlsSettings字段有一项certificates,这里需要填写Caddy生成的证书文件所在的位置。由于Caddy生成证书存储的路径过长,我们可以建两个软链,省去了在配置中写一大长串路径的必要。
ln -s /etc/ssl/caddy/acme/acme-v02.api.letsencrypt.org/sites/<domain.com>/<domain.com>.crt /etc/v2ray/v2ray.crt ln -s /etc/ssl/caddy/acme/acme-v02.api.letsencrypt.org/sites/<domain.com>/<domain.com>.key /etc/v2ray/v2ray.key
之后就可以启动V2Ray了
sudo systemctl start v2ray
启动后调用以下命令查看V2Ray运行状态
sudo systemctl status v2ray
如果看到状态为running,证明配置没有出错
● v2ray.service - V2Ray Service
Loaded: loaded (/etc/systemd/system/v2ray.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2018-06-28 03:51:32 UTC; 21min ago
Main PID: 14647 (v2ray)
Tasks: 7 (limit: 2321)
CGroup: /system.slice/v2ray.service
└─14647 /usr/bin/v2ray/v2ray -config /etc/v2ray/config.json
Jun 28 03:51:32 localhost systemd[1]: Started V2Ray Service.
Jun 28 03:51:32 localhost v2ray[14647]: V2Ray v3.26 (die Commanderin) 20180614
Jun 28 03:51:32 localhost v2ray[14647]: A unified platform for anti-censorship.
如果发现启动失败,可以查看/var/log/v2ray/error.log排查错误。确认v2ray服务端没有问题后,我们可以运行以下命令将V2Ray设置成开机自启
sudo systemctl enable v2ray
3.3 配置Caddy
由于有前端的伪装站,只有访问路径为</path>的请求才会转发给V2Ray做代理处理。Caddy作为前端服务器,也需要调整配置。直接将以下配置覆盖到/etc/caddy/Caddyfile,注意替换<port> <domain.com> <email>
http://<domain.com> {
redir https://<domain.com>{url}
}
https://<domain.com> {
root /var/www/
tls <email> {
ciphers ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-CBC-SHA
curves p384
key_type p384
}
proxy </path> https://localhost:<port> {
insecure_skip_verify
header_upstream X-Forwarded-Proto "https"
header_upstream Host "<domain.com>"
}
header / {
Strict-Transport-Security "max-age=31536000;"
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}
保存配置后重启Caddy
sudo systemctl restart caddy
3.4 配置客户端
基本上客户端的配置注意对应项和服务端保持一致即可。一般GUI的软件,提供<uuid></path> <domain.com>并选择http2,启用tls即可。如果使用的是V2Ray Core,需要使用json做配置文件的话,按照以下配置模版修改,同样,注意<uuid> <domain.com> </path>和3.2中服务端的配置保持一致
{
"log": {
"loglevel": "warning"
},
"inbound": {
"port": 1080,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
"outbound": {
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "<domain.com>",
"port": 443,
"users": [
{
"id": "<uuid>",
"alterId": 64
}]
}]
},
"mux": {
"enabled": true,
"concurrency": 8
},
"streamSettings": {
"network": "h2",
"security": "tls",
"tlsSettings": {
"serverName": "<domain.com>"
},
"httpSettings": {
"host": [
"<domain.com>"
],
"path": "</path>"
}
}
},
"outboundDetour": [
{
"protocol": "freedom",
"settings": {},
"tag": "direct"
},
{
"protocol": "blackhole",
"settings": {},
"tag": "adblock"
}
],
"dns": {
"servers": [
"9.9.9.9",
"8.8.8.8",
"localhost"
]
},
"routing": {
"strategy": "rules",
"settings": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"0.0.0.0/8",
"10.0.0.0/8",
"100.64.0.0/10",
"127.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.0.0.0/24",
"192.0.2.0/24",
"192.168.0.0/16",
"198.18.0.0/15",
"198.51.100.0/24",
"203.0.113.0/24",
"::1/128",
"fc00::/7",
"fe80::/10",
"geoip:cn"
],
"outboundTag": "direct"
}
]
}
}
}
配置好后应该可以代理成功。如果失败,请检查客户端和服务端的错误日志/访问日志排查问题。如有疑惑,还可以加入V2Ray的telegram组群询问大佬。
IV. 后续步骤
至此,所谓“H2+TLS+Web”的配置就完成了。当然,此时前端站点还是我们当初用来测试的那个静态页面。不论是从伪装效果还是VPS的利用讲都算不上令人满意。下一步,我们可以将VPS改造成个人博客,图床,或者私有云。不论选择哪一种,都会涉及新软件的安装,以及Caddy配置的变更。在选择前端站的过程中,一定要事先查清是否可以由Caddy反代,并且运行上不和V2Ray冲突再尝试建站,并记得做好备份。
1 条评论
medking · 09/27/2018 下午9:16
关于配置文件 兄弟你有没有兴趣再弄一篇文章出来啊 现在更新了很多新特性 我感觉目前没有文章能对配置文件讲的很好 特别是H2+TLS+WEB这种