wei/个人文档/申万实时同步配置.md
2026-06-04 13:57:41 +08:00

15 KiB
Raw Permalink Blame History

CentOS 9 创建仅密钥登录用户并设置 IP 白名单笔记

本文档记录了在 CentOS 9 系统上创建用户 swdata,配置仅允许 SSH 密钥登录,并设置来源 IP 白名单的完整步骤。


1. 创建新用户

# 创建用户 swdata并禁用密码登录--disabled-password 在 CentOS 中需使用 passwd -l 或创建时不设密码)
sudo useradd -m -s /bin/bash swdata
# 或者直接创建后锁定密码(确保无法通过密码登录)
sudo passwd -l swdata

说明-m 创建家目录,-s 指定登录 Shell。

2. 配置 SSH 密钥登录

2.1 在客户端生成密钥对(如尚未有)

# 在本地客户端生成 ed25519 密钥对(推荐)
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519

2.2 将公钥添加到服务器对应用户的 authorized_keys

# 方法一:使用 ssh-copy-id需临时开启密码登录或已有其他认证方式
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 swdata@服务器IP

# 方法二:手动复制
# 将本地 ~/.ssh/id_ed25519.pub 内容粘贴到服务器的 /home/swdata/.ssh/authorized_keys

2.3 设置正确的权限

sudo -u swdata mkdir -p /home/swdata/.ssh
sudo -u swdata chmod 700 /home/swdata/.ssh
sudo -u swdata touch /home/swdata/.ssh/authorized_keys
sudo -u swdata chmod 600 /home/swdata/.ssh/authorized_keys
# 编辑 authorized_keys粘贴公钥内容

3. 配置 SSH 服务(白名单与密钥登录)

编辑 SSH 配置文件 /etc/ssh/sshd_config

sudo vi /etc/ssh/sshd_config

添加或修改以下内容:

# 全局设置(可根据需要调整)
PubkeyAuthentication yes
PasswordAuthentication no          # 禁用密码登录(可选,若仅部分用户禁用则使用 Match 块)

# 在文件末尾添加以下内容

# swdata用户配置 - 只允许密钥登录并且设置白名单IP
Match User swdata
    PasswordAuthentication no
    PubkeyAuthentication yes
    # 允许的IP列表例如
    AllowUsers swdata@192.168.1.* swdata@10.0.0.*
    # 或者使用CIDR格式
    # AllowUsers swdata@192.168.1.0/24 swdata@10.0.0.0/8
    # 如果你有特定公网IP
    # AllowUsers swdata@123.45.67.89
    
# 其他用户的配置 - 只允许内网登录
Match User *,!swdata
    PasswordAuthentication yes  # 或者改为no来禁用密码
    AllowUsers *@192.168.1.0/24 *@10.0.0.0/8
    # 如果需要完全禁止其他用户远程登录:
    # DenyUsers *

注意AllowUsers 的格式为 user@hosthost 可以是 IP、网段CIDR或域名。如果希望允许所有来源但仅限密钥登录可以省略 AllowUsers 只保留 PasswordAuthentication no

4. 重启 SSH 服务

sudo systemctl restart sshd

检查 SSH 服务状态:

sudo systemctl status sshd

5. 测试登录

5.1 从允许的 IP 测试

ssh -i ~/.ssh/id_ed25519 -p 22 swdata@服务器IP

预期:无需密码直接登录成功。

5.2 从非白名单 IP 测试

预期:连接被拒绝(Permission denied 或超时)。

5.3 验证密码登录是否被禁用

ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password swdata@服务器IP

预期:提示 Permission denied (publickey),即使密码正确也无法登录。

6. 查看 SSH 登录日志(调试用)

# 查看实时日志
sudo journalctl -u sshd -f

# 或查看历史认证记录
sudo grep "sshd" /var/log/secure

