1. TLS

从 v1.19 起引入了 TLS,TLS 中文译名是传输层安全,如果你没听说过,请 Google 了解一下。以下给出些我认为介绍较好的文章链接:

SSL/TLS协议运行机制的概述

传输层安全协议

1.1. 注册一个域名

如果已经注册有域名了可以跳过。TLS 需要一个域名,域名有免费的和有付费的,如果你不舍得为一个域名每年花点钱,用个免费域名也可以,但总体来说付费的会优于免费的。为了方便,在本文中我就忽略如何注册购买域名了。关于如何获取域名,具体搜索相关文章教程。

注册好域名之后务必记得添加一个 A 记录指向你的 VPS!

以下假设注册的域名为 mydomain.me,请将之替换成自己的域名。

1.2. 证书生成

TLS 是证书认证机制,所以使用 TLS 需要证书,证书也有免费付费的,同样的这里使用免费证书,证书认证机构为 Let's Encrypt。证书的生成有许多方法,这里使用的是比较简单的方法:使用 acme.sh 脚本生成,本部分说明部分内容参考于acme.sh README

证书有两种,一种是 ECC 证书(内置公钥是 ECDSA 公钥),一种是 RSA 证书(内置 RSA 公钥)。简单来说,同等长度 ECC 比 RSA 更安全,也就是说在具有同样安全性的情况下,ECC 的密钥长度比 RSA 短得多(加密解密会更快)。但问题是 ECC 的兼容性会差一些,Android 4.x 以下和 Windows XP 不支持。只要您的设备不是非常老的老古董,建议使用 ECC 证书。

以下将给出这两类证书的生成方法,请大家根据自身的情况自行选择其中一种证书类型。

证书生成只需在服务器上操作。

1.2.1. 安装 acme.sh

执行以下命令,acme.sh 会安装到 ~/.acme.sh 目录下。

  1. $ curl https://get.acme.sh | sh
  2. % Total % Received % Xferd Average Speed Time Time Time Current
  3. Dload Upload Total Spent Left Speed
  4. 100 671 100 671 0 0 680 0 --:--:-- --:--:-- --:--:-- 679
  5. % Total % Received % Xferd Average Speed Time Time Time Current
  6. Dload Upload Total Spent Left Speed
  7. 100 112k 100 112k 0 0 690k 0 --:--:-- --:--:-- --:--:-- 693k
  8. [Fri 30 Dec 01:03:32 GMT 2016] Installing from online archive.
  9. [Fri 30 Dec 01:03:32 GMT 2016] Downloading https://github.com/Neilpang/acme.sh/archive/master.tar.gz
  10. [Fri 30 Dec 01:03:33 GMT 2016] Extracting master.tar.gz
  11. [Fri 30 Dec 01:03:33 GMT 2016] Installing to /home/user/.acme.sh
  12. [Fri 30 Dec 01:03:33 GMT 2016] Installed to /home/user/.acme.sh/acme.sh
  13. [Fri 30 Dec 01:03:33 GMT 2016] Installing alias to '/home/user/.profile'
  14. [Fri 30 Dec 01:03:33 GMT 2016] OK, Close and reopen your terminal to start using acme.sh
  15. [Fri 30 Dec 01:03:33 GMT 2016] Installing cron job
  16. no crontab for user
  17. no crontab for user
  18. [Fri 30 Dec 01:03:33 GMT 2016] Good, bash is found, so change the shebang to use bash as preferred.
  19. [Fri 30 Dec 01:03:33 GMT 2016] OK
  20. [Fri 30 Dec 01:03:33 GMT 2016] Install success!

安装成功后执行 source ~/.bashrc 以确保脚本所设置的命令别名生效。

如果安装报错,那么可能是因为系统缺少 acme.sh 所需要的依赖项,acme.sh 的依赖项主要是 netcat(nc),我们通过以下命令来安装这些依赖项,然后重新安装一遍 acme.sh:

  1. $ sudo apt-get -y install netcat

1.2.2. 使用 acme.sh 生成证书

证书生成

