文章正文内容

前言

今天在帮一个粉丝调试他的家庭实验室(Home Lab)时,遇到了一个让人极其抓狂的问题:运营商把宽带的80和443端口封死了。

这就导致了一个很尴尬的局面:明明买了漂亮的域名,部署了牛逼的微服务,结果访问的时候非得在后面拖个“小尾巴”,变成 https://www.my-site.com:8443 或者 http://www.my-site.com:8080

作为一个有代码洁癖的全栈开发,这种 URL 简直是对审美的侮辱!难道没有 80/443 就不能优雅访问了吗?

当然不是!今天就把我压箱底的两套解决方案分享给大家,无论你是想“白嫖”还是想“硬核自建”,总有一款适合你。


目录

  1. 方案一:Cloudflare Tunnel (Zero Trust) —— 免公网IP的神器
  2. 方案二:FRP + 廉价VPS中转 —— 只有全栈才懂的极致掌控
  3. 避坑指南 & 经验总结
  4. 文末总结

1. 方案一:Cloudflare Tunnel (Zero Trust) —— 免公网IP的神器

如果你不想买额外的服务器,且域名托管在 Cloudflare,这是目前最完美的方案。它通过在你的内网服务器运行一个守护进程,主动向 Cloudflare 建立加密隧道。

原理图:

User -> Cloudflare Edge -> (加密隧道) -> 你的内网服务器(端口任意)

✅ 核心优势
  • 无需公网IP:大内网也能穿透。
  • 无需开防火墙:不需要服务器对外暴露任何端口。
  • 自动HTTPS:CF 自动给你颁发证书。
🛠️ 实战配置 (Docker版)

假设你的服务运行在本地的 localhost:3000

第一步:获取 Token
去 Cloudflare Zero Trust 面板 -> Access -> Tunnels -> Create a tunnel,你会得到一段包含 Token 的安装命令。

第二步:编写 Docker Compose
直接在你的服务器上跑这个容器:

# docker-compose.yml
version: '3.8'

services:
  tunnel:
    image: cloudflare/cloudflared:latest
    container_name: cf-tunnel
    restart: unless-stopped
    # 这里的 command 是你在 CF 后台获取的,注意替换你的 token
    command: tunnel run --token eyJhIjoi....(你的超长token)
    network_mode: host # 建议使用 host 模式方便访问本地服务,或者将服务加入同一网络

第三步:配置域名映射
回到 Cloudflare 控制台,在 Tunnel配置页面的 Public Hostname 中:

  • Subdomain: blog (比如)
  • Domain: yourdomain.com
  • Service: http://localhost:3000

搞定! 现在直接访问 https://blog.yourdomain.com,没有端口号,自带绿锁,完美!


2. 方案二:FRP + 廉价VPS中转 —— 只有全栈才懂的极致掌控

如果你的网络环境连接 Cloudflare 较慢,或者想完全掌握数据链路,这个方案是首选。我们需要一台有公网IP且开放80/443端口的廉价VPS(比如阿里云99元机,或海外5刀机)做中转。

架构设计 (Mermaid):

架构设计

🛠️ 第一步:服务端配置 (VPS)
  1. 安装 frps (服务端)
    下载对应的 release 包,编辑 frps.toml (新版配置):

    # frps.toml
    bindPort = 7000       # frp 通讯端口
    vhostHTTPPort = 8080  # http 转发端口(不用80,留给Nginx)
    auth.token = "MySecretKey123" # 安全令牌,必须改!
    
  2. 配置 Nginx 反向代理 (关键步骤)
    我们不让用户直接访问 8080,而是访问 Nginx 的 443,再由 Nginx 转发给 FRP。

    # /etc/nginx/conf.d/blog.conf
    server {
        listen 80;
        listen 443 ssl http2;
        server_name blog.yourdomain.com;
    
        # SSL证书配置 (使用 acme.sh 或 certbot 生成)
        ssl_certificate /etc/nginx/ssl/fullchain.cer;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.key;
    
        location / {
            # 转发到本机的 frp vhost 端口
            proxy_pass http://127.0.0.1:8080; 
            
            # 标准代理头
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
🛠️ 第二步:客户端配置 (内网服务器)

编辑 frpc.toml

# frpc.toml
serverAddr = "x.x.x.x" # VPS的公网IP
serverPort = 7000
auth.token = "MySecretKey123"

[[proxies]]
name = "web-blog"
type = "http"
localIP = "127.0.0.1"
localPort = 3000       # 你本地真实服务的端口
customDomains = ["blog.yourdomain.com"]

启动后,流量路径:用户 -> VPS Nginx(443) -> VPS FRP(8080) -> 内网 FRP -> 内网服务(3000)
虽然路径长了点,但用户体验是完美的 HTTPS 直连!


3. 🛡️ 踩坑/注意点 (资深经验)

  1. Cloudflare 减速警告
    在国内部分网络环境下,Cloudflare 的 Anycast 节点可能会绕路,导致访问延迟较高。如果你的服务是国内用户为主,建议慎用,或者使用优选 IP(风险自负)。

  2. Nginx Header 丢失问题
    在方案二中,一定要在 Nginx 里加上 proxy_set_header Host $host;。因为 frp 是根据 Host 域名来区分不同的代理服务的,如果不传 Host,frp 不知道要把请求转给谁。

  3. 安全性(必看)

    • FRP Token:千万别用默认弱密码,否则别人能扫描到你的 frps 端口并借用你的服务器搭梯子,导致你的 VPS 被封!
    • Docker 权限:内网跑 Cloudflare Tunnel 时,尽量不要挂载 /var/run/docker.sock,除非你清楚自己在做什么。
  4. 备案问题
    如果你的 VPS 是国内的(阿里云/腾讯云),通过域名访问必须备案,否则 80/443 端口会被云厂商拦截。这也是很多人选择香港或海外 VPS 做中转节点的原因。


4. 总结

  • 想省心、省钱、无公网IP 👉 选 Cloudflare Tunnel
  • 追求速度、已有VPS、需要完全掌控 👉 选 FRP + Nginx

无论哪种方法,都能让你告别丑陋的端口号,像大厂一样优雅地提供服务!


✍️ 互动

兄弟们,你们在部署家庭服务器时还遇到过哪些奇葩的网络坑?是公网 IP 突然变了,还是 NAT 类型限制?
欢迎在评论区留言吐槽!如果你觉得这篇教程解决了你的强迫症,请点赞、收藏支持一波,这对我很重要!👇

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