欢迎光临
我们一直在努力

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

在这里插入图片描述

🔥草莓熊Lotso:个人主页

❄️个人专栏: 《C++知识分享》 《Linux 入门到实践:零基础也能懂》

✨生活是默默的坚持,毅力是永久的享受!


🎬 博主简介:

在这里插入图片描述


文章目录

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

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

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

在这里插入图片描述


二. 环境准备

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

2.1 所需设备

  • 公网云服务器:任意厂商的 Linux 服务器均可,必须有公网 IP,本文以 Ubuntu 系统为例。
  • 内网机器:本文用 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 命令等:

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

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

    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:

    bindPort = 8888

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

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

    ./frps

    正确启动方式:

    ./frps -c ./frps.toml

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

    frps tcp listen on 0.0.0.0:8888
    frps started successfully

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

    netstat -nltp

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

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

    3.2 客户端配置与启动

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

    # 公网服务器的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

    配置完成后启动客户端:

    ./frpc -c ./frpc.toml

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

  • login to server success:与服务端建立控制连接成功
  • proxy added: [ssh-service]:代理规则注册成功
  • start proxy success:SSH 代理正式生效
  • 此时回到公网服务器查看端口,会发现 frps 进程新增了 8081 端口的监听,这就是对外提供 SSH 访问的代理端口。

    3.3 公网远程连接验证

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

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

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

    在这里插入图片描述 在这里插入图片描述


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

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

    4.1 内网部署 Nginx

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

    # Ubuntu/Debian 系统
    sudo apt install -y nginx

    # CentOS 系统
    # sudo yum install nginx

    启动 Nginx 服务:

    sudo nginx

    验证 80 端口监听状态:

    sudo netstat -nltp

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

    4.2 新增 Web 代理配置

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

    # 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 服务,我们可以修改内网的首页文件:

    sudo vim /var/www/html/index.nginx-debian.html

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

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

    在这里插入图片描述


    五. 后台守护运行

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

    服务端后台启动命令:

    nohup ./frps -c ./frps.toml &> /dev/null &

    客户端后台启动命令:

    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 服务端核心流程

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

  • 主动建立连接:客户端启动后,根据配置的serverAddr和serverPort,主动向公网服务端发起连接,完成版本校验与登录。
  • 注册代理规则:控制连接建立成功后,客户端将本地所有代理规则发送给服务端,完成注册。
  • 响应转发请求:收到服务端的新连接通知后,客户端主动连接本地的目标服务,随后配合服务端完成双向的数据转发。
  • 本质上,frp 就是利用一条客户端主动发起的长连接,反向代理多个端口的 TCP 流量,巧妙地绕开了内网无法被外部主动访问的限制。理解了 TCP 代理的逻辑,再去学习 HTTP 域名代理、HTTPS、UDP 等高级功能,都会事半功倍。

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

    在这里插入图片描述

    核心考点与常见坑点总结

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

  • 结尾:

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

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

    ✨把这些内容吃透超牛的!放松下吧✨

    ʕ˘ᴥ˘ʔ

    づきらど

    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » 【Linux网络加餐】手动部署:SSH 与 Web 服务实战 + 底层原理全解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址