7. 额外安全建议

  • 修改 SSH 默认端口(可选):在 /etc/ssh/sshd_config 中修改 Port 值,并更新防火墙规则。
  • 使用防火墙限制端口访问(结合白名单):
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="22" protocol="tcp" accept'
    sudo firewall-cmd --reload
    
  • 禁用 root 远程登录:设置 PermitRootLogin no
  • 启用 SSH 日志审计:确保 LogLevel INFO 已启用。

注意事项

  • 修改 sshd_config 前建议备份:sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
  • 每次修改后务必用 sudo sshd -t 检查语法,再重启服务。
  • 如果使用防火墙,确保允许白名单 IP 访问 SSH 端口。


完整的KR数据实时同步方案

1. 创建同步脚本

创建脚本文件 /usr/local/bin/kr_data_sync.sh

#!/bin/bash

# ============================================
# KR数据实时同步脚本
# 监控指定日期目录的变化并同步到目标机器
# ============================================

# 日志配置
LOG_DIR="/var/log/kr_data_sync"
LOG_FILE="$LOG_DIR/sync_$(date +%Y%m%d).log"

# 源目录配置
SRC_BASE="/home/sysop/kr_md_save_centos7_9_v4/data/stockdata"

# 目标配置(通过路由器端口映射)
DEST_HOST="swdata@119.167.194.234"
DEST_PORT="60000"
DEST_BASE="/mnt/data1/data_new/data/stockdata"

# SSH配置
SSH_OPTS="-o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=30 -o ServerAliveInterval=60 -o ServerAliveCountMax=3"

# 确保日志目录存在
mkdir -p $LOG_DIR

# 日志函数
log_info() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] $1" >> $LOG_FILE
    echo "$1"
}

log_error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] $1" >> $LOG_FILE
    echo "$1"
}

# 获取当天日期目录
get_current_date_dir() {
    echo $(date +%Y%m%d)
}

# 检查SSH连接
check_ssh_connection() {
    log_info "检查SSH连接到目标服务器..."
    
    if ssh -p $DEST_PORT $SSH_OPTS $DEST_HOST "echo 'SSH连接测试成功'" 2>/dev/null; then
        log_info "SSH连接正常"
        return 0
    else
        log_error "SSH连接失败"
        return 1
    fi
}

# 执行同步
perform_sync() {
    local src_dir="$1"
    local dest_dir="$2"
    
    if [ ! -d "$src_dir" ]; then
        log_error "源目录不存在: $src_dir"
        return 1
    fi
    
    log_info "开始同步: $src_dir -> $dest_dir"
    
    # 使用rsync同步通过指定端口连接
    rsync -avz --progress --delete \
        -e "ssh -p $DEST_PORT $SSH_OPTS" \
        "$src_dir/" \
        "$DEST_HOST:$dest_dir/" 2>&1 | while read line; do
            echo "$(date '+%Y-%m-%d %H:%M:%S') [SYNC] $line" >> $LOG_FILE
            echo "$line"
        done
    
    local sync_result=${PIPESTATUS[0]}
    
    if [ $sync_result -eq 0 ]; then
        log_info "同步完成: $src_dir"
    else
        log_error "同步失败: $src_dir (退出码: $sync_result)"
    fi
    
    return $sync_result
}

