综合

网站映射

时间:2010-12-5 17:23:32  作者:娱乐   来源:百科  查看:  评论:0
内容摘要:去年帮朋友处理一个线上问题,折腾到凌晨两点。他公司内网跑着一套测试环境,想让外地的同事访问,结果路由器端口转发配了半天没通。我远程连过去看了一眼,问题不在路由器——他把内网服务的端口映射到了公网,但服

去年帮朋友处理一个线上问题,网站映射折腾到凌晨两点。网站映射他公司内网跑着一套测试环境,网站映射想让外地的网站映射同事访问,结果路由器端口转发配了半天没通。网站映射我远程连过去看了一眼,网站映射问题不在路由器——他把内网服务的网站映射端口映射到了公网,但服务本身绑定的网站映射监听地址是127.0.0.1。外面请求进来,网站映射服务根本不接。网站映射

这就是网站映射网站映射最容易被忽略的一层:你以为在路由器上开了门,可屋里的网站映射人压根没打算见客。

映射到底在做什么

说白了,网站映射网站映射就是网站映射给一个网络地址找个“替身”。外部用户访问的网站映射是公网IP的某个端口,实际处理请求的可能是内网另一台机器的另一个端口。中间那层做转换的东西,可以是一台路由器、一台Nginx服务器、或者一段代码。

最常见的场景:公司只有一条宽带、一个公网IP,但内部有OA、GitLab、监控面板好几个服务都要对外。不可能给每个服务拉一条专线。于是用Nginx做反向代理,根据域名或路径把请求分发到不同内网机器。用户访问 git.company.com 和 oa.company.com,DNS都指向同一个IP,Nginx看域名决定转给谁。

这个过程里,Nginx就是映射的执行者。它不生产内容,只做搬运和转发。

端口映射和反向代理,不是一回事

很多人把这两个混着说。端口映射(DNAT)工作在网络层,路由器把公网IP的8080端口直接“嫁接”到内网192.168.1.100的80端口。请求到了内网机器上,服务看到的来源IP是路由器的内网地址,不是真实客户端。反向代理工作在应用层,Nginx收到HTTP请求后重新发起一个请求给后端,可以通过X-Forwarded-For头把真实客户端IP传过去。

区别在哪?端口映射更“透明”,但灵活性差,一个端口只能对应一个内网服务。反向代理更“聪明”,能改请求头、能做SSL终止、能按URL路径分流,但配置错了更容易出问题。

我自己的博客用的是反向代理。一台VPS上跑了三个站点,Nginx根据server_name区分,每个站点各自有独立的SSL证书。如果换成端口映射,得用三个不同端口,访问时还得记端口号,体验差很多。

一个具体的配置案例

拿Nginx举例。假设内网有一台机器跑着Web服务,监听在192.168.1.50:3000。公网服务器上的Nginx配置大概长这样:

server {  listen 80; server_name app.example.com; location / {  proxy_pass http://192.168.1.50:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

这段配置做了几件事:监听80端口,匹配域名app.example.com,把请求转发给内网那台机器。同时把原始Host头和客户端IP塞进请求头里,后端服务才能知道到底是谁在访问。

少写proxy_set_header Host $host会怎样?后端服务可能根据Host头做重定向,结果跳转到一个内网地址,用户浏览器打不开。这种问题排查起来很烦,因为Nginx日志显示200,但用户看到的是超时。

内网穿透是另一条路

没有公网IP怎么办?家庭宽带、公司内网,很多时候拿不到公网地址。这时候用内网穿透工具,比如frp、ngrok、Cloudflare Tunnel。原理是内网机器主动向外建立一条长连接,外部请求通过这条隧道回到内网。

frp的配置很直观。服务端跑在有公网IP的机器上,客户端跑在内网。客户端告诉服务端:“我要把本地的3000端口暴露出去。”服务端分配一个公网端口,所有发到这个端口的请求,通过隧道转发到内网机器的3000端口。

这种方式的好处是不用动路由器,不用求网管开端口。代价是多了一层转发,延迟会高一点。我测过frp在普通宽带下的延迟,比直连大概多20到50毫秒。对网页浏览影响不大,但对实时性要求高的服务就得掂量一下。

几个容易踩的坑

SSL证书配在映射层还是后端?建议配在映射层。Nginx处理证书,后端只跑HTTP,省去每台机器都要续证书的麻烦。但要注意,如果后端服务生成的链接是http://开头的,用户从HTTPS页面点过去会被浏览器拦截。得让后端知道自己在HTTPS后面,通常通过X-Forwarded-Proto头来判断。

WebSocket连接容易被反向代理断开。Nginx默认的proxy_read_timeout是60秒,WebSocket长连接超过这个时间没数据就会被切。加两行配置:

proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

还有跨域。前端页面在a.com,API通过映射暴露在b.com,浏览器直接拦请求。要么后端加CORS头,要么把前端和API放在同一个域名下用路径区分。后者更省事,Nginx配一个location /api/转发就完了。

网站映射这事,表面看是配几条规则,实际上是对整个请求链路的一次梳理。哪一层做什么、数据怎么流、谁负责加密、谁负责转发,想清楚了再动手,比配完了再猜哪里出问题要快得多。

最近更新
热门排行
copyright © 2026 powered by 烟消火灭网   sitemap