0. 前言

今年的形势非常严峻,年中的时候未雨绸缪准备了下55R,结果没多久就不行了,现在明显是被墙嗅探到,使用几分钟之后就IP无法ping通,停止使用后IP恢复。鉴于55的作者及55R的作者相继仙隐,放弃这个软件是比较正确的选择。找了一圈,看来只有v2ray还能看一看。

1. V2Ray

几个信息来源这里简单列下:

文章:

  • V2Ray安全混淆教程:用的工具有点小众,作为程序员可以不需要这个工具,拓扑结构可以看下
  • V2Ray安装使用手记:比较通俗易懂的一篇文章,推荐
  • WebSocket:其实就是列表第一篇教程的官方推荐三方教程,所以看这篇就够

2. 拓扑结构

主要可以看这幅图: 拓扑结构

文字描述简单来说就是:
别的代理都是直接客户端穿墙使用TCP、HTTP或自定义协议和墙外的服务器连接。
V2Ray的这套方案则是在墙外做一个启用HTTPS的Nginx服务,使用本地的客户端和墙外的Nginx以WS协议进行连接(这就和一个真正的网站行为一模一样了)。然后在Nginx背后用代理进行内容的访问。
这样的解决方案墙是无法分辨到底是一个代理服务器还是一个正常用户在用HTTPS访问网站,HTTPS也保证了墙无法探知流量的内容。

3. 安装

3.1 V2Ray本体

官方有提供安装脚本,直接使用即可:

