Files
nexus/raw/Home Office/在Ubuntu上通过VPS+内网反向代理实现域名访问内网穿透.md
2026-04-27 16:26:34 +08:00

22 KiB
Raw Blame History

#vps #caddy #frp #reverse-proxy #troubleshooting #cloudflare #ubuntu

思路Cloudflare DNS 指向 公网上的一台VPSVPS 上运行 Caddy内网主机通过 frp 将服务暴露到 VPS本地 127.0.0.1 或某个端口VPS 反向代理到该端口。

  • 在 VPS 上运行 frpsfrp server
  • 在每个内网设备运行 frpc (frp client),将本地服务映射到 VPS 上的独立端口或域名映射frp 支持 http/https 映射,和 subdomain 映射需要 frp 企业/配置域名解析到 VPS
  • VPS 上的 Caddy 反向代理到 frps 映射端口127.0.0.1:xxxxx

frp 优点:专为内网穿透设计,支持 NAT、自动重连、Web 管理面板(可选)。推荐当你有多台设备和多端口时使用。 !IMG-20260313104655355.png !IMG-20260313104655497.png

前置共识(已知条件)

  • 域名:ishenwei.online(在阿里云 DNS/Cloudflare 控制台管理)

  • 内网服务:

    • NAS server192.168.3.17:5000(对应 nas.ishenwei.online
    • NAS mysql server192.168.3.17:3306(对应 mysql.ishenwei.online
    • Ubuntu1 n8n192.168.3.47:5678(希望对应 n8n.ishenwei.online
    • Ubuntu1 transmission: 192.168.3.47:9091(希望对应 transmission.ishenwei.online
    • Ubuntu1 Grafana: 192.168.3.47:3000(希望对应 grafana.ishenwei.online
  • 你有一台公网 VPSUbuntu可用于反代或做中继IP: 192.227.222.142(固定)

🧭 目标

  • 公网 VPSUbuntu公网 IP = 192.227.222.142
  • 内网 NAS (192.168.3.17:5000)
  • 内网 Ubuntu (192.168.3.47:5678)
  • 通过 frp 建立安全的反向隧道
  • 通过 Caddy 在 VPS 上为每个子域名提供 HTTPS 域名访问:
域名 映射目标
https://nas.ishenwei.online → NAS 192.168.3.17:5000
https://n8n.ishenwei.online → Ubuntu 192.168.3.47:5678
公网VPSfrps服务端
↓(公网端口转发)
192.227.222.142
通过 frp 反向代理访问内网主机
内网 Ubuntu (192.168.3.47) 启动 frpc
├─ n8n 服务 (5678)
├─ Transmission (9091)
└─ Grafana (3000)

🧱 拓扑图

Internet │ ▼ ┌──────────────────────────┐ │ VPS (192.227.222.142) │ │ - frps (监听 7000) │ │ - Caddy (80/443 TLS) │ │ ├─ nas.ishenwei.online → 127.0.0.1:15000 (映射NAS:5000) │ └─ n8n.ishenwei.online → 127.0.0.1:15678 (映射Ubuntu:5678) └──────────────────────────┘ ▲ ▲ │ frp tunnel │ frp tunnel ┌────────────┐ ┌────────────┐ │ NAS (192.168.3.17) │ │ Ubuntu (192.168.3.47) │ │ frpc.ini │ │ frpc.ini │ │ 映射5000→15000 │ │ 映射5678→15678 │ └────────────┘ └────────────┘

第 1 步Cloudflare DNS 配置

主机记录 记录类型 记录值 TTL
nas A 192.227.222.142 600
n8n A 192.227.222.142 600
Cloudflare Dashboard -> DNS
!IMG-20260313104655641.png

保存即可。
验证命令(任意机器执行):

dig nas.ishenwei.online +short # 应返回 192.227.222.142

🧩 第 2 步:在 VPS 安装 Caddy + frps

1 安装 Caddy

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list 
chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg 
chmod o+r /etc/apt/sources.list.d/caddy-stable.list 
sudo apt update 
sudo apt install caddy

cd Caddy 安装后会自动作为系统服务运行。


2 安装 frpfrp 服务端)

# 在 VPS 与内网主机都执行(分别下载到 /opt/frp
cd /opt 
sudo mkdir frp && cd frp 

FRP_VER=0.65.0   # 若有更新,可替换版本号 
curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz
tar xzf frp_${FRP_VER}_linux_amd64.tar.gz
sudo mv frp_${FRP_VER}_linux_amd64 /opt/frp

创建配置文件 /opt/frp/frps.ini

[common]
bind_addr = 0.0.0.0
bind_port = 7000


---
title: 前置共识(已知条件)
author: shenwei
tags: [caddy, cloudflare, frp, reverse-proxy, troubleshooting, ubuntu, vps]
---
---
title: 前置共识(已知条件)
source:
author: shenwei
published:
created:
description:
tags: [caddy, cloudflare, frp, reverse-proxy, troubleshooting, ubuntu, vps]
---

# Dashboard
dashboard_addr = 0.0.0.0
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = StrongPassword123!

# 认证 Token
token = Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs



创建 systemd 单元 /etc/systemd/system/frps.service

[Unit]
Description=frp server (frps)
After=network.target

[Service]
Type=simple
ExecStart=/opt/frp/frps -c /opt/frp/frps.ini
Restart=on-failure

[Install]
WantedBy=multi-user.target


启动:


sudo systemctl daemon-reload
sudo systemctl enable --now frps

验证:

sudo systemctl status frps
ss -ltnp | grep 7000

3 VPS 防火墙设置(允许必要端口)

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 7000/tcp   # frp server 端口
sudo ufw allow 7050 # frp server dashboard
sudo ufw allow 60022 # Ubuntu1 SSH
sudo ufw allow 60023 # NAS SSH
sudo ufw allow 60024 # Ubuntu2 SSH
sudo ufw allow 65005 # webdav
sudo ufw allow 63306 # NAS mysql
sudo ufw allow 60080 # NAS web
sudo ufw enable
sudo ufw status verbose

运行结果:

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
7000/tcp                   ALLOW IN    Anywhere
7500/tcp                   ALLOW IN    Anywhere
7050                       ALLOW IN    Anywhere
60022                      ALLOW IN    Anywhere
65005                      ALLOW IN    Anywhere
60023                      ALLOW IN    Anywhere
60021/tcp                  ALLOW IN    Anywhere
60021/udp                  ALLOW IN    Anywhere
63306                      ALLOW IN    Anywhere
60080                      ALLOW IN    Anywhere
60024                      ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
443/tcp (v6)               ALLOW IN    Anywhere (v6)
7000/tcp (v6)              ALLOW IN    Anywhere (v6)
7500/tcp (v6)              ALLOW IN    Anywhere (v6)
7050 (v6)                  ALLOW IN    Anywhere (v6)
60022 (v6)                 ALLOW IN    Anywhere (v6)
65005 (v6)                 ALLOW IN    Anywhere (v6)
60023 (v6)                 ALLOW IN    Anywhere (v6)
60021/tcp (v6)             ALLOW IN    Anywhere (v6)
60021/udp (v6)             ALLOW IN    Anywhere (v6)
63306 (v6)                 ALLOW IN    Anywhere (v6)
60080 (v6)                 ALLOW IN    Anywhere (v6)
60024 (v6)                 ALLOW IN    Anywhere (v6)

如果你想让 frp dashboard 从本地访问:ssh -L 7500:127.0.0.1:7500 ubuntu@192.227.222.142,然后本地打开 http://127.0.0.1:7500

🧩 第 3 步:在 内网NAS服务器 与内网 Ubuntu服务器 安装 frpc

两台机器都执行以下步骤(路径、端口配置不同)

2 安装 frpfrp 客户端)

# 在 VPS 与内网主机都执行(分别下载到 /opt/frp
cd /opt 
sudo mkdir frp && cd frp 

FRP_VER=0.65.0   # 若有更新,可替换版本号 
curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz
tar xzf frp_${FRP_VER}_linux_amd64.tar.gz
sudo mv frp_${FRP_VER}_linux_amd64 /opt/frp

3 内网 NAS192.168.3.17)配置

创建 /opt/frp/frpc.ini

[common]
server_addr = 192.227.222.142
server_port = 7000
token = Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs

# 每个本地服务一个 section
# nas 映射: 本地 5000 -> VPS 127.0.0.1:15000
[nas]
type = tcp
local_ip = 127.0.0.1
local_port = 5000
remote_port = 15000

# Navidrome: 本地 4533 -> VPS 127.0.0.1:4533
[navidrome]
type = tcp
local_ip = 127.0.0.1
local_port = 4533
remote_port = 14533

# Calibre: 本地 8083 -> VPS 127.0.0.1:18083
[calibre]
type = tcp
local_ip = 127.0.0.1
local_port = 8083
remote_port = 18083

[webdav]
type = tcp
local_ip = 127.0.0.1
local_port = 5005
remote_port = 65005

[miniflux]
type = tcp
local_ip = 127.0.0.1
local_port = 8080
remote_port = 18080

[zipline]
type = tcp
local_ip = 127.0.0.1
local_port = 3333
remote_port = 13333

[nas_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22

[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3307
remote_port = 63307

[nas_web]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 10080


创建 systemd 单元 /etc/systemd/system/frpc.service


[Unit]
Description=frp client
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target


启动:

sudo systemctl daemon-reload
sudo systemctl enable --now frpc
sudo systemctl status frpc

如需重启

sudo systemctl restart frpc

3 内网 Ubuntu192.168.3.47)配置

创建 /opt/frp/frpc.ini

[common]
server_addr = 192.227.222.142
server_port = 7000
token = Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs

# 每个本地服务一个 section
# n8n 映射: 本地 5678 -> VPS 127.0.0.1:15678
[n8n]
type = tcp
local_ip = 127.0.0.1
local_port = 5678
remote_port = 15678

# Transmission: 本地 9091 -> VPS 127.0.0.1:19091
[transmission]
type = tcp
local_ip = 127.0.0.1
local_port = 9091
remote_port = 19091

# Grafana: 本地 3000 -> VPS 127.0.0.1:13000
[grafana]
type = tcp
local_ip = 127.0.0.1
local_port = 3000
remote_port = 13000

# 🆕 SSH 映射
[ubuntu_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 60022

[homarr]
type = tcp
local_ip = 127.0.0.1
local_port = 7575
remote_port = 17575

[superset]
type = tcp
local_ip = 127.0.0.1
local_port = 8777
remote_port = 18777

[tk]
type = tcp
local_ip = 127.0.0.1
local_port = 8888
remote_port = 18888

创建 systemd 单元 /etc/systemd/system/frpc.service


[Unit]
Description=frp client 
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.ini
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

启动:

sudo systemctl daemon-reload
sudo systemctl enable --now frpc
sudo systemctl status frpc

如需重启

sudo systemctl restart frpc

🧩 第 4 步VPS 上配置 Caddy 反向代理

编辑 /etc/caddy/Caddyfile

# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.

:80 {
        # Set this path to your site's directory.
        root * /usr/share/caddy

        # Enable the static file server.
        file_server

        # Another common task is to set up a reverse proxy:
        # reverse_proxy localhost:8080

        # Or serve a PHP site through php-fpm:
        # php_fastcgi localhost:9000
}
transmission.ishenwei.online {
    reverse_proxy 127.0.0.1:19091
    #log {
    #    output file /var/log/caddy/transmission.access.log
    #    format single_field common_log
    #}
}

grafana.ishenwei.online {
    reverse_proxy 127.0.0.1:13000
    #log {
    #    output file /var/log/caddy/grafana.access.log
    #    format single_field common_log
    #}
}

nas.ishenwei.online {
    reverse_proxy 127.0.0.1:15000
}

navidrome.ishenwei.online {
    reverse_proxy 127.0.0.1:14533
}

calibre.ishenwei.online {
    reverse_proxy 127.0.0.1:18083
}
dashboard.ishenwei.online {
    reverse_proxy 127.0.0.1:17575
}
miniflux.ishenwei.online {
    reverse_proxy 127.0.0.1:18080
}
zipline.ishenwei.online {
    reverse_proxy 127.0.0.1:13333
}
superset.ishenwei.online {
    reverse_proxy 127.0.0.1:18777
}
tk.ishenwei.online {
    reverse_proxy 127.0.0.1:18888
}
web.ishenwei.online {
    reverse_proxy 127.0.0.1:10080
}

# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile


如需重启 Caddy


sudo systemctl reload caddy
sudo systemctl status caddy

或者:

#彻底重启 Caddy 服务(强制方式)
sudo systemctl restart caddy

Caddy 会自动申请并更新 Let's Encrypt 证书,提供 HTTPS 访问。

如果 systemctl 无响应Caddy 卡死或崩溃)

sudo systemctl stop caddy 
sudo pkill -9 caddy       # 杀掉所有残留进程 sudo systemctl start caddy

验证 Caddyfile 语法(最关键)

sudo caddy validate --config /etc/caddy/Caddyfile

如果返回: Valid configuration 说明语法正确,可以重载。 如果报错Caddy 会指明哪一行有问题,例如: parse error: unknown directive at line 12 你需要根据提示修正。

🧩 第 5 步:测试验证

1 在 VPS 上

curl http://127.0.0.1:15678
curl http://127.0.0.1:15000
curl http://127.0.0.1:19091
curl http://127.0.0.1:13000

ss -ltnp | egrep '15678|19091|13000|7000|60022'
root@racknerd-66f115a:~# ss -ltnp | egrep '15678|19091|13000|7000'
LISTEN 0      4096               *:19091            *:*    users:(("frps",pid=59421,fd=10))
LISTEN 0      4096               *:13000            *:*    users:(("frps",pid=59421,fd=8))
LISTEN 0      4096               *:15678            *:*    users:(("frps",pid=59421,fd=9))
LISTEN 0      4096               *:7000             *:*    users:(("frps",pid=59421,fd=6))

2 在浏览器中

访问:

应能通过 HTTPS 打开对应服务。

🧩 第 6 步:可选安全加固

1 Caddy 基础认证

在 Caddyfile 的 n8n.ishenwei.online 段中加入:

basicauth /* {     admin JDJhJDE0JDN3ZXVhV2YyZG9SY2hvYzVmZ2h3QUlVblpOMU4vS1ptcENrSlhySElMb3l5dytOMkh0Tk93 }

caddy hash-password 生成密码散列。

2 防火墙

只放行必要端口:

sudo ufw allow 22,80,443,7000/tcp 
sudo ufw enable

🧩 第 7 步Dashboard可选

访问:


http://192.227.222.142:7500 

用户名admin 密码StrongPassword123!

你可以实时查看 frp 客户端的连接状态。

FRP 架构已经稳定运行HTTP 反代验证通过),接下来要实现 通过域名 ubuntu1.ishenwei.online SSH 到内网的 Ubuntu (192.168.3.47:22)

⚠️ 重点提醒(安全性)
SSH 穿透与 HTTP 不同,它是纯 TCP 流量,不经 CaddyCaddy 只处理 HTTP/HTTPS所以

  • Caddy 不参与 SSH 的代理

  • 只用 frps + frpc 配置即可完成

  • CaddyFile 无需修改

🧭 拓扑关系

外部SSH客户端
   │
   ▼
ubuntu1.ishenwei.online:60022  VPS公网
   │
   ▼
FRP Server (frps) on VPS
   │
   ▼
FRP Client (frpc) on 192.168.3.47
   │
   ▼
Local Ubuntu SSH (192.168.3.47:22)

🧩 VPS 端frps配置

编辑 /opt/frp/frps.ini

不需要添加新的 section这里只是定义基础参数。frps 会自动识别来自客户端的 TCP 映射。


🧩 内网 Ubuntu192.168.3.47)端 frpc 配置

编辑 /opt/frp/frpc.ini,在现有配置文件中追加:


# SSH 映射
[ubuntu_ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 60022


  • type = tcp 表示这是纯 TCP 代理,不走 HTTP 协议
  • remote_port = 60022 是 VPS 上暴露的端口(外部 SSH 连接入口)

🔧 启动并验证

在内网机器上:

sudo systemctl restart frpc 
sudo systemctl status frpc

验证日志中是否出现:

[ubuntu_ssh] start proxy success


🌐 在外部电脑上连接 SSH

从公网(任意地方)执行:

ssh -p 60022 user@ubuntu1.ishenwei.online

注意DNS 只解析到 IPSSH 的端口要显式指定为 -p 60022

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 7000/tcp   # frp server 端口
sudo ufw allow 7050
sudo ufw allow 60022
sudo ufw enable
sudo ufw status verbose

🔒 (可选)安全加固建议

  1. 不要直接使用 22 或常见端口,比如:

    remote_port = 26222

    避免被扫描。

  2. 限制来源 IP(仅 VPS 防火墙开放指定来源):

    sudo ufw allow from <your_home_ip> to any port 60022 proto tcp

  3. 使用公钥认证禁用密码登录

    • 编辑 /etc/ssh/sshd_config

      PasswordAuthentication no

    • 重启 SSH

      sudo systemctl restart ssh


总结

组件 是否需要修改 说明
Caddy 无需修改 不处理 SSH
frps (VPS) 保持默认端口即可
frpc (内网 Ubuntu) 新增 [ubuntu_ssh] section
DNS 添加 ubuntu1.ishenwei.online -> VPS公网IP
SSH 连接 使用 ssh -p 60022 user@ubuntu1.ishenwei.online

错误排查 #troubleshooting

✔ 检查Server上配置的代理服务器可能会有冲突

NAS上安装的V2RayA 会对FRP有影响需要停止代理服务器并重启FRPC

✔ 第 1 步:确认 frps 是否真的在监听端口(排除端口被占用/劫持)

ss -lntup | grep 7000
ss -lntup | grep frps

结果:

root@racknerd-66f115a:~# ss -lntup | grep 7000
tcp   LISTEN 0      4096               *:7000             *:*    users:(("frps",pid=413014,fd=6))
root@racknerd-66f115a:~# ss -lntup | grep frps
tcp   LISTEN 0      4096               *:7000             *:*    users:(("frps",pid=413014,fd=6))
tcp   LISTEN 0      4096               *:7500             *:*    users:(("frps",pid=413014,fd=3))

如果这里显示:

端口被 Caddy/Nginx 占用
frps 未绑定 0.0.0.0
frps 在 LISTEN 但不是你期望的配置文件

✔ 第 2 步:确定 frps 进程读取的配置是否跟你想的一样

执行:

ps -ef | grep frps

你要看到类似:

root@racknerd-66f115a:~# ps -ef | grep frps
root      413014       1  0 02:23 ?        00:00:00 /opt/frp/frps -c /opt/frp/frps.ini
root      419007  414182  0 02:57 pts/1    00:00:00 grep --color=auto frps

如果看到:

  • 路径不对
  • 配置文件不对
  • 或者正运行旧版本二进制

那 frps 实际载入的 token、bind_port 等信息就不匹配。

尤其要确认 token 是否是你以为的那个。

👉 很多人遇到的问题是:
他们编辑了 /opt/frp/frps.ini,但 systemd service 其实加载另一个路径,例如 /etc/frp/frps.ini

✔ 第 3 步:确认防火墙是否把 7000 封了

在 VPS 执行:

sudo iptables -L -n 
sudo ufw status 
sudo firewall-cmd --list-all

你需要确保:

  • tcp 7000ACCEPT

  • Cloudflare 没有影响你(你用的是直连 IP不会影响

  • Caddy/Nginx 没修改 nftables某些 One-key 脚本会修改)

✔ 第 4 步:确认没有 Caddy/Nginx 误 proxy 了 TCP 7000

检查 Caddy 配置:

vi /etc/caddy/Caddyfile

是否存在以下配置:

:7000 { reverse_proxy ... }

如果有 → FRP 就没法直接监听这个端口。

✔ 第 5 步:确认 frps 日志是否有拒绝认证token mismatch

执行:

journalctl -u frps -n 100 --no-pager

如果你看到类似:

authentication failed token mismatch invalid login

那肯定是 token 和 frpc 不一致。

👉 很多人以为一样,但实际是空格、换行、编码问题导致不一致。

✔ 第 6 步:尝试手动 telnet 登录后观察 frps 日志变化

非常关键的诊断动作

你从任意 frpc 客户端执行:

telnet 192.227.222.142 7000

同时在 frps VPS 执行:

journalctl -u frps -f

正常情况下,你应该看到 frps 有日志反应:

  • 有连接建立
  • 有 login 请求

如果 frps 完全无反应:

说明请求没有到达 frps 进程 → 必然是端口被别的服务占用 / iptables 拦截 / SELinux 限制 / Caddy/Nginx 覆盖了端口

✔ 第 7 步:强制重启 frps 和 frpc

在 frps 机器上:

systemctl restart frps

确认状态:

systemctl status frps

在 frpc 机器上:

systemctl restart frpc 
systemctl status frpc 
journalctl -u frpc -n 50

如果 frpc 日志里直接报: dial tcp 192.227.222.142:7000: connection reset ➡ 防火墙问题

如果报: authentication failed ➡ token 不一致

如果: wait until server ready ➡ frps 端口被劫持

Reference