☰
树莓派4B公网远程访问:SSH、端口转发、DDNS与安全加固
2026/10/31 4:02:24 网站建设 项目流程

1. 先把需求想透:树莓派4B 的远程访问到底在解决什么

树莓派4B 这东西买回来头一个月最热闹,装着系统、插着显示器、键盘鼠标摆一桌,等新鲜劲过去,它就被塞到电视柜后面吃灰了。我见过太多这样的板子。真正让一台树莓派4B 持续产生价值的,不是它性能多强,而是你能不能在任何地方、任何设备上,随时随地连上它——这就是树莓派4B 远程访问的核心命题。说白了,你要的不是一块开发板,而是一台放在家里、永远在线、随时听候差遣的小服务器。

这篇内容适合三类人:刚拿到板子、连 SSH 都还没连通过的新手;已经把局域网访问跑通、想让它在外面也能用的进阶用户;以及之前折腾过远程访问、被各种报错折腾到放弃、想重新系统梳理一遍的老哥。我会从一个完全零基础的角度出发,把整套流程拆成"局域网打通 → 公网可达 → 安全加固 → 长期运行"四段,每一段都给出可以直接复制的配置和命令,也会把我自己踩过的坑原原本本写出来。

需要先明确一点:远程访问不等于把设备直接扔到公网上裸奔。很多人第一次配置完端口转发,第二天就发现日志里有上千条陌生 IP 的登录尝试,这不是危言耸听,是必然会发生的事。所以我在整篇文章里会把"安全"这条线贯穿到底,而不是放到最后当补丁打。你按我这个顺序做,最后得到的是一个"外面能连、别人进不来、断电重启自己爬起来"的完整方案。

1.1 三种典型场景,对应三套不同的方案

我先把场景分清楚,因为很多人一上来就问"怎么远程连树莓派",但不同场景的技术选型差别非常大,选错了后面全是返工。

场景 A:同一个人、同一个局域网。你在书房用笔记本,树莓派在客厅电视柜。这种情况压根不需要什么公网方案,局域网 SSH 直连就够了,配置五分钟,速度还快。很多人被网上那些复杂教程带偏,一上来就搞公网映射,纯属自找麻烦。

场景 B:人不在家,需要连回家里的树莓派。出差在外想看家里的监控画面、想取回树莓派上跑着的下载任务结果、想临时改一段脚本。这是最普遍的需求,也是这篇内容的重头戏——需要在路由器上做端口转发,再配一个动态域名解析(DDNS),因为家庭宽带的公网地址是动态变化的,今天能连明天就可能失效。

场景 C:树莓派上跑了个小网页或者面板,想让别人也能打开看。比如一个家庭相册、一个温湿度看板、一个自己写的小工具。这类需求本质上和场景 B 是同一套底层机制,只是多了一个 Web 服务的端口要开放,还要考虑 HTTP 和 HTTPS 的区别。

我把三种场景的选型整理成一张表,你可以先对号入座,再往下看具体操作:

场景核心方案需要公网地址配置耗时安全风险等级
A 局域网内访问局域网 SSH / VNC不需要5 分钟极低
B 异地访问命令行端口转发 + DDNS需要40 分钟中(需加固)
C 对外发布 Web 服务端口转发 + DDNS + 证书需要60 分钟较高(需加固)

1.2 为什么不选第三方托管方案,而坚持自建

市面上做远程访问的方案大致分两类:一类是自建,路由器和树莓派两头配置,数据全程走你自己的链路;另一类是第三方托管,把树莓派挂到一个平台上,通过平台的入口访问。后者上手快,不用折腾路由器,但它有三个绕不开的问题。

第一是数据经过别人的服务器。哪怕加密做得再好,连接的元信息终究不在你手上,对于家里有摄像头、有 NAS、有个人文件的情况,我不太愿意接受。

第二是带宽和延迟不可控。免费额度通常限速,看个 720P 的监控画面都卡,付费版按月算下来一年也不少钱,长期成本比自建高。

