一、为什么?
1. 自建CA为什么比Let's Encrypt强?
不能把CA放公网!Let's Encrypt是给公网服务用的(比如10.0.0.30的Web服务),但内网服务(比如OpenVPN)必须用自签CA。
CA私钥必须物理隔离,不能与业务服务器共存。
2. 为什么必须用SSH+sudo?
直接用root SSH?等着被勒索吧!
管理账号必须最小权限,禁止root直接登录。
3.base64加解密
echo -n 'zjx!@12345'|base64 #加密
emp4IUAxMjM0NQ==
root@D-3PGMZJ3-0948:~# echo -n 'emp4IUAxMjM0NQ==' |base64 -d #解密
zjx!@12345root@D-3PGMZJ3-0948:~#
加密不等于保密,本质是编码。敏感数据需额外加密(如 AES + Base64)
生成随机8位长度密码:openssl rand -base64 10 | head -c8
4.创建10个新用户,并指定8个字符长度的随机密码脚本:
#!/bin/bash
#
#********************************************************************
#Author: zz_zjx
#Feature Description: 批量创建10个用户 + 8位随机密码(Ubuntu 适用)
#Date: 2025-09-15
#FileName: user.sh
#Copyright (C): 2025 All rights reserved
#********************************************************************
set -euo pipefail # 严格模式:遇到错误/未定义变量/管道失败时立即退出OUTPUT_FILE="user_credentials.txt"
LOG_FILE="user_creation.log"# 初始化文件
> "$OUTPUT_FILE"
> "$LOG_FILE"echo "🔐 正在创建 10 个新用户(user01 到 user10)..."
echo "📄 账号密码将保存到:$OUTPUT_FILE"
echo "📝 详细日志:$LOG_FILE"for i in {1..10}; doUSERNAME="user$(printf "%02d" $i)"# 生成 8 位纯字母数字密码(使用 [:alnum:] 更规范)PASSWORD=$(LC_ALL=C openssl rand -base64 12 | tr -dc '[:alnum:]' | head -c 8)# 检查用户是否已存在if id "$USERNAME" &>/dev/null; thenecho "⚠️ [$USERNAME] 已存在,跳过创建。" | tee -a "$LOG_FILE"echo "$USERNAME : (已存在,未设新密码)" >> "$OUTPUT_FILE"continuefi# 创建用户(-m 创建家目录,-s 设置默认 shell)if sudo useradd -m -s /bin/bash "$USERNAME" 2>>"$LOG_FILE"; then# 设置密码(通过 chpasswd)if echo "$USERNAME:$PASSWORD" | sudo chpasswd 2>>"$LOG_FILE"; then# ✅ 可选:强制用户首次登录修改密码(推荐用于真实环境)sudo passwd -e "$USERNAME" 2>>"$LOG_FILE"echo "✅ 用户 [$USERNAME] 创建成功,初始密码: $PASSWORD" | tee -a "$LOG_FILE"echo "$USERNAME : $PASSWORD" >> "$OUTPUT_FILE"elseecho "❌ 为 [$USERNAME] 设置密码失败!" | tee -a "$LOG_FILE"sudo userdel -r "$USERNAME" 2>/dev/null # 回滚:删除用户fielseecho "❌ 创建用户 [$USERNAME] 失败!" | tee -a "$LOG_FILE"fidoneecho "=========================================="
echo "🎉 所有用户创建完成!"
echo "📁 账户信息文件:$(pwd)/$OUTPUT_FILE"
echo "📄 请妥善保管或分发后立即删除该文件!"
echo "=========================================="
5.服务器规划表(IP段10.0.0.0/24,等保三级要求内网隔离):
服务器角色 | IP地址 | 用途 | 关键配置 | 安全要求 | 生产事故教训 |
---|---|---|---|---|---|
CA服务器 | 10.0.0.10 | 内网根CA签发 | openssl自建CA | 等保三级物理隔离 | 2018年CA私钥被盗,全内网证书失效瘫痪4小时 |
Web服务器 | 10.0.0.20 | 对外HTTPS服务 | Let's Encrypt自动续期 | 等保二级,证书有效期90天 | 2021年证书过期未及时续期,客户投诉300+次 |
管理服务器 | 10.0.0.30 | SSH管理入口 | 密钥认证+IP白名单 | 等保三级,禁止密码登录 | 2019年密码登录被暴力破解,删了2台DB服务器 |
应用服务器 | 10.0.0.40 | 业务应用 | sudo最小权限 | 等保二级,禁止root直连 | 2022年运维误执行rm -rf / ,全集群崩盘 |
二、怎么配?
1️⃣自签名证书
1.openssl加解密:
openssl genrsa -out test.key -aes256 -passout pass:"123456"
root@D-3PGMZJ3-0948:/test/ca# ls
test.key
root@D-3PGMZJ3-0948:/test/ca# openssl rsa -in test.key -out test.key2
Enter pass phrase for test.key:
writing RSA key
root@D-3PGMZJ3-0948:/test/ca# ls
test.key test.key2
2.openssl证书格式转换:
例如,PEM 格式的CRT证书转换为.pem格式。openssl x509 -in certificate.crt -outform PEM -out certificate.pem
例如,DER 格式的CRT证书转换为.pem格式。openssl x509 -inform DER -in certificate.crt -outform PEM -out
certificate.pem例如,将PEM证书转换为CRT证书。openssl x509 -inform PEM -in certificate.pem -outform DER -out
certificate.crt
3 内网CA配置(CA服务器 10.0.0.10)
#!/bin/bash
#
#********************************************************************
#Author: zz_zjx
#Feature Description: 全自动创建企业级私有根 CA(Root Certificate Authority)
#Date: 2025-09-15
#FileName: create_root_ca.sh
#Copyright (C): 2025 All rights reserved
#********************************************************************
# 启用严格模式:
# -e:命令出错立即退出
# -u:引用未定义变量时报错
# -o pipefail:管道中任意命令失败则整体失败
set -euo pipefail# ========================
# 🧱 1. 定义基础变量
# ========================
CA_DIR="/root/ca" # CA 根目录(所有文件存放位置)# ========================
# 📁 2. 创建标准 CA 目录结构
# ========================
echo "📁 正在创建 CA 目录结构..."
sudo mkdir -p "$CA_DIR"/{certs,crl,newcerts,private}
# 🔐 private 目录权限设为 700(仅 root 可访问)
sudo chmod 700 "$CA_DIR/private"
echo "✅ 目录结构创建完成"# ========================
# 🔑 3. 生成 CA 根私钥(4096位 RSA + AES256 加密)
# ========================
echo "🔐 正在生成 CA 根私钥(需输入密码)..."
# 生成 4096 位 RSA 私钥,使用 AES-256-CBC 加密保护
# ⚠️ 生产环境请使用高强度密码(16位以上,字母+数字+符号)
sudo openssl genrsa -aes256 -out "$CA_DIR/private/ca.key" 4096
# 🔐 设置私钥文件权限为 600(仅 root 可读写)
sudo chmod 600 "$CA_DIR/private/ca.key"
echo "✅ 私钥生成完成(已加密)"# ========================
# 📄 4. 创建 OpenSSL 配置文件(核心!)
# ========================
echo "📄 正在生成 OpenSSL 配置文件..."
sudo tee "$CA_DIR/openssl.cnf" > /dev/null <<'EOF'
# ============================================================
# OpenSSL 配置文件(用于根 CA 证书生成和后续签发)
# 注意:使用 'EOF' 禁止 Shell 变量展开,$dir 由 OpenSSL 自行解析
# ============================================================# [ req ] 段:控制证书请求/自签名证书生成行为
[ req ]
# 默认密钥长度(req 命令时)
default_bits = 4096
# 指定 DN(Distinguished Name)字段配置段
distinguished_name = req_distinguished_name
# 自签名时使用的 X.509 v3 扩展段
x509_extensions = v3_ca
# 强制使用 UTF-8 编码
string_mask = utf8only
# 关闭交互式提示(全自动,适合脚本)
prompt = no# [ req_distinguished_name ] 段:定义证书主题信息(DN)
[ req_distinguished_name ]
# 国家代码(2字母)
countryName = CN
# 省/州名称
stateOrProvinceName = Sichuan
# 城市名称
localityName = Chengdu
# 组织/公司名称
organizationName = MyOrg
# 部门名称
organizationalUnitName = PKI Department
# 通用名称(最重要!显示在证书中)
commonName = MyOrg Root CA# [ ca ] 段:指定默认 CA 配置段(用于后续 openssl ca 命令)
[ ca ]
default_ca = CA_default# [ CA_default ] 段:CA 默认配置(目录、文件、策略等)
[ CA_default ]
# 基础目录(所有路径基于此)
dir = /root/ca
# 存放已签发证书
certs = $dir/certs
# 存放证书吊销列表(CRL)
crl_dir = $dir/crl
# 证书签发数据库(记录所有签发历史)
database = $dir/index.txt
# 每次签发的证书副本(OpenSSL 自动保存)
new_certs_dir = $dir/newcerts
# CA 根证书路径
certificate = $dir/certs/ca.crt
# 证书序列号文件(每次签发递增)
serial = $dir/serial
# CA 私钥路径
private_key = $dir/private/ca.key
# 默认签发时使用的扩展段
x509_extensions = v3_ca
# 默认证书有效期(天)
default_days = 3650
# 默认签名摘要算法
default_md = sha256# [ v3_ca ] 段:X.509 v3 扩展(标识为 CA 证书)
[ v3_ca ]
# 用公钥生成唯一指纹(Subject Key Identifier)
subjectKeyIdentifier = hash
# 包含签发者密钥 ID 和名称(Authority Key Identifier)
authorityKeyIdentifier = keyid:always,issuer
# 标记为 CA 证书,且为关键扩展(客户端必须识别)
basicConstraints = critical, CA:true
# 密钥用途:可签发证书、签发 CRL、数字签名(关键扩展)
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
EOF
echo "✅ 配置文件生成完成"# ========================
# 🧮 5. 初始化 serial 和 index.txt(OpenSSL 必需)
# ========================
echo "🧮 正在初始化证书序列号和数据库..."
# 创建空数据库文件
sudo touch "$CA_DIR/index.txt"
# 初始化序列号从 1000 开始(避免与系统证书冲突)
echo 1000 | sudo tee "$CA_DIR/serial"
echo "✅ 初始化完成"# ========================
# 📜 6. 生成自签名根 CA 证书(有效期10年)
# ========================
echo "📜 正在生成自签名根 CA 证书..."
# 使用私钥 + 配置文件 + v3_ca 扩展生成证书
# 系统会提示输入私钥密码(因私钥是加密的)
sudo openssl req -new -x509 -days 3650 \-key "$CA_DIR/private/ca.key" \-out "$CA_DIR/certs/ca.crt" \-config "$CA_DIR/openssl.cnf" \-extensions v3_ca
echo "✅ 根证书生成完成"# ========================
# 🔐 7. 设置证书文件权限
# ========================
# 证书是公钥,设为 644(所有用户可读)
sudo chmod 644 "$CA_DIR/certs/ca.crt"# ========================
# 🎉 8. 输出完成信息
# ========================
echo "=========================================="
echo "🎉 根 CA 创建成功!"
echo "🔑 私钥路径:$CA_DIR/private/ca.key"
echo " → 请立即备份并离线保存!生产环境中应从在线系统移除!"
echo "📜 证书路径:$CA_DIR/certs/ca.crt"
echo " → 可分发到所有需要信任此 CA 的服务器"
echo "⚙️ 配置文件:$CA_DIR/openssl.cnf"
echo " → 后续签发证书时会用到"
echo "=========================================="
echo "不要白嫖我,好不好"
4 查看证书:
openssl x509 -in /root/ca/certs/ca.crt -noout -text Certificate:Data:Version: 3 (0x2)Serial Number:1b:30:e6:90:85:3a:3b:a5:07:8a:4d:df:ed:83:7e:fa:60:76:99:43Signature Algorithm: sha256WithRSAEncryptionIssuer: C = CN, ST = Sichuan, L = Chengdu, O = MyOrg, OU = PKI Department, CN = MyOrg Root CAValidityNot Before: Sep 15 09:32:50 2025 GMTNot After : Sep 13 09:32:50 2035 GMTSubject: C = CN, ST = Sichuan, L = Chengdu, O = MyOrg, OU = PKI Department, CN = MyOrg Root CASubject Public Key Info:Public Key Algorithm: rsaEncryptionPublic-Key: (4096 bit)Modulus:00:97:e7:e8:b9:c3:ca:06:06:eb:55:e2:99:69:40:
生产为什么这么干:CA私钥必须存物理隔离服务器,4096位密钥防暴力破解。2018年事故就是私钥存服务器,被黑客直接拿走。
5 证书分发:
#!/bin/bash# ============================ 配置与参数 ============================
# 默认值定义
DEFAULT_CERT="/root/ca/certs/ca.crt"
DEFAULT_USER="deploy"# 参数提示
echo " 参数说明(可选):"
echo " 参数1:SSH 登录用户名(默认: $DEFAULT_USER)"
echo " 参数2:本地 CA 证书路径(默认: $DEFAULT_CERT)"
echo # 读取参数,未传参则使用默认值
SSH_USER="${1:-$DEFAULT_USER}"
CERT_FILE="${2:-$DEFAULT_CERT}"# 目标服务器列表(按需修改)
SERVERS=("10.0.0.20" "10.0.0.30" "10.0.0.40")# 远程系统 CA 证书目录(Debian/Ubuntu 标准路径)
REMOTE_CA_DIR="/usr/local/share/ca-certificates"# 远程证书文件名(建议带描述性)
# 自动生成带日期的自签名内部根证书文件名
REMOTE_CERT_NAME="self-signed-internal-root-ca-$(date +%Y%m%d).crt"# ============================ 预检本地文件 ============================
if [ ! -f "$CERT_FILE" ]; thenecho "❌ 错误:本地证书文件不存在 → $CERT_FILE"echo "💡 请检查路径或通过参数1指定正确的证书路径。"exit 1
fiecho "✅ 使用证书文件: $CERT_FILE"
echo "✅ 使用 SSH 用户: $SSH_USER"
echo "✅ 目标部署目录: $REMOTE_CA_DIR"
echo "========================================"# ============================ 批量部署 ============================
for server in "${SERVERS[@]}"; doechoecho "🚀 开始部署到服务器: $server"# Step 1: 复制证书到远程临时文件if scp "$CERT_FILE" "$SSH_USER@$server:~/ca.crt.tmp"; thenecho " ✅ 证书文件传输成功"# Step 2: 在远程执行部署命令(创建目录 + 复制 + 更新 + 清理)if ssh "$SSH_USER@$server" "# 创建目标目录(如不存在)sudo mkdir -p '$REMOTE_CA_DIR' &&# 复制并重命名证书sudo cp ~/ca.crt.tmp '$REMOTE_CA_DIR/$REMOTE_CERT_NAME' &&# 更新系统 CA 信任库sudo update-ca-certificates &&# 清理临时文件rm ~/ca.crt.tmp"; thenecho " ✅ ✅ 部署成功:证书已安装并生效!"elseecho " ❌ ❌ 部署失败:请检查远程 sudo 权限或系统兼容性。"fielseecho " ❌ ❌ 证书传输失败:请检查网络、SSH 密钥或用户权限。"fi
doneecho
echo "🎉 所有服务器部署任务已完成!"
2️⃣CA机构签名证书
Let's Encrypt配置(Web服务器 10.0.0.20)
1.通过let's encrypt 自动安装nginx 并自动续约
免费申请 DV ssl证书并自动续约,非国内云厂商版本_dv证书续约-CSDN博客
2.通过编译安装nginx,在安装证书并自动续约 脚本
待nginx编译安装篇链接
3️⃣ SSH密钥认证配置(管理服务器 10.0.0.30)
1.SSH配置解读:
root@D-3PGMZJ3-0948:~# ls /etc/ssh
moduli ssh_config.d sshd_config.d ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub ssh_host_rsa_key.pub
ssh_config sshd_config ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key ssh_import_id解读:ssh_host_rsa_key 和 ssh_host_rsa_key.pub 这两对文件是SSH服务器用于RSA认证的密钥对。服务器使用私钥进行认证,而公钥则分发给希望连接服务器的客户端。ssh_host_ecdsa_key 和 ssh_host_ecdsa_key.pub这两对文件是SSH服务器用于ECDSA(椭圆曲线数字签名算法)认证的密钥对。ECDSA是一种较新的、更安全的算法,相对于RSA提供了更高的安全性。ssh_host_ed25519_key 和 ssh_host_ed25519_key.pub这两对文件是SSH服务器用于Ed25519认证的密钥对。Ed25519是一种基于椭圆曲线的公钥加密算法,以其高效和安全性而著称。moduli这个文件包含了用于Diffie-Hellman密钥交换算法的参数。Diffie-Hellman是一种安全协议,用于在不安全的通道上安全地交换密钥。ssh_config这是一个客户端配置文件,用于指定SSH客户端(如ssh命令)的行为。例如,你可以在这里设置默认的用户名、端口号、是否启用X11转发、是否启用压缩等。ssh_config.d/这是一个目录,用于存放额外的客户端配置文件。系统管理员或用户可以在这里添加额外的配置片段,这些配置会被ssh_config文件包含并应用。sshd_config这是一个服务器配置文件,用于指定SSH服务器(通常是sshd服务)的行为。包括允许哪些用户登录、监听哪些端口、是否允许密码认证或仅允许密钥认证、是否启用日志记录等。
2.用脚本实现公钥批量部署:
ssh-keygen -t ed25519 -C "2414421189@qq.com"
公钥生成
#!/bin/bash
#
#********************************************************************
#Author: zz_zjx
#Feature Description: 功能描述
#Date: 2025-09-16
#FileName: ssh.sh
#Copyright (C): 2025 All rights reserved
#********************************************************************
# 登录用户名
LOGIN_USER='root'
# 目标主机列表(空格分隔)
HOST="172.20.15.91 10.0.0.20"
# 登录密码
PASS=123# 加载系统信息(用于判断发行版)
. /etc/os-release# 安装 sshpass 工具(根据系统类型)
pre_os () {if [[ $ID =~ ubuntu ]];thendpkg -l sshpass &> /dev/null || { apt update; apt -y install sshpass; }elif [[ $ID =~ rocky|centos|rhel ]];thenrpm -q sshpass &>/dev/null || yum -y install sshpasselseecho "不支持当前操作系统"exitfi
}# 生成 ed25519 类型 SSH 密钥对(无密码,路径 ~/.ssh/id_ed25519)
create_sshkey(){yes | ssh-keygen -t ed25519 -P "" -f ~/.ssh/id_ed25519 &>/dev/null
}# 将公钥批量复制到目标主机,实现免密登录(并发执行)
scp_key_func(){for i in $HOST; do{echo "🔄 [$i] 正在部署公钥..."# 读取本地公钥内容,通过 sshpass + ssh 远程追加到 authorized_keysPUBKEY=$(cat ~/.ssh/id_ed25519.pub)sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 $LOGIN_USER@$i "mkdir -p ~/.sshchmod 700 ~/.sshecho '$PUBKEY' >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keysecho '公钥写入成功' > /dev/null" &>/dev/nullif [ $? -eq 0 ]; thenecho "✅ [$i] 部署成功"elseecho "❌ [$i] 部署失败"fi}&donewait
}# 主函数:依次执行环境准备、生成密钥、分发公钥
main(){pre_oscreate_sshkeyscp_key_funcecho "✅ SSH 免密配置完成"
}# 执行主函数
main
3.加固配置:
cat > /etc/ssh/sshd_config.d/99-security-hardening.conf << 'EOF'
# =============================================================================
# 文件名:/etc/ssh/sshd_config.d/99-security-hardening.conf
# 用途:SSH 服务安全加固配置(模块化加载)
# 修改时间:$(date '+%Y-%m-%d %H:%M:%S')
# 适用系统:OpenSSH >= 8.4p1
# 加载方式:主配置文件 /etc/ssh/sshd_config 中需包含:
# Include /etc/ssh/sshd_config.d/*.conf
# =============================================================================# ==================== 基础安全加固 ====================
# 强制 IPv4(避免 IPv6 配置不全导致监听失败)
AddressFamily inet
# 强制使用 SSH 协议版本 2
Protocol 2
# 修改默认端口(防自动化扫描)
Port 22222
# 禁止 root 登录
PermitRootLogin no
# 禁用密码认证
PasswordAuthentication no
# 禁用空密码登录(纵深防御)
PermitEmptyPasswords no
# 禁用挑战响应认证
ChallengeResponseAuthentication no
# 禁用 PAM(如需 LDAP/2FA 请设为 yes)
UsePAM no
# 只允许指定用户登录(缩小攻击面)
AllowUsers adminuser# ==================== 连接与会话控制 ====================
# 客户端保活间隔(秒)
ClientAliveInterval 300
# 最大无响应次数(300*2=600秒断开)
ClientAliveCountMax 2
# 登录超时时间
LoginGraceTime 60
# 单次连接最大认证尝试次数
MaxAuthTries 3
# 每连接最大会话数(防滥用)
MaxSessions 2
# 未认证连接限制(start:rate:full)
MaxStartups 10:30:60# ==================== 功能限制 ====================
# 禁用 TCP 转发
AllowTcpForwarding no
# 禁用网关端口绑定
GatewayPorts no
# 禁用 X11 转发
X11Forwarding no
# 禁用隧道
PermitTunnel no
# 禁用压缩(防 CRIME 类攻击)
Compression no# ==================== 加密算法强化 ====================
# 使用 ed25519 主机密钥
HostKey /etc/ssh/ssh_host_ed25519_key
# 密钥交换算法
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
# 加密算法
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
# MAC 算法
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com# ==================== 日志与审计 ====================
# 详细日志级别
LogLevel VERBOSE
# 使用 AUTHPRIV 设施
SyslogFacility AUTHPRIV
# 不显示 MOTD(避免信息泄露)
PrintMotd no
# 显示上次登录时间(帮助发现异常)
PrintLastLog yes
# 禁止用户环境变量(防注入)
PermitUserEnvironment no
EOF
4.QA:
问:为什么第一次连接的时候有yes,后面就不会有了?
[root@rocky9 ~]# grep ask /etc/ssh/ssh_config# StrictHostKeyChecking ask
问:不想连接的时候,输入yes,怎么办?
[root@rocky9 ~]# ssh -o StrictHostKeyChecking=no 10.0.0.12
首次连接之后,如果保存了远程主机的公钥,后续远程主机发生了改变,则会提示,如果远程主机确实发
生了改变,则可以删除本地~.ssh/know_host中的对应的公钥
ssh root@10.0.0.206@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!Someone could be eavesdropping on you right now (man-in-the-middle attack)!It is also possible that a host key has just been changed.The fingerprint for the ED25519 key sent by the remote host isSHA256:1eOK9Aygq1kbA+smlYjwRwRsx+ZdSRkDnNy5AFp3aPE.Please contact your system administrator.Add correct host key in /root/.ssh/known_hosts to get rid of this message.Offending ECDSA key in /root/.ssh/known_hosts:3remove with:ssh-keygen -f "/root/.ssh/known_hosts" -R "10.0.0.206"Host key for 10.0.0.206 has changed and you have requested strict checking.Host key verification failed.问: 如何多机互相打通
ABC 3机器 10.0.0.10 10.0.020 10.0.0.30
方法 1:使用 ssh-copy-id 工具
# 将公钥复制到 B (10.0.0.20)
ssh-copy-id user@10.0.0.20# 将公钥复制到 C (10.0.0.30)
ssh-copy-id user@10.0.0.30
替换 user 为目标机器的用户名(例如 centos 或 fedora)。
方法 2:手动复制公钥
如果未安装 ssh-copy-id,可以手动操作:# 在机器 A 上获取公钥内容
cat ~/.ssh/id_rsa.pub# 登录到 B (10.0.0.20)
ssh user@10.0.0.20
mkdir -p ~/.ssh
echo "公钥内容" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
exit# 登录到 C (10.0.0.30) 并重复上述操作
ssh user@10.0.0.30
mkdir -p ~/.ssh
echo "公钥内容" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
exit
步骤 3:验证 SSH 免密码登录
测试连接
bash
深色版本
# 从 A 登录到 B
ssh user@10.0.0.20# 从 A 登录到 C
ssh user@10.0.0.30
如果无需输入密码即可登录,则配置成功。
退出连接
输入 exit 返回机器 A。
步骤 4:确保单向互信
机器 B 和 C 无法免密码登录到 A
因为只在机器 A 上配置了到 B 和 C 的公钥,未在 B 或 C 上配置到 A 的公钥。
2.SCP命令:
命令格式:scp [选项] 源路径 目标路径注意:远程主机目标位置的表现样式: 用户名@主机名:路径
login_user@remote_addr:/path/to/target常用选项-r #递归复制
一般选项-C #压缩数据流-p #保持原文件的属性信息-q #静默模式-P PORT #指定远程服务器的端口,默认22常用样式:将文件复制到远程主机:scp logs.tar.gz root@10.0.0.13:/tmp将目录复制到远程主机:scp -r syslog root@10.0.0.13:/tmp将文件从远程系统复制到本地系统:scp root@10.0.0.13:/root/passwd /tmp/将目录从远程主机复制到本地系统:scp -r root@10.0.0.13:/root/scripts /tmp/
3.文件同步rsync
全量与增量备份:rsync支持全量备份和增量备份。全量备份意味着每次都会复制所有文件,而增量备份则只复 制那些自上次备份以来已经改变的文件。
跨平台支持:rsync适用于Unix、Linux、Windows等多种操作系统平台,可以在不同平台之间进行数据同 步。
保持文件属性:rsync在复制文件时,可以保持文件的权限、时间戳、软硬链接、属主、组等属性不变。 高效传输:rsync使用独特的“quick check”算法,仅同步大小或最后修改时间发生变化的文件或目录,提高 了数据传输效率。
多种传输方式:rsync可以使用rcp、rsh、ssh等方式来配合进行隧道加密传输文件,也可以使用socket(进 程方式)传输文件和数据。
匿名或认证传输:rsync支持匿名传输,也支持通过用户认证进行传输,保证了数据的安全性。
排除指定文件或目录:rsync具有排除指定文件或目录同步的功能,类似于打包命令tar的排除功能。
定时备份:可以通过crond+rsync来实现定时备份,确保数据的定期同步和备份。
实时备份:可以通过inotify(sersync)+rsync来实现实时备份,当文件有任何变动时,就触发rsync同 步,解决了同步数据的实时性问题。
数据迁移:rsync可以用于在不同服务器之间迁移数据,支持远程同步,方便快捷。
镜像网站:rsync支持匿名传输,可以方便地用于网站镜像,使多个网站之间保持数据同步。
①.常用选项速查表
|
| 归档模式(递归+保留权限/时间/链接/所有者等),最常用 | ✅✅✅ |
|
| 显示详细过程 | ✅✅ |
|
| 启用压缩传输 | ✅✅ |
|
| 人类可读单位(如 2.3M) | ✅ |
| — | 显示传输进度(百分比、速度、剩余时间) | ✅✅ |
|
| 递归复制目录( | ⚠️ |
|
| 保留软链接( | ⚠️ |
|
| 保留权限( | ⚠️ |
|
| 保留修改时间( | ⚠️ |
|
| 保留组( | ⚠️ |
|
| 保留所有者(需 root)( | ⚠️ |
|
| 保留设备文件( | ⚠️ |
| — | 删除目标端多余文件(同步后两端完全一致) | ✅⚠️(慎用) |
| — | 排除匹配文件或目录(如 | ✅✅ |
| — | 包含匹配文件(常配合 exclude 使用) | ✅ |
| — | 试运行:只显示操作,不执行(强烈推荐先测试) | ✅✅✅ |
| — | 保留部分传输文件,支持断点续传 | ✅✅ |
| — | 限速传输(单位 KB/s) | ✅ |
| — | 指定 SSH 命令或端口(如 | ✅✅ |
| — | 显示传输统计信息(文件数、字节数、速度等) | ✅ |
💡 推荐默认组合:
-avz
或-avzh --progress
②、路径语义说明
| 同步目录内所有内容(不包含 dir 本身) |
|
| 同步整个目录(包括 dir 本身) |
|
| 同步单个文件 |
|
| 远程路径(SSH) |
|
| rsync daemon 模式 |
|
③、使用场景速查表
📁 本地目录同步 |
| 保持目录结构和属性 |
➡️ 本地 → 远程 |
| 通过 SSH 推送 |
⬅️ 远程 → 本地 |
| 从远程拉取文件 |
↔️ 远程 → 远程 |
| 本地中转(默认) |
🧹 同步并删除多余文件 |
| ⚠️ 操作前务必 |
🚫 排除特定文件 |
| 支持通配符和目录 |
📜 使用排除文件 |
| 适合复杂过滤规则 |
📊 显示进度+断点续传 |
| 大文件推荐 |
🐢 限速传输 |
| 1000 KB/s = 1MB/s |
🔍 试运行预览 |
| 不实际执行,只显示将要操作 |
④、高级功能对比表
rsync daemon 模式 | 配置 |
| 高频/大规模同步,内网专用 |
SSH 密钥认证 | 使用 |
| 自动化脚本免密同步 |
时间/权限保留 |
|
| 备份、部署需保留元数据 |
增量同步 | 默认行为 | 无需额外参数 | 所有场景默认启用 |
压缩传输 |
|
| 网络慢或文本文件多时使用 |
日志记录 | 重定向输出或 |
| 自动化备份脚本 |
⑤注意事项 & 最佳实践
🔐 安全 | 优先使用 SSH 通道;daemon 模式需配置认证和访问控制 |
⚠️ 删除操作 | 使用 |
🔄 路径写法 | 末尾 |
💾 权限 | 保留所有者( |
🚦 网络中断 | 使用 |
🧪 测试先行 | 任何重要操作前加 |
📈 性能 | 压缩对已压缩文件无效;大量小文件可用 |
⑥、与其他工具对比
工具 | 是否增量 | 是否断点续传 | 是否压缩 | 是否权限保留 | 使用场景 |
---|---|---|---|---|---|
| ❌ | ❌ | ❌ | ✅(-a部分) | 本地快速复制 |
| ❌ | ❌ | ✅( | ✅( | 一次性安全传输小文件 |
| ✅ | ✅( | ✅( | ✅( | 备份、同步、部署首选 |
⑦、实用脚本模板
#!/bin/bash
# 自动备份脚本(带日志和错误处理)SRC="/data/app/"
DST="backup@nas:/backup/app/"
LOG="/var/log/backup_$(date +%Y%m%d).log"echo "=== Backup Start: $(date) ===" >> "$LOG"rsync -avz \--delete \--exclude='*.tmp' \--exclude='logs/' \--partial \--progress \--stats \"$SRC" "$DST" 2>&1 >> "$LOG"if [ $? -eq 0 ]; thenecho "✅ SUCCESS: Backup completed." >> "$LOG"
elseecho "❌ FAILED: Check log for details." >> "$LOG"exit 1
fiecho "=== Backup End: $(date) ===" >> "$LOG"
⑧、排错速查表
现象 | 可能原因 | 解决方案 |
---|---|---|
| 目标路径无写权限 | 检查远程用户权限或使用 |
| 路径错误或不存在 | 检查路径拼写,加 |
传输慢 | 未压缩或网络差 | 加 |
文件没同步 | 路径末尾 | 检查源路径是否应加 |
删除了不该删的 | 误用 | 今后先用 |
SSH 端口不对 | 默认 22,实际非 22 | 加 |
⑨、终极口诀
“-avz 是黄金组合,--delete 前先 dry-run,路径斜杠别搞错,--exclude 过滤准,--partial 可续传,-e 指定 SSH 端口稳!”
4️⃣ sudo权限管理(应用服务器 10.0.0.40)
# 1. 创建普通用户(生产必须用非root用户)
sudo adduser --system --group --shell /bin/bash appuser# 2. 配置sudo权限(生产必须限制命令,别用ALL)
sudo visudo
# 添加:appuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 为什么?避免执行rm -rf /等危险命令# 3. 验证权限(生产必须测试)
sudo -u appuser /usr/bin/systemctl restart nginx # 成功才给权限
常见 sudoers 权限规则表
完全无密码ROOT权限(危险!) |
| 用户 | ⚠️ 高危 |
完全有密码ROOT权限(标准管理员) |
| 用户 | ✅ 中(推荐) |
仅允许特定命令(无密码) |
| 用户可无密码重启 nginx,其他命令无权限。适合自动化脚本或受限运维。 | ✅ 高 |
允许一组相关命令(使用命令别名) |
| 先定义命令组别名 | ✅ 高 |
允许以特定用户身份执行命令 |
| 用户 | ✅ 高 |
仅允许查看系统状态类命令 |
| 授予只读监控权限,用于系统巡检,不涉及修改。 | ✅ 高 |
允许使用包管理器更新(有密码) |
| 开发者可自行更新系统包,但需输入密码,防止误操作。 | ✅ 中 |
禁止执行危险命令 |
| 允许所有命令,但排除修改 root 密码或执行 | ⚠️ 中低(不推荐依赖此方式) |
按组授权(推荐批量管理) |
| 授权给用户组 | ✅ 中高 |
限制在特定主机生效 |
| 仅当用户在 | ✅ 中 |
🔐 关键安全原则
- 最小权限原则:只给用户完成工作所必需的最小权限。
- 避免 NOPASSWD:ALL:除非是自动化服务账户,否则不要使用。
- 使用绝对路径:命令必须写完整路径(如
/usr/bin/systemctl
),防止 PATH 劫持。 - 善用别名:
User_Alias
,Host_Alias
,Cmnd_Alias
可让配置更清晰、易维护。 - 分文件管理:将不同用户的权限写入
/etc/sudoers.d/username
文件,用visudo -f /etc/sudoers.d/filename
编辑,避免主文件混乱。
✅ 最佳实践示例:
# /etc/sudoers.d/web_deployer
Cmnd_Alias NGINX = /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx
Cmnd_Alias GIT = /usr/bin/git pull, /usr/bin/git checkout%deployers ALL=(www-data) NOPASSWD: GIT
%deployers ALL=(root) NOPASSWD: NGINX
此配置允许 deployers
组的用户以 www-data
身份执行 git 命令,以 root
身份重载 nginx,权限清晰且安全。