# 主函数
main() {
    log_info "========== KR数据同步服务启动 =========="
    log_info "当前日期: $(date)"
    log_info "源目录: $SRC_BASE"
    log_info "目标主机: $DEST_HOST:$DEST_PORT"
    log_info "目标目录: $DEST_BASE"
    
    # 检查依赖
    if ! command -v rsync &> /dev/null; then
        log_error "未找到 rsync请安装: yum install rsync"
        exit 1
    fi
    
    # 检查SSH密钥认证
    if [ ! -f ~/.ssh/id_rsa ]; then
        log_error "未找到SSH私钥 ~/.ssh/id_rsa"
        exit 1
    fi
    
    # 检查SSH连接
    if ! check_ssh_connection; then
        log_error "SSH连接检查失败"
        exit 1
    fi
    
    # 设置信号处理
    trap 'log_info "接收到终止信号,退出监控"; exit 0' SIGINT SIGTERM
    
    # 主监控循环
    while true; do
        current_date=$(get_current_date_dir)
        src_dir="$SRC_BASE/$current_date"
        
        log_info "检查目录: $src_dir"
        
        # 检查源目录是否存在
        if [ ! -d "$src_dir" ]; then
            log_info "目录不存在,等待创建..."
            sleep 60
            continue
        fi
        
        log_info "开始监控目录: $src_dir"
        
        # 初始同步
        perform_sync "$src_dir" "$DEST_BASE/$current_date"
        
        # 检查inotifywait是否存在
        if command -v inotifywait &> /dev/null; then
            # 使用inotifywait监控
            inotifywait -m -r -e create,close_write,moved_to,delete \
                --timefmt '%Y-%m-%d %H:%M:%S' \
                --format '%T %w%f %e' \
                "$src_dir" 2>/dev/null | while read datetime filepath event
            do
                # 过滤临时文件
                if [[ "$filepath" =~ \.(tmp|swp|part)$ ]] || [[ "$filepath" =~ ~$ ]]; then
                    continue
                fi
                
                log_info "检测到变化: $filepath (事件: $event)"
                
                # 延迟2秒避免频繁同步
                sleep 2
                perform_sync "$src_dir" "$DEST_BASE/$current_date"
            done
        else
            # 轮询方式监控
            log_info "inotifywait未安装使用轮询方式每30秒检查一次"
            local last_check=""
            while true; do
                # 检查目录是否存在
                if [ ! -d "$src_dir" ]; then
                    log_info "目录消失,返回主循环"
                    break
                fi
                
                # 检查是否有新文件或修改
                current_check=$(find "$src_dir" -type f -name "*.csv" -exec stat -c "%Y %n" {} + 2>/dev/null | sort | tail -5)
                if [ "$current_check" != "$last_check" ]; then
                    log_info "检测到文件变化,开始同步..."
                    perform_sync "$src_dir" "$DEST_BASE/$current_date"
                    last_check="$current_check"
                fi
                
                sleep 30
            done
        fi
        
        log_info "监控退出等待30秒后重新检查..."
        sleep 30
    done
}

# 执行主函数
main

给脚本执行权限:

sudo chmod +x /usr/local/bin/kr_data_sync.sh

2. 安装依赖CentOS 7

在线安装依赖:

# 安装rsync必须
sudo yum install -y rsync

# 安装inotify-tools可选但推荐
sudo yum install -y inotify-tools

# 安装bc用于计算文件大小可选
sudo yum install -y bc

离线安装inotify-tools

如果有网络可以下载RPM包然后在离线机器安装

# 在有网络的机器上下载包:
yum install --downloadonly --downloaddir=./inotify-packages inotify-tools