第三是依赖别人的存亡。这类平台的服务条款和可用性变动很频繁,哪天服务调整或者停止,你整套方案就得推倒重来。自建的好处是,只要家里的宽带还在、路由器还在,这套东西就一直能用,谁也管不着。

所以我这篇走的是纯自建路线:路由器端口转发 + 一个自己的域名做动态解析。前期配置确实比一键方案麻烦一点,但配完之后你可以五年不用再碰它。

2. 硬件与系统准备:这一步偷懒,后面全是坑

很多人远程访问配不通,回头排查半天,最后发现是电源功率不够导致的网络间歇性断连,或者 TF 卡质量太差导致系统隔三差五卡死。树莓派4B 对供电和存储的要求比前几代高得多,这一步千万别省。

2.1 树莓派4B 的选型与外围配置清单

先说你手上那块板子。树莓派4B 有 1G、2G、4G、8G 四个内存版本。很多人以为只是跑 SSH 就随便买个 1G 的,我建议至少 2G 起步,原因很实际:系统本身加上 sshd、cron、日志服务就要吃掉 300M 左右,你但凡想在上面跑个 Docker 容器或者一个轻量的 Web 服务,1G 版本的内存很快就会到 85% 以上,触发 OOM 杀进程,表现出来的症状就是"莫名其妙连不上了"。想跑容器化服务,4G 是舒服的起点。

电源这块必须重点说。树莓派4B 的官方要求是 5V/3A,USB-C 接口。市面上大量标称"5V3A"的充电头实际带载能力根本达不到,电压一跌到 4.65V 以下,板子就会触发欠压保护,表现为 USB 设备掉线、网卡重连、系统日志里刷Under-voltage detected。远程访问最怕的就是网络间歇性断一下,因为这会让你的连接莫名其妙断开,而你人不在家根本看不到板子上的红灯。买官方电源或者口碑好的品牌电源,这一百来块钱省不得。

存储用 A2 级别的 TF 卡,容量 32G 起。日志、Docker 镜像、下载的文件都堆在卡上,杂牌卡跑几个月后出现坏块非常常见。我自己有两张卡就是这么废掉的,症状是系统启动到一半卡死,串口也没输出。

散热方面,树莓派4B 满载跑起来温度能到 80 度以上,超过 80 度会触发降频。被动散热片压不住长时间的高负载,我建议直接上带风扇的金属外壳,或者至少加个 5V 小风扇贴着散热片吹。判断方法很简单,SSH 连上去执行vcgencmd measure_temp,如果待机就在 65 度以上,说明散热不够。

网络连接上,能用网线就别用 WiFi。树莓派4B 的无线是 802.11ac 双频,日常够用,但长时间大流量传输(比如你从外面拖一个几 G 的文件回来)会出现丢包和速率波动,而且 WiFi 在路由器重启后重连有时会慢半拍。千兆有线口是这块板子最靠谱的网络通道,一根网线插上去,省掉后续一半的排查工作。

2.2 系统烧录与首次开机必须做的四件事

烧录用官方的镜像写入工具,选 Raspberry Pi OS Lite(无桌面版)就行,跑远程访问不需要桌面环境,省内存还少一堆服务。写入工具的高级选项里可以直接预置几项关键配置,一定要用上:设置主机名、创建用户名和密码、开启 SSH 服务、配置 WiFi(如果你确实只能用无线)。

这里有个很多人踩过的坑:从较新的系统版本开始,默认的网络管理方式从 dhcpcd 换成了 NetworkManager,网上大量老教程还在教改/etc/dhcpcd.conf固定 IP,照着做在新区型上根本没反应。判断方法很简单,登录后执行systemctl status NetworkManager,如果服务是 active,就走 NetworkManager 的配置方式。

首次开机后有四件事必须马上做,我按优先级排:

第一,改掉默认密码。树莓派的历史默认账号密码是公开的,任何扫描器第一件事就是试这个组合。哪怕你后面要禁用密码登录,也先把密码改掉。

