简介:面向内网环境中的Linux运维人员,在无法访问互联网时,为Rocky Linux服务器配置基于HTTP的局域网YUM源是提升软件部署效率、保障版本一致性的核心手段。资源以Rocky 9.2为例,完整覆盖从镜像挂载、本地仓库配置、httpd服务安装到客户机成功接入全流程,适合系统管理员及企业内网部署者参考。压缩包共1个docx格式文档,120KB,内容以文字与命令示例为主,详细说明服务器端(192.168.15.100)与客户端(192.168.15.101)两侧配置,包括local.repo中BaseOS和AppStream仓库的URL设置、yum clean all与makecache验证方法等。目前已有1691人学习浏览,实用性强。文档从实际项目出发,指出将镜像挂载至HTTP根目录、关闭firewalld及临时降低SELinux策略等关键细节,可帮助读者快速搭建并应用于其他基于RPM的Linux发行版。
1. 内网几十台机器装软件装到怕:先搭一个基于 HTTP 的局域网 yum 源
几十台 Linux 服务器泡在内网里,没外网,装软件先被依赖项教育一遍:yum install 一个包,报一串 error: Failed dependencies,手动去拉 rpm,又连环缺依赖,半天装不出一个 httpd。这种环境我负责的群组里每天都在上演。与其每台机器单独配本地源,或者抱着 U 盘来回拷包,不如拿一台机器当仓库,把 Rocky-9.2-x86_64-dvd.iso 挂载后用 httpd 通过 HTTP 协议把 yum 仓库吐给整个局域网,其余服务器把 baseurl 指过来,yum install 和 yum update 立刻恢复正常体验。这篇拆一下我在 Rocky 9.2 上做完这套的完整过程:挂载、配源、验证、排错,适合被内网装机磨掉耐心的运维,也适合第一次搭局域网源的新手。
2. 选型与仓库结构:为什么是 HTTP + BaseOS/AppStream,而不是 NFS 或 DVD 直挂
2.1 三条内网软件分发路线对比
内网环境里给一批 Linux 机器提供软件包,常见路线无非三条:HTTP、NFS、共享目录或 U 盘。我做这套之前先纠结了一阵,后来把三条路的成本列了个表,选型就清楚了。
| 分发方式 | 客户机要求 | 防火墙端口 | 跨网段能力 | 适合场景 |
|---|---|---|---|---|
| HTTP | 仅 yum/dnf,零额外组件 | 只需放行 80 | 好,路由可达即可 | 通用首选,本文方案 |
| NFS | 需要 nfs-utils 和 rpcbind | 111 + mountd 动态端口 | 一般,要放一串端口 | 机房已有成熟 NFS 存储 |
| U 盘/共享目录 | 每台机器人工操作 | 无 | 差,得一台台跑 | 三五台机器的临时救急 |
NFS 方案看着直接,把 ISO 挂载目录 export 出去就行,但客户机要装 nfs-utils、要处理 rpcbind 和动态端口放行,几十台机器的规模并不省事。U 盘方案更难受,每台机器都要手动挂载,跟「每台配本地源」本质上没区别,软件包一旦更新,又要重跑一遍。
HTTP 的优势在于 yum/dnf 原生支持 http 协议的 baseurl,客户机不需要装任何额外组件,只要网络能通 80 端口就能用。而且排错手段特别直接——curl 一下 URL,通不通、返回什么状态码一目了然,这在后面验证仓库可用性的时候会反复用到。生产环境还能用 httpd 的访问日志看谁在拉包,这是 NFS 给不了的可见性。
2.2 Rocky 9.2 的仓库结构:BaseOS 与 AppStream 各管什么
从 CentOS 7 时代过来的人,对仓库结构的认知通常是 base、extras、updates 三个源各指一个 URL。Rocky 9 这套完全变了:DVD 镜像里只有 BaseOS 和 AppStream 两个仓库目录,客户机必须同时用上这两个,少一个都会遇到「软件包找不到」的尴尬。
BaseOS 承担的是操作系统核心内容,kernel、glibc、systemd、核心 shell 工具这类最底层的东西;AppStream 承载应用和运行时,httpd、nginx、python、php 都归它管。这也是为什么原文配置里 local.repo 必须写两段——你只配 BaseOS 去 yum install httpd,会直接告诉你 No match for argument,因为 httpd 的 rpm 躺在 AppStream 的 Packages 目录里。网上搜 centos7 配置网络 yum 源的教程套到 Rocky 9 上必翻车,就是这个结构差异。
AppStream 还带模块流的概念,同一个软件有多个 stream 版本可选,默认装 default stream。对应到局域网源,客户机只要用默认的 yum install 行为就行,不需要额外处理模块流,源服务器端也不用做任何特殊设置,ISO 里的 repodata 已经把这些元数据都带上了。真正要记住的是:两个仓库段都要 enabled=1,并且 baseurl 分别指向挂载点下的 BaseOS 和 AppStream 两个子目录。
2.3 动手前的核对清单:IP、镜像、目录约定一次想清楚
原文档里其实埋了一个小坑:环境准备部分写的是 192.168.15.100,后面的配置示例里又出现过 192.168.1.100 的写法。这种 IP 笔误在实操里是 404 的头号原因,后面避坑章节会展开。动手前先把这些固定下来:yum 服务器 192.168.15.100(linux1),客户机 192.168.15.101(linux2),镜像固定用 Rocky-9.2-x86_64-dvd.iso,ISO 文件放 /opt 下,挂载点固定在 /var/www/html/opt。
这个目录约定不是随便定的。/var/www/html 是 httpd 的默认文档根目录,ISO 挂到这里之后,客户机访问 http://192.168.15.100/opt/BaseOS/ 就等价于读服务器上的 /var/www/html/opt/BaseOS/,不需要额外配置 httpd 的 Alias。要是图省事把挂载点放在别的路径,还得去改 httpd 配置,多一层出错机会。
环境预检在搭之前跑一遍,确认镜像文件完整、磁盘够放、SELinux 当前状态心里有数:
# 检查磁盘空间,ISO 接近 10GB,/opt 和 /var/www 至少要留出镜像体积的空间 df -h /opt /var/www # 确认 ISO 已经就位 ls -lh /opt/Rocky-9.2-x86_64-dvd.iso # 看 SELinux 当前状态,后面验证排错会用到 getenforcedf 是看磁盘剩余空间的,ISO 文件体积不小,万一空间不够,挂载和后续解包都会出问题;ls 确认镜像文件传输完整,SecureFX 或 scp 传大文件偶尔会中断,文件大小和源端对不上就得重传;getenforce 返回 Enforcing 或 Permissive,这个值决定了第五章节里 403 排错的走向。
3. 服务器端实操:挂载 ISO、先装 httpd、再用 curl 自证仓库可访问
3.1 挂载镜像 ISO:目录规划与只读挂载的讲究
服务器端的第一步是把 ISO 挂载到 httpd 的文档根目录下。挂载这种动作我习惯显式带上参数写清楚,不依赖系统自动推断,这样后续排查时 mount 输出的信息更明确。
# 创建挂载点目录,-p 保证父目录不存在时一并创建 mkdir -p /var/www/html/opt # 以 loop 回环设备方式挂载 ISO,只读挂载避免误写 mount -o loop,ro /opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt # 确认挂载结果:能看到 BaseOS 和 AppStream 两个目录说明 ISO 内容完整 ls /var/www/html/opt # 查看文件系统类型,应该是 iso9660 df -hT /var/www/html/opt-o loop是把 ISO 文件当作块设备挂载的关键参数,新版 util-linux 有时候会自动补 loop,但显式写出来更稳,老版本系统不会翻车。ro是只读,ISO 本身是只读文件系统,多写这个参数是给 mount 一个明确约束。df 输出里文件系统类型显示 iso9660 就说明挂载成功,挂载点容量就是镜像实际大小。
这里有个小细节:挂载点 /var/www/html/opt 的命名里带 opt,会跟服务器上 /opt 目录混淆。它俩一个是 httpd 的 URL 路径前缀,一个是 ISO 文件的存放位置,逻辑上是独立的。URL 访问路径是 http://192.168.15.100/opt/BaseOS/,对应文件系统路径是 /var/www/html/opt/BaseOS/,这个映射关系在客户机配置章节还要再强调一次。
3.2 先配本地源再装 httpd:解决先有鸡还是先有蛋的问题
服务器本身也没有外网,yum install httpd 之前必须先让这台机器能访问到仓库。这时候 ISO 已经挂载好了,直接配一个指向本地文件系统的 local.repo,让 yum 从 file:// 协议读取仓库元数据。
# 写本地源配置文件 cat > /etc/yum.repos.d/local.repo <<'EOF' [Rocky-BaseOS] name=Rocky-BaseOS baseurl=file:///var/www/html/opt/BaseOS enabled=1 gpgcheck=0 [Rocky-AppStream] name=Rocky-AppStream baseurl=file:///var/www/html/opt/AppStream enabled=1 gpgcheck=0 EOFbaseurl 用 file:// 协议指向挂载点下的两个仓库目录,yum 会去这两个目录里找 repodata 子目录读元数据。gpgcheck=0 在这个场景下是合理的:内网源没有外网来拉取 RPM 签名密钥,实验环境直接关掉校验;严谨的团队可以改成 gpgcheck=1 并从镜像里提取 RPM-GPG-KEY-rockyofficial 配置 gpgkey,但那是后话。
接下来处理一个关键动作:把系统自带的 Rocky 官方源配置文件挪走。Rocky 9 安装完后 /etc/yum.repos.d/ 下有一堆自带的 .repo 文件,它们指向公网的 mirrorlist。如果不处理,yum 会先尝试连外网域名,在内网环境里每次都要等到超时才会切到本地源,体验极其糟糕。
# 备份系统自带的官方源,而不是直接删,留后悔药 mkdir -p /root/repobak mv /etc/yum.repos.d/Rocky-*.repo /root/repobak/ 2>/dev/null # 重建缓存并确认只剩两个仓库 yum clean all yum makecache yum repolistmv 到 /root/repobak 而不是 rm,是我搭源以来养成的习惯。系统自带的 Rocky-BaseOS.repo、Rocky-AppStream.repo 这些文件本身没毛病,只是不适合内网,万一后面要恢复外网源,mv 回去就行。yum repolist 输出会列出两个仓库,同时显示数量,如果这里只看到一个仓库或者报错,说明 local.repo 语法或路径有问题,尽早处理,别等到客户机配置完才返工。
3.3 启动 httpd 并用 curl 自证仓库可访问
本地源就位后,安装 httpd 就是一条命令的事。安装完之后启动服务、设置开机自启,然后立刻用 curl 验证 HTTP 层面能不能访问到仓库元数据,这是整个搭建过程中最容易跳过但最重要的一步——服务器自己都访问不到,客户机就更别想了。
# 安装 httpd,-y 跳过交互确认 yum install -y httpd # 启动并设置开机自启,--now 等价于 start + enable 两步 systemctl enable --now httpd # 本机自证:请求仓库元数据文件,预期返回 200 OK curl -I http://127.0.0.1/opt/BaseOS/repodata/repomd.xml # 用服务器自己的 IP 再验证一次,确认监听地址没问题 curl -I http://192.168.15.100/opt/BaseOS/repodata/repomd.xmlcurl -I 是发送 HEAD 请求,只看响应头不拉正文,速度快且够用。返回 200 OK 说明路径映射、文件权限、httpd 配置全链路都通;返回 404 基本是 URL 路径和实际文件系统路径对不上;返回 403 则指向权限或 SELinux。repomd.xml 是 yum 仓库元数据的入口文件,它请求通了,说明整个 BaseOS 仓库的 HTTP 发布是完好的。
防火墙和 SELinux 在这个阶段要先做临时的处理,好让验证能跑通。内网测试环境我一般直接停掉 firewalld,省得排查干扰;生产环境则用 firewall-cmd 放行 http 服务而不是停防火墙:
# 内网测试环境临时做法 systemctl stop firewalld # 生产环境推荐做法:只放行 80 端口 firewall-cmd --permanent --add-service=http firewall-cmd --reload # SELinux 临时设为 Permissive setenforce 0setenforce 0 只是当前内核生效,重启后恢复 Enforcing,这一点对后续的 403 排错很关键。这里先临时放行让链路跑通,第五节会用 semanage 给出 SELinux 的永久解法。
4. 客户机端接入:baseurl 换成 http 协议后,三步验证源可用
4.1 客户机的 local.repo:URL 怎么写才不会 404
客户机端的配置核心就一件事:把 baseurl 从 file:// 协议换成 http:// 协议,指向服务器的仓库路径。这个 URL 的构成逻辑是新手最容易绕晕的地方:服务器文件系统上的完整路径是 /var/www/html/opt/BaseOS,但 httpd 把 /var/www/html 当作文档根目录,所以 URL 里只写 /opt/BaseOS,不写 /var/www/html。
# linux2 客户机上执行,写入局域网源配置 cat > /etc/yum.repos.d/local.repo <<'EOF' [Rocky-BaseOS] name=Rocky-BaseOS baseurl=http://192.168.15.100/opt/BaseOS enabled=1 gpgcheck=0 [Rocky-AppStream] name=Rocky-AppStream baseurl=http://192.168.15.100/opt/AppStream enabled=1 gpgcheck=0 EOFrepo 配置里的其他字段和服务器端完全一致,变的只是协议和主机部分。这个配置文件可以理解为一个「地址簿」:yum 每次用包的时候,根据 baseurl 去对应位置下载 rpm 和元数据。192.168.15.100 是 linux1 的 IP,端口 80 是 http 默认端口,URL 里不写也没问题。
客户机的系统官方源同样需要处理,跟服务器端一模一样的操作:把 Rocky-*.repo 全部 mv 到备份目录。这一步在客户机上尤其重要,因为客户机原本的源文件指向公网,如果不处理,yum makecache 会先去连接公网 mirrorlist,在内网里白白等到超时。这也就是「could not retrieve mirrorlist」报错的源头,第五节细说。
4.2 清缓存、重建缓存、列清单:三步走完源就活了
配置写完之后,验证的动作是固定的三步,我在每台客户机上都是这么操作:clean all 清掉旧缓存,makecache 重新拉取元数据,repolist 和 list 确认仓库可用、能列出软件包。
# 清掉 yum 缓存,避免旧数据干扰 yum clean all # 重建缓存,成功时会显示下载 repomd.xml 和 primary 元数据 yum makecache # 确认仓库 ID、状态和软件包数量 yum repolist # 列出可安装的软件包,验证源真正可用 yum list | head -n 20makecache 的输出里有几个信息值得看:每个仓库会显示 metadata 下载成功,并展示软件包数量。如果这里 BaseOS 显示几千个包、AppStream 显示几千个包,说明源已经通了。yum list 会输出大量软件包列表,配 head 只看前面部分避免刷屏。
再进一步验证实际操作,装一个小工具最直接。比如 yum install -y tree,装完执行 tree --version 看能不能跑。这一步的意义在于验证的不只是元数据访问,还有 rpm 包本身的下载和安装链路——元数据能拉不代表 rpm 文件权限没问题,实际装一个包才算闭环。
4.3 批量下发:几十台客户机怎么快速替换 repo 文件
单台客户机手动配置没问题,但如果是几十台机器,一台台 vi 文件会浪费大量时间。常见做法是把 local.repo 用 scp 批量推送,配合 for 循环每台机器清一次缓存。这个操作我在内网环境里用过无数次,效率提升明显。
# 从服务器或管理机执行,批量下发 repo 配置并重建缓存 for h in 192.168.15.101 192.168.15.102 192.168.15.103; do scp /etc/yum.repos.d/local.repo root@$h:/etc/yum.repos.d/ ssh root@$h "yum clean all && yum makecache" donefor 循环里做的事情等价于手动两步:scp 把配置推过去,ssh 远程执行清缓存和重建。几十台机器的规模用这种 shell 循环足够,规模再大就上 ansible 的 copy 模块和 command 模块,思路一样。批量操作前先在单台客户机上把 4.1 和 4.2 完整跑通,确认配置模板没问题再铺开。另外注意 scp 推之前,客户机上的 Rocky-*.repo 也得先备份移走,否则新配置文件跟系统源并存,makecache 照样会去碰公网地址。
5. 避坑指南:404、mirrorlist 报错、rm -rf 陷阱,五个真实翻车现场
5.1 makecache 报 Could not retrieve mirrorlist 或 404
现象:客户机执行 yum makecache 时卡住,最终报 Could not retrieve mirrorlist http://mirrorlist.rockylinux.org 之类的错误;或者报 [Errno 14] HTTP Error 404 - Not Found,仓库 ID 后面跟着一大段 URL,明确提示哪个地址找不到。
原因:前者十有八九是客户机 /etc/yum.repos.d/ 下系统自带的 Rocky-*.repo 没清掉,yum 优先访问公网 mirrorlist,内网无外网,只能干等到超时;后者是 baseurl 里的 IP 或路径写错,比如把 192.168.15.100 写成 192.168.1.100,或者多写了 /var/www/html 前缀。
解决:先备份移走系统官方源,只留 local.repo;然后在客户机上用 curl -I 手动验证 URL,返回 200 再去做 makecache。curl 这一步能把「网络不通」「路径不对」「服务没起」三类问题区分开,比反复 yum 试错快得多。IP 这类笔误,配置完用 grep 确认一遍 baseurl 里的地址再收工。
5.2 curl 返回 403 Forbidden,服务器日志有 Permission denied
现象:服务器本机 curl -I http://127.0.0.1/opt/BaseOS/repodata/repomd.xml,返回 403 Forbidden;查看 /var/log/httpd/error_log,能看到 Permission denied 或者 SELinux 相关的 avc 拒绝记录。
原因:SELinux 在 Enforcing 模式下,httpd 进程对 /var/www/html/opt 这个挂载点目录没有 httpd_sys_content_t 标签,默认策略拒绝访问。有时候也可能是目录权限缺 o+x,但内网环境里刚挂载的目录出现 403,SELinux 的嫌疑最大。
解决:先 setenforce 0 临时放行,如果 curl 立刻变 200,确认是 SELinux 问题,然后做永久配置而不是停在临时放行:
# 安装 SELinux 管理工具 yum install -y policycoreutils-python-utils # 给挂载目录打上 httpd 可读的标签 semanage fcontext -a -t httpd_sys_content_t "/var/www/html/opt(/.*)?" restorecon -Rv /var/www/html/opt # 重新验证 curl -I http://127.0.0.1/opt/BaseOS/repodata/repomd.xmlsemanage 给目录加一条类型规则,restorecon 把规则应用到现有文件和目录上。做完这两步,即使 SELinux 保持 Enforcing,httpd 也能正常读仓库目录。这里必须强调:setenforce 0 只是临时手段,重启后失效,到时候 403 卷土重来,还不如一次做到位。
5.3 rm -rf !(local.repo) 删不干净甚至直接报错
现象:网上不少文档推荐用 rm -rf !(local.repo) 这种「排除式删除」来清掉多余 repo 文件,实际操作时,交互式 bash 里直接报 bash: !: event not found,或者报 syntax error near unexpected token(';就算开了 extglob,命令里带着空格(比如写成 !( local.repo))还会匹配出诡异的模式,可能误删文件。
原因:!(pattern) 是 bash 的 extglob 扩展语法,默认不开启,需要先执行 shopt -s extglob,而且这种写法在交互式 shell 里会跟历史展开冲突。很多教程直接甩一行命令却不交代前置条件,照着抄翻车太正常了,我还见过带空格笔误把排除目标写错造成误删的。
解决:别在批量文件操作上用这类玄学写法,用可预期的命令:
# 方案一:安全备份法,先备份再清理 ls /etc/yum.repos.d/*.repo | grep -v '^/etc/yum.repos.d/local.repo$' | xargs -r mv -t /root/repobak/ # 方案二:如果确定系统自带的源文件命名规律,直接按名字清 rm -f /etc/yum.repos.d/Rocky-*.repo /etc/yum.repos.d/rocky*.repo # 删除后习惯性确认,再重建缓存 ls /etc/yum.repos.d/ yum makecache方案一用 grep -v 做排除,逻辑直观可见,mv 到备份目录而不是 rm,出问题能恢复。方案二依赖 Rocky 官方源的文件命名规律,直接点名删除。两条路都比 extglob 好理解。重点不是命令多高级,而是删完必须 ls 看一眼目录里剩什么,再 makecache 验证,这套确认动作能挡住绝大多数手误。
5.4 客户机 curl 超时或拒绝连接,但服务器本机正常
现象:客户机执行 curl http://192.168.15.100/opt/BaseOS/ 超时或者 connection refused,但登录到服务器本机 curl 却是通的。
原因:服务器本机通说明挂载和 httpd 配置没问题,问题在网络层或服务状态上。最常见三个:第一,httpd 启动了但没设置开机自启,其实当前是停止状态(enable 和 start 是两回事,systemctl enable --now 一步做完最省事);第二,firewalld 在运行且没放行 80 端口;第三,客户机和服务器跨网段,中间交换机有访问控制列表拦了。
解决:在服务器上按顺序排查,哪一步异常处理哪一步:
# 看 httpd 监听状态,能监听 0.0.0.0:80 才说明服务活着 ss -ltnp | grep ':80 ' # 看防火墙放行情况 firewall-cmd --list-all # 没放行就加一条,生产环境别直接 stop firewalld firewall-cmd --permanent --add-service=http firewall-cmd --reload # 确认 httpd 开机自启 systemctl enable httpd排查顺序有讲究:先确认服务在听,再检查防火墙,最后才考虑交换机。这里如果 SELinux 之前是 setenforce 0 临时放行,重启后又变回 Enforcing,客户机也会看到异常,但表现通常是 403 而不是连接拒绝,注意区分。
5.5 服务器重启后所有客户机集体 404
现象:服务器机房断电重启后,所有客户机 yum 全部报 404,仓库目录空空如也。登录服务器看,/var/www/html/opt 目录存在但里面没有文件,df 也看不到挂载信息。
原因:mount 命令只对当前内核运行期生效,重启后挂载关系丢失,/var/www/html/opt 变成一个空目录,HTTP 请求自然 404。同时 setenforce 0 也会随重启失效,如果之前依赖临时放行,这时候 403 也会跟着回来。
解决:把挂载关系写进 /etc/fstab,让系统开机自动挂载,这是一劳永逸的做法:
# 追加一行到 /etc/fstab,字段顺序: 设备 挂载点 类型 选项 dump fsck cat >> /etc/fstab <<'EOF' /opt/Rocky-9.2-x86_64-dvd.iso /var/www/html/opt iso9660 loop,ro,defaults 0 0 EOF # 用 mount -a 验证 fstab 配置语法没问题,再重启 mount -a df -hT /var/www/html/optfstab 六个字段依次是设备文件、挂载点、文件系统类型、挂载选项、是否 dump 备份、是否 fsck 检查。iso9660 是光盘文件系统类型,loop 表示回环设备,ro 只读,defaults 补全常规选项。关键动作是 mount -a:它按 fstab 重新挂载一遍,语法有错当场暴露,不会等到重启才炸。fstab 写错最严重的情况是系统起不来,所以 mount -a 验证这一下绝不能省。SELinux 如果之前用 setenforce 0 临时放过行,现在要把 5.2 里的 semanage 命令也一并做掉,否则重启后又是 403。
6. 进阶打磨:目录索引、EPEL 离线中转与仓库健康自查脚本
6.1 打开 httpd 目录索引,浏览器直接看仓库内容
源搭好能用之后,我习惯把 httpd 的目录索引打开,这样浏览器访问 http://192.168.15.100/opt/ 就能直接看到 BaseOS 和 AppStream 两个目录,人工确认包是否落位非常直观。默认 httpd 对 /var/www/html 是开了 Indexes 的,如果之前改过全局配置,单独给仓库目录补一个配置段:
# 给仓库目录明确开启目录索引 cat > /etc/httpd/conf.d/repo.conf <<'EOF' <Directory "/var/www/html/opt"> Options Indexes FollowSymLinks Require all granted </Directory> EOF # 重载配置生效 systemctl reload httpdOptions Indexes 允许显示目录列表,FollowSymLinks 允许跟随符号链接,Require all granted 是允许所有客户端访问。这些参数对仓库目录是合理的,毕竟它本来就是给内网机器读的。打开目录索引还有个好处:客户机报 404 的时候,浏览器一开就能看出路径结构和实际目录对不对得上。
6.2 EPEL 和扩展软件包怎么进局域网源
DVD 镜像里的 BaseOS 和 AppStream 覆盖面有限,内网机器想装 EPEL 里的软件时,标准做法是在一台有外网的机器上把 EPEL 仓库同步下来,再打包传回内网源服务器。这个流程就是把公网源变成局域网源的通用套路。
# 在有外网的机器上执行:安装工具并同步 epel 仓库 dnf install -y epel-release createrepo_c mkdir -p /tmp/epel dnf reposync --repoid=epel --downloaddir=/tmp/epel --download-metadata # 把同步好的仓库目录传回内网源服务器 scp -r /tmp/epel root@192.168.15.100:/var/www/html/ # 在内网源服务器上重新生成元数据 createrepo_c -v /var/www/html/epelreposync 是 dnf 插件提供的命令,按仓库 ID 把 rpm 全部拉下来,--download-metadata 会顺带下载元数据。传到内网后还要跑一次 createrepo_c 生成索引,是因为跨机器搬运可能导致元数据路径失效。客户机要用的仓库段就是在 local.repo 里再加一个 [epel-local],baseurl 指向 http://192.168.15.100/epel。注意不同版本的 dnf 对 reposync 参数支持有差异,执行前先 dnf reposync --help 确认参数名,另外 EPEL 全量仓库非常大,建议只同步实际需要的软件包组,否则几百 GB 的传输会拖垮内网带宽。
6.3 十分钟健康自查脚本:搭完源先跑一遍
交付一个局域网源之前,我习惯跑一个自查脚本,把服务器端和客户机端的核心链路一次性验完。脚本逻辑很简单:curl 逐个请求仓库元数据文件,检查 HTTP 状态码,再确认服务监听和挂载状态。
#!/bin/bash # repo_check.sh 在源服务器本机执行 for u in \ http://127.0.0.1/opt/BaseOS/repodata/repomd.xml \ http://127.0.0.1/opt/AppStream/repodata/repomd.xml; do code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 3 "$u") echo "$code $u" done # 检查 httpd 监听端口 ss -ltnp | grep -q ':80 ' && echo "httpd listener: PASS" || echo "httpd listener: FAIL" # 检查挂载点 df -hT /var/www/html/opt | tail -n 1 # 检查 SELinux 关键标签 ls -Zd /var/www/html/optcurl 的 -w '%{http_code}' 只输出状态码,-o /dev/null 丢弃正文,--connect-timeout 3 避免内网环境里长时间挂起。状态码的解读规则:200 是仓库可访问,404 查挂载和路径,403 查 SELinux 和权限,000 是连接失败查 httpd 和防火墙。客户机端排查时,把脚本里的 127.0.0.1 换成服务器 IP 再跑一遍,就能快速定位是服务器问题还是客户机网络问题。
从那以后,我每次搭完或者维护完一个局域网 yum 源,都强制自己走一遍这套动作:curl 请求 repomd.xml、客户机 makecache、再实际 yum install 一个最小软件包,三步全部通过才算交付。这个习惯帮我挡掉了好几次重启后集体翻车的事故。希望帮到你。
本文还有配套的精品资源,点击获取