一种零成本的服务器磁盘空间扩展方法——内网磁盘映射到公网服务器的两种方案

内网磁盘映射到公网服务器的两种方案

前言

你是否遇到过这样的场景:有一台云服务器,但磁盘空间有限;而本地电脑有大容量硬盘,却因为处于内网环境无法被服务器直接访问。

本文将介绍两种方案来实现这个需求:

  1. SSH反向隧道:简单快速,无需额外软件,适合临时使用
  2. frp内网穿透:稳定可靠,适合长期运行

一、场景说明

1.1 需求背景

  • 服务器:公网IP,磁盘空间有限(如40G)
  • 本地电脑:内网环境,有大容量硬盘(如200G+),无法被外部直接访问
  • 目标:让服务器能够访问本地磁盘,并通过Web服务对外提供文件访问

1.2 解决方案对比

方案 优点 缺点 适用场景
SSH反向隧道 无需额外软件、配置简单、安全 需要保持SSH连接、断线需手动重连 临时共享、轻量级需求
frp 功能强大、自动重连、支持多种协议、有Dashboard 需要额外部署服务端和客户端 长期稳定的服务暴露
WireGuard 性能优异、VPN级别访问 配置复杂、需要内核支持 需要完整网络互通
NFS/SMB 标准文件系统协议 需要公网IP或VPN 局域网或有固定IP环境

方案一:SSH反向隧道

二、SSH反向隧道原理

2.1 什么是SSH反向隧道?

正常情况下,SSH连接是从本地主动连接到远程服务器:

复制代码
本地电脑 ────────SSH连接────────> 服务器
         (本地可以访问服务器)

但服务器无法主动连接本地电脑,因为本地处于内网,没有公网IP。

反向隧道的巧妙之处在于:利用本地主动建立的SSH连接,在其中"偷偷"开一个反向通道,让服务器能通过这个通道访问本地。

复制代码
┌─────────────┐                           ┌─────────────┐
│   本地电脑   │                           │    服务器    │
│  (内网IP)   │                           │  (公网IP)   │
├─────────────┤                           ├─────────────┤
│             │   ① 本地主动建立SSH连接     │             │
│             │ ─────────────────────────> │             │
│             │                           │             │
│             │   ② 在连接中开反向通道      │             │
│             │ <───────────────────────── │             │
│             │                           │             │
│   SSH服务   │   ③ 服务器通过通道访问本地  │  localhost  │
│   (端口22)  │ <═════════════════════════ │  (端口2222) │
└─────────────┘                           └─────────────┘

2.2 整体架构

复制代码
┌───────────────────────────┐                      ┌───────────────────────────┐
│         本地电脑           │                      │          服务器            │
│       (内网Debian)         │                      │      xxx.xxx.xxx.xxx      │
├───────────────────────────┤                      ├───────────────────────────┤
│                           │                      │                           │
│  /home/user/大硬盘/book    │   SSH反向隧道(端口2222)  │       localhost:2222      │
│                           │◄══════════════════════│            ↓              │
│                           │      (加密通道)        │       sshfs挂载          │
│                           │                      │            ↓              │
│       SSH服务 (端口22)     │                      │    /var/www/html/books    │
│             ↑             │                      │            ↓              │
│             │             │   本地主动建立隧道      │        nginx:80          │
│             └─────────────┼──────────────────────┤            ↓              │
│                           │     ssh -R 命令       │     http对外访问          │
└───────────────────────────┘                      └───────────────────────────┘

三、SSH方案安装配置

3.1 环境要求

  • 本地电脑:Linux系统(本文以Debian为例),需要安装SSH服务
  • 服务器:Linux系统,需要安装sshfs
  • 网络条件:本地能够SSH连接到服务器

3.2 本地电脑配置

步骤1:安装并启动SSH服务

本地需要运行SSH服务,才能接受来自隧道的连接。

复制代码
# 安装OpenSSH服务端
sudo apt install -y openssh-server