第二,设置静态地址。树莓派必须有一个固定的局域网地址,否则路由器重启后 IP 一变,你的端口转发规则全部失效,人在外面就是连不上还不知道为什么。用 NetworkManager 的话,命令是这样的:

# 查看当前连接名称,通常是有线为 "Wired connection 1" nmcli connection show # 把地址、网关、DNS 固定下来 sudo nmcli connection modify "Wired connection 1" \ ipv4.method manual \ ipv4.addresses 192.168.1.50/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns "192.168.1.1,223.5.5.5" # 生效 sudo nmcli connection up "Wired connection 1"

地址我建议选 100 以后的号段(比如 192.168.1.50),避开路由器 DHCP 自动分配的默认区间,避免和别人撞地址。这一步做完,用ip addr确认一下地址已经变了,而且从别的设备能 ping 通,再往下走。

第三,更新系统。sudo apt update && sudo apt full-upgrade -y跑一遍,然后重启。为什么要先更新?因为安全补丁。远程访问意味着这台机器要暴露在公网上,系统里一个已知漏洞没修,你后面所有的安全配置都是白搭。

第四,确认时区正确。timedatectl set-timezone Asia/Shanghai。时区不对会导致日志时间戳错乱,你排查问题时看到的时间和你实际点击的时间对不上,会很抓狂。

3. 局域网里先把 SSH 打通,别急着往外跑

我一直建议的做法是:先把局域网内的访问打磨到顺手,再考虑公网。局域网都不通的,公网必然也不通,而且公网的问题要排查的因素多得多,你分不清是服务的问题还是网络的问题。

3.1 SSH 服务端的关键配置与密钥登录

系统默认的 SSH 配置在/etc/ssh/sshd_config。直接上来就用默认配置连也行,但我建议你一开始就把几个关键项改到位,省得后面来回重启服务。这是我用的一套配置片段:

# /etc/ssh/sshd_config # 改动监听端口,避开默认 22 Port 5022 # 只监听 IPv4,避免 IPv6 地址不通导致的连接超时 AddressFamily inet # 禁止 root 直接登录 PermitRootLogin no # 禁止密码认证,只用密钥 PasswordAuthentication no PubkeyAuthentication yes ChallengeResponseAuthentication no # 只允许指定用户登录 AllowUsers piworker # 认证次数与宽限时间收紧 MaxAuthTries 3 LoginGraceTime 30 # 心跳保活:60 秒探一次,连续 3 次无响应断开 ClientAliveInterval 60 ClientAliveCountMax 3

逐条说一下为什么这么设。监听端口改成 5022,是因为 22 端口是自动化扫描的第一目标,全世界几百万个扫描器盯着它,改成高位端口能挡掉 95% 以上的无效攻击流量,日志会干净很多,看日志时真正的异常才浮得出来。

禁止 root 登录 + 只允许指定用户,是权限最小化原则。攻击者就算猜到了密码,也没有一个能用的账号名。

禁用密码认证,这是最关键的一条。密码可以被暴力破解,密钥不行——ed25519 密钥的强度在现有算力下等同于不可破解。代价是你必须保管好私钥,丢了就得物理接触设备重新配。

心跳参数那两行,解决的是"连接放着不动几分钟就断"的问题。很多家用路由器会清理长时间空闲的连接表项,加了心跳之后,SSH 每 60 秒发一个空包,连接就不会被认为空闲。60 × 3 = 180秒,也就是三分钟内完全没有响应才会断开,这个阈值在网络抖动时比较宽容。

改完配置,先在本地生成密钥对。用 ed25519,不要用 RSA,前者密钥短、握手快、强度高:

ssh-keygen -t ed25519 -C "raspi-remote" -f ~/.ssh/raspi_ed25519

会生成raspi_ed25519(私钥)和raspi_ed25519.pub(公钥)两个文件。私钥绝对不能外传,权限也要收紧,chmod 600 ~/.ssh/raspi_ed25519。

