Alvis 发表于 2024-8-26 16:30:05

Serv00 折腾-SSH跳板登录+Cron保活

#### 背景

Serv00 会时不时清理 Cron 定时任务。

#### 思路

如果我们有多台 Serv00 或者有其他服务器,就可以在服务器A设置定时任务 SSH 登录服务器B,执行检测 B里面的 Cron 是否被清除。同理,也可以在B检测A,甚至三台两两检测。(不知道会不会因为“滥用”全部封掉哈哈哈)

> 下面的用户名 密码 服务器地址等修改成自己实际的,灵活变通。

#### 设置无密码登录

目的:在 A 执行定时任务时,SSH 直接连上 B 并执行脚本会方便很多。

1. **在服务器 `A (serv00)` 上生成 SSH 密钥对**: 如果你还没有 SSH 密钥对,可以使用以下命令生成:

   ```css
   ssh-keygen -t rsa -b 4096 -C "[email protected]"
   ```

   按照提示操作,通常直接按 `Enter` 使用默认路径即可。(建议)如果你不想设置密码短语,可以直接按 `Enter` 跳过。

   > Enter passphrase (empty for no passphrase) 时候按 Enter 跳过

2. **将公钥复制到服务器 `B (serv01)`**: 使用以下命令将公钥复制到 `B` 服务器上:

   ```sql
   ssh-copy-id user@serv01
   ```

   这将会将 `A` 服务器上的公钥添加到 `B` 服务器的 `~/.ssh/authorized_keys` 文件中。如果 `ssh-copy-id` 命令不可用,可以手动复制:

   - 在 `A` 服务器上查看生成的公钥内容:

   ```bash
   cat ~/.ssh/id_rsa.pub
   ```

   - 在 `B` 服务器上使用 SSH 登录,然后将上面的公钥内容追加到 `~/.ssh/authorized_keys` 文件中:

   ```bash
   echo "your-public-key" >> ~/.ssh/authorized_keys
   ```

   - 如果没有该文件,则需要新建

       ```shell
       mkdir -p ~/.ssh
       touch ~/.ssh/authorized_keys
       chmod 700 ~/.ssh
       chmod 600 ~/.ssh/authorized_keys
       ```

3. **验证无密码登录**: 在 `A` 服务器上运行以下命令,验证是否可以无密码登录到 `B` 服务器:

   ```sql
   ssh user@serv01
   ```

   如果配置正确,你应该可以直接登录而不需要输入密码。

   实测就算配了公钥,在这一步还是需要在连接的提示里输入 ‘yes’ 来连接一次,之后就是无密码登录了。

   **建议做这步骤**,不然会在运行 B 的 sh 文件时候可能出现 SSH 登录相关问题。

#### Cron 保活

例如服务器A检测服务器B的Cron任务是否存在,不存在时就添加Cron任务。

1. 服务器A 增加文件:monitor_crontab.sh

```bash
#!/bin/bash

# 定义日志文件路径
log_file="/home/用户名/domains/script/monitor_crontab-log.txt"

# 检查并创建工作目录日志文件
touch "$log_file"

# 通过 SSH 执行 B 服务器上的检查并修复脚本
result=$(ssh 用户名@web7.serv00.com '~/domains/script/check_crontab.sh')

# 将执行结果写入日志文件,并附加日期和时间
echo "$(date '+%Y-%m-%d %H:%M:%S') - $result" >> $log_file
```

添加 cron 任务,例如,每30min运行一次:

> 可以添加完 A B 服务器相关sh文件后自行单测后,最后再 在服务器A 加 cron 任务。

```ruby
crontab -e

*/30 * * * * /home/user2/domains/script/monitor_crontab.sh >/dev/null 2>&1

ctrl+o,回车,ctrl+x
```

1. 服务器B 增加文件:check_crontab.sh

```bash
#!/bin/bash

# 定义日志文件路径
log_file="/home/用户名/domains/script/check_crontab-log.txt"

touch "$log_file"

# 定义你要检查和恢复的 cron 任务
tasks=(
"19 1 1 * * /usr/bin/env TZ=Asia/Shanghai ~/domains/script/auto-ssh.sh >/dev/null 2>&1"
"19 1 15 * * /usr/bin/env TZ=Asia/Shanghai ~/domains/script/auto-ssh.sh >/dev/null 2>&1"
"@reboot /usr/bin/env TZ=Asia/Shanghai ~/domains/script/auto-ssh.sh >/dev/null 2>&1"
)

# 获取当前用户的 crontab 内容
current_crontab=$(crontab -l 2>/dev/null)

# 初始化一个标志,检查是否有任务被修复
tasks_missing=0

# 写入日志文件的函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$log_file"
}

# 检查每个任务是否存在
for task in "${tasks[@]}"; do
    if ! echo "$current_crontab" | grep -qF "$task"; then
      # 如果任务不存在,添加到 crontab
      (crontab -l 2>/dev/null; echo "$task") | crontab -
      log "Task added: $task"
      tasks_missing=1
    else
      log "Task already present: $task"
    fi
done

# 输出结果并写入日志
if [ $tasks_missing -eq 1 ]; then
    log "Missing tasks were restored."
    echo "Missing and restored" >> "$log_file"
else
    log "All tasks are present."
    echo "All tasks present" >> "$log_file"
fi
```

#### 拓展

如果还有多台服务器,那就可以修改 monitor_crontab.sh 文件,步骤和上面一样。

```bash
#!/bin/bash

# 定义日志文件路径
log_file="/home/user01/domains/script/monitor_crontab-log.txt"

# 检查并创建工作目录日志文件
touch "$log_file"

# 通过 SSH 执行 B 服务器上的检查并修复脚本
result=$(ssh [email protected] '~/domains/script/check_crontab.sh')

# 将执行结果写入日志文件,并附加日期和时间
echo "user2》$(date '+%Y-%m-%d %H:%M:%S') - $result" >> $log_file


# 通过 SSH 执行 B 服务器上的检查并修复脚本
result=$(ssh [email protected] '~/domains/script/check_crontab.sh')

# 将执行结果写入日志文件,并附加日期和时间
echo "user1》$(date '+%Y-%m-%d %H:%M:%S') - $result" >> $log_file
```
页: [1]
查看完整版本: Serv00 折腾-SSH跳板登录+Cron保活