期望效果

通过个人解析的域名esxi.yionr.cn访问本地内网的esxi后台,并且能操控每个虚拟机。

esxi域账号 esxi绑定域名_登录页面

前言

搭建的方式有很多种,但是我在网上暂时没看到有很完善的教程,遂着笔此文。

阅读要求

本篇文章适合会自己简单配置使用nginx(SSL)、frp的玩家阅读。

实验环境与过程

实验环境

局域网环境

  • esxi 的ip为 192.168.1.5 ,本地第一次通过浏览器访问会出现证书错误的页面。
  • esxi 中有一台虚拟机用来做反向代理,ip 为 192.168.1.4,下文称此机器为代理机

云端环境

  • 阿里云ECS中安装 frps 和 nginx。
  • 一个申请了 SSL 证书的域名地址esxi.yionr.cn

双方的 nginx 均为最新版,frp 为 snowdreamtech/frp(s/c):0.31.2

过程

本地环境配置

代理机 nginx 配置本地随便一个不被占用的端口转发至 192.168.1.5,比如我使用的是 9651 端口

server{
    listen  9651;
    server_name     127.0.0.1;
    
    location / {
            proxy_pass https://192.168.1.5;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;

			proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

其中

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

这三句很重要,至于为什么在下文讲。

上一步配置成功并启动nginx之后,就能通过http://192.168.1.4:9651访问到 esxi 的登录界面了,而且并不会像直接访问 192.168.1.5 一样强制转换为https然后警告证书错误,这一点很重要。

esxi域账号 esxi绑定域名_SSL_02

然后配置 frpc,最普通不过的配置:

[common]
server_addr = xxx
server_port = 7000
token = xxx

[yionr-esxi]
type = http
local_ip = 127.0.0.1
local_port = 9651
custom_domains = esxi.yionr.cn

云端环境配置

frps 也是用的最普通的配置,要和代理机中 frpc 配置的匹配上

[common]
bind_port = 7000
token = xxx
vhost_http_port = 520

然后配置 nginx,先配置强制https转发(如果不配置使用 https 访问,而直接用 http 访问的话,之后会出现问题,具体见下文问题解析:esxi 登录页面提示“请刷新你的浏览器”

server{
        listen  80;
        rewrite ^(.*)$  https://$host$1 permanent;
}

然后配置 esxi.yionr.cn 域名对应的配置文件。当 ngxin 收到https://esxi.yionr.cn的请求时,将请求转发到本地 520 端口处理。520 端口就是我的 frps 中配置的 http 接收端口vhost_http_port = 520

server{
        listen  443     ssl;
        server_name     esxi.yionr.cn;

        ssl_certificate cert/esxi.yionr.cn.pem;
        ssl_certificate_key     cert/esxi.yionr.cn.key;
        ssl_session_timeout     5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
                proxy_pass http://127.0.0.1:520;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-Forward-Proto https;
                
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
}

这里需要注意的也是 location 中最后这三句。和代理机中的一样,这个的功能是开启 nginx 对于 websocket 的支持,esxi 后台虚拟机控制台的图形化窗口就是通过 websocket 通信的,如果 nginx 不支持 websocket,会导致无法使用 esxi 的控制台功能。(具体见下文问题解析:esxi 控制台显示“无法连接”

至此,启动双方的 frp 和云主机的 nginx,就可以通过https://esxi.yionr.cn访问 esxi 了。以上就是我的成功案例,根据以上内容将 ip 地址证书域名端口等内容换成自己的即可,加油!

各种可能出现的问题解析

以下会有部分问题我不知道出现的原因。但是我会通过将上面的正解修改个别配置从而复现问题。阅读我的配置方式,至少应该能让你知道问题出现在哪个环节。

nginx502

esxi域账号 esxi绑定域名_SSL_03

导致502的原因是本地没使用nginx将https代理为http,而直接使用https作为frp传输类型

esxi域账号 esxi绑定域名_登录页面_04

然后在服务器 nginx 中也将请求转发至 frps 中配置的 vhost_https_port 端口

esxi域账号 esxi绑定域名_esxi域账号_05

esxi域账号 esxi绑定域名_esxi域账号_06

然后其实也能在 nginx 的日志中找到报错

esxi域账号 esxi绑定域名_esxi域账号_07

猜测是本地 esxi 证书错误导致的,所以我的解决方案在本地起了一个 nginx 将 https 转换为 http,frp 传输 http 流量

esxi控制台显示“无法连接”

esxi域账号 esxi绑定域名_esxi域账号_08

根据别的博客,这有可能是浏览器的问题,可以换个浏览器试试。如果不行的话,那就是 websocket 传输受阻了,可以打开浏览器 console 看看是否有提示

esxi域账号 esxi绑定域名_运维_09

如何解决?首先,frp 是不需要额外配置 websocket 通信的,所以问题只会出现在 nginx 中,我的方案中有两个地方使用到了 nginx,所以本地和云主机 nginx 的配置文件对应地方都要加上以下三句才能让 websocket 通信通顺。

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

具体配置见正文。

esxi登录页面提示“请刷新你的浏览器”

esxi域账号 esxi绑定域名_运维_10

(此时服务器端的配置)

esxi域账号 esxi绑定域名_运维_11

以上教程中,如果在服务器端 nginx 不配置 SSL,直接通过 http80 端口接收 esxi.yionr.cn 的话,就会出现这个问题。