把公钥推到树莓派上:

ssh-copy-id -i ~/.ssh/raspi_ed25519.pub -p 5022 piworker@192.168.1.50

如果ssh-copy-id用不了(比如 Windows 上没这个命令),手动把公钥内容追加到树莓派上的~/.ssh/authorized_keys里,然后确保.ssh目录权限是 700、authorized_keys是 600。权限不对的话 SSH 会直接拒绝密钥认证,而且日志里只给一句含糊的提示,这是新手最容易卡住的地方之一。

注意:改 sshd 配置的时候,永远保留一个已经连上的会话不要关。新开一个终端测试新配置能不能连上,确认没问题了再关掉旧会话。我见过太多人改完配置重启服务,结果新配置有语法错误,服务起不来,旧会话也断了,只能去拔电源接显示器。重启服务的正确姿势是先跑sudo sshd -t检查配置语法,通过了再sudo systemctl restart ssh。

3.2 客户端连接与几个高频报错

连接命令是ssh -i ~/.ssh/raspi_ed25519 -p 5022 piworker@192.168.1.50。每次都敲这么长一串很烦,在~/.ssh/config里加个别名,以后一条ssh pi就进去了:

Host pi HostName 192.168.1.50 Port 5022 User piworker IdentityFile ~/.ssh/raspi_ed25519 ServerAliveInterval 60 ServerAliveCountMax 3

这个配置文件里的ServerAliveInterval是客户端侧的心跳,和服务端侧的ClientAliveInterval是两回事,两边都配上才最保险——路由器清理连接表项是不看你哪一端发起的。

几个高频报错我列一下,遇到的时候对照着看:

Permission denied (publickey)——服务端不接受你提供的密钥。八成是authorized_keys的权限或者内容有问题,也可能是AllowUsers里没有你当前用的用户名。加-v参数看详细握手过程,会明确告诉你用了哪些密钥、服务端接受了哪些。

Host key verification failed——你重装过系统或者换过设备,指纹变了。确认是你自己的设备后,ssh-keygen -R "[192.168.1.50]:5022"清掉旧记录再连。

Connection refused——TCP 层通了,但目标端口上没有服务在监听。检查systemctl status ssh,或者用ss -tlnp | grep 5022看端口有没有被别的程序占了。

Connection timed out——连 TCP 握手都没完成。要么地址写错了,要么中间有防火墙挡着。先ping通再说。

4. 从局域网跨到公网:端口转发与动态域名解析

局域网打通之后,剩下的问题就两个:怎么让外面的请求找到你家路由器,以及怎么让路由器认得出这个请求该转给树莓派。这两件事分别对应端口转发和动态域名解析。

4.1 路由器端口转发的配置逻辑

端口转发的本质是在路由器上建一条规则:所有从外部打到某个公网端口上的连接,都原样转给局域网内某个地址的某个端口。不同品牌路由器里这个功能叫的名字不一样,有的叫"端口转发",有的叫"虚拟服务器",有的藏在"安全"或"NAT"下面,但填的字段都是那四样:

字段填什么说明
外部端口5022外网访问时用的端口
内部地址192.168.1.50树莓派的固定局域网地址
内部端口5022树莓派上 sshd 实际监听的端口
协议TCPSSH 只用 TCP,不要选"TCP+UDP"

这里我建议内外端口保持一致,排错的时候脑子清楚。但外部端口最好和内部端口错开一点,或者就用一个高位端口,理由前面说过——22 端口是扫描重灾区。我用 5022,你也可以用 22022、40022 之类的,选 1024 到 65535 之间任意没被占用的就行。

配置完保存,会要求重启路由器生效。重启后,局域网内的设备先测一遍ssh -p 5022 piworker@192.168.1.50确认没被影响,然后到外面去测公网访问。

