573 lines
15 KiB
Markdown
573 lines
15 KiB
Markdown
# 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管理,稳定可靠
|
||
|