跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 基于主机名的 Nginx TCP 转发问题
未分類
17 2 月 2021

基于主机名的 Nginx TCP 转发问题

基于主机名的 Nginx TCP 转发问题

資深大佬 : pydiff 2

nginx 可以通过不同的主机名相同端口号来区分不同的 http 服务,今天想利用 nginx 来转发 tcp(非 http)的端口,找遍了百度都是引用了 sf 上的一个帖子的设置方法:地址:https://stackoverflow.com/questions/34741571/nginx-tcp-forwarding-based-on-hostname

stream {      map $ssl_preread_server_name $name {         vpn1.app.com vpn1_backend;         vpn2.app.com vpn2_backend;         https.app.com https_backend;         default https_default_backend;     }      upstream vpn1_backend {         server 10.0.0.3:443;     }      upstream vpn2_backend {         server 10.0.0.4:443;     }      upstream https_backend {         server 10.0.0.5:443;     }      upstream https_default_backend {         server 127.0.0.1:443;     }      server {         listen 10.0.0.1:443;         proxy_pass $name;         ssl_preread on;     } } 

然而我对着设置了却报这个错,

2021/02/20 09:31:32 [error] 23#23: *22 connect() failed (111: Connection refused) while connecting to upstream, client: 1.1.1.1, server: 192.168.0.5:9443, upstream: "127.0.0.1:9443", bytes from/to client:0/0, bytes from/to upstream:0/0  

实在找不到解决方法了想过来问问各位大佬

现在我已经用 8443 端口在跑着 web 服务了,还想通过改下主机名来代理不同的服务,如 mysql.test.com 代理 mysql 的 3306,redis.test.com 代理 redis 的 6379, 另外如果将上面的 upstream 配置中 443 改成 8443 则报错

nginx: [emerg] bind() to 192.168.0.5:8443 failed (98: Address already in use) 

想懂的大佬指点下

大佬有話說 (20)

  • 資深大佬 : fucUup

    大哥你标题写错了吧, tcp 转发应该是 https

    tcp 哪有域名的呀大哥

    全文都在讲 https sni 嗅探

  • 資深大佬 : villivateur

    域名是 http 里面的概念,tcp 不存在域名一说

  • 資深大佬 : ysc3839

    你贴的这段配置前面有一段话

    This allows Nginx to read the TLS Client Hello and decide based on the SNI extension which backend to use.

  • 主 資深大佬 : pydiff

    @fucUup 可能我的表达有误,我的需求就是 mysql.test.com:8443 代理 mysql 的 3306,redis.test.com:8443 代理 redis 的 6379,能搞定这个就行了

  • 資深大佬 : FingerLiu

    你这个只能按分配不同的端口来区分,不能通过域名,因为 tcp 连接没有域名的概念

  • 資深大佬 : delpo

    同上所说,stream 转发的是 tcp 链接,所以你的需求是不能通过这个方法完成的。
    但是如果你开启了 tls,就可以通过 pread server name 来进行区分,这个指令只能区分 client hello 的域名

  • 資深大佬 : noe132

    tcp 没有域名。你连接前域名已经被 dns 解析成 ip 后才建立的 tcp 链接。tcp 是根据 ip+端口区分链接的。

  • 資深大佬 : delpo

    pread –> preread

  • 資深大佬 : Qetesh

    haproxy 轻松四层负载

  • 資深大佬 : snoopyxdy1

    @pydiff 也可以实现,配置 2 台 nginx 服务器,然后将域名 mysql.test.com 和 redis.test.com 分别指向这 2 台 nginx 服务器的 ip 地址即可

  • 資深大佬 : iseki

    做不到的吧,这个功能是 TLS SNI proxy,得是带有 SNI 的 TLS 链接才起作用

  • 主 資深大佬 : pydiff

    @FingerLiu
    @delpo
    @noe132 好的,学习了,多谢大佬指点

  • 主 資深大佬 : pydiff

    @Qetesh 没用过,改天有空时试试

  • 資深大佬 : also24

    原理上的错误前面很多人说了,不多赘述。

    你这个原始需求也有点奇怪啊,为什么要把 mysql 和 redis 跑在 80 端口呢?

    直接:
    mysql.test.com:3306

  • 資深大佬 : also24

    直接:

    mysql 点 test 点 com:3306
    redis 点 test 点 com:6379

    这样使用不好么

    (前面没打完不小心按到了回复)

  • 主 資深大佬 : pydiff

    @also24 因为不想映射太多端口号出来呀,想着用多个主机名来区分,还容易记

  • 資深大佬 : also24

    @pydiff #16
    emmmm 反正前面已经很多人科普了,你的思路在原理上是不可行的,还是按常规操作来吧。
    (其实到也不是完全不可行,自己做一套解析协议的分发,也许可以做到)

  • 主 資深大佬 : pydiff

    @also24 #17
    这个还是算了,菜鸡一个,哪会这种东西

  • 資深大佬 : xinyifly

    我也作过这个尝试,如果我没理解错的话,我再详细解释一下 @noe132 的答案:

    1. mysql 客户端收到 mysql.test.com:8443 的连接配置
    2. mysql 通过操作系统的 DNS 功能查询到 mysql.test.com 的 ip 为 69.172.200.109
    3. mysql 向 69.172.200.109:8443 发起连接

    对于 redis 也是一样的。

    所以你可以看到,对于提供 TCP 服务(非 HTTP )的服务器,是收不到域名(或主机名)信息的。

    总结:对于目前大部分基于 TCP 而非 HTTP 的服务而言,想通过域名或主机名区分流量是不可能的,因为客户端并未发送域名(或主机名)信息。

    其它思路:Linux 内核提供了多个服务复用同一个端口的功能,也有通过嗅探连接类型作转发的代理服务(比如 sslh ),我没有尝试过,主有需要可以参考一下。

  • 主 資深大佬 : pydiff

    @xinyifly #19
    好的,谢谢解答哈

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具