前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx 根据子域名动态反向代理 暴露内网 HTTP 服务

Nginx 根据子域名动态反向代理 暴露内网 HTTP 服务

作者头像
iVampireSP.com
发布2023-10-21 10:33:02
8060
发布2023-10-21 10:33:02
举报
文章被收录于专栏:iVampireSPの物语iVampireSPの物语

由于我有个内网的服务器,做开发或测试使用,一个个的暴露或者反代 HTTP 服务很不方便。于是就有了这样的想法 —— 动态反向代理。

环境

*请注意,在实验室环境中,内网 IP 和 VMID 所对应。比如 VMID 为 101,则内网 IP 是 192.168.0.101。

虚拟化环境

Proxmox VE

反向代理

Nginx

操作系统

Debian11

虚拟化

LXC

内网网段

192.168.0.0/24

服务名称

VMID

端口

Nginx 反向代理

123

443

Nextcloud

101

80

Jupyter

117

8080

CodeServer

112

8080

所有服务监听 IP 都为 0.0.0.0,防火墙均已关闭。

名词解释

名词

解释

name

服务名称,在这里做区分作用。

vmid

虚拟机在 Proxmox VE 中的唯一 ID。

port

目标 IP 提供 HTTP 服务的端口,常见有 80, 8080。

解决方案

将域名泛解析到 Nginx 的服务器,将所有请求交给 Nginx。

在 Nginx 的 server_name 中,使用正则表达式进行模糊匹配,匹配 name, vmidport,并且过滤路由器等地址。

DNS

*.example -> your_nginx_server

安装 Nginx

不做过多说明。

代码语言:javascript
复制
apt install nginx-full -y

配置文件

仅需要编辑默认的 /etc/nginx/sites-available

代码语言:javascript
复制
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''   close;
}

server {

        listen 80 default_server;

        # 监听 IPv6
        listen [::]:80 default_server;

        listen 443 ssl http2;
        #listen 2083 ssl http2;

        # 这里改成你的证书(如有需要的话)。
        ssl_certificate    /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key    /etc/letsencrypt/live/example.com/privkey.pem;
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        add_header Strict-Transport-Security "max-age=31536000";
        error_page 497  https://$host$request_uri;
    
        # 这里是重点,使用正则来匹配 name, vmid 和 port。
        server_name ~^(?<name>\w+)\-(?<vmid>\w+)\-(?<port>\w+)\.example\.com example.com;


        # 如果 name 为空,则代表域名格式不合法。
        if ($name = "") {
                return 400 '没有输入服务名称,请检查域名格式。';
        }

        # 如果 vmid 为空,也就是没有填写被代理的机器。
        if ($vmid = "") {
                return 400 '格式中缺少被代理的 VMID。';
        }

        # 如果 port 为空,也就是没有指定要代理的端口。
        if ($port = "") {
                return 400 '格式中缺少端口。';
        }

        # 禁止一些 vmid,比如 路由器 等。
        if ($vmid = "1") {
                return 403;
        }

        if ($vmid = "2") {
                return 403;
        }

        if ($vmid = "254") {
                return 403;
        }


        # 禁止代理其自己。这里看上面的 环境 表格。
        if ($vmid = "123") {
                return 400 "无法代理自己。";
        }

        # 开始反向代理
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
      
                # 这里替换成你的内网网段。
                proxy_pass http://192.168.0.$vmid:$port;
                proxy_read_timeout 90;
        }
             

}

应用更改

先检查配置文件有无错误。

代码语言:javascript
复制
nginx -t

重新加载 Nginx。

代码语言:javascript
复制
sudo systemctl reload nginx

测试

访问 Jupyter

https://www-117-8080.example.com 访问在 117 上的 8080 端口的 www 服务。

其他服务依次。

测试成功图片
测试成功图片

其他

还有个 Nginx 搭建流媒体服务器的

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境
  • 名词解释
  • 解决方案
    • DNS
      • 安装 Nginx
        • 配置文件
        • 应用更改
        • 测试
        • 其他
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档