SSH CA 登录认证
注意:
新买的云主机一定要修改sshd服务端口- 查看主机被暴力破解登录记录: lastb
- 同级具体登录失败IP数量前十: lastb -f /var/log/btmp |awk '{print $3}'|sort|uniq -c |sort -nr|head -n 10
或者: lastb -f /var/log/btmp | awk '{ip[$3]++}END{for(i in ip) {print ip[i], i}}'|sort -nr |head -n 10
说明
bash
# CA: 192.168.165.71 (进行CA证书签发)
# CLIENT: 192.168.165.72 (可做堡垒机进行登录认证用户管理)
# SERVER: 192.168.165.73 (业务节点)相关示意截图
- CA服务器证书目录结构

- CLIENT服务器用户目录结构

- SERVER服务器sshd目录结构

- CA服务器证书目录结构
CA服务器
bash
##### 初始化CA证书
sudo mkdir -p /etc/ssh/ca
sudo chmod 755 /etc/ssh/ca
cd /etc/ssh/ca
## 生成CA密钥对(使用Ed25519算法,更安全高效):这里使用的算法,在下面客户端生成用户密钥时要对应
ssh-keygen -t ed25519 -f ca_key -C "SSH Certificate Authority"
## 创建存放认证用户密钥目录
mkdir /etc/ssh/ca/user_keys
##### 获取认证用户的个人公钥放在 /etc/ssh/ca/user_keys 路径进行签名 (CLIENT进行认证用户的相关操作后执行)
## 对认证用户: alice 进行认证: 参数 -n 标识登录用户为张三(服务端必须创建此登录用户), -O "force-command=/usr/local/bin/audit-wrapper" 每次用户登录时都会执行的脚本
## ssh-keygen -s ca_key -I "alice_to_zhangsan" -n zhangsan -V +52w /etc/ssh/ca/user_keys/alice.pub
## ssh-keygen -s ca_key -I alice_to_zhangsan -n zhangsan -O force-command=/usr/local/bin/audit-wrapper -V +52w /etc/ssh/ca/user_keys/alice.pub
ssh-keygen -s ca_key -I efls_to_zhangsan -n zhangsan -V +2w -O extension:realuser=efls /etc/ssh/ca/user_keys/efls.pub
## 查看认证详情
ssh-keygen -L -f /etc/ssh/ca/user_keys/alice-cert.pub
## 将生成的用户证书alice-cert.pub回传到客户端(CLIENT): /home/alice/.ssh/id_rsa-cert.pub- sshd服务端
bash
## 创建一个用于登录的用户(zhangsan): adduser -m zhangsan
## 将CA服务器上生成的CA证书公钥拷贝到SERVER服务器上并进行配置
## scp root@192.168.165.71:/etc/ssh/ca/ca_key.pub /etc/ssh/ca_key.pub
## 配置CA登录认证
cat >/etc/ssh/sshd_config.d/10-ca-auth.conf<< 'EOF'
TrustedUserCAKeys /etc/ssh/ca_key.pub
PubkeyAuthentication yes
PasswordAuthentication no
## 下面的配置用于: ssh-keygen -s ca_key -I alice_to_zhangsan -n zhangsan -V +2h -O extension:realuser=alice /etc/ssh/ca/user_keys/alice.pub
TrustedUserCAKeys /etc/ssh/ca_key.pub
PubkeyAuthentication yes
PasswordAuthentication no
ExposeAuthInfo yes
AuthorizedPrincipalsCommand /usr/local/bin/ssh-principal-map.sh
AuthorizedPrincipalsCommandUser nobody
PermitUserEnvironment no
#ForceCommand /usr/local/bin/ssh-forcecmd.sh
Match User zhangsan
AcceptEnv SSH_USER_CERTIFICATE REAL_USER SSH_KEY_ID LANG LC_*
# 使用ForceCommand包装器
ForceCommand /usr/local/bin/ssh-forcecmd.sh
#AuthorizedKeysCommand /usr/local/bin/ssh-forcecmd.sh %u %k %t %T %I %f
#AuthorizedKeysCommandUser nobody
EOF
## 创建: /usr/local/bin/ssh-principal-map.sh
cat >/usr/local/bin/ssh-principal-map.sh<'EOF'
#!/bin/bash
echo zhangsan
EOF
chmod +x /usr/local/bin/ssh-principal-map.sh
## 创建: /usr/local/bin/ssh-forcecmd.sh
cat >/usr/local/bin/ssh-forcecmd.sh<'EOF'
#!/bin/bash
#CERT_ID="$SSH_CERT_KEY_ID" # OpenSSH 内置环境变量
#REAL_USER="${CERT_ID%@*}" # 取 alice / bob
#export REAL_USER
#logger -p authpriv.notice "ssh-login real_user=$REAL_USER unix_user=$USER src=$SSH_CONNECTION cert_id=$SSH_CERT_KEY_ID"
#exec /bin/bash -l
CERT_FILE=$SSH_USER_AUTH
if [[ -n "$CERT_FILE" && -f "$CERT_FILE" ]]; then
#ssh-keygen -Lf <(cat "$CERT_FILE"|awk '{sub($1 OFS, ""); print}')
## 这里解析的登录认证,需要在签发登录用户证书时使用 -O extension:realuser=alice 进行参数传递
REAL_USER=$(ssh-keygen -Lf <(cat "$CERT_FILE"|awk '{sub($1 OFS, ""); print}') | awk '/realuser/ {print $4}'| xxd -r -p | tail -c +5)
else
REAL_USER="unknown"
fi
#echo $REAL_USER
export REAL_USER
LOG=/var/log/session/${REAL_USER}-$(date +%Y%m%d%H%M%S)-$$.log
logger -p authpriv.notice "ssh-login real_user=$REAL_USER unix_user=$USER src=$SSH_CONNECTION cert_id=$SSH_CERT_KEY_ID log=$LOG"
exec script -q -f "$LOG"
EOF
chmod +x /usr/local/bin/ssh-forcecmd.sh
## 创建会话回放目录: mkdir /var/log/session && chown zhangsan:zhangsan /var/log/session
## 测试配置文件: sshd -t
## 重启sshd服务: systemctl restart sshd- sshd客户端
bash
## 创建认证用户: alice 并生成用户密钥
sudo adduser -m alice
su alice && cd ~
mkdir .ssh
## 这里使用ed25519要与上面初始化CA证书时使用的算法一致
ssh-keygen -t ed25519 -f .ssh/id_ed25519 -N "" -C "alice@ssh-client"
## 将alice公钥拷贝到CA服务器进行认证
## cat cat .ssh/id_rsa.pub | ssh root@192.168.165.71:/etc/ssh/ca/user_keys/alice.pub
## CA服务端进行用户认证后, 将生成的alice-cert.pub证书放到客户端用户家目录中的.ssh/id_rsa-cert.pub
## 配置用户alice登录
cat > ~/.ssh/config <<'EOF'
Host 192.168.165.73
HostName 192.168.165.73
User zhangsan
IdentityFile ~/.ssh/id_ed25519
CertificateFile ~/.ssh/id_ed25519-cert.pub
EOF- 日志与审计
bash
#!/bin/bash
## 在所有服务端新建审计bash脚本: /usr/local/bin/ssh-forcecmd.sh
## 检查 /var/log/session 路径是否存在,并授权登录用户zhangsan可访问: chown zhangsan:zhangsan /var/log/session
## 用户登录时需要先调用此脚本(需要sshd服务端进行相关配置才能生效)
CERT_FILE=$SSH_USER_AUTH
if [[ -n "$CERT_FILE" && -f "$CERT_FILE" ]]; then
#ssh-keygen -Lf <(cat "$CERT_FILE"|awk '{sub($1 OFS, ""); print}')
## 这里解析的登录认证,需要在签发登录用户证书时使用 -O extension:realuser=alice 进行参数传递
REAL_USER=$(ssh-keygen -Lf <(cat "$CERT_FILE"|awk '{sub($1 OFS, ""); print}') | awk '/realuser/ {print $4}'| xxd -r -p | tail -c +5)
else
REAL_USER="unknown"
fi
#echo $REAL_USER
export REAL_USER
LOG=/var/log/session/${REAL_USER}-$(date +%Y%m%d%H%M%S)-$$.log
logger -p authpriv.notice "ssh-login real_user=$REAL_USER unix_user=$USER src=$SSH_CONNECTION cert_id=$SSH_CERT_KEY_ID log=$LOG"
exec script -q -f "$LOG"
# chmod +x /usr/local/bin/ssh-forcecmd.sh