# 启动SSH服务
sudo systemctl start ssh

# 设置开机自启
sudo systemctl enable ssh

# 检查服务状态
sudo systemctl status ssh

说明:如果你的本地电脑已经安装并运行了SSH服务,可以跳过这一步。

步骤2:建立SSH反向隧道

这是整个方案的核心步骤,一条命令搞定:

复制代码
# 基础命令
ssh -NfR 2222:localhost:22 用户名@服务器IP

参数详解

参数 含义
-N 不执行远程命令,仅建立隧道(纯转发模式)
-f 后台运行,不会占用当前终端
-R 2222:localhost:22 反向隧道:服务器2222端口 → 本地22端口
2222 服务器上开放的端口(可自定义,需未被占用)
localhost:22 本地的SSH服务地址

实际使用示例

复制代码
# 简单版本
ssh -NfR 2222:localhost:22 myuser@xxx.xxx.xxx.xxx

# 推荐版本(带心跳保活)
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -NfR 2222:localhost:22 myuser@xxx.xxx.xxx.xxx

心跳参数说明

  • ServerAliveInterval=30:每30秒发送一次心跳
  • ServerAliveCountMax=3:3次心跳无响应则断开

这些参数可以防止因为长时间无数据传输导致连接被防火墙或NAT断开。

步骤3:验证隧道是否建立成功
复制代码
# 本地查看隧道进程
ps aux | grep "ssh.*2222"

# 应该能看到类似输出:
# user  12345  ... ssh -NfR 2222:localhost:22 myuser@xxx.xxx.xxx.xxx

3.3 服务器配置

步骤1:安装必要软件
复制代码
# 安装sshfs(核心组件)
sudo apt install -y sshfs

# 安装sshpass(可选,用于脚本自动输入密码)
sudo apt install -y sshpass
步骤2:配置FUSE
复制代码
# 编辑fuse配置文件
sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf

# 验证配置
cat /etc/fuse.conf | grep user_allow_other
# 应输出:user_allow_other

为什么要这个配置?

默认情况下,FUSE挂载的目录只有挂载者本人可以访问。开启user_allow_other后,Web服务器(如nginx)才能读取挂载的文件。

步骤3:创建挂载点并挂载
复制代码
# 创建挂载目录
sudo mkdir -p /var/www/html/books
sudo chown $USER:$USER /var/www/html/books

# 挂载命令
sshfs 本地用户名@localhost:/本地磁盘路径 /挂载点 -p 2222 -o StrictHostKeyChecking=no,allow_other

# 实际示例
sshfs myuser@localhost:/home/myuser/大硬盘/book /var/www/html/books -p 2222 -o StrictHostKeyChecking=no,allow_other

参数说明

参数 含义
本地用户名@localhost 本地电脑的用户名,通过隧道(localhost)连接
-p 2222 使用隧道端口2222
StrictHostKeyChecking=no 跳过主机密钥验证(隧道场景需要)
allow_other 允许其他用户访问挂载目录
步骤4:验证挂载
复制代码
# 查看挂载状态
df -h /var/www/html/books

# 查看文件列表
ls /var/www/html/books

# 测试Web访问
curl http://localhost/books/

方案二:frp内网穿透

四、frp方案原理

4.1 什么是frp?

frp(Fast Reverse Proxy)是一个高性能的反向代理应用,专门用于内网穿透。相比SSH反向隧道,frp具有以下优势:

特性 SSH反向隧道 frp
设计初衷 临时会话连接 专用内网穿透工具
断线重连 需要外部脚本(autossh/crontab) 内置自动重连机制
心跳机制 简单的ServerAlive参数 完善的心跳检测+多级重试
状态监控 需手动检查进程 提供Dashboard可视化
连接恢复 断开后隧道端口可能残留 自动清理+重建
NAT穿透 依赖SSH连接保持 专门优化NAT场景

4.2 frp工作原理