执行以下命令生成证书:

以下的命令会临时监听 80 端口,请确保执行该命令前 80 端口没有使用

  1. $ sudo ~/.acme.sh/acme.sh --issue -d mydomain.me --standalone -k ec-256
  2. [Fri Dec 30 08:59:12 HKT 2016] Standalone mode.
  3. [Fri Dec 30 08:59:12 HKT 2016] Single domain='mydomain.me'
  4. [Fri Dec 30 08:59:12 HKT 2016] Getting domain auth token for each domain
  5. [Fri Dec 30 08:59:12 HKT 2016] Getting webroot for domain='mydomain.me'
  6. [Fri Dec 30 08:59:12 HKT 2016] _w='no'
  7. [Fri Dec 30 08:59:12 HKT 2016] Getting new-authz for domain='mydomain.me'
  8. [Fri Dec 30 08:59:14 HKT 2016] The new-authz request is ok.
  9. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip.
  10. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip http-01.
  11. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip http-01.
  12. [Fri Dec 30 08:59:14 HKT 2016] Verify finished, start to sign.
  13. [Fri Dec 30 08:59:16 HKT 2016] Cert success.
  14. -----BEGIN CERTIFICATE-----
  15. MIIEMTCCAxmgAwIBAgISA1+gJF5zwUDjNX/6Xzz5fo3lMA0GCSqGSIb3DQEBCwUA
  16. MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
  17. ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjEyMjkyMzU5MDBaFw0x
  18. NzAzMjkyMzU5MDBaMBcxFTATBgNVBAMTDHdlYWtzYW5kLmNvbTBZMBMGByqGSM49
  19. ****************************************************************
  20. 4p40tm0aMB837XQ9jeAXvXulhVH/7/wWZ8/vkUUvuHSCYHagENiq/3DYj4a85Iw9
  21. +6u1r7atYHJ2VwqSamiyTGDQuhc5wdXIQxY/YQQqkAmn5tLsTZnnOavc4plANT40
  22. zweiG8vcIvMVnnkM0TSz8G1yzv1nOkruN3ozQkLMu6YS7lk/ENBN7DBtYVSmJeU2
  23. VAXE+zgRaP7JFOqK6DrOwhyE2LSgae83Wq/XgXxjfIo1Zmn2UmlE0sbdNKBasnf9
  24. gPUI45eltrjcv8FCSTOUcT7PWCa3
  25. -----END CERTIFICATE-----
  26. [Fri Dec 30 08:59:16 HKT 2016] Your cert is in /root/.acme.sh/mydomain.me_ecc/mydomain.me.cer
  27. [Fri Dec 30 08:59:16 HKT 2016] Your cert key is in /root/.acme.sh/mydomain.me_ecc/mydomain.me.key
  28. [Fri Dec 30 08:59:16 HKT 2016] The intermediate CA cert is in /root/.acme.sh/mydomain.me_ecc/ca.cer
  29. [Fri Dec 30 08:59:16 HKT 2016] And the full chain certs is there: /root/.acme.sh/mydomain.me_ecc/fullchain.cer

-k 表示密钥长度,后面的值可以是 ec-256ec-3842048307240968192,带有 ec 表示生成的是 ECC 证书,没有则是 RSA 证书。在安全性上 256 位的 ECC 证书等同于 3072 位的 RSA 证书。

证书更新

由于 Let's Encrypt 的证书有效期只有 3 个月,因此需要 90 天至少要更新一次证书,acme.sh 脚本会每 60 天自动更新证书。也可以手动更新。

手动更新 ECC 证书,执行:

  1. $ sudo ~/.acme.sh/acme.sh --renew -d mydomain.com --force --ecc

如果是 RSA 证书则执行:

  1. $ sudo ~/.acme.sh/acme.sh --renew -d mydomain.com --force

由于本例中将证书生成到 /etc/v2ray/ 文件夹,更新证书之后还得把新证书生成到 /etc/v2ray。

1.2.3. 安装证书和密钥

ECC 证书

