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这种

发表评论