# 将下载的RPM包复制到目标机器然后安装
sudo rpm -ivh inotify-packages/*.rpm

3. 配置SSH免密登录

# 1. 生成SSH密钥如果没有
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# 2. 复制公钥到目标机器
ssh-copy-id -p 60000 swdata@119.167.194.234

# 3. 测试连接
ssh -p 60000 swdata@119.167.194.234 "echo '连接成功'"

4. 创建Systemd服务

创建服务文件 /etc/systemd/system/kr-data-sync.service

sudo tee /etc/systemd/system/kr-data-sync.service << 'EOF'
[Unit]
Description=KR Data Real-time Sync Service
After=network.target
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=sysop
Group=sysop
WorkingDirectory=/home/sysop
ExecStart=/usr/local/bin/kr_data_sync.sh
Restart=on-failure
RestartSec=10
StartLimitInterval=60
StartLimitBurst=5

# 日志配置
StandardOutput=append:/var/log/kr_data_sync/service.log
StandardError=append:/var/log/kr_data_sync/error.log

# 安全设置
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/log/kr_data_sync /tmp /home/sysop/kr_md_save_centos7_9_v4/data/stockdata

[Install]
WantedBy=multi-user.target
EOF

创建日志目录:

sudo mkdir -p /var/log/kr_data_sync
sudo chown -R sysop:sysop /var/log/kr_data_sync
sudo chmod 755 /var/log/kr_data_sync

5. 启用和启动服务

# 重载systemd配置
sudo systemctl daemon-reload

# 启用服务(开机自启)
sudo systemctl enable kr-data-sync.service

# 启动服务
sudo systemctl start kr-data-sync.service

# 查看服务状态
sudo systemctl status kr-data-sync.service

# 查看服务日志
sudo journalctl -u kr-data-sync.service -f

6. 配置计划任务(每天重启服务)

# 编辑crontab
crontab -e

# 添加以下内容每天凌晨00:10重启服务
10 0 * * * /bin/systemctl restart kr-data-sync.service

# 也可以添加日志轮转(可选)
0 0 * * * find /var/log/kr_data_sync -name "sync_*.log" -mtime +7 -delete

7. 测试和验证

测试脚本:

# 手动运行脚本测试
/usr/local/bin/kr_data_sync.sh

# 在另一个终端创建测试目录和文件
mkdir -p /home/sysop/kr_md_save_centos7_9_v4/data/stockdata/$(date +%Y%m%d)
touch /home/sysop/kr_md_save_centos7_9_v4/data/stockdata/$(date +%Y%m%d)/test.csv

查看同步状态:

# 查看服务状态
sudo systemctl status kr-data-sync.service

# 查看同步日志
tail -f /var/log/kr_data_sync/sync_$(date +%Y%m%d).log

# 查看进程
ps aux | grep kr_data_sync

# 查看SSH连接
ss -tnp | grep 60000

8. 监控和管理命令

# 查看服务状态
sudo systemctl status kr-data-sync.service

# 重启服务
sudo systemctl restart kr-data-sync.service

# 停止服务
sudo systemctl stop kr-data-sync.service

# 查看实时日志
sudo journalctl -u kr-data-sync.service -f

# 查看今天的所有日志
cat /var/log/kr_data_sync/sync_$(date +%Y%m%d).log

# 检查同步的文件
ls -la /home/sysop/kr_md_save_centos7_9_v4/data/stockdata/$(date +%Y%m%d)/

# 测试SSH连接
ssh -p 60000 swdata@119.167.194.234 "ls -la /mnt/data1/data_new/data/stockdata/$(date +%Y%m%d)/"

9. 故障排查

# 1. 检查SSH连接
ssh -p 60000 -v swdata@119.167.194.234 "echo test"

# 2. 检查脚本语法
bash -n /usr/local/bin/kr_data_sync.sh

# 3. 检查文件权限
ls -la /usr/local/bin/kr_data_sync.sh
ls -la ~/.ssh/id_rsa

# 4. 检查依赖
which rsync
which inotifywait

# 5. 手动运行调试
bash -x /usr/local/bin/kr_data_sync.sh 2>&1 | head -50

10. 卸载/清理

如果需要卸载服务:

# 停止服务
sudo systemctl stop kr-data-sync.service

# 禁用服务
sudo systemctl disable kr-data-sync.service

# 删除服务文件
sudo rm -f /etc/systemd/system/kr-data-sync.service

# 删除脚本
sudo rm -f /usr/local/bin/kr_data_sync.sh

# 清理日志
sudo rm -rf /var/log/kr_data_sync

# 重载systemd
sudo systemctl daemon-reload

关键点说明

  1. SSH连接:直接通过 ssh -p 60000 swdata@119.167.194.234 连接
  2. 日期监控自动监控当天日期目录格式YYYYMMDD
  3. 实时同步使用inotifywait监控文件变化实时同步
  4. 计划任务每天00:10重启服务开始监控新的日期目录
  5. 日志管理:日志按日期分割,方便查看和清理
  6. 错误处理:包含完善的错误检测和重试机制
  7. 依赖最小化只需要rsyncinotify-tools是可选的

这样配置后,服务会:

  • 每天自动监控当前日期的目录
  • 检测到新文件时实时同步
  • 每天凌晨自动重启,切换到新的日期目录
  • 通过systemd管理稳定可靠