fix: auto-derive SSH username from SSO email prefix, create Linux user if needed

- Cloudflare browser SSH forces email prefix as SSH username
- Add --sso-email parameter to auto-extract username
- Auto-create Linux user with sudo when it doesn't exist
- Update prompts and help to explain email prefix requirement
- Fix next-steps output with email prefix instructions
This commit is contained in:
chunzhi 2026-04-12 13:26:47 +08:00
parent dbf7cc4a94
commit 0ab0e12b05

View File

@ -19,11 +19,12 @@
# 非交互式(全部参数传入): # 非交互式(全部参数传入):
# sudo bash setup-cf-browser-ssh.sh \ # sudo bash setup-cf-browser-ssh.sh \
# --ca-pubkey "ecdsa-sha2-nistp256 AAAA... open-ssh-ca@cloudflareaccess.org" \ # --ca-pubkey "ecdsa-sha2-nistp256 AAAA... open-ssh-ca@cloudflareaccess.org" \
# --login-user root \ # --sso-email admin@example.com \
# --tunnel-token "eyJhIjoiNz..." # --tunnel-token "eyJhIjoiNz..."
# #
# 选项: # 选项:
# --ca-pubkey <string|filepath> Cloudflare short-lived CA 公钥(内容或文件路径) # --ca-pubkey <string|filepath> Cloudflare short-lived CA 公钥(内容或文件路径)
# --sso-email <email> Cloudflare SSO 登录邮箱(用于提取用户名)
# --login-user <username> 浏览器终端登录的 Linux 用户默认root # --login-user <username> 浏览器终端登录的 Linux 用户默认root
# --tunnel-token <token> cloudflared Tunnel Token可选不传则跳过服务注册 # --tunnel-token <token> cloudflared Tunnel Token可选不传则跳过服务注册
# --skip-cloudflared 跳过 cloudflared 安装 # --skip-cloudflared 跳过 cloudflared 安装
@ -51,7 +52,8 @@ step() { echo -e "\n${CYAN}===> $*${NC}"; }
# ----- 默认值 ----- # ----- 默认值 -----
CA_PUBKEY="" CA_PUBKEY=""
LOGIN_USER="root" SSO_EMAIL=""
LOGIN_USER=""
TUNNEL_TOKEN="" TUNNEL_TOKEN=""
SKIP_CLOUDFLARED=false SKIP_CLOUDFLARED=false
ALLOW_ALL_PRINCIPALS=false ALLOW_ALL_PRINCIPALS=false
@ -79,6 +81,7 @@ BACKUP_SUFFIX="bak.$(date +%Y%m%d_%H%M%S)"
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--ca-pubkey) CA_PUBKEY="$2"; shift 2 ;; --ca-pubkey) CA_PUBKEY="$2"; shift 2 ;;
--sso-email) SSO_EMAIL="$2"; shift 2 ;;
--login-user) LOGIN_USER="$2"; shift 2 ;; --login-user) LOGIN_USER="$2"; shift 2 ;;
--tunnel-token) TUNNEL_TOKEN="$(extract_tunnel_token "$2")"; shift 2 ;; --tunnel-token) TUNNEL_TOKEN="$(extract_tunnel_token "$2")"; shift 2 ;;
--skip-cloudflared) SKIP_CLOUDFLARED=true; shift ;; --skip-cloudflared) SKIP_CLOUDFLARED=true; shift ;;
@ -140,10 +143,23 @@ prompt_missing_params() {
exit 1 exit 1
fi fi
# 登录用户 # SSO 邮箱 → 登录用户
if [[ -z "$LOGIN_USER" ]]; then if [[ -z "$LOGIN_USER" ]]; then
read -rp "浏览器终端登录的 Linux 用户 [root]: " LOGIN_USER if [[ -z "$SSO_EMAIL" ]]; then
LOGIN_USER="${LOGIN_USER:-root}" echo ""
echo -e " ${YELLOW}⚠️ 重要Cloudflare 浏览器 SSH 强制使用 SSO 邮箱前缀作为用户名${NC}"
echo " 例如admin@moe.tips → 用户名自动变为 admin"
echo " 你无法在浏览器终端里选择用户名,它由邮箱前缀决定。"
echo ""
read -rp "请输入你的 Cloudflare SSO 登录邮箱: " SSO_EMAIL
fi
if [[ -n "$SSO_EMAIL" ]]; then
LOGIN_USER="${SSO_EMAIL%%@*}"
info "从邮箱 '$SSO_EMAIL' 提取的登录用户名: $LOGIN_USER"
else
LOGIN_USER="root"
warn "未提供邮箱,默认使用 root仅当你的邮箱前缀是 root 时才有效)"
fi
fi fi
# root 模式自动启用 allow-all-principals # root 模式自动启用 allow-all-principals
@ -427,6 +443,33 @@ validate_and_reload() {
fi fi
} }
# ----- 创建登录用户(如不存在) -----
create_login_user() {
local user="$1"
# root 不需要创建
if [[ "$user" == "root" ]]; then
return 0
fi
step "检查 Linux 用户: $user"
if id "$user" &>/dev/null; then
info "用户 '$user' 已存在"
return 0
fi
if [[ "$DRY_RUN" == true ]]; then
info "[DRY-RUN] 将创建用户 '$user' 并加入 sudo 组"
return 0
fi
info "创建用户 '$user'(无密码,仅证书登录)..."
adduser --disabled-password --gecos "" "$user"
usermod -aG sudo "$user"
info "用户 '$user' 已创建并加入 sudo 组 ✓"
}
# ----- 打印后续手工步骤 ----- # ----- 打印后续手工步骤 -----
print_next_steps() { print_next_steps() {
echo "" echo ""
@ -450,14 +493,24 @@ print_next_steps() {
echo "" echo ""
echo " 5. 测试" echo " 5. 测试"
echo " → 浏览器访问你配置的域名" echo " → 浏览器访问你配置的域名"
echo " → 完成 SSO 登录后,应出现网页 SSH 终端" echo " → 完成 SSO 登录后,应直接进入网页 SSH 终端"
echo " → 用户名输入: $LOGIN_USER" echo ""
echo -e " ${YELLOW} 浏览器终端强制使用 SSO 邮箱前缀作为用户名${NC}"
echo " 你必须用邮箱前缀为 '${LOGIN_USER}' 的账号登录 SSO"
if [[ -n "$SSO_EMAIL" ]]; then
echo " 即使用: ${SSO_EMAIL}"
fi
echo "" echo ""
if [[ "$LOGIN_USER" == "root" ]]; then if [[ "$LOGIN_USER" == "root" ]]; then
echo -e " ${YELLOW}⚠️ 重要提醒:${NC}" echo -e " ${YELLOW}⚠️ 重要提醒:${NC}"
echo -e " ${YELLOW} 你配置的是 root 登录模式,服务器安全性完全依赖 Access Policy。${NC}" echo -e " ${YELLOW} 你配置的是 root 登录模式。${NC}"
echo -e " ${YELLOW} 务必确保 Access Policy 只允许受信任的用户访问!${NC}" echo -e " ${YELLOW} 只有邮箱前缀为 'root' 的 SSO 账号才能通过浏览器 SSH 登录!${NC}"
echo -e " ${YELLOW} 服务器安全性完全依赖 Access Policy确保只允许受信任的用户访问${NC}"
echo ""
else
echo -e " ${GREEN}✅ 服务器已配置用户 '${LOGIN_USER}'(带 sudo 权限)${NC}"
echo " 登录后可用 sudo -i 获取 root shell"
echo "" echo ""
fi fi
@ -491,6 +544,7 @@ main() {
echo "" echo ""
info "配置摘要:" info "配置摘要:"
info " SSO 邮箱: ${SSO_EMAIL:-(未提供)}"
info " 登录用户: $LOGIN_USER" info " 登录用户: $LOGIN_USER"
info " 允许任意 principal: $ALLOW_ALL_PRINCIPALS" info " 允许任意 principal: $ALLOW_ALL_PRINCIPALS"
info " 安装 cloudflared: $( [[ "$SKIP_CLOUDFLARED" == true ]] && echo '跳过' || echo '是' )" info " 安装 cloudflared: $( [[ "$SKIP_CLOUDFLARED" == true ]] && echo '跳过' || echo '是' )"
@ -517,7 +571,10 @@ main() {
# 2. CA 公钥 # 2. CA 公钥
write_ca_pubkey write_ca_pubkey
# 3. sshd 配置 # 3. 创建登录用户
create_login_user "$LOGIN_USER"
# 4. sshd 配置
configure_sshd configure_sshd
# 4. 后续步骤 # 4. 后续步骤