bash <(curl -L -s https://install.direct/go.sh)

几个位置信息:

bin命令:/usr/bin/v2ray/v2ray
配置文件:/etc/v2ray/config.json
service:/lib/systemd/system/v2ray.service
日志指定是放在配置文件里的:log.access 和 log.error,一般放在:/var/log/v2ray/access.log 和 /var/log/v2ray/error.log

3.2 安装nginx

apt-get install nginx

nginx的几个信息:

配置路径:/etc/nginx
www路径:/var/www/html
日志:/var/log/nginx

3.3 安装证书

参考这篇文章:使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书

安装 acme.sh 命令:

curl https://get.acme.sh | sh
source ~/.bashrc

申请证书:

acme.sh --issue -d ${domain} -w /var/www/html

[email protected]:~/opt# acme.sh –issue -d ${domain} -w /var/www/html
[Tue Oct 24 09:00:39 UTC 2017] Registering account
[Tue Oct 24 09:00:40 UTC 2017] Registered
[Tue Oct 24 09:00:40 UTC 2017] Update account tos info success.
[Tue Oct 24 09:00:40 UTC 2017] ACCOUNT_THUMBPRINT=’…’
[Tue Oct 24 09:00:40 UTC 2017] Creating domain key
[Tue Oct 24 09:00:40 UTC 2017] The domain key is here: /root/.acme.sh/${domain}/${domain}.key
[Tue Oct 24 09:00:40 UTC 2017] Single domain=’${domain}’
[Tue Oct 24 09:00:40 UTC 2017] Getting domain auth token for each domain
[Tue Oct 24 09:00:40 UTC 2017] Getting webroot for domain=’${domain}’
[Tue Oct 24 09:00:40 UTC 2017] Getting new-authz for domain=’${domain}’
[Tue Oct 24 09:00:41 UTC 2017] The new-authz request is ok.
[Tue Oct 24 09:00:41 UTC 2017] Verifying:${domain}
[Tue Oct 24 09:00:44 UTC 2017] Success
[Tue Oct 24 09:00:44 UTC 2017] Verify finished, start to sign.
/root/.acme.sh/acme.sh: line 1819: warning: command substitution: ignored null byte in input
[Tue Oct 24 09:00:45 UTC 2017] Cert success.
—–BEGIN CERTIFICATE—–

—–END CERTIFICATE—–
[Tue Oct 24 09:00:45 UTC 2017] Your cert is in /root/.acme.sh/${domain}/${domain}.cer
[Tue Oct 24 09:00:45 UTC 2017] Your cert key is in /root/.acme.sh/${domain}/${domain}.key
[Tue Oct 24 09:00:45 UTC 2017] The intermediate CA cert is in /root/.acme.sh/${domain}/ca.cer
[Tue Oct 24 09:00:45 UTC 2017] And the full chain certs is there: /root/.acme.sh/${domain}/fullchain.cer

安装证书:

acme.sh --installcert -d ${domain} \
        --keypath       /var/www/ssl/${domain}.key  \
        --fullchainpath /var/www/ssl/${domain}.key.pem \
        --reloadcmd     "sudo service nginx force-reload"

[Tue Oct 24 09:23:54 UTC 2017] Installing key to:/var/www/ssl/${domain}.key
[Tue Oct 24 09:23:54 UTC 2017] Installing full chain to:/var/www/ssl/${domain}.key.pem
[Tue Oct 24 09:23:54 UTC 2017] Run reload cmd: sudo service nginx force-reload
[Tue Oct 24 09:23:54 UTC 2017] Reload success

生成 dhparam.pem 文件:

openssl dhparam -out /var/www/ssl/dhparam.pem 2048

修改 Nginx 配置:

http {
    # 新增
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    # 兼容其他老浏览器的 ssl_ciphers 设置请访问 https://wiki.mozilla.org/Security/Server_Side_TLS

    server {
        listen 80 default_server;
        # 新增
        listen 443 ssl;
        ssl_certificate         /var/www/ssl/${domain}.key.pem;
        ssl_certificate_key     /var/www/ssl/${domain}.key;
        # ssl_dhparam 
        ssl_dhparam             /var/www/ssl/dhparam.pem;

        # 其他省略
    }
}

使用检测工具查看安全评级:https://www.ssllabs.com/ssltest/analyze.html?d=${domain}

使用 crontab 命令查看 acme.sh 添加的证书刷新脚本:

crontab -l

并手动尝试执行,看下结果:

[Tue Oct 24 09:47:37 UTC 2017] ===Starting cron===
[Tue Oct 24 09:47:37 UTC 2017] Renew: ‘${domain}’
[Tue Oct 24 09:47:37 UTC 2017] Skip, Next renewal time is: Sat Dec 23 09:00:45 UTC 2017
[Tue Oct 24 09:47:37 UTC 2017] Add ‘–force’ to force to renew.
[Tue Oct 24 09:47:37 UTC 2017] Skipped ${domain}
[Tue Oct 24 09:47:37 UTC 2017] ===End cron===

时间没到命令并不会直接刷新证书,要尝试的话,可以添加 –force 来强制执行:

[Tue Oct 24 09:48:45 UTC 2017] ===Starting cron===
[Tue Oct 24 09:48:45 UTC 2017] Renew: ‘${domain}’
[Tue Oct 24 09:48:45 UTC 2017] Single domain=’${domain}’
[Tue Oct 24 09:48:45 UTC 2017] Getting domain auth token for each domain
[Tue Oct 24 09:48:45 UTC 2017] Getting webroot for domain=’${domain}’
[Tue Oct 24 09:48:45 UTC 2017] Getting new-authz for domain=’${domain}’
[Tue Oct 24 09:48:46 UTC 2017] The new-authz request is ok.
[Tue Oct 24 09:48:46 UTC 2017] ${domain} is already verified, skip http-01.
[Tue Oct 24 09:48:46 UTC 2017] Verify finished, start to sign.
/root/.acme.sh/acme.sh: line 1819: warning: command substitution: ignored null byte in input
[Tue Oct 24 09:48:47 UTC 2017] Cert success.
—–BEGIN CERTIFICATE—–

—–END CERTIFICATE—–
[Tue Oct 24 09:48:47 UTC 2017] Your cert is in /root/.acme.sh/${domain}/${domain}.cer
[Tue Oct 24 09:48:47 UTC 2017] Your cert key is in /root/.acme.sh/${domain}/${domain}.key
[Tue Oct 24 09:48:47 UTC 2017] The intermediate CA cert is in /root/.acme.sh/${domain}/ca.cer
[Tue Oct 24 09:48:47 UTC 2017] And the full chain certs is there: /root/.acme.sh/${domain}/fullchain.cer
[Tue Oct 24 09:48:47 UTC 2017] Installing key to:/var/www/ssl/${domain}.key
[Tue Oct 24 09:48:47 UTC 2017] Installing full chain to:/var/www/ssl/${domain}.key.pem
[Tue Oct 24 09:48:47 UTC 2017] Run reload cmd: sudo service nginx force-reload
[Tue Oct 24 09:48:47 UTC 2017] Reload success
[Tue Oct 24 09:48:47 UTC 2017] ===End cron===

3.4 配置V2Ray服务器

编辑配置文件/etc/v2ray/config.json

{
    "log": {
        "access": "/var/log/v2ray/access.log",
        "error": "/var/log/v2ray/error.log",
        "loglevel": "warning"
    },
    "inbound": {
        "port": 10000,
        "listen":"127.0.0.1",
        "protocol": "vmess",
        "settings": {
            "clients": [
                {
                    "id": "${UUID}",
                    "level": 1,
                    "alterId": 64,
                    "security": "aes-128-cfb"
                }
            ]
        },
        "streamSettings": {
            "network": "ws",
            "security": "auto",
            "wsSettings": {
                "connectionReuse": true,
                "path": "/serv/"
            }
        }
    },
    "outbound": {
        "protocol": "freedom",
        "settings": {}
    }
}

使用命令启动v2ray:

service v2ray start

3.5 配置Nginx

在之前安装HTTPS更改过的nginx配置中再添加一个location:

location /serv/ {
    proxy_redirect off;
    proxy_pass http://127.0.0.1:10000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
}

重启nginx:

service nginx restart

3.6 配置本地V2Ray

仍旧编辑config.json文件:

{
    "log": {
        "access": ".../log/access.log",
        "error": ".../log/error.log",
        "loglevel": "warning"
    },
    "inbound": {
        "port": 10801,
        "listen": "127.0.0.1",
        "protocol": "socks",
        "settings": {
            "auth": "noauth",
            "udp": false
        }
    },
    "outbound": {
        "protocol": "vmess",
        "settings": {
            "vnext": [
                {
                    "address": "${domain}",
                    "port": 443,
                    "users": [
                        {
                            "id": "${UUID}",
                            "level": 1,
                            "alterId": 64,
                            "security": "aes-128-cfb"
                        }
                    ]
                }
            ]
        },
        "streamSettings": {
            "network": "ws",
            "security": "tls",
            "wsSettings": {
                "connectionReuse": true,
                "path": "/serv/"
            },
            "tlsSettings": {
                "serverName": "${domain}",
                "allowInsecure": false
            }
        }
    }
}

启动本地的v2ray:

v2ray -config …/config.json

3.7 制作MAC启动文件

vim org.v2ray.macos.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>GroupName</key>
	<string>wheel</string>
	<key>KeepAlive</key>
	<dict>
		<key>SuccessfulExit</key>
		<false/>
	</dict>
	<key>Label</key>
	<string>org.v2ray.macos</string>
	<key>WorkingDirectory</key>
	<string>.../V2Ray/</string>
	<key>ProgramArguments</key>
	<array>
		<string>.../V2Ray/v2ray/v2ray</string>
		<string>-config</string>
		<string>config/config.json</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>StandardErrorPath</key>
	<string>.../V2Ray/log/error.log</string>
	<key>StandardOutPath</key>
	<string>.../V2Ray/log/access.log</string>
	<key>UserName</key>
	<string>root</string>
</dict>
</plist>

MAC启动

vim /Library/LaunchDaemons/org.v2ray.macos.plist
sudo launchctl load ./org.v2ray.macos.plist