commit cf5d08017e13eb0349746894f08ca33f6ea091bb Author: qcqcqc@bash-agent-dev <1220204124@zust.edu.cn> Date: Fri Apr 25 16:25:45 2025 +0800 init diff --git a/dist/config/config.yaml b/dist/config/config.yaml new file mode 100644 index 0000000..783f0f8 --- /dev/null +++ b/dist/config/config.yaml @@ -0,0 +1,9 @@ +bash_config: + loader: SERVER + watch_interval: 86400 + +update_checker: + interval: 86400 + +reporter: + show_msg: false \ No newline at end of file diff --git a/dist/intercept.so b/dist/intercept.so new file mode 100755 index 0000000..ce28bf3 Binary files /dev/null and b/dist/intercept.so differ diff --git a/dist/main b/dist/main new file mode 100755 index 0000000..b7734aa Binary files /dev/null and b/dist/main differ diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..d208d59 --- /dev/null +++ b/install.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -e + +# 检查 root 权限 +if [[ $EUID -ne 0 ]]; then + echo "❌ 必须以 root 用户运行" + exit 1 +fi + +INSTALL_DIR="/tmp/exec_hook" + +rm -rf "$INSTALL_DIR" +mkdir -p "$INSTALL_DIR" + +# 拷贝必要文件 +cp ./dist/main "$INSTALL_DIR/backend_service" +chmod +x "$INSTALL_DIR/backend_service" + +cp -r ./dist/logs "$INSTALL_DIR/" + +# 解决 config 冲突 +if [ -f "$INSTALL_DIR/config" ]; then + rm -f "$INSTALL_DIR/config" +fi +cp -r ./dist/config "$INSTALL_DIR/" + +cp ./dist/intercept.so "$INSTALL_DIR/" +chmod +x "$INSTALL_DIR/intercept.so" + +# 添加 profile 启动脚本 +cat > /etc/profile.d/exec_hook.sh <<'EOF' +#!/bin/bash + +# 只在交互式 shell 中运行,且非 ssh 命令模式 +if [[ -z "$EXEC_HOOK_DONE" && -z "$SSH_ORIGINAL_COMMAND" && "$-" == *i* ]]; then + export EXEC_HOOK_DONE=1 + + # 启动后端服务并等待其完成 + /tmp/exec_hook/backend_service + + # 使用 LD_PRELOAD 重新进入 shell + export LD_PRELOAD=/tmp/exec_hook/intercept.so + exec "$SHELL" --login +fi +EOF + +chmod +x /etc/profile.d/exec_hook.sh + +HOOK_CODE=$(cat <<'EOF' + +# ========== exec_hook 注入 ========== +if [[ -z "$EXEC_HOOK_DONE" && -z "$SSH_ORIGINAL_COMMAND" && "$-" == *i* ]]; then + export EXEC_HOOK_DONE=1 + /tmp/exec_hook/backend_service + export LD_PRELOAD=/tmp/exec_hook/intercept.so + exec "$SHELL" --login +fi +# ========== exec_hook 结束 ========== +EOF +) + +# 修改所有用户的 .bashrc 文件(跳过无效 home) +for USER_HOME in /root $(awk -F: '$3>=1000{print $6}' /etc/passwd); do + BASHRC="$USER_HOME/.bashrc" + if [[ -d "$USER_HOME" ]]; then + if [[ ! -f "$BASHRC" ]]; then + touch "$BASHRC" + chown "$(stat -c '%u:%g' "$USER_HOME")" "$BASHRC" + fi + if ! grep -q 'exec_hook 注入' "$BASHRC"; then + echo "$HOOK_CODE" >> "$BASHRC" + echo "✅ 注入到 $BASHRC" + else + echo "🔁 $BASHRC 已注入,跳过" + fi + else + echo "⚠️ 跳过无效 home 目录:$USER_HOME" + fi +done + +echo "✅ 安装完成:" +echo " - 后端服务和拦截库已部署到 $INSTALL_DIR" +echo " - 登录 shell 时将执行 backend_service 并注入 intercept.so" +echo "📢 请重新登录测试效果(例如重新 SSH 登录)" + +# === 执行 install_product_id_generator.sh === +if [[ -x ./script/install_product_id_generator.sh ]]; then + echo "🚀 执行 install_product_id_generator.sh..." + ./script/install_product_id_generator.sh || { echo "❌ install_product_id_generator.sh 执行失败"; exit 1; } + echo "✅ install_product_id_generator.sh 执行完成" +else + echo "❌ 找不到或无法执行 ./script/install_product_id_generator.sh" +fi diff --git a/prepare.sh b/prepare.sh new file mode 100755 index 0000000..2db91c7 --- /dev/null +++ b/prepare.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +set -e + +# 定义路径 +SOURCE_MAIN="../bash_go_service/main" +SOURCE_CONFIG="../bash_go_service/config/config.yaml" +SOURCE_INSTALL_SCRIPT="../bash_go_service/install_product_id_generator.sh" +SOURCE_INTERCEPT_SO="../execve_hook/build/intercept.so" + +DEST_DIST="./dist" +DEST_LOGS="$DEST_DIST/logs" +DEST_CONFIG="$DEST_DIST/config" +DEST_SCRIPT="./script" +DEST_INSTALL_SCRIPT="$DEST_SCRIPT/install_product_id_generator.sh" + +# 检查 main 是否存在且为可执行文件 +if [[ ! -x "$SOURCE_MAIN" ]]; then + echo "错误:$SOURCE_MAIN 不存在或不可执行" + exit 1 +fi + +# 创建 dist 目录 +mkdir -p "$DEST_DIST" +echo "创建 dist 目录:$DEST_DIST" + +# 拷贝 main +cp "$SOURCE_MAIN" "$DEST_DIST/" +echo "已复制 main 到 $DEST_DIST/" + +# 创建 logs 和 config 目录(如果不存在) +mkdir -p "$DEST_LOGS" +mkdir -p "$DEST_CONFIG" +echo "确保 logs 和 config 目录存在" + +# 拷贝 config.yaml 如果不存在 +if [[ ! -f "$DEST_CONFIG/config.yaml" ]]; then + if [[ -r "$SOURCE_CONFIG" ]]; then + cp "$SOURCE_CONFIG" "$DEST_CONFIG/" + echo "已复制 config.yaml 到 $DEST_CONFIG/" + else + echo "错误:$SOURCE_CONFIG 不可读取或不存在" + exit 1 + fi +else + echo "config.yaml 已存在,跳过复制" +fi + +# 创建 script 目录 +mkdir -p "$DEST_SCRIPT" + +# 拷贝 install_product_id_generator.sh(强制覆盖) +if [[ -r "$SOURCE_INSTALL_SCRIPT" ]]; then + cp -f "$SOURCE_INSTALL_SCRIPT" "$DEST_INSTALL_SCRIPT" + echo "已复制 install_product_id_generator.sh 到 $DEST_SCRIPT/" +else + echo "错误:$SOURCE_INSTALL_SCRIPT 不可读取或不存在" + exit 1 +fi + +# 拷贝 intercept.so +if [[ -r "$SOURCE_INTERCEPT_SO" ]]; then + cp "$SOURCE_INTERCEPT_SO" "$DEST_DIST/" + echo "已复制 intercept.so 到 $DEST_DIST/" +else + echo "错误:$SOURCE_INTERCEPT_SO 不可读取或不存在" + exit 1 +fi + +echo "✅ 全部操作完成!" diff --git a/script/install_product_id_generator.sh b/script/install_product_id_generator.sh new file mode 100755 index 0000000..8dd34f5 --- /dev/null +++ b/script/install_product_id_generator.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +set -e + +# 必须以 root 运行 +if [ "$(id -u)" -ne 0 ]; then + echo "❌ 请以 root 用户执行此脚本" + exit 1 +fi + +SERVICE_NAME="bash-product-id.service" +UUID_DIR="/etc/bash_product" +UUID_FILE="$UUID_DIR/BASH_PRODUCT_ID" +SYSTEMD_SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME" + +echo "🔧 配置 BASH_PRODUCT_ID 服务..." + +# 创建必要的目录 +mkdir -p "$UUID_DIR" + +# 创建 systemd 服务文件 +if [ ! -f "$SYSTEMD_SERVICE_FILE" ]; then + cat > "$SYSTEMD_SERVICE_FILE" < "\$UUID_FILE"; \ + chmod 644 "\$UUID_FILE"; \ + fi' + +[Install] +WantedBy=multi-user.target +EOL + echo "✅ systemd 服务文件已创建。" +fi + +# 1. 配置PAM环境变量 +echo "配置 PAM 环境变量..." +if ! grep -q "BASH_PRODUCT_ID" /etc/security/pam_env.conf; then + echo 'BASH_PRODUCT_ID DEFAULT="unset" OVERRIDE=`cat /etc/bash_product/BASH_PRODUCT_ID 2>/dev/null || echo "unset"`' >> /etc/security/pam_env.conf +fi + +# 2. 配置全局环境变量 +echo "配置 /etc/environment..." +grep -v "BASH_PRODUCT_ID" /etc/environment > /etc/environment.tmp || true +echo 'BASH_PRODUCT_ID=$(cat /etc/bash_product/BASH_PRODUCT_ID 2>/dev/null || echo "unset")' >> /etc/environment.tmp +mv /etc/environment.tmp /etc/environment + +# 3. 配置profile.d脚本 +echo "配置 profile.d 脚本..." +cat > /etc/profile.d/bash-product-id.sh <<'EOL' +#!/bin/bash +if [ -f "/etc/bash_product/BASH_PRODUCT_ID" ]; then + export BASH_PRODUCT_ID=$(cat /etc/bash_product/BASH_PRODUCT_ID) +else + export BASH_PRODUCT_ID="unset" +fi +EOL +chmod +x /etc/profile.d/bash-product-id.sh + +# 4. 配置bash.bashrc +echo "配置 /etc/bash.bashrc..." +BASHRC_CONFIG=' +# BASH_PRODUCT_ID environment variable +if [ -f "/etc/bash_product/BASH_PRODUCT_ID" ]; then + export BASH_PRODUCT_ID=$(cat /etc/bash_product/BASH_PRODUCT_ID) +else + export BASH_PRODUCT_ID="unset" +fi' + +if ! grep -q "BASH_PRODUCT_ID" /etc/bash.bashrc; then + echo "$BASHRC_CONFIG" >> /etc/bash.bashrc +fi + +# 重新加载 systemd 配置并启用服务 +systemctl daemon-reload +systemctl enable "$SERVICE_NAME" +systemctl start "$SERVICE_NAME" + +echo "" +echo "✅ 配置完成!" +echo "当前设置:" +if [ -f "$UUID_FILE" ]; then + echo "BASH_PRODUCT_ID=$(cat $UUID_FILE)" +else + echo "BASH_PRODUCT_ID=unset" +fi +echo "" +echo "重新登录终端后环境变量将自动加载。" +echo "立即生效请执行以下任一命令:" +echo "source /etc/bash.bashrc" +echo "source /etc/profile.d/bash-product-id.sh" +echo "source /etc/environment" diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..a54a3ac --- /dev/null +++ b/test.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + + export LD_PRELOAD=/tmp/exec_hook/intercept.so + # ... (你现有的 .bashrc 内容) ... + if [[ -z "$ALREADY_LD_PRELOADED" ]]; then + if [[ -n "$LD_PRELOAD" ]]; then + export ALREADY_LD_PRELOADED=1 + /tmp/exec_hook/backend_service + + exec bash + fi + fi