Files
nexus/raw/Home Office/通过VPS+内网反向代理实现域名访问内网穿透.md

20 KiB
Raw Blame History

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

思路Aliyun 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 管理面板(可选)。推荐当你有多台设备和多端口时使用。

前置共识(已知条件)

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

  • 内网服务:

    • NAS192.168.3.17:5000(对应 nas.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 步:阿里云 DNS 配置

进入阿里云控制台 → 域名解析:

主机记录 记录类型 记录值 TTL
nas A 192.227.222.142 600
n8n A 192.227.222.142 600

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

`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

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


2 安装 frpsfrp 服务端)

cd /opt 
sudo mkdir frp && cd frp 
FRP_VER=0.65.0   # 若有更新,可替换版本号 
sudo curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz 
sudo 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, log, reverse-proxy, troubleshooting, vps]
---
---
title: 前置共识(已知条件)
source:
author: shenwei
published:
created:
description:
tags: [caddy, cloudflare, frp, log, reverse-proxy, troubleshooting, 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 # Ubuntu SSH
sudo ufw allow 60023 # NAS 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

如果你想让 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 安装 frpsfrp 服务端)

cd /opt 
sudo mkdir frp && cd frp 
FRP_VER=0.65.0   # 若有更新,可替换版本号 
sudo curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz 
sudo 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 = 60055

创建 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

创建 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
}


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

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
}

# 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

✔ 第 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 端口被劫持