先确认你家宽带是不是有独立的公网地址,这一步很多人跳过,结果配了半天端口转发,发现根本连不上。判断方法:在树莓派上执行curl -s https://api.ipify.org,记下这个结果;再登录路由器管理后台,看 WAN 口显示的地址。两个地址一模一样,说明你有公网地址;如果路由器 WAN 口显示的是类似 10.x.x.x、100.64.x.x 到 100.127.x.x 这种号段,说明你在运营商的共享地址池后面,端口转发到不了你这一层。

遇到后者也不用慌,有两条路:一是打运营商客服申请一个公网地址,这是正当需求,说明自己需要在家里访问监控设备,多数情况下能办下来;二是放弃公网方案,改用局域网内的方案,比如到家用同一个内网再访问,或者用树莓派主动连出去的方式。我个人推荐第一条,配好之后一劳永逸。

还有一个很多人忽略的点:不要图省事开 DMZ 主机。DMZ 会把树莓派的全部端口都暴露出去,等于把门全打开。你要的是什么端口就转发什么端口,一棵树莓派上真正需要从外面访问的服务通常不超过三个。

4.2 动态域名解析的落地方式

家庭宽带的公网地址通常每隔几天到几十天会变一次,具体取决于运营商的租期策略。地址一变,你之前记的那个 IP 就失效了。动态域名解析(DDNS)的作用就是:树莓派定时检测自己的公网地址,一旦发现变了,就自动去域名服务商那边把 A 记录改成新地址。你在外面只需要记一个固定的域名,永远能连上。

前提是你得有一个域名。不用买贵的,普通后缀一年几十块钱,解析记录随便改。买完之后在域名服务商的控制台里建一条 A 记录,先随便指向一个地址,然后拿到 API 密钥。

我用一个 bash 脚本干这件事,逻辑是"取当前公网地址 → 和上次记录的比对 → 不一致就调 API 更新"。这是简化版:

#!/bin/bash # /home/piworker/ddns.sh set -euo pipefail DOMAIN="your.domain.example" SUBDOMAIN="home" TOKEN="这里填你的 API 令牌" CACHE_FILE="/home/piworker/.last_ip" CURRENT_IP=$(curl -s --max-time 10 https://api.ipify.org) if [ -z "$CURRENT_IP" ]; then echo "$(date '+%F %T') 获取公网地址失败" exit 1 fi LAST_IP="" [ -f "$CACHE_FILE" ] && LAST_IP=$(cat "$CACHE_FILE") if [ "$CURRENT_IP" = "$LAST_IP" ]; then exit 0 fi RESP=$(curl -s --max-time 15 -X PUT \ "https://api.yourdns.example/v1/records" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d "{\"name\":\"$SUBDOMAIN\",\"type\":\"A\",\"content\":\"$CURRENT_IP\"}") echo "$(date '+%F %T') $LAST_IP -> $CURRENT_IP | $RESP" echo "$CURRENT_IP" > "$CACHE_FILE"

几个实操细节值得说。set -euo pipefail这三件套必须加,否则 curl 失败了脚本还会往下走,把空值写进缓存文件,下次比对全乱。--max-time参数也要加,不加的话网络卡住脚本会挂在那里,cron 任务越堆越多。缓存文件的作用是减少 API 调用,免费套餐一般有调用次数限制,五分钟一次已经足够及时了,别设成一分钟一次。

挂到 cron 上,每五分钟跑一次:

chmod +x /home/piworker/ddns.sh # crontab -e 里加一行 */5 * * * * /home/piworker/ddns.sh >> /home/piworker/ddns.log 2>&1

日志一定要重定向保存,不然出问题的时候完全看不到线索。我一般会隔一两周瞄一眼ddns.log,如果看到大段连续的错误,说明令牌过期了或者 API 改了,及早处理。

配置完成后,外面用ssh -p 5022 piworker@home.your.domain.example就能连了。第一次连上的时候心里会有点爽,但先别急着庆祝,接下来的部分才是决定这套东西能不能长期用的关键。

5. 暴露到公网之前,这六件事必须做完

