作者: 启鑫

  • FortiGate与StrongSwan IPsec VPN隧道实现互联互通

    如何利用 IPsec VPN 技术,在 FortiGate防火墙 与 StrongSwan 开源IPsec工具之间建立稳定且安全的互联互通隧道。IPsec VPN作为一种成熟可靠的加密隧道技术,广泛应用于连接不同的分支机构或云环境,确保跨网络通信的安全。实现两端网络的加密通信。

    拓扑概述

    在开始配置之前,请确保您对IPsec VPN的基本概念有一定了解。本文的配置基于以下假设:

    • FortiGate 端:公网IP为 10.10.20.1,内部网络为 192.168.1.0/24
    • StrongSwan 端:公网IP为 10.10.10.1,内部网络为 192.168.2.0/24
    • 预共享密钥 (PSK)qixinlee.com

    我们的目标是建立一个IPsec隧道,使 192.168.1.0/24192.168.2.0/24 两个子网能够相互通信。

    StrongSwan配置步骤

    StrongSwan是一款功能强大的开源IPsec实现,常用于Linux系统。以下是详细的配置步骤:

    1. 系统准备与安装

    首先更新系统并安装StrongSwan:

    apt update
    apt install strongswan -y

    2. 启用IP转发

    为了让StrongSwan服务器能够转发来自VPN隧道的数据包,您需要启用IPv4转发:

    echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
    sysctl -p

    运行sysctl -p是为了立即应用配置,无需重启系统。

    3. 配置防火墙(UFW)

    如果您的StrongSwan服务器启用了UFW防火墙,需要允许IPsec相关的流量通过:

    ufw allow 500/udp   # IKE(Internet Key Exchange)端口
    ufw allow 4500/udp  # NAT-T(NAT Traversal)端口
    ufw allow proto esp from any to any # 允许ESP协议
    ufw allow proto ah from any to any  # 允许AH协议(如果使用)

    注意: 在调试阶段,您可以临时禁用UFW (ufw disable) 以排除防火墙引起的问题,但在生产环境中务必重新启用并配置正确的规则。

    4. 配置预共享密钥

    编辑 /etc/ipsec.secrets 文件,添加FortiGate的公网IP、StrongSwan的公网IP和预共享密钥:

    vim /etc/ipsec.secrets
    10.10.10.1 10.10.20.1 : PSK "qixinlee.com"

    重要提示: 密钥应使用强密码,并妥善保管。

    5. 配置IPsec连接

    编辑 /etc/ipsec.conf 文件,定义IPsec连接的详细参数:

    vim /etc/ipsec.conf
    config setup
        charondebug="ike 2, knl 2, cfg 2, net 2"
    
    conn fortigate-cloud-vpn
        auto=start # StrongSwan启动时自动建立连接
        keyexchange=ikev2 # 使用IKEv2协议,更安全高效
        ike=aes256-sha256-modp2048! # 阶段1加密算法:AES256, 完整性算法:SHA256, DH组:MODP2048 (Group 14)
        esp=aes256-sha256! # 阶段2加密算法:AES256, 完整性算法:SHA256
        ikelifetime=8h # 阶段1密钥生存周期
        lifetime=1h # 阶段2密钥生存周期
        dpddelay=30 # DPD检测间隔
        dpdtimeout=120 # DPD超时时间
        dpdaction=restart # DPD超时后重启隧道
        authby=secret # 认证方式为预共享密钥
    
        left=%defaultroute # StrongSwan的本地IP使用默认路由接口IP
        leftid=10.10.10.1 # StrongSwan的本地ID,应与FortiGate配置的远端ID匹配
        leftsubnet=192.168.2.0/24 # StrongSwan本地网络的子网
    
        right=10.10.20.1 # FortiGate的对端公网IP
        rightid=10.10.20.1 # FortiGate的对端ID,应与FortiGate配置的本地ID匹配
        rightsubnet=192.168.1.0/24 # FortiGate远程网络的子网

    6. 重启IPsec服务并检查状态

    保存 ipsec.conf 文件后,重启StrongSwan服务并检查隧道状态:

    ipsec down fortigate-cloud-vpn # 如果连接已存在,先关闭
    ipsec restart # 重启StrongSwan服务
    ipsec up fortigate-cloud-vpn # 尝试建立连接
    ipsec status # 查看IPsec隧道状态

    您应该能看到隧道建立成功的相关信息。

    FortiGate配置步骤

    FortiGate防火墙的配置通常通过图形界面完成,以下将列出关键配置项:

    1. 网络配置(FortiGate VPN阶段1通用设置)

    • IP版本: IPv4
    • 远端网关: 静态IP地址,填写StrongSwan的公网IP 10.10.10.1
    • 接口: 填写 FortiGate 出口到公网的网卡(例如 wan1
    • NAT穿越: 启用
    • 保持存活: 10 秒
    • 对等体状态探测(DPD): 按需
    • DPD重试计数: 4
    • DPD重试间隔: 30 秒

    2. 认证(FortiGate VPN阶段1认证设置)

    • 方法: 预共享密钥
    • 预共享密钥: qixinlee.com
    • IKE版本: 2

    3. VPN阶段1(Phase 1)配置

    阶段1定义了ISAKMP(Internet Security Association and Key Management Protocol)的安全参数:

    • 加密算法: AES256
    • 认证算法: SHA256
    • Diffie-Hellman组: 组 14 (与StrongSwan的 modp2048 对应)
    • 密钥生存时间 (秒): 28800 (8小时,与StrongSwan的 ikelifetime 对应)
    • 本地ID: 10.10.20.1 (FortiGate的公网IP)。这个ID与StrongSwan的 rightid 对应。

    4. VPN阶段2(Phase 2)配置

    阶段2定义了IPsec隧道的安全参数:

    • 本地地址: 子网 192.168.1.0/24
    • 对端地址: 子网 192.168.2.0/24
    • 加密算法: AES256
    • 认证算法: SHA256
    • Diffie-Hellman组: 组 14 (与StrongSwan的 modp2048 对应)
    • 启用重放检测: 启用
    • PFS (Perfect Forward Secrecy): 启用
    • 本地端口: 全部
    • 对端端口: 全部
    • 协议: 全部
    • 密钥周期 (秒/kb): 3600 秒 (1小时,与StrongSwan的 lifetime 对应)

    5. 隧道接口与策略路由

    建立IPsec隧道后,您需要配置相应的策略路由和防火墙策略,以允许流量通过隧道:

    • 创建IPsec隧道接口: 在FortiGate中,您需要创建一个虚拟IPsec隧道接口,例如 VPN_to_StrongSwan
    • 策略路由:
      • FG_to_VPN (FortiGate到VPN):
        • 源接口: 内部网络接口 (例如 lan)。
        • 源地址: 192.168.1.0/24
        • 目的接口: VPN_to_StrongSwan 隧道接口。
        • 目的地址: 192.168.2.0/24
        • 动作: 接受 (ACCEPT)。
        • NAT: 不启用 NAT。
      • VPN_to_FG (VPN到FortiGate):
        • 源接口: VPN_to_StrongSwan 隧道接口。
        • 源地址: 192.168.2.0/24
        • 目的接口: 内部网络接口 (例如 lan)。
        • 目的地址: 192.168.1.0/24
        • 动作: 接受 (ACCEPT)。
        • NAT: 不启用 NAT。

    验证与故障排除

    配置完成后,请务必进行验证:

    1. 检查IPsec状态: 在StrongSwan端运行 ipsec status,在FortiGate端查看VPN监控界面。
    2. Ping测试: 从StrongSwan内部网络的主机Ping FortiGate内部网络的主机,反之亦然。
    3. 抓包分析: 如果通信不畅,可以使用tcpdump (StrongSwan) 或 FortiGate的诊断工具进行抓包分析,查看是否有加密和解密的数据包。
    4. 日志分析: 检查FortiGate和StrongSwan的系统日志,寻找任何错误或警告信息。StrongSwan的 charondebug 参数可以帮助提供详细的IKE日志。

    常见问题与排查思路:

    • 预共享密钥不匹配: 确保两端的PSK完全一致。
    • IKE/ESP参数不匹配: 加密算法、认证算法、DH组、密钥生存周期等参数必须严格一致。
    • NAT穿越问题: 如果任何一端位于NAT设备后面,确保端口 500/udp4500/udp 已正确转发。
    • 防火墙规则: 确保两端防火墙都允许IPsec流量(UDP 500, UDP 4500, ESP协议)。
    • 子网定义错误: 确保 leftsubnetrightsubnet 定义正确,且与实际网络匹配。
    • 路由问题: 检查路由表,确保流量被正确地送入IPsec隧道。
  • Windows 系统使用 Robocopy 高效备份文件夹

    如果你想快速又稳定地复制电脑里的某个文件夹(比如 D 盘中的某个目录)到另一个位置,那么 Windows 自带的 Robocopy 工具会是你的得力助手。它比你平时拖动复制文件强大得多,能够处理各种细节,让备份变得更加高效、省心。

    一、设置命令行编码

    在使用 Robocopy 命令之前,建议你先在命令行窗口运行以下命令:

    chcp 65001

    这会将当前命令行窗口的字符编码设置为 UTF-8,避免中文路径或文件名出现乱码问题。

    二、完整保留文件权限的复制命令

    要镜像复制一个文件夹并保留所有文件元数据(包括权限信息),可以使用这个命令:

    robocopy "D:\AAA" "E:\AAA-backup" /MIR /COPY:DATS /R:3 /W:5 /MT:8

    这个命令会将 D:\AAA 文件夹完整镜像复制E:\AAA-backup,确保目标文件夹是源文件夹的精确副本,包含安全信息。

    参数解析:

    使用 /COPY:DATS 通常需要管理员权限才能成功复制权限。否则,可能会出现权限复制失败的情况。

    • "D:\AAA":这是源目录,即你要复制的原始文件夹。
    • "E:\AAA-backup":这是目标目录,文件将复制到这里。
    • /MIR:启用镜像模式。目标目录将与源目录保持完全一致——包括新增、修改和删除的内容。请注意:此参数可能会删除目标目录中存在但源目录中没有的文件,务必小心使用。
    • /COPY:DATS:指定要复制的内容包括:
      • D:数据(文件内容)
      • A:属性(如只读、隐藏等)
      • T:时间戳(创建、修改时间)
      • S:安全信息(即 NTFS 权限)
    • /R:3:失败时最多重试 3 次。
    • /W:5:每次重试之间等待 5 秒。
    • /MT:8:启用 8 线程并发复制,可以显著提升性能,尤其是在处理大量小文件或大文件时。

    三、无需复制权限的轻量级备份命令

    如果你不需要保留文件权限,可以使用一个更轻量级的命令:

    robocopy "D:\AAA" "E:\AAA-backup" /MIR /COPY:DAT /R:3 /W:5 /MT:8

    参数解析:

    使用 /COPY:DAT 通常不需要管理员权限,兼容性更好,适合普通用户。

    • "D:\AAA":你的源目录
    • "E:\AAA-backup":你的目标目录
    • /MIR:启用镜像模式,使目标目录与源目录精确匹配。同样需要注意,这可能会删除目标目录中不存在于源目录的文件。
    • /COPY:DAT:指定要复制的内容包括:
      • D:数据(文件内容)
      • A:属性
      • T:时间戳
    • /R:3:失败时最多重试 3 次。
    • /W:5:每次重试之间等待 5 秒。
    • /MT:8:启用 8 线程并发复制,以提高性能。

    四、如何选择 /COPY:DATS 还是 /COPY:DAT

    你的选择取决于你的具体需求:

    • 选择 /COPY:DATS(完整权限,需要管理员权限),适用于:
      • 备份包含重要权限设置的文件(如服务器配置文件、用户资料、共享目录)。
      • 需要在目标目录中完全还原访问控制的场景。
    • 选择 /COPY:DAT(不保留权限,适用于一般用户),适用于:
      • 个人数据备份、日常同步。
      • 不关心权限保留,只关注文件内容和属性。
      • 在权限不足无法复制 ACL(访问控制列表)的环境中。

    五、生成日志,方便备份追踪与排错

    如果希望保留哪些文件被复制、跳过或出错,可以使用下面这个更推荐的写法:

    robocopy "D:\AAA" "E:\AAA-backup" /MIR /COPY:DAT /R:3 /W:5 /MT:8 /LOG:"E:\backup-log.txt"

    如果希望保留所有历史记录,并且实时查看输出信息,可以使用下面这个更推荐的写法:

    robocopy "D:\AAA" "E:\AAA-backup" /MIR /COPY:DAT /R:3 /W:5 /MT:8 /LOG+:"E:\backup-log.txt" /TEE /NP

    常用日志参数说明:

    • /LOG:"路径":将输出写入指定的日志文件(覆盖原内容)。
    • /LOG+:"路径":将输出追加到现有日志文件中,避免覆盖历史记录。
    • /TEE:在命令行中显示的同时写入日志文件,便于观察进度。
    • /NP:不显示进度百分比,使日志更简洁易读。
  • Docker 部署 FossFLOW轻松绘制3D云架构与网络拓扑图

    什么是 FossFLOW

    FossFLOW 是一个专注于架构可视化的轻量级前端工具,旨在简化复杂系统图的绘制过程。它采用独特的 等距视角,将网络、云架构、系统拓扑等内容以 3D 立体效果清晰呈现,让抽象结构一目了然。

    主要特点与优势

    • 3D 等距视图:带来更具透视感的展示方式,帮助快速识别组件之间的关系。
    • 纯前端应用:无需部署后端,直接在浏览器中使用,轻便高效。
    • 专为架构设计打造:内置丰富的云计算、网络设备组件,专注支持云架构、网络拓扑、数据流图等场景。
    • 易于使用: 直观的界面和拖放功能使得用户可以快速上手并创建专业的架构图。

    应用场景

    FossFLOW 的设计使其非常适合以下场景:

    • 云架构设计: 无论是 AWS、Azure 还是 Google Cloud,FossFLOW 可以帮助架构师和工程师可视化云资源、服务和它们之间的关系,从而更好地规划和管理云部署。
    • 网络拓扑: 绘制服务器、路由器、交换机、防火墙等网络设备的连接图,清晰展示数据流路径和网络结构。
    • 系统设计: 用于描绘软件系统的组件、模块及其交互,帮助开发团队理解系统的高层结构。

    使用 Docker 部署 FossFLOW

    FossFLOW 是前端应用,部署过程非常简单。借助 Docker可以在几分钟内启动并使用。

    1. 克隆代码仓库

    打开终端,执行以下命令:

    git clone https://github.com/stan-smith/FossFLOW
    cd FossFLOW

    这会将 FossFLOW 的代码下载到本地机器,并进入项目根目录。

    2. 运行容器

    docker compose up -d

    3. 打开浏览器访问:

    http://localhost:3000

    看到 FossFLOW 的界面,现在可以开始拖拽组件、连接节点、构建专属的 3D 架构图了!

  • Web 部署新选择:Docker 还是 Podman

    容器化已成为现代 Web 网站部署的核心策略。无论是 Docker 还是 Podman,都能将你的网站及其所有依赖打包成一个独立、可移植的单元,从而极大地简化部署流程。作为开发者,你需要了解它们在架构和使用上的差异,因为这些差异会直接影响你的部署效率、系统安全性,甚至是未来的可扩展性。容器仅仅是一种工具,而非最终目的。

    Docker

    Docker 作为容器技术的先行者,凭借其强大的生态系统和丰富的工具链,已成为 Web 应用部署的事实标准

    优点:

    • 海量镜像资源,开发部署高效: Docker Hub 上拥有庞大的官方和社区镜像库,涵盖了 Nginx、Node.js、MySQL 等各类服务。这意味着你无需从头配置,就能快速拉取所需环境,大幅缩短开发和部署周期。
    • Docker Compose 简化多服务部署: 现代 Web 应用常由多个服务构成(如 Web 服务器、数据库、缓存)。docker-compose.yml 文件允许你通过一份声明式配置,一次性定义并启动所有相关服务,实现“一键部署”,极大地简化了开发、测试和生产环境的管理。
    • 与云原生编排工具无缝集成: 如果你的网站未来需要扩展到集群环境以应对高并发(例如使用 Kubernetes 或 Docker Swarm),Docker 能提供良好的兼容性。这为你的大规模部署奠定了坚实的基础,确保平滑过渡。
    • 跨平台一致性,提升团队协作效率: 无论团队成员使用 Windows、macOS 还是 Linux,Docker Desktop 都能提供统一的容器开发和运行体验,有效减少“在我机器上能跑”的问题,确保开发与生产环境的高度一致。

    适用场景:

    • 容器技术初学者,希望快速入门并能找到大量学习资料和社区支持。
    • 需要同时管理多个相互依赖的服务,例如 WordPress + MySQL。
    • 计划将 Web 应用部署到大型云平台或 Kubernetes 集群
    • 团队成员操作系统多样,需要统一的开发环境以提高协作效率。

    Podman

    Podman 是容器领域的一颗新星,以其独特的无守护进程架构卓越的安全性在 Linux 环境中脱颖而出。

    优点:

    • 无守护进程,支持无 Root 运行,安全性更高: 这是 Podman 的核心优势。它没有常驻后台的守护进程,并且支持“无根容器”(rootless containers)。这意味着你可以以普通用户身份运行容器,即使容器被攻陷,攻击者也难以获得宿主机的 Root 权限,显著降低了安全风险。
    • 与 Systemd 原生集成,简化服务管理: 在 Linux 服务器上,你可以将容器直接注册为 systemd 服务,享受系统级的自启动、守护和监控功能。这让 Web 服务的长期管理变得异常简单和可靠,特别适合在 VPS 或物理服务器上部署。
    • 资源占用低,提升边缘设备性能: 由于 Podman 没有常驻守护进程,它仅在执行命令时才消耗资源。这使得它在资源有限的服务器(如小型 VPS 或边缘设备)上更为高效,能有效节省内存和 CPU,提升系统整体性能。
    • 支持 Pod 架构,与 Kubernetes 理念一致: Podman 能够管理“Pod”(一组共享网络和存储的容器),这与 Kubernetes 的设计理念完全一致。你可以将 Web 服务和数据库打包进一个 Pod,简化它们之间的通信和数据共享,同时也为未来迁移到 Kubernetes 做了技术储备。

    适用场景:

    • 对安全性有极高要求,希望容器能够在无 Root 权限下运行。
    • 主要在 Linux 服务器上进行部署,并希望容器能与系统服务 (systemd) 紧密集成。
    • 资源受限的环境,追求极致的性能和效率。
    • 希望提前熟悉 Kubernetes 的 Pod 概念,为未来的云原生转型做准备。

    实际使用中的关键差异

    除了核心特性,实际部署中还有一些细节差异值得开发者注意:

    • 1. 命令行兼容性并非百分百: 尽管 Podman 的命令与 Docker 大致相似,但在一些高级用法、网络配置或特定参数上仍存在细微差别。习惯 Docker 的用户可能需要短暂的适应期。
    • 2. 镜像构建方式: Docker 主要使用 docker build 命令和 Dockerfile 来构建镜像。Podman 虽然也支持 podman build,但它更推崇与 Buildah 工具集成。Buildah 提供了更底层的控制和更多样的构建方式(甚至无需 Dockerfile),这对于需要高度定制化构建流程的开发者来说非常有用。
    • 3. 存储卷与权限处理: 在 Linux 系统下,Docker 和 Podman 在处理容器存储卷的默认权限和 SELinux 安全上下文时可能有所不同。特别是在 Podman 的无根容器模式下,存储卷的权限配置需要开发者更加细致地处理,以避免潜在的文件访问问题。

    特性对比

    特性/维度DockerPodman
    架构有守护进程(dockerd无守护进程,命令直接调用容器引擎
    无 Root 运行需要 Root (或 sudo)支持 rootless 模式
    多容器编排Docker Compose / Swarm支持 Pod,但 Compose 支持较弱
    与 Systemd 集成需额外配置或借助外部工具原生支持 systemd 生成服务文件
    镜像构建docker build (基于 Dockerfile)podman build + Buildah (更灵活)
    资源占用较高 (后台常驻 dockerd)更低 (按需启动,无守护)
    安全性中等 (需注意权限)高 (支持无 Root 容器,强权限隔离)

    Docker 和 Podman 并非相互对立,它们代表了两种不同的容器设计理念:

    • Docker = 生态成熟 + 上手快 + 支持云原生全流程。
    • Podman = 安全优先 + 系统集成强 + 更贴近 Linux 哲学。
  • 使用 Podman 部署 Cockpit 和 Immich 机器学习容器

    使用 Podman 部署安装 Cockpit 管理工具并使用 Podman 启动 Immich 的机器学习容器。以便在浏览器中方便配置和访问

    一、开放所需端口

    在默认情况下,Linux 防火墙(firewalld)可能会阻止一些端口的外部访问。为了确保 Cockpit 和 Immich 模块能够正常被访问,需要永久放行相关端口。

    1. 放行 9090 端口(用于 Cockpit)

    firewall-cmd --add-port=9090/tcp --permanent
    firewall-cmd --reload

    2. 放行 3003 端口(用于 Immich 机器学习容器)

    firewall-cmd --permanent --add-port=3003/tcp
    firewall-cmd --reload

    二、安装 Cockpit 和 Podman

    Cockpit 是一款轻量级的 Web 管理工具,可用于查看系统信息、容器、服务等。

    dnf install podman cockpit cockpit-podman -y

    安装完成后,启用并启动 Cockpit:

    systemctl enable --now cockpit.socket

    然后可通过浏览器访问 Cockpit:

    https://<你的服务器IP>:9090

    注意:首次访问时浏览器可能提示 SSL 证书不安全,可选择“继续前往”。

    三、部署 Immich Machine Learning 容器

    Immich 是一个支持自动图片整理、面部识别等功能的自托管照片管理系统。我们配置immich的远程机器学习提高计算速度

    1. 下载镜像

    podman pull ghcr.io/immich-app/immich-machine-learning:release

    2. 运行容器

    podman run \
      --name immich_machine_learning \
      --restart=always \
      --replace \
      -p 3003:3003 \
      -v model-cache:/cache \
      -e TZ=Asia/Shanghai \
      -d \
      ghcr.io/immich-app/immich-machine-learning:release

    此命令的作用如下:

    • --name: 指定容器名称
    • --restart=always: 容器自动重启策略
    • --replace: 替换已有同名容器
    • -p 3003:3003: 映射本地端口
    • -v model-cache:/cache: 使用持久卷缓存模型
    • -e TZ=Asia/Shanghai: 设置时区
    • -d: 后台运行容器

    四、配置容器开机自动启动(可选但推荐)

    虽然运行容器时使用了 --restart=always,但 Podman 默认并不会像 Docker 一样在系统启动时自动重启容器。要实现真正的“开机自启”,需依赖 systemd 启动服务。

    1. 生成并安装 systemd 单元文件

    podman generate systemd --name immich_machine_learning --files --restart-policy=always

    这将在当前目录生成 container-immich_machine_learning.service 文件。将其移动到系统服务目录并启用:

    mv container-immich_machine_learning.service /etc/systemd/system/
    systemctl daemon-reexec
    systemctl enable container-immich_machine_learning.service

    五、验证部署

    • 访问 Cockpit Web 控制台查看容器状态:
      https://<你的服务器IP>:9090
    • 访问 Immich ML 控制台查看容器状态:
      http://<你的服务器IP>:3003

  • RHEL 10 局域网 Repo 服务器配置指南

    在一台 Red Hat Enterprise Linux 10 (RHEL 10) 主机配置为本地 Repo 服务器。通过此设置,局域网内的其他 RHEL 10 客户端将能够高效地进行系统更新和软件包安装,无需直接连接到 Red Hat 官方仓库提供更快更稳定的传输。

    1. 前提条件

    在开始配置之前,请确保满足以下条件:

    • 操作系统: 一台已安装 Red Hat Enterprise Linux 10 (RHEL 10) 的物理机或虚拟机。
    • Red Hat 订阅: 拥有一个有效的、已附加到该主机的 Red Hat 订阅。
    • 网络连接: 能够访问互联网,以便从 Red Hat 官方同步软件包。
    • IP 地址: Repo 服务器拥有一个固定的局域网 IP 地址,例如 192.168.1.199
    • 存储空间: 至少拥有 1TB 的可用磁盘空间。
    • 权限: 拥有 root 权限。

    2. Repo 服务器配置步骤

    2.1. 注册Red Hat Subscription Management 并刷新订阅信息

    注册 Red Hat Subscription Management 并刷新订阅信息,以确保能够访问 Red Hat 官方仓库。

    [root@192-168-1-199 ~]# subscription-manager register

    注册完成后,刷新机器上的信息:

    [root@192-168-1-199 ~]# subscription-manager refresh
    All local data refreshed

    2.2. 安装并配置 Apache Web 服务器

    使用 Apache HTTP Server 来提供同步的软件包文件。

    [root@192-168-1-199 ~]# dnf update -y
    [root@192-168-1-199 ~]# dnf install -y httpd
    [root@192-168-1-199 ~]# systemctl start httpd
    [root@192-168-1-199 ~]# systemctl enable httpd

    配置防火墙以允许 HTTP 流量(默认端口 80):

    [root@192-168-1-199 ~]# firewall-cmd --permanent --add-port=80/tcp
    success
    [root@192-168-1-199 ~]# firewall-cmd --reload
    success

    2.3. 安装 yum-utils 工具

    yum-utils 软件包包含了 reposync 工具,用于同步远程仓库。

    [root@192-168-1-199 ~]# dnf install -y yum-utils

    2.4. 查看已启用的仓库 ID

    在同步软件包之前,我们需要确认哪些 Red Hat 仓库是可用的。

    [root@192-168-1-199 ~]# dnf repolist
    Updating Subscription Management repositories.
    repo id                               repo name
    rhel-10-for-x86_64-appstream-rpms     Red Hat Enterprise Linux 10 for x86_64 - AppStream (RPMs)
    rhel-10-for-x86_64-baseos-rpms        Red Hat Enterprise Linux 10 for x86_64 - BaseOS (RPMs)

    从输出中可以看到,我们需要同步的仓库 ID 是 rhel-10-for-x86_64-baseos-rpmsrhel-10-for-x86_64-appstream-rpms

    2.5. 创建本地仓库存储目录

    把同步的软件包存储在 Apache 的默认网站根目录 /var/www/html/ 下的一个子目录 rhel10-repo 中。

    [root@192-168-1-199 ~]# mkdir -p /var/www/html/rhel10-repo

    2.6. 同步 Red Hat 仓库

    使用 reposync 命令同步 BaseOSAppStream 仓库。

    # 同步 BaseOS 仓库
    reposync --repo=rhel-10-for-x86_64-baseos-rpms -p /var/www/html/rhel10-repo --newest-only --delete
    
    # 同步 AppStream 仓库
    reposync --repo=rhel-10-for-x86_64-appstream-rpms -p /var/www/html/rhel10-repo --newest-only --delete
    • --repo=<repo_id>: 指定要同步的仓库 ID。
    • -p /path/to/download: 指定下载软件包的本地路径。
    • --newest-only: 只下载每个软件包的最新版本,这可以节省大量的磁盘空间和同步时间。
    • --delete: 删除本地仓库中已不存在于远程仓库的软件包,以保持同步。

    2.7. 创建仓库元数据

    同步完成后,需要为本地仓库创建元数据,以便客户端能够识别和使用这些软件包。如果未安装 createrepo_c,请先安装:

    [root@192-168-1-199 ~]# dnf install -y createrepo_c

    为每个同步的仓库创建元数据:

    # 为 BaseOS 仓库创建元数据
    [root@192-168-1-199 ~]# createrepo_c /var/www/html/rhel10-repo/rhel-10-for-x86_64-baseos-rpms/
    
    # 为 AppStream 仓库创建元数据
    [root@192-168-1-199 ~]# createrepo_c /var/www/html/rhel10-repo/rhel-10-for-x86_64-appstream-rpms/

    您可以通过浏览器访问 http://192.168.1.199/rhel10-repo/ 来验证目录结构和文件是否已成功同步。

    3. 配置局域网客户端

    在局域网内需要使用此本地 Repo 服务器的 RHEL 10 客户端机器上,进行以下配置:

    3.1. 备份并禁用现有 Red Hat 仓库

    首先备份并禁用客户端上现有的 Red Hat 官方仓库配置,以避免冲突。

    [root@client-machine ~]# mkdir -p /etc/yum.repos.d/bak
    [root@client-machine ~]# mv /etc/yum.repos.d/redhat.repo /etc/yum.repos.d/bak/

    3.2. 创建新的本地仓库文件

    创建一个新的 .repo 文件,指向您的本地 Repo 服务器。

    [root@client-machine ~]# vi /etc/yum.repos.d/local-rhel10.repo

    在文件中添加以下内容:

    [local-baseos]
    name=Local RHEL 10 BaseOS
    baseurl=http://192.168.1.199/rhel10-repo/rhel-10-for-x86_64-baseos-rpms/
    enabled=1
    gpgcheck=0
    
    [local-appstream]
    name=Local RHEL 10 AppStream
    baseurl=http://192.168.1.199/rhel10-repo/rhel-10-for-x86_64-appstream-rpms/
    enabled=1
    gpgcheck=0
    • baseurl: 指向您的 Repo 服务器的 IP 地址和正确的仓库路径。
    • enabled=1: 表示启用这个仓库。
    • gpgcheck=0: 表示不进行 GPG 密钥检查。在受信任的内部局域网环境中,这通常是可以接受的简化操作。如果您希望启用 GPG 检查以提高安全性,则需要将 Red Hat 的 GPG 密钥导入到客户端。

    3.3. 清除 dnf 缓存并测试

    清除 dnf 缓存并测试是否能正确列出新的本地仓库。

    [root@client-machine ~]# dnf clean all
    [root@client-machine ~]# dnf repolist

    如果一切配置正确,您应该会看到 local-baseoslocal-appstream 这两个仓库。

    4. 自动化维护

    为了确保本地 Repo 服务器始终提供最新的软件包,建议设置一个定时任务来定期同步仓库和更新元数据。

    4.1. 创建自动化脚本

    在 Repo 服务器上创建一个脚本,用于执行 reposynccreaterepo_c 命令。

    [root@192-168-1-199 ~]# mkdir -p /root/script/
    [root@192-168-1-199 ~]# vi /root/script/update_local_repo.sh

    添加以下内容到 update_local_repo.sh 文件中:

    #!/bin/bash
    
    # 脚本日志文件
    LOG_FILE="/var/log/repo_sync.log"
    
    # 要同步的仓库ID列表
    REPOS=(
      "rhel-10-for-x86_64-baseos-rpms"
      "rhel-10-for-x86_64-appstream-rpms"
    )
    
    # 仓库根目录
    REPO_PATH="/var/www/html/rhel10-repo"
    
    echo "==========================================" >> $LOG_FILE
    echo "脚本开始于: $(date)" >> $LOG_FILE
    
    # 同步所有仓库
    for REPO_ID in "${REPOS[@]}"; do
      echo "--> 正在同步仓库: $REPO_ID" | tee -a $LOG_FILE
      reposync --repo=$REPO_ID -p $REPO_PATH --newest-only --delete >> $LOG_FILE 2>&1
    done
    
    # 为更新后的仓库重新创建元数据
    for REPO_ID in "${REPOS[@]}"; do
      REPO_DIR="$REPO_PATH/$REPO_ID"
      if [ -d "$REPO_DIR" ]; then
        echo "--> 正在为 $REPO_ID 创建元数据" | tee -a $LOG_FILE
        createrepo_c -v $REPO_DIR >> $LOG_FILE 2>&1
      fi
    done
    
    echo "脚本结束于: $(date)" >> $LOG_FILE
    echo "==========================================" >> $LOG_FILE

    4.2. 授予脚本执行权限

    [root@192-168-1-199 ~]# chmod +x /root/script/update_local_repo.sh

    4.3. 设置 Cron 定时任务

    编辑 crontab,设置脚本在每天凌晨 2:30 自动运行。

    [root@192-168-1-199 ~]# crontab -e

    在打开的 crontab 编辑器中添加以下一行:

    30 2 * * * /root/script/update_local_repo.sh

    查看crontab 任务计划列表

    [root@192-168-1-199 ~]# crontab -l
    30 2 * * * /root/script/update_local_repo.sh
    [root@192-168-1-199 ~]#

    本地 Repo 服务器将每天自动同步 Red Hat 官方仓库并更新元数据,确保局域网内的客户端始终能够获取到最新的软件包。