将证书和密钥安装到 /etc/v2ray 中:

  1. $ sudo ~/.acme.sh/acme.sh --installcert -d mydomain.me --fullchainpath /etc/v2ray/v2ray.crt --keypath /etc/v2ray/v2ray.key --ecc

RSA 证书

  1. $ sudo ~/.acme.sh/acme.sh --installcert -d mydomain.me --fullchainpath /etc/v2ray/v2ray.crt --keypath /etc/v2ray/v2ray.key

注意:无论什么情况,密钥(即上面的v2ray.key)都不能泄漏,如果你不幸泄漏了密钥,可以使用 acme.sh 将原证书吊销,再生成新的证书,吊销方法请自行参考 acme.sh 的手册

1.3. 配置 V2Ray

1.3.1. 服务器

  1. {
  2. "inbounds": [
  3. {
  4. "port": 443, // 建议使用 443 端口
  5. "protocol": "vmess",
  6. "settings": {
  7. "clients": [
  8. {
  9. "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297",
  10. "alterId": 64
  11. }
  12. ]
  13. },
  14. "streamSettings": {
  15. "network": "tcp",
  16. "security": "tls", // security 要设置为 tls 才会启用 TLS
  17. "tlsSettings": {
  18. "certificates": [
  19. {
  20. "certificateFile": "/etc/v2ray/v2ray.crt", // 证书文件
  21. "keyFile": "/etc/v2ray/v2ray.key" // 密钥文件
  22. }
  23. ]
  24. }
  25. }
  26. }
  27. ],
  28. "outbounds": [
  29. {
  30. "protocol": "freedom",
  31. "settings": {}
  32. }
  33. ]
  34. }

1.3.2. 客户端

  1. {
  2. "inbounds": [
  3. {
  4. "port": 1080,
  5. "protocol": "socks",
  6. "sniffing": {
  7. "enabled": true,
  8. "destOverride": ["http", "tls"]
  9. },
  10. "settings": {
  11. "auth": "noauth"
  12. }
  13. }
  14. ],
  15. "outbounds": [
  16. {
  17. "protocol": "vmess",
  18. "settings": {
  19. "vnext": [
  20. {
  21. "address": "mydomain.me", // tls 需要域名,所以这里应该填自己的域名
  22. "port": 443,
  23. "users": [
  24. {
  25. "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297",
  26. "alterId": 64
  27. }
  28. ]
  29. }
  30. ]
  31. },
  32. "streamSettings": {
  33. "network": "tcp",
  34. "security": "tls" // 客户端的 security 也要设置为 tls
  35. }
  36. }
  37. ]
  38. }

1.4. 验证

一般来说,按照以上步骤操作完成,V2Ray 客户端能够正常联网说明 TLS 已经成功启用。但要是有个可靠的方法来验证是否正常开启 TLS 无疑更令人放心。验证的方法有很多,我仅介绍一种小白化一点的,便是 Qualys SSL Labs's SSL Server Test

注意:使用 Qualys SSL Labs's SSL Server Test 要求使用 443 端口,意味着你服务器配置的 inbound.port 应当是 443

打开 Qualys SSL Labs's SSL Server Test,在Hostname 中输入你的域名,点提交,过一会结果就出来了。TLS - 图1

TLS - 图2这是对于你的 TLS/SSL 的一个总体评分,我这里评分为 A,看来还不错。有这样的界面算是成功了。

TLS - 图3这是关于证书的信息。从图中可以看出,我的这个证书有效期是从 2016 年 12 月 27 号到 2017 年的 3 月 27 号,密钥是 256 位的 ECC,证书签发机构是 Let's Encrypt,重要的是最后一行,TrustedYes,表明我这个证书可信。

1.5. 温馨提醒

V2Ray 的 TLS 不是伪装或混淆,这是完整、真正的 TLS。因此才需要域名和证书。后文提到的 WS(WebSocket) 也不是伪装。


1.6. 更新历史

  • 2017-08-06 加点提醒
  • 2017-12-31 修正文字错误
  • 2018-04-05 Update
  • 2018-11-17 V4.0+ 配置