# CentOS 9 创建仅密钥登录用户并设置 IP 白名单笔记 本文档记录了在 **CentOS 9** 系统上创建用户 `swdata`,配置仅允许 SSH 密钥登录,并设置来源 IP 白名单的完整步骤。 --- ## 1. 创建新用户 ```bash # 创建用户 swdata,并禁用密码登录(--disabled-password 在 CentOS 中需使用 passwd -l 或创建时不设密码) sudo useradd -m -s /bin/bash swdata # 或者直接创建后锁定密码(确保无法通过密码登录) sudo passwd -l swdata ``` > **说明**:`-m` 创建家目录,`-s` 指定登录 Shell。 ## 2. 配置 SSH 密钥登录 ### 2.1 在客户端生成密钥对(如尚未有) ```bash # 在本地客户端生成 ed25519 密钥对(推荐) ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519 ``` ### 2.2 将公钥添加到服务器对应用户的 `authorized_keys` ```bash # 方法一:使用 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 设置正确的权限 ```bash 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`: ```bash sudo vi /etc/ssh/sshd_config ``` 添加或修改以下内容: ```ini # 全局设置(可根据需要调整) 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@host`,`host` 可以是 IP、网段(CIDR)或域名。如果希望允许所有来源但仅限密钥登录,可以省略 `AllowUsers` 只保留 `PasswordAuthentication no`。 ## 4. 重启 SSH 服务 ```bash sudo systemctl restart sshd ``` 检查 SSH 服务状态: ```bash sudo systemctl status sshd ``` ## 5. 测试登录 ### 5.1 从允许的 IP 测试 ```bash ssh -i ~/.ssh/id_ed25519 -p 22 swdata@服务器IP ``` 预期:无需密码直接登录成功。 ### 5.2 从非白名单 IP 测试 预期:连接被拒绝(`Permission denied` 或超时)。 ### 5.3 验证密码登录是否被禁用 ```bash ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password swdata@服务器IP ``` 预期:提示 `Permission denied (publickey)`,即使密码正确也无法登录。 ## 6. 查看 SSH 登录日志(调试用) ```bash # 查看实时日志 sudo journalctl -u sshd -f # 或查看历史认证记录 sudo grep "sshd" /var/log/secure ``` ## 7. 额外安全建议 - **修改 SSH 默认端口**(可选):在 `/etc/ssh/sshd_config` 中修改 `Port` 值,并更新防火墙规则。 - **使用防火墙限制端口访问**(结合白名单): ```bash 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`: ```bash #!/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 ``` ### 给脚本执行权限: ```bash sudo chmod +x /usr/local/bin/kr_data_sync.sh ``` ## 2. 安装依赖(CentOS 7) ### 在线安装依赖: ```bash # 安装rsync(必须) sudo yum install -y rsync # 安装inotify-tools(可选,但推荐) sudo yum install -y inotify-tools # 安装bc(用于计算文件大小,可选) sudo yum install -y bc ``` ### 离线安装inotify-tools: 如果有网络可以下载RPM包,然后在离线机器安装: ```bash # 在有网络的机器上下载包: yum install --downloadonly --downloaddir=./inotify-packages inotify-tools # 将下载的RPM包复制到目标机器,然后安装: sudo rpm -ivh inotify-packages/*.rpm ``` ## 3. 配置SSH免密登录 ```bash # 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`: ```bash 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 ``` ### 创建日志目录: ```bash 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. 启用和启动服务 ```bash # 重载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. 配置计划任务(每天重启服务) ```bash # 编辑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. 测试和验证 ### 测试脚本: ```bash # 手动运行脚本测试 /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 ``` ### 查看同步状态: ```bash # 查看服务状态 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. 监控和管理命令 ```bash # 查看服务状态 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. 故障排查 ```bash # 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. 卸载/清理 如果需要卸载服务: ```bash # 停止服务 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. **依赖最小化**:只需要rsync,inotify-tools是可选的 这样配置后,服务会: - 每天自动监控当前日期的目录 - 检测到新文件时实时同步 - 每天凌晨自动重启,切换到新的日期目录 - 通过systemd管理,稳定可靠