复制代码
┌───────────────────────────┐                      ┌───────────────────────────┐
│         本地电脑           │                      │          服务器            │
│       (运行frpc)           │                      │       (运行frps)          │
├───────────────────────────┤                      ├───────────────────────────┤
│                           │                      │                           │
│                           │   ① 建立控制连接       │                           │
│         frpc   ───────────────────────────────>  │         frps              │
│                           │     (端口7000)        │                           │
│                           │                      │                           │
│                           │   ② 注册代理规则       │                           │
│         frpc   ───────────────────────────────>  │         frps              │
│                           │   "我要暴露22端口"      │                           │
│                           │                      │                           │
│                           │                      │    ③ 开放2222端口监听       │
│                           │                      │       (供外部访问)         │
│                           │                      │                           │
│                           │   ④ 外部请求到达时      │                           │
│         frpc   <───────────────────────────────  │         frps              │
│        (转发到本地22)       │   转发流量到frpc      │      (接收请求)            │
└───────────────────────────┘                      └───────────────────────────┘

核心概念

  • frps(服务端):运行在有公网IP的服务器上,监听端口,转发流量
  • frpc(客户端):运行在内网电脑上,主动连接frps,注册代理规则
  • 控制连接:frpc与frps之间的长连接,用于传递控制信息和心跳
  • 数据连接:实际传输数据的连接,按需建立

4.3 整体架构

复制代码
┌───────────────────────────┐                      ┌───────────────────────────┐
│         本地电脑           │                      │          服务器            │
│       (内网Debian)         │                      │      xxx.xxx.xxx.xxx      │
├───────────────────────────┤                      ├───────────────────────────┤
│                           │                      │                           │
│  /home/user/大硬盘/book    │                      │        frps:7000          │
│                           │                      │            ↓              │
│                           │      frp隧道          │       :2222 (映射端口)    │
│         frpc   ─────────────────────────────────>│            ↓              │
│                           │     (自动重连)        │       sshfs挂载          │
│                           │                      │            ↓              │
│       SSH服务 (端口22)     │                      │    /var/www/html/books    │
│                           │                      │            ↓              │
│                           │                      │        nginx:80          │
│                           │                      │            ↓              │
│                           │                      │     http对外访问          │
└───────────────────────────┘                      └───────────────────────────┘

五、frp方案安装配置

5.1 下载frp

frp是一个单文件程序,无需安装,下载解压即可使用。

下载地址https://github.com/fatedier/frp/releases

选择对应平台的版本,本文以Linux amd64为例:

复制代码
# 下载
wget https://github.com/fatedier/frp/releases/download/v0.68.0/frp_0.68.0_linux_amd64.tar.gz

# 解压
tar -xzf frp_0.68.0_linux_amd64.tar.gz
cd frp_0.68.0_linux_amd64

# 查看文件
ls
# frpc      - 客户端程序
# frpc.toml - 客户端配置
# frps      - 服务端程序
# frps.toml - 服务端配置

5.2 服务器配置(frps)

步骤1:上传frps到服务器
复制代码
# 方法1:使用scp
scp frps 用户名@服务器IP:~/frp/

# 方法2:直接在服务器上下载
ssh 用户名@服务器IP
mkdir -p ~/frp && cd ~/frp
wget https://github.com/fatedier/frp/releases/download/v0.68.0/frp_0.68.0_linux_amd64.tar.gz
tar -xzf frp_0.68.0_linux_amd64.tar.gz --strip-components=1 frp_0.68.0_linux_amd64/frps
步骤2:创建frps配置文件

在服务器上创建 ~/frp/frps.toml

复制代码
# frps.toml - 服务端配置

# frp服务端口(frpc连接此端口)
bindPort = 7000

# 认证token(建议设置,增加安全性)
# auth.token = "your_token_here"

# Dashboard配置(可选,用于查看连接状态)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin123"

# 日志配置
log.to = "/home/用户名/frp/frps.log"
log.level = "info"
log.maxDays = 3
步骤3:启动frps
复制代码
# 前台运行(测试用)
./frps -c frps.toml