树莓派一旦能从公网连上,你的日志里就会开始出现陌生的地址。这不是"可能",是"必然"——留给公网的端口在几小时内就会被扫到。我在一台新机器上配完端口转发,第二天起床看日志,/var/log/auth.log里躺着两百多条失败登录记录。

5.1 账号策略与密钥管理

前面已经禁用密码认证和 root 登录了,这两条是底线。再补充几点:

密钥不要到处复制。我见过有人把同一把私钥拷到公司电脑、笔记本、手机上,哪个丢了自己都不知道。正确做法是每台设备生成独立的密钥对,把各自的公钥加到树莓派的authorized_keys里,一条一行。这样哪台设备丢了,删掉对应那一行就行,其他设备不受影响。authorized_keys里每行末尾的注释就是用来区分设备的,写清楚一点,比如piworker@laptop-2024。

定期清理无效公钥。换过手机、重装过系统,对应的公钥就该删掉。这件事没人提醒,全靠自觉,我建议每季度花两分钟过一遍。

给常用账号加 sudo 白名单,别让日常账号直接就是全能的。虽然听起来啰嗦,但真出事的时候能少损失一点:

# 只允许 piworker 免密执行几个固定命令 echo "piworker ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp" | sudo tee /etc/sudoers.d/piworker sudo chmod 440 /etc/sudoers.d/piworker

5.2 防火墙:只放该放的,其余全关

Ubuntu/Debian 系上我习惯用 ufw,配置简单直观。默认策略设成"拒绝所有入站、允许所有出站",然后逐条放行需要的端口:

sudo apt install ufw -y sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 5022/tcp comment 'ssh' sudo ufw allow from 192.168.1.0/24 to any port 8080 proto tcp comment 'web 仅内网' sudo ufw enable sudo ufw status verbose

注意8080那条规则——我用from限定了只有局域网能访问。这是个很实用的技巧:Web 管理面板、数据库这类服务,永远不要直接开给公网,需要远程访问的时候走 SSH 隧道或者只允许特定来源地址。

这里补一句,树莓派上如果同时跑着 Docker,容器映射出来的端口会绕过 ufw 的规则,因为 Docker 直接操作 iptables。这个坑很多人踩:明明 ufw 里没放行 3306,外面却能连上 MySQL。解决办法是在daemon.json里配置"iptables": false或者给容器绑定127.0.0.1:3306:3306,我推荐后者,简单直接,端口只在本机可达,需要外部访问时再通过 SSH 转发。

5.3 登录审计与自动封禁

被扫是常态,关键是要能自动处理。fail2ban 就是干这个的:盯着日志,发现某个地址在短时间内连续登录失败超过阈值,就临时封掉它的地址。

sudo apt install fail2ban -y sudo tee /etc/fail2ban/jail.local <<'EOF' [DEFAULT] bantime = 3600 findtime = 600 maxretry = 4 [sshd] enabled = true port = 5022 logpath = /var/log/auth.log backend = systemd EOF sudo systemctl enable --now fail2ban sudo fail2ban-client status sshd

参数解释一下:maxretry = 4表示十分钟内失败四次就封;bantime = 3600表示封一小时。这两个值是我的经验值——设得太松没效果,设得太严自己手滑输错几次就被锁在外面,还得去路由器上换个出口地址才能连回来,很狼狈。如果你经常在外面连,建议把maxretry调到 5 或者 6。

backend = systemd这行很重要,新版系统的 SSH 日志走 journald 而不是写文件,不指定的话 fail2ban 找不到日志,规则形同虚设。

光靠自动封禁还不够,每周花五分钟看一下登录统计,能提前发现一些慢速试探:

# 看最近成功登录的记录 last -a | head -20 # 统计失败登录的来源地址 top 10 sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

如果last里出现了你不认识的登录时间或者来源地址,立刻改密码、换密钥、检查有没有可疑的定时任务(crontab -l和/etc/cron.d/目录)。别心存侥幸,宁可白忙一场。

6. 让它自己活下去:开机自启与长期运行

