15 KiB
15 KiB
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@host,host可以是 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
关键点说明
- SSH连接:直接通过
ssh -p 60000 swdata@119.167.194.234连接 - 日期监控:自动监控当天日期目录(格式:YYYYMMDD)
- 实时同步:使用inotifywait监控文件变化,实时同步
- 计划任务:每天00:10重启服务,开始监控新的日期目录
- 日志管理:日志按日期分割,方便查看和清理
- 错误处理:包含完善的错误检测和重试机制
- 依赖最小化:只需要rsync,inotify-tools是可选的
这样配置后,服务会:
- 每天自动监控当前日期的目录
- 检测到新文件时实时同步
- 每天凌晨自动重启,切换到新的日期目录
- 通过systemd管理,稳定可靠