# 后台运行(生产用)
nohup ./frps -c frps.toml > /dev/null 2>&1 &

# 检查是否启动成功
ps aux | grep frps
ss -tlnp | grep 7000
步骤4:设置开机自启(systemd)

创建服务文件 /etc/systemd/system/frps.service

复制代码
[Unit]
Description=frps service
After=network.target

[Service]
Type=simple
User=你的用户名
ExecStart=/home/你的用户名/frp/frps -c /home/你的用户名/frp/frps.toml
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

启用服务:

复制代码
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl status frps

5.3 本地电脑配置(frpc)

步骤1:准备frpc程序
复制代码
# 创建目录
mkdir -p ~/frp
cd ~/frp

# 下载frp(如果还没下载)
wget https://github.com/fatedier/frp/releases/download/v0.68.0/frp_0.68.0_linux_amd64.tar.gz
tar -xzf frp_0.68.0_linux_amd64.tar.gz --strip-components=1 frp_0.68.0_linux_amd64/frpc
步骤2:创建frpc配置文件

创建 ~/frp/frpc.toml

复制代码
# frpc.toml - 客户端配置

# frps服务器地址
serverAddr = "xxx.xxx.xxx.xxx"
serverPort = 7000

# 认证token(需与frps配置一致)
# auth.token = "your_token_here"

# 日志配置
log.to = "~/frp/frpc.log"
log.level = "info"
log.maxDays = 3

# 心跳配置(保持连接稳定)
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90

# 代理配置 - SSH端口转发
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 2222

配置详解

配置项 说明
serverAddr frps服务器IP地址
serverPort frps监听端口
name 代理名称,可自定义
type 协议类型,TCP用于SSH
localIP 本地服务地址
localPort 本地服务端口(SSH默认22)
remotePort 服务器上开放的端口
步骤3:启动frpc
复制代码
# 前台运行(测试用)
./frpc -c frpc.toml

# 后台运行(生产用)
nohup ./frpc -c frpc.toml > /dev/null 2>&1 &

# 检查是否启动成功
ps aux | grep frpc

成功启动后会看到类似输出:

复制代码
[I] [root.go:139] start frpc service for config file [frpc.toml]
[I] [service.go:299] [xxx] login to server success
[I] [proxy_manager.go:156] [xxx] proxy added: [ssh]
[I] [control.go:173] [xxx] [ssh] start proxy success
步骤4:设置开机自启(systemd)

创建服务文件 /etc/systemd/system/frpc.service

复制代码
[Unit]
Description=frpc service
After=network.target

[Service]
Type=simple
User=你的用户名
ExecStart=/home/你的用户名/frp/frpc -c /home/你的用户名/frp/frpc.toml
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target

启用服务:

复制代码
sudo systemctl daemon-reload
sudo systemctl enable frpc
sudo systemctl start frpc
sudo systemctl status frpc

5.4 验证frp隧道

复制代码
# 在服务器上检查2222端口是否开放
ss -tlnp | grep 2222

# 应该看到:
# LISTEN  0  4096  *:2222  *:*  users:(("frps",pid=xxx,fd=x))

# 测试隧道
ssh -p 2222 本地用户名@服务器IP 'hostname'
# 应该返回本地电脑的主机名

5.5 挂载磁盘

frp隧道建立后,挂载步骤与SSH方案相同:

复制代码
# 在服务器上执行
sshfs 本地用户名@localhost:/本地磁盘路径 /挂载点 -p 2222 -o StrictHostKeyChecking=no,allow_other

# 示例
sshfs myuser@localhost:/home/myuser/大硬盘/book /var/www/html/books -p 2222 -o StrictHostKeyChecking=no,allow_other

5.6 frp Dashboard监控

如果启用了Dashboard,可以通过浏览器访问:

复制代码
http://xxx.xxx.xxx.xxx:7500
用户名: admin
密码: admin123

注意:需要确保服务器防火墙开放7500端口:

复制代码
# 开放端口(如使用ufw)
sudo ufw allow 7500/tcp

在Dashboard中可以查看:

  • 当前连接的客户端
  • 各代理的状态和流量统计
  • 连接日志

安全建议:生产环境建议修改默认密码,或限制只允许内网访问(将webServer.addr改为内网IP)。


通用配置

六、SSHFS挂载配置(两种方案通用)

无论使用SSH隧道还是frp,挂载步骤相同。

6.1 服务器安装sshfs

复制代码
sudo apt install -y sshfs sshpass

6.2 配置FUSE

复制代码
sudo sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf

6.3 挂载命令

复制代码
# 基本挂载
sshfs 用户名@localhost:/本地路径 /挂载点 -p 2222 -o StrictHostKeyChecking=no,allow_other

# 带重连选项(推荐)
sshfs 用户名@localhost:/本地路径 /挂载点 -p 2222 -o StrictHostKeyChecking=no,allow_other,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3

6.4 开机自动挂载

创建systemd服务 /etc/systemd/system/sshfs-mount.service

复制代码
[Unit]
Description=SSHFS Mount
After=network.target frps.service

[Service]
Type=oneshot
User=服务器用户名
ExecStart=/usr/bin/sshfs 本地用户名@localhost:/本地路径 /挂载点 -p 2222 -o StrictHostKeyChecking=no,allow_other,_netdev
ExecStop=/usr/bin/fusermount -u /挂载点
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload
sudo systemctl enable sshfs-mount
sudo systemctl start sshfs-mount

七、常用操作命令

7.1 挂载管理

复制代码
# 查看所有sshfs挂载
mount | grep fuse.sshfs

# 卸载挂载
fusermount -u /挂载点

# 强制卸载
fusermount -u -z /挂载点
# 或
sudo umount -l /挂载点

7.2 SSH隧道管理

复制代码
# 查看隧道进程
ps aux | grep "ssh.*2222"

# 断开隧道
pkill -f "ssh.*2222"

# 重新建立隧道
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -NfR 2222:localhost:22 用户@服务器IP

7.3 frp管理

复制代码
# 查看frps/frpc进程
ps aux | grep frp

# 重启frps
sudo systemctl restart frps

# 重启frpc
sudo systemctl restart frpc

# 查看日志
tail -f ~/frp/frps.log
tail -f ~/frp/frpc.log

# 检查端口
ss -tlnp | grep -E "7000|2222"

八、常见问题与解决方案

8.1 SSH隧道连接失败

问题:执行ssh -R命令后,服务器上2222端口无法访问

排查步骤

复制代码
# 1. 检查本地SSH服务是否运行
sudo systemctl status ssh

# 2. 检查服务器上端口是否监听
ss -tlnp | grep 2222

# 3. 检查服务器SSH配置是否允许端口转发
sudo grep -i "AllowTcpForwarding" /etc/ssh/sshd_config
# 如果被注释或为no,需要改为yes并重启sshd

8.2 frp连接失败

问题:frpc提示连接frps失败

排查步骤

复制代码
# 1. 检查服务器frps是否运行
ps aux | grep frps
ss -tlnp | grep 7000

# 2. 检查防火墙是否开放7000端口
sudo ufw status
sudo ufw allow 7000/tcp

# 3. 检查frpc配置中的服务器地址是否正确
cat ~/frp/frpc.toml | grep serverAddr

# 4. 查看frpc日志
tail -50 ~/frp/frpc.log

8.3 挂载失败:Permission denied

问题:sshfs挂载时提示权限被拒绝

解决方案

复制代码
# 1. 确认隧道/frp可用
ssh -p 2222 本地用户名@localhost 'whoami'

# 2. 检查本地用户密码是否正确
# 3. 检查本地SSH服务是否允许密码登录
sudo grep -i "PasswordAuthentication" /etc/ssh/sshd_config
# 应该是 yes 或被注释(默认yes)

8.4 挂载目录无法访问