一套远程访问方案配好之后,真正的考验是时间。板子断电重启、系统更新、进程崩溃、内存泄漏——这些事在你不在家的时候发生,而你根本不知道。所以我最后这部分讲的是怎么让它"挂了能自己爬起来"。

6.1 用 systemd 托管你的后台服务

不管你在树莓派上跑的是采集脚本、Web 服务还是定时任务,都别用nohup xxx &这种野路子。那玩意儿 SSH 一断就没了,重启更不用说。正确做法是写一个 systemd 单元。

假设你有个数据采集脚本放在/home/piworker/app/collector.py,单元文件这么写:

# /etc/systemd/system/collector.service [Unit] Description=Home data collector After=network-online.target Wants=network-online.target [Service] Type=simple User=piworker WorkingDirectory=/home/piworker/app ExecStart=/usr/bin/python3 /home/piworker/app/collector.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target

几个参数的意义:After=network-online.target加Wants,保证网络真正就绪之后再启动,不加的话开机时服务会比网络先起来,一上来就连不上外部接口,然后崩溃重试,日志里一堆连接错误。Restart=always加RestartSec=10,表示无论什么原因退出都等 10 秒重来,10 秒的间隔是为了防止疯狂重启把日志刷爆。Environment=PYTHONUNBUFFERED=1是 Python 专属的坑,不加这个的话输出会缓冲在内存里,你在journalctl里看不到实时日志,排查问题时会以为程序卡死了。

启用并查看状态:

sudo systemctl daemon-reload sudo systemctl enable --now collector sudo systemctl status collector sudo journalctl -u collector -f --lines=50

journalctl -f实时跟踪日志,排查时的第一手工具。加上--since "1 hour ago"只看最近的,输出会干净很多。

6.2 温度、磁盘、内存的日常监控

树莓派跑久了,最容易出问题的三样是温度、TF 卡空间和内存。我做了一个每天早上跑一次的小脚本,输出写日志,出问题时回看:

#!/bin/bash # /home/piworker/health.sh echo "=== $(date '+%F %T') ===" echo "温度: $(vcgencmd measure_temp)" echo "磁盘: $(df -h / | awk 'NR==2 {print $5" 已用,剩 "$4}')" echo "内存: $(free -h | awk 'NR==2 {print "已用 "$3" / 总 "$2}')" echo "负载: $(cat /proc/loadavg)" echo "运行时长: $(uptime -p)" echo "SSH 失败数: $(sudo grep -c 'Failed password' /var/log/auth.log 2>/dev/null || echo 0)"

vcgencmd measure_temp返回的温度超过 80 度就要处理了,清灰、换硅脂、加风扇。磁盘使用率超过 85% 也得清,TF 卡写满之后系统会变得极慢,甚至无法写入日志。负载值看三位数,如果 1 分钟负载长期在 2 以上(四核),说明有东西在持续吃 CPU。

这个脚本挂在 cron 里每天早八点跑:

0 8 * * * /home/piworker/health.sh >> /home/piworker/health.log 2>&1

日志文件记得做轮转,不然一年下来能占几百兆。系统自带的 logrotate 加一条配置就行:

# /etc/logrotate.d/piworker-health /home/piworker/health.log { weekly rotate 8 compress missingok notifempty }

还有个容易被忽略的点:给树莓派配一个定时重启。不是必须,但对于跑了几个月的系统,每周重启一次能清掉不少内存碎片和僵尸进程。用systemd的定时器或者直接 cron 加一行0 4 * * 0 /sbin/reboot,凌晨四点重启,不影响使用。

7. 排查实录:连不上的时候按这个顺序查

远程访问出问题,最怕的是没有章法地乱试。我按"从下往上"的逻辑整理了一套排查顺序,从物理层到应用层,一层层往上,每层都有明确的判断方法,能快速定位问题出在哪一段。

7.1 五层排查法,逐层缩小范围

