【Linux网络加餐】手动部署:SSH 与 Web 服务实战 + 底层原理全解析


🔥草莓熊Lotso: 个人主页
❄️个人专栏: 《C++知识分享》 《Linux 入门到实践:零基础也能懂》
✨生活是默默的坚持,毅力是永久的享受!


🎬 博主简介:


文章目录

  • 前言:
  • [一. frp 内网穿透核心原理](#一. frp 内网穿透核心原理)
    • [1.1 核心角色](#1.1 核心角色)
    • [1.2 两类关键端口](#1.2 两类关键端口)
    • [1.3 流量转发流程](#1.3 流量转发流程)
  • [二. 环境准备](#二. 环境准备)
    • [2.1 所需设备](#2.1 所需设备)
    • [2.2 安装包下载](#2.2 安装包下载)
    • [2.3 文件上传与解压](#2.3 文件上传与解压)
  • [三. 实战一:SSH 服务内网穿透](#三. 实战一:SSH 服务内网穿透)
    • [3.1 服务端配置与启动](#3.1 服务端配置与启动)
    • [3.2 客户端配置与启动](#3.2 客户端配置与启动)
    • [3.3 公网远程连接验证](#3.3 公网远程连接验证)
  • [四. 实战二:Nginx Web 服务内网穿透](#四. 实战二:Nginx Web 服务内网穿透)
    • [4.1 内网部署 Nginx](#4.1 内网部署 Nginx)
    • [4.2 新增 Web 代理配置](#4.2 新增 Web 代理配置)
    • [4.3 浏览器访问验证](#4.3 浏览器访问验证)
  • [五. 后台守护运行](#五. 后台守护运行)
  • [六. 核心实现逻辑浅析](#六. 核心实现逻辑浅析)
    • [6.1 服务端核心流程](#6.1 服务端核心流程)
    • [6.2 客户端核心流程](#6.2 客户端核心流程)
  • 结尾:

前言:

相信很多做开发的朋友都有过这种经历:本地写了个 Web 项目想给朋友演示,或者需要远程连接家里实验室的 Linux 机器,却因为没有公网 IP 一筹莫展。内网穿透就是解决这个问题的核心技术,而 frp 凭借轻量、高性能、配置灵活的优势,成为了绝大多数人的选择。网上一键部署的教程很多,但大多是 "复制粘贴完事",很少讲清楚背后的原理,出了问题也无从排查。今天我们就从零开始,手动完成 frp 的服务端与客户端部署,实现 SSH 远程登录和 Nginx Web 服务穿透两个经典场景,再从网络编程的角度拆解它的实现逻辑,帮你彻底搞懂内网穿透到底是怎么一回事。


一. frp 内网穿透核心原理

frp 采用经典的C/S(客户端 / 服务端)架构,核心思路是 "反向连接"------ 利用内网机器主动向外发起连接的能力,绕开 "外部无法主动访问内网" 的限制。

1.1 核心角色

  • frps(服务端):部署在拥有公网 IP 的云服务器上,负责接收客户端连接、对外暴露代理端口、转发流量。
  • frpc(客户端):部署在内网机器上,主动连接公网服务端,把本地服务的流量转发到公网。

1.2 两类关键端口

很多新手容易混淆端口作用,这里先明确区分:

  • 通信端口(bindPort):服务端专门用来和客户端建立控制长连接的端口,比如后文配置的 8888。这个端口只用于客户端和服务端之间传输控制指令,外部用户不需要使用。
  • 代理端口(remotePort):服务端对外暴露的业务端口,每一个内网服务对应一个独立的代理端口。外部用户访问「公网 IP + remotePort」,就等价于访问内网机器的对应服务。

1.3 流量转发流程

以 SSH 穿透为例,完整的流量路径如下:

Plain 复制代码
外部SSH客户端 -> 公网服务器:8081(remotePort) -> frps服务端 
-> 控制长连接(8888) -> frpc客户端 -> 内网机器:22(SSH服务)

响应数据则沿原路返回,最终实现公网访问内网服务的效果。


二. 环境准备

正式部署前,我们先把两端的环境和安装包准备妥当。

2.1 所需设备

  1. 公网云服务器:任意厂商的 Linux 服务器均可,必须有公网 IP,本文以 Ubuntu 系统为例。
  2. 内网机器:本文用 VMware 虚拟机(Ubuntu 系统)演示,也可以是本地物理机、树莓派等设备,只要能正常访问公网即可。

小提示:虚拟机推荐使用 NAT 网络模式,此时 Windows 主机构成虚拟局域网,虚拟机可以正常访问外网,满足 frp 客户端的网络要求。

2.2 安装包下载

frp 的官方仓库为 fatedier/frp,本文使用 v0.58.1 版本。下载时必须匹配系统和 CPU 架构 ,x86 架构的 Linux 服务器和虚拟机都选择 frp_0.58.1_linux_amd64.tar.gz,不要误选 arm 版本。

如果 GitHub 下载速度较慢,可以借助 Watt Toolkit 等工具加速下载。

2.3 文件上传与解压

下载完成后,将安装包分别上传到公网服务器和内网虚拟机中,常用的传输方式有 rz 命令、scp 命令等:

bash 复制代码
# 示例:Windows通过scp传输到虚拟机
scp frp_0.58.1_linux_amd64.tar.gz 用户名@虚拟机IP:/目标目录

上传完成后,在两端分别执行解压:

bash 复制代码
tar xzf frp_0.58.1_linux_amd64.tar.gz
cd frp_0.58.1_linux_amd64

解压后的核心文件:

  • frps:服务端可执行程序
  • frps.toml:服务端配置文件
  • frpc:客户端可执行程序
  • frpc.toml:客户端配置文件

注意:v0.58.1 版本默认使用 toml 格式的配置文件,不要沿用旧版本的 ini 文件名,否则会出现 open ./frpc.ini: no such file or directory 的报错。


三. 实战一:SSH 服务内网穿透

我们第一个实战场景,是把内网机器的 22 号 SSH 端口映射到公网,实现公网直接远程登录内网机器。

3.1 服务端配置与启动

公网服务器的配置非常简洁,只需要指定通信端口即可。编辑 frps.toml

toml 复制代码
bindPort = 8888

这里有一个高频踩坑点:启动时必须通过 -c 参数指定配置文件,否则程序会使用默认参数(默认端口 7000),修改的配置不会生效。

错误启动方式(使用默认端口):

bash 复制代码
./frps

正确启动方式:

bash 复制代码
./frps -c ./frps.toml

启动成功后,控制台会输出关键日志:

Plain 复制代码
frps tcp listen on 0.0.0.0:8888
frps started successfully

我们可以用 netstat 命令验证端口监听状态:

bash 复制代码
netstat -nltp

能看到 8888 端口处于 LISTEN 状态,进程为 frps,说明服务端启动正常。

重要提醒:云服务器的安全组、系统防火墙必须放开 8888 端口,以及后续所有用到的代理端口,否则客户端会连接失败。

3.2 客户端配置与启动

在内网虚拟机上编辑 frpc.toml,配置服务端地址和 SSH 代理规则:

toml 复制代码
# 公网服务器的IP地址
serverAddr = "你的公网服务器IP"
# 与服务端bindPort保持一致
serverPort = 8888

# SSH代理规则
[[proxies]]
name = "ssh-service"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 8081

参数说明:

  • name:代理的自定义名称,同一客户端下不能重复
  • type:代理协议类型,SSH 使用 TCP 协议
  • localIP + localPort:内网 SSH 服务的地址和端口,本地服务填 <127.0.0.1> 即可
  • remotePort:公网服务器对外暴露的端口,外部通过此端口访问 SSH

配置完成后启动客户端:

bash 复制代码
./frpc -c ./frpc.toml

启动成功后,日志会依次输出:

  1. login to server success:与服务端建立控制连接成功
  2. proxy added: [ssh-service]:代理规则注册成功
  3. start proxy success:SSH 代理正式生效

此时回到公网服务器查看端口,会发现 frps 进程新增了 8081 端口的监听,这就是对外提供 SSH 访问的代理端口。

3.3 公网远程连接验证

打开 Xshell 等 SSH 工具,新建连接:

  • 主机:公网服务器 IP
  • 端口:8081(注意不是默认的 22 端口)

连接成功后登录系统,查看主机名、用户目录、文件结构,就能确认登录的正是内网虚拟机。我们可以正常执行命令、创建删除文件,和本地操作完全一致。


四. 实战二:Nginx Web 服务内网穿透

第二个场景,我们在内网部署 Nginx Web 服务,并将其映射到公网,实现浏览器直接访问内网网页。

4.1 内网部署 Nginx

先在内网虚拟机上安装并启动 Nginx:

bash 复制代码
# Ubuntu/Debian 系统
sudo apt install -y nginx

# CentOS 系统
# sudo yum install nginx

启动 Nginx 服务:

bash 复制代码
sudo nginx

验证 80 端口监听状态:

bash 复制代码
sudo netstat -nltp

看到 80 端口处于 LISTEN 状态,说明 Nginx 启动成功。

4.2 新增 Web 代理配置

frp 支持一个客户端同时配置多个代理,我们不需要删除已有的 SSH 配置,直接在 frpc.toml 中追加 Nginx 的代理规则:

toml 复制代码
# Nginx Web代理规则
[[proxies]]
name = "http-service"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 8082

修改完成后,重启 frpc 客户端。启动成功后,公网服务器上会新增 8082 端口的监听。此时 frps 一共监听三个端口:8888(控制通信)、8081(SSH 代理)、8082(Web 代理)。

4.3 浏览器访问验证

打开浏览器,访问 http://你的公网IP:8082,即可看到 Nginx 的默认欢迎页面。

为了确认访问的确实是内网的 Nginx 服务,我们可以修改内网的首页文件:

bash 复制代码
sudo vim /var/www/html/index.nginx-debian.html

在页面中加入一行自定义内容,比如 <p>hello world, hello bit</p>,保存后刷新浏览器,页面会同步更新。

如果关闭 frpc 客户端,浏览器会立即无法访问;重新启动客户端后访问恢复,由此可以验证穿透的生效逻辑。


五. 后台守护运行

前面的启动方式都是前台运行,终端关闭后程序就会停止。实际使用中,我们需要让 frp 在后台持续运行,这里用 nohup 命令实现后台守护。

服务端后台启动命令:

bash 复制代码
nohup ./frps -c ./frps.toml &> /dev/null &

客户端后台启动命令:

bash 复制代码
nohup ./frpc -c ./frpc.toml &> /dev/null &

命令拆解:

  • nohup:让程序忽略终端挂起信号,终端关闭后继续运行
  • &> /dev/null:将标准输出和标准错误全部重定向到 /dev/null/dev/null 是 Linux 中的特殊设备文件,写入的内容会被直接丢弃,作用是屏蔽所有日志输出,避免生成大量日志文件
  • 末尾的 &:让命令在后台执行

启动后可以通过 ps aux | grep frp 查看进程,确认程序在后台正常运行。


六. 核心实现逻辑浅析

frp 是基于 Go 语言开发的项目,但底层的网络编程逻辑和经典 TCP C/S 模型完全相通。我们从 TCP 代理的角度拆解核心流程,帮大家理解底层的工作机制。

6.1 服务端核心流程

  1. 监听控制端口 :服务端启动后创建 TCP 套接字,绑定bindPort并进入监听状态,等待客户端主动连接。对应日志中的 frps tcp listen on 0.0.0.0:8888
  2. 建立控制连接:客户端连接上来后,服务端通过 accept 得到一条持久的控制连接,用于传输代理注册、连接通知等控制指令。
  3. 创建代理监听 :收到客户端的代理注册请求后,服务端为每个代理创建独立的套接字,绑定对应的remotePort并开始监听外部请求。
  4. 流量转发调度:当外部用户连接代理端口时,服务端通过控制连接通知客户端;客户端连接本地服务后,服务端负责在外部连接和客户端连接之间做双向数据拷贝,完成流量透传。

6.2 客户端核心流程

  1. 主动建立连接 :客户端启动后,根据配置的serverAddrserverPort,主动向公网服务端发起连接,完成版本校验与登录。
  2. 注册代理规则:控制连接建立成功后,客户端将本地所有代理规则发送给服务端,完成注册。
  3. 响应转发请求:收到服务端的新连接通知后,客户端主动连接本地的目标服务,随后配合服务端完成双向的数据转发。

本质上,frp 就是利用一条客户端主动发起的长连接,反向代理多个端口的 TCP 流量,巧妙地绕开了内网无法被外部主动访问的限制。理解了 TCP 代理的逻辑,再去学习 HTTP 域名代理、HTTPS、UDP 等高级功能,都会事半功倍。

  • 再来看看真实的远程测试

核心考点与常见坑点总结

  1. 架构角色区分:frps 部署在公网服务器,frpc 部署在内网机器,二者角色不能颠倒。
  2. 端口作用区分
    1. bindPort:服务端与客户端的通信端口,客户端serverPort必须与其一致
    2. remotePort:公网对外暴露的业务端口,每个代理唯一,不能冲突
    3. localPort:内网服务的实际监听端口
  3. 配置文件易错点 :启动必须加-c参数指定配置文件,否则使用默认参数;v0.58.1 及以上版本配置文件为 toml 格式,不要误用 ini 后缀。
  4. 网络排查优先级:连接失败时优先检查云服务器安全组、系统防火墙是否放开了所有用到的端口。
  5. 多代理特性 :一个客户端可以配置多组[[proxies]],同时映射多个不同的内网服务。
  6. 后台运行原理 :理解 nohup、重定向、&的各自作用,以及/dev/null设备的含义。

结尾:

html 复制代码
🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!

结语:手动完整部署一遍 frp,最大的价值从来不是得到一个能用的穿透工具,而是真正搞懂 "内网穿透" 背后的网络逻辑 ------ 它没有什么黑魔法,本质就是反向代理 + 流量转发。很多时候我们依赖一键脚本、可视化面板,确实提升了效率,但也跳过了最核心的原理细节,遇到问题就只能束手无策。从手动部署入手,搞懂每一个配置项的含义、每一步流量的走向,再去使用高级功能或者排查问题,都会轻松很多。后续大家还可以继续探索 frp 的高级玩法,比如按域名分流的 HTTP 代理、HTTPS 证书配置、端口复用、负载均衡等等,底层逻辑都是相通的。

✨把这些内容吃透超牛的!放松下吧✨ ʕ˘ᴥ˘ʔ づきらど

相关推荐
小妖同学学AI1 小时前
60.8k星!开源金融数据神器OpenBB:连接一切数据,让分析师、量化交易员和AI智能体如虎添翼!
人工智能·金融·开源
weixin_440730501 小时前
python+request实现接口-参数化小结
开发语言·python
YOLO数据集集合1 小时前
UAVDT 无人机车辆检测数据集 - 无人机航拍 | 车辆检测 | 目标检测 | YOLO格式 | 智能交通 | 城市管理 | 多类别数据集 | 计算机视觉
人工智能·yolo·目标检测·机器学习·计算机视觉·目标跟踪·无人机
CHHH_HHH1 小时前
【Linux系统篇】深入解析Linux文件系统:从磁盘寻址到软硬链接
linux·服务器·开发语言·后端·ubuntu
剑锋所指,所向披靡!1 小时前
TCP并发服务器
服务器·网络·tcp/ip
aneasystone本尊1 小时前
大模型推理介绍:从一次提问说起
人工智能
小王2041 小时前
Day 21:卷积神经网络CNN — 深入理解卷积
人工智能·神经网络·cnn
网安蟹佬霸2 小时前
密码学安全实战:从加密原理到哈希破解的完整攻防指南
网络·算法·安全·web安全·开源·密码学·哈希算法
DevNo2 小时前
学生党课堂复习利器:三款音视频转文字工具实测对比
人工智能