You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux启动阶段验证授权文件:无授权则阻止启动并要求激活

Linux启动时验证授权密钥:阻止登录并处理用户输入的方案

完全可以实现你要的需求——在系统启动时检查授权文件,不存在则要求输入密钥,验证失败就重启系统。你之前遇到的init脚本无法输出和获取输入的问题,主要是因为早期启动阶段stdout/stdin还没默认绑定到控制台,只要明确指定控制台设备就能解决。下面分主流的systemd和传统SysVinit两种场景给你具体方案:

一、Systemd系统(绝大多数现代Linux发行版:Ubuntu、CentOS 7+、Debian 9+等)

1. 编写授权验证脚本

创建一个可执行脚本/usr/local/bin/check_license.sh,负责检查授权文件、获取用户输入并处理验证逻辑:

#!/bin/bash

# 定义授权文件路径和控制台设备
LICENSE_FILE="/etc/license.key"
CONSOLE="/dev/console"

# 输出信息到控制台(解决早期启动无输出的问题)
echo "=== System License Check ===" > $CONSOLE

# 检查授权文件是否存在
if [ ! -f "$LICENSE_FILE" ]; then
    echo "License file not detected! Please enter your activation key:" > $CONSOLE
    # 从控制台读取用户输入
    read -r ACTIVATION_KEY < $CONSOLE

    # 这里替换为你的密钥验证逻辑(示例:对比预设的有效密钥哈希或调用验证逻辑)
    # 建议用哈希对比,避免明文存储有效密钥,比如:
    # EXPECTED_HASH="5d41402abc4b2a76b9719d911017c592"
    # INPUT_HASH=$(echo -n "$ACTIVATION_KEY" | md5sum | cut -d' ' -f1)
    # if [ "$INPUT_HASH" = "$EXPECTED_HASH" ]; then

    if [ "$ACTIVATION_KEY" = "YOUR_VALID_ACTIVATION_KEY" ]; then
        echo "Activation successful! Saving license file..." > $CONSOLE
        echo "$ACTIVATION_KEY" > "$LICENSE_FILE"
        echo "Proceeding with system boot..." > $CONSOLE
    else
        echo "ERROR: Invalid activation key!" > $CONSOLE
        echo "System will restart in 5 seconds..." > $CONSOLE
        sleep 5
        # 强制重启
        reboot -f
    fi
else
    # 可选:验证现有授权文件的有效性(避免篡改)
    echo "License file found, verifying validity..." > $CONSOLE
    EXISTING_KEY=$(cat "$LICENSE_FILE")
    if [ "$EXISTING_KEY" != "YOUR_VALID_ACTIVATION_KEY" ]; then
        echo "ERROR: Invalid existing license!" > $CONSOLE
        echo "Please re-enter your activation key:" > $CONSOLE
        read -r ACTIVATION_KEY < $CONSOLE
        if [ "$ACTIVATION_KEY" != "YOUR_VALID_ACTIVATION_KEY" ]; then
            echo "Invalid key! Restarting system..." > $CONSOLE
            sleep 5
            reboot -f
        else
            echo "License reactivated successfully!" > $CONSOLE
            echo "$ACTIVATION_KEY" > "$LICENSE_FILE"
        fi
    else
        echo "License validation passed. Proceeding with boot..." > $CONSOLE
    fi
fi

给脚本添加执行权限:

chmod +x /usr/local/bin/check_license.sh

2. 创建Systemd服务,让脚本在启动最早期运行

创建服务文件/etc/systemd/system/check-license.service,确保它在系统初始化前执行:

[Unit]
Description=Validate System License Before Boot
Before=sysinit.target
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/usr/local/bin/check_license.sh
# 绑定控制台作为输入输出设备
StandardInput=tty
StandardOutput=tty
StandardError=tty
TTYPath=/dev/console

[Install]
WantedBy=sysinit.target

启用并生效服务:

systemctl daemon-reload
systemctl enable check-license.service

这样系统每次启动时,都会先运行这个脚本,只有授权验证通过才会继续启动到Shell/GUI;验证失败则直接重启。

二、SysVinit系统(老版本CentOS、Debian等)

对于使用SysVinit的系统,直接修改/etc/inittab,让验证脚本在系统初始化的最开始运行:

打开/etc/inittab,在最顶部添加一行:

si::sysinit:/usr/local/bin/check_license.sh

保存后,下次启动就会先执行验证脚本。脚本的内容和systemd版本一致,同样通过/dev/console处理输入输出。

关键问题解决:为什么你的init脚本无法输出/获取输入?

早期启动阶段,系统还没完成控制台的初始化绑定,stdout/stdin并没有默认关联到物理控制台。所以在脚本里明确把输出重定向到/dev/console,并从/dev/console读取输入,就能解决这个问题。在systemd服务里通过StandardInput=tty和TTYPath=/dev/console配置,也是同样的道理——强制把脚本的IO绑定到控制台设备。

内容的提问来源于stack exchange,提问作者Malik Hamza Murtaza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:29:35