问题:挂载成功但Web服务无法访问文件

解决方案

复制代码
# 1. 检查fuse配置
cat /etc/fuse.conf | grep user_allow_other

# 2. 确认挂载时使用了allow_other选项
mount | grep allow_other

# 3. 重新挂载
fusermount -u /挂载点
sshfs ... -o allow_other

8.5 连接经常断开

SSH隧道方案

复制代码
# 使用autossh自动重连
sudo apt install -y autossh
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NfR 2222:localhost:22 用户@服务器IP

frp方案

frp内置自动重连,检查配置:

复制代码
# frpc.toml中确保有这些配置
transport.heartbeatInterval = 30
transport.heartbeatTimeout = 90

九、安全注意事项

9.1 端口安全

端口 用途 安全建议
22 正常SSH服务 保持默认,使用密钥认证
7000 frp控制端口 设置auth.token,限制IP访问
2222 隧道/代理端口 SSH隧道默认只监听localhost,frp可限制IP
7500 frp Dashboard 设置强密码,或绑定内网IP

9.2 认证安全

SSH方案

  • 生产环境建议使用SSH密钥认证
  • 禁用密码登录:PasswordAuthentication no

frp方案

  • 设置auth.token认证
  • Dashboard设置强密码
  • 考虑使用HTTPS(配置webServer.tls)

9.3 访问控制

限制代理端口访问(修改frpc.toml):

复制代码
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 2222
# 限制只有服务器本地可以访问此端口
allowIPs = ["127.0.0.1"]

限制frps控制端口访问(使用防火墙):

复制代码
# 只允许特定IP连接frps控制端口
sudo ufw allow from 你的本地公网IP to any port 7000

十、方案选择建议

场景 推荐方案 理由
临时共享文件(几小时~几天) SSH反向隧道 无需额外软件,一行命令搞定
长期稳定运行 frp 自动重连,有监控Dashboard
需要暴露多个服务 frp 支持多代理配置
追求极致简单 SSH反向隧道 最少的配置步骤
需要监控连接状态 frp Dashboard可视化
服务器资源紧张 SSH反向隧道 SSH已安装,无额外开销

十一、总结

本文介绍了两种将内网磁盘映射到公网服务器的方案:

SSH反向隧道方案

  • 优点:零依赖、配置简单(一条命令)、安全可靠
  • 缺点:需要保持连接、断线需手动重连
  • 适用:临时共享、轻量级需求

frp方案

  • 优点:自动重连、有Dashboard监控、支持多代理
  • 缺点:需要额外部署服务端和客户端
  • 适用:长期稳定运行、生产环境

两种方案各有优劣,根据实际需求选择即可。核心的SSHFS挂载部分是通用的,切换方案时只需更换隧道/代理部分。

十二、参考链接


作者声明:本文为原创技术分享,欢迎转载,请注明出处。

相关推荐
Mark White2 小时前
深入理解 Linux 打印体系:CUPS、驱动、ULD 与 Docker 容器化
linux·运维·docker
服务器专卖店2 小时前
你的OA系统需要一台高性价比服务器
服务器
没头脑的男大2 小时前
宇树的自己电脑的适配
linux·服务器·网络
guygg883 小时前
OPC UA Helper: 连接PLC获取变量值
服务器·网络·c#
我命由我123453 小时前
U 盘里出现的文件 BOOTEX.LOG
运维·服务器·经验分享·笔记·学习·硬件工程·学习方法
舒一笑3 小时前
我把前端从 /ais 改到 /kb 后,连续踩了 7 个 Nginx 坑(含 405/413/502/404 终极解法)
运维·nginx·程序员
IMPYLH3 小时前
Linux 的 paste 命令
linux·运维·服务器·bash
Kk.08023 小时前
Linux(十三)fork + exec进程创建
linux·运维·服务器
墨着染霜华3 小时前
Linux 下查看 Java 服务进程占用(CPU / 内存)并定位具体服务
java·linux·运维