跳至正文

WebSocket+TLS+CDN+Web,Apache2 部署V2Ray

网上教程或多或少有些错误,这里做一些完善、总结

这篇文章参考了官方文档、白话文教程Github issuehttps://ferrummagnus.com/2017/12/22/v2ray-websocket-tls-apache/,但你完全没有必要去查看它们。

前提条件:你有一台使用 Apache2 建立了博客的服务器。

我的境遇:架设博客的服务器IP被墙,不想换IP且希望保持国内访问与支持国际代理服务。

获取CDN服务

你可以考虑选择 cloudflare 作为你的CDN服务商。

具体步骤不再阐述,网上有很多。

配置 Apache

我们假设,你已经有了一个可以正常运行的V2Ray环境和Apache2。

1. 在服务器上开启以下 Apache 模组

sudo a2enmod ssl
sudo a2enmod proxy
sudo a2enmod proxy_wstunnel
sudo a2enmod proxy_http
sudo a2enmod rewrite
sudo a2enmod headers

2. 修改Apache 配置文件

我们找到配置文件,一般在 /etc/apache2 文件夹下。

一般,我们可以在该目录下找到sites-available(可用的配置文件) 和 sites-enabled(启用的配置文件)

我们进入 sites-enabled,找到 443(即 HTTPS 配置文件,例如:000-default-le-ssl.conf)。

把以下配置加到<VirtualHost></VirtualHost>之间

<LocationMatch "/{ws_path}}/">
	ProxyPass ws://127.0.0.1:{port}/{ws_path}/ upgrade=WebSocket
	ProxyAddHeaders Off
	ProxyPreserveHost On
	RequestHeader set Host %{HTTP_HOST}s
	RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
</LocationMatch>

例如,我的配置文件如下所示:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf


ServerName www.xzos.net
Include /etc/letsencrypt/options-ssl-apache.conf
ServerAlias xzos.net
SSLCertificateFile /etc/letsencrypt/live/www.xzos.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.xzos.net/privkey.pem

<LocationMatch "/ray/">
        ProxyPass ws://127.0.0.1:1080/ray/ upgrade=WebSocket
        ProxyAddHeaders Off
        ProxyPreserveHost On
        RequestHeader set Host %{HTTP_HOST}s
        RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
</LocationMatch>
</VirtualHost>
</IfModule

3. 重启 Apache 服务

sudo systemctl restart apache2.service

这时,你通过浏览器访问 https://<你的域名>/ray/ 应该是这样的

配置 V2Ray(参考白话文教程,但有所不同)

V2Ray 配置文件

服务器 V2Ray 配置

{
  "inbounds": [
    {
      "port": 1080,
      "listen":"127.0.0.1",//只监听 127.0.0.1,避免除本机外的机器探测到开放了 10000 端口,docker运行需要0.0.0.0
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "b831381d-6324-4d53-ad4f-8cda48b30811",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
        "path": "/ray/" // 这里是 “/ray/”
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    }
  ]
}

客户端 V2Ray 配置

{
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      },
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "xzos.net",
            "port": 443,
            "users": [
              {
                "id": "b831381d-6324-4d53-ad4f-8cda48b30811",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "wsSettings": {
          "path": "/ray/"  // 这里是 “/ray/”
        }
      }
    }
  ]
}

Docker 运行 V2Ray

可以参考 Docker 部署 V2Ray

docker run -dit --restart unless-stopped -d --name v2ray -v $HOME/.config/v2ray/config.json:/etc/v2ray/config.json -p 127.0.0.1:1080:1080 v2ray/official v2ray -config=/etc/v2ray/config.json

注意事项(参考白话文教程,但有所不同)

最后启动重启V2Ray服务即可

Emjoy!:)

NOTE:推荐阅读客户端负载均衡教程

标签:

《WebSocket+TLS+CDN+Web,Apache2 部署V2Ray》有19个想法

  1. Pingback: 利用Appche2,实现V2ray的WebSocket+TLS+Web伪装 - 无名神殿

    1. 可以,可以使用 header 代替 url 进行分流(这部分似乎 Nginx 的资料更多)。

  2. Pingback: v2ray-build-up-tutorial-advanced - BobMaster's Blog

  3. 感谢分享,网上都是一大堆从零开始的教程,对于有一些半成品环境的情况反倒不知道该从哪里下手了,按照文中的方法成功了,有个地方想说明一下:apache的配置端口、v2ray的端口、chrome代理插件switchyomega的端口都要一致,也就是你文中的1080,在这个问题上排了半天雷,总算搞定了,但还不明白其中的原理,不知道是否必须一致才行。

    1. 注意,你可能需要学习一下网络端口相关知识
      服务端的 Apache 为 443 端口的原因:你需要伪造访问网站的访问行为,一般使用https端口而不是高位端口(端口无所谓,只是高位端口容易被封)
      服务端的 V2ray 为 1080 端口的原因:个人习惯,随便改(反正是服务器内部转发流量)
      客户端的 V2ray 为 1080 端口的原因:同上

      所以,端口并不是要点,走哪个道开哪个门即可

  4. 我在一篇文章中看到过,如果使用cloudflare的DNS服务,就不能使用CDN(DNS设置里面的cloudflare图标是灰色而不是黄色)

    1. 以我的配置方法来说,直接使用 Cloudflare 的 DNS,并在 Proxy status 项选择 Proxied(橘黄色云朵图标) 即可我的网站 DNS 配置截图

  5. Pingback: 记v2ray进阶操作达成 – Joynaruto

  6. 感谢博客分享,研究apache + tls + ws N久,尝试了多个教程,终于在您这个搞定。

    严重感谢 🙂

    1. 这个不太了解,只是因为我这边用 V2ray 官网的不能用。
      就去看了一下 Apache 的官方资料,自己改了一下
      所有的资料均在文章中注明

  7. 启动apache服务的时候,指向 ProxyPass ws://127.0.0.1:1080/ray/ upgrade=WebSocket 这条有问题,status反馈
    ProxyPass unknown Worker parameter
    查了各种文档,也没有解决,请教大佬怎么处理。各种模块已经加载了的。

  8. 您好,我使用您的方法去配置之后,开启CDN之前连接正常,开启CDN之后连接失败不知道是为什么

    1. 一般来说,套一层 CDN 是避免主机IP被封,利用 CDN 服务器回源数据。
      我觉得,你这个情况说明服务器配置没问题,但是可能需要确认一下你的设备访问 CDN 是否正常(客户端)和 CDN 配置是否正常(服务端)

    1. 所以,我一般选择复制命令🙃。
      当然,也你可以选择 docker-compose😋。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

🌍 Language