第一层:设备活着吗。人在外面的时候,最简单的判断是看路由器后台有没有树莓派的在线记录。能进路由器管理页面,说明家里宽带是通的;设备列表里有树莓派,说明板子在跑;如果没有,八成是断电或者系统挂了,这就得回家处理了。

第二层:局域网通不通。如果你在家,直接ping 192.168.1.50。不通的话,检查网线、检查电源指示灯、检查是不是 IP 被别人占了(路由器后台看看 DHCP 分配列表)。这一步不通,后面全免谈。

第三层:服务在不在。ping通了但 SSH 连不上,在树莓派上(或者接显示器)执行:

sudo systemctl status ssh sudo ss -tlnp | grep 5022

服务没起就systemctl start ssh,看报错原因;服务起了但端口没监听,多半是配置文件里Port写错或者被注释掉了。

第四层:端口转发生效了吗。这一层区分"内网能连、外网不能连"的情况。用手机开流量(别连 WiFi),访问一个在线的端口检测工具,输入你的域名和外部端口,看是不是 open。如果显示 closed 或 filtered,回去检查路由器上的转发规则:内部地址对不对、协议选没选 TCP、规则有没有启用、有没有和别的规则冲突。

第五层:域名解析对不对。nslookup home.your.domain.example看一下解析出来的地址是不是当前的真实公网地址。对不上就是 DDNS 脚本没跑或者跑失败了,去看ddns.log。

这套顺序的价值在于,任何一次故障你都能定位到具体是哪一层出问题,而不是盲目地重启所有东西。我见过太多人一出问题就重启路由器、重装系统,折腾一晚上,最后发现只是 TF 卡满了导致 sshd 起不来。

7.2 高频问题速查表

现象最可能的原因处理方式
家里能连,外面连不上端口转发没生效检查路由器规则,确认公网地址存在
早上能连,下午就不行了公网地址变了,DDNS 没更新看 ddns.log,检查 API 令牌
连上后几分钟自动断开连接空闲被路由器清理双侧都配心跳参数
提示 Connection refused服务没起或端口变了systemctl status ssh、ss -tlnp
提示 Permission denied密钥权限或 AllowUsers 问题检查文件权限 600/700,加-v看握手
偶尔能连偶尔不能电源欠压或 WiFi 抖动换电源、插网线、看dmesg里的欠压记录
速度极慢上行带宽限制、散热降频测速、查温度、看有没有其他进程占带宽
系统卡死、无响应TF 卡坏块、内存耗尽换卡、加 swap、看dmesg里的 I/O 错误

表格里"偶尔能连偶尔不能"这一条我特别想展开说。这个症状最折磨人,因为每次你去查的时候它又是好的。我的经验是,八成出在电源上。查证方法:dmesg | grep -i voltage,如果有Under-voltage detected的记录,基本可以确诊。换一个靠谱的电源,症状立刻消失。剩下两成是无线信号问题,插网线解决。

还有一条没写进表格但很关键:TF 卡寿命。树莓派的系统盘是 TF 卡,频繁写入会加速磨损。日志、数据库、Docker 镜像都是写入大户。如果你打算长期跑,我强烈建议接一个 USB 移动硬盘或者固态盘,把系统迁过去,或者至少把/var/log和数据库目录挂到外置存储上。这一步能让你的设备寿命从一两年延长到五年以上。迁移系统的方法是把整个根分区用rsync同步到新盘,改一下/boot/firmware/cmdline.txt里的根分区 UUID,具体步骤网上有很多,核心思路就是"同步数据、改引导参数、验证能启动之后再格式化旧卡"。

最后分享一个我自己的习惯:每次改动配置之前先备份。/etc/ssh/sshd_config、路由器的配置导出、DDNS 脚本,改之前都复制一份加日期后缀。远程设备最怕的就是改坏了还进不去,有个备份至少能让你在物理接触设备的时候快速回滚,而不是从零开始重配一遍。这套东西我现在已经跑了很久,中间经历过搬家、换路由器、换宽带,每次迁移都是照着这几步走一遍,一小时以内搞定。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询