feat: add Cloudflare browser SSH + short-lived certificate setup script
This commit is contained in:
commit
0115f54b04
513
setup-cf-browser-ssh.sh
Normal file
513
setup-cf-browser-ssh.sh
Normal file
@ -0,0 +1,513 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# =============================================================================
|
||||||
|
# setup-cf-browser-ssh.sh
|
||||||
|
# Cloudflare Browser-rendered SSH + Short-lived Certificate 服务器端一键配置
|
||||||
|
# 支持系统:Ubuntu / Debian
|
||||||
|
#
|
||||||
|
# 功能:
|
||||||
|
# 1. 安装 cloudflared(如未安装)
|
||||||
|
# 2. 可选:用 Tunnel Token 注册 cloudflared 系统服务
|
||||||
|
# 3. 写入 Cloudflare CA 公钥到 /etc/ssh/ca.pub
|
||||||
|
# 4. 配置 sshd_config 信任 Cloudflare CA
|
||||||
|
# 5. 配置用户名映射(支持 root 共享登录)
|
||||||
|
# 6. 校验 sshd 配置并 reload
|
||||||
|
#
|
||||||
|
# 用法:
|
||||||
|
# 交互式(推荐):
|
||||||
|
# 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" \
|
||||||
|
# --login-user root \
|
||||||
|
# --tunnel-token "eyJhIjoiNz..."
|
||||||
|
#
|
||||||
|
# 选项:
|
||||||
|
# --ca-pubkey <string|filepath> Cloudflare short-lived CA 公钥(内容或文件路径)
|
||||||
|
# --login-user <username> 浏览器终端登录的 Linux 用户(默认:root)
|
||||||
|
# --tunnel-token <token> cloudflared Tunnel Token(可选,不传则跳过服务注册)
|
||||||
|
# --skip-cloudflared 跳过 cloudflared 安装
|
||||||
|
# --allow-all-principals 允许任意 Access 用户登录 --login-user(默认开启 root 时自动启用)
|
||||||
|
# --dry-run 只打印将要执行的操作,不实际修改
|
||||||
|
# -h, --help 显示帮助
|
||||||
|
#
|
||||||
|
# 回滚:
|
||||||
|
# 脚本会在修改前备份 sshd_config,备份文件名如 sshd_config.bak.20260412_120000
|
||||||
|
# 如果 sshd -t 校验失败,脚本会自动还原备份并拒绝 reload。
|
||||||
|
# =============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ----- 颜色输出 -----
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
||||||
|
step() { echo -e "\n${CYAN}===> $*${NC}"; }
|
||||||
|
|
||||||
|
# ----- 默认值 -----
|
||||||
|
CA_PUBKEY=""
|
||||||
|
LOGIN_USER="root"
|
||||||
|
TUNNEL_TOKEN=""
|
||||||
|
SKIP_CLOUDFLARED=false
|
||||||
|
ALLOW_ALL_PRINCIPALS=false
|
||||||
|
DRY_RUN=false
|
||||||
|
|
||||||
|
SSHD_CONFIG="/etc/ssh/sshd_config"
|
||||||
|
CA_PUB_FILE="/etc/ssh/ca.pub"
|
||||||
|
BACKUP_SUFFIX="bak.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
|
||||||
|
# ----- 参数解析 -----
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--ca-pubkey) CA_PUBKEY="$2"; shift 2 ;;
|
||||||
|
--login-user) LOGIN_USER="$2"; shift 2 ;;
|
||||||
|
--tunnel-token) TUNNEL_TOKEN="$2"; shift 2 ;;
|
||||||
|
--skip-cloudflared) SKIP_CLOUDFLARED=true; shift ;;
|
||||||
|
--allow-all-principals) ALLOW_ALL_PRINCIPALS=true; shift ;;
|
||||||
|
--dry-run) DRY_RUN=true; shift ;;
|
||||||
|
-h|--help)
|
||||||
|
awk '/^# =====/{ if(n++) exit } n{ sub(/^# ?/,""); print }' "$0"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*) err "未知参数: $1"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# ----- 前置检查 -----
|
||||||
|
check_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
err "请使用 root 或 sudo 执行此脚本"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_os() {
|
||||||
|
if [[ ! -f /etc/os-release ]]; then
|
||||||
|
err "无法检测操作系统,此脚本仅支持 Ubuntu/Debian"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source /etc/os-release
|
||||||
|
case "$ID" in
|
||||||
|
ubuntu|debian) info "检测到系统: $PRETTY_NAME" ;;
|
||||||
|
*)
|
||||||
|
err "此脚本仅支持 Ubuntu/Debian,当前系统: $ID"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 交互式收集缺失参数 -----
|
||||||
|
prompt_missing_params() {
|
||||||
|
# CA 公钥
|
||||||
|
if [[ -z "$CA_PUBKEY" ]]; then
|
||||||
|
echo ""
|
||||||
|
warn "未提供 Cloudflare CA 公钥。"
|
||||||
|
echo " 获取方式:Cloudflare One → Access controls → Service credentials → SSH"
|
||||||
|
echo " → 选择对应 Application → 复制 CA public key"
|
||||||
|
echo ""
|
||||||
|
read -rp "请粘贴 CA 公钥(一行,以 ecdsa-sha2 或 ssh-rsa 开头),或输入本地文件路径: " CA_PUBKEY
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果是文件路径,读取内容
|
||||||
|
if [[ -f "$CA_PUBKEY" ]]; then
|
||||||
|
info "从文件读取 CA 公钥: $CA_PUBKEY"
|
||||||
|
CA_PUBKEY="$(cat "$CA_PUBKEY")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 校验公钥格式
|
||||||
|
if [[ ! "$CA_PUBKEY" =~ ^(ecdsa-sha2-nistp256|ssh-rsa|ssh-ed25519)[[:space:]] ]]; then
|
||||||
|
err "CA 公钥格式不正确,应以 ecdsa-sha2-nistp256 / ssh-rsa / ssh-ed25519 开头"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 登录用户
|
||||||
|
if [[ -z "$LOGIN_USER" ]]; then
|
||||||
|
read -rp "浏览器终端登录的 Linux 用户 [root]: " LOGIN_USER
|
||||||
|
LOGIN_USER="${LOGIN_USER:-root}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# root 模式自动启用 allow-all-principals
|
||||||
|
if [[ "$LOGIN_USER" == "root" ]]; then
|
||||||
|
ALLOW_ALL_PRINCIPALS=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tunnel Token
|
||||||
|
if [[ -z "$TUNNEL_TOKEN" && "$SKIP_CLOUDFLARED" != true ]]; then
|
||||||
|
echo ""
|
||||||
|
echo -e " ${CYAN}Tunnel Token 获取方式:${NC}"
|
||||||
|
echo " Cloudflare One → Networks → Tunnels → 选择/创建 Tunnel → Install connector"
|
||||||
|
echo ""
|
||||||
|
echo " 控制台会给你一条类似这样的命令:"
|
||||||
|
echo -e " ${GREEN}sudo cloudflared service install eyJhIjoiZDZjN2MwNT...${NC}"
|
||||||
|
echo ""
|
||||||
|
echo " 你只需要复制 eyJ 开头的那串 Token 粘贴到下面即可。"
|
||||||
|
echo " (留空则跳过隧道服务注册,之后可手动执行)"
|
||||||
|
echo ""
|
||||||
|
read -rp "请输入 Tunnel Token: " TUNNEL_TOKEN
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 安装 cloudflared -----
|
||||||
|
install_cloudflared() {
|
||||||
|
step "安装 cloudflared"
|
||||||
|
|
||||||
|
if command -v cloudflared &>/dev/null; then
|
||||||
|
local ver
|
||||||
|
ver=$(cloudflared --version 2>&1 | head -1)
|
||||||
|
info "cloudflared 已安装: $ver(跳过安装)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
info "[DRY-RUN] 将安装 cloudflared(apt 方式)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "添加 Cloudflare GPG key 和 apt 源..."
|
||||||
|
mkdir -p --mode=0755 /usr/share/keyrings
|
||||||
|
curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg \
|
||||||
|
| tee /usr/share/keyrings/cloudflare-public-v2.gpg >/dev/null
|
||||||
|
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main" \
|
||||||
|
| tee /etc/apt/sources.list.d/cloudflared.list >/dev/null
|
||||||
|
|
||||||
|
info "正在安装 cloudflared(全程无交互)..."
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq cloudflared
|
||||||
|
|
||||||
|
if command -v cloudflared &>/dev/null; then
|
||||||
|
info "cloudflared 安装成功: $(cloudflared --version 2>&1 | head -1)"
|
||||||
|
else
|
||||||
|
err "cloudflared 安装失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 注册 cloudflared 系统服务 -----
|
||||||
|
register_cloudflared_service() {
|
||||||
|
step "注册 cloudflared 系统服务"
|
||||||
|
|
||||||
|
if [[ -z "$TUNNEL_TOKEN" ]]; then
|
||||||
|
warn "未提供 Tunnel Token,跳过服务注册"
|
||||||
|
echo ""
|
||||||
|
echo " 后续手动注册命令:"
|
||||||
|
echo " sudo cloudflared service install <YOUR_TUNNEL_TOKEN>"
|
||||||
|
echo ""
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active --quiet cloudflared 2>/dev/null; then
|
||||||
|
info "cloudflared 服务已在运行(跳过)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
info "[DRY-RUN] 将执行: cloudflared service install <TOKEN>"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "执行 cloudflared service install ..."
|
||||||
|
cloudflared service install "$TUNNEL_TOKEN"
|
||||||
|
|
||||||
|
if systemctl is-active --quiet cloudflared 2>/dev/null; then
|
||||||
|
info "cloudflared 服务已启动"
|
||||||
|
else
|
||||||
|
warn "cloudflared 服务注册完成但未自动启动,尝试启动..."
|
||||||
|
systemctl start cloudflared
|
||||||
|
systemctl enable cloudflared
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 写入 CA 公钥 -----
|
||||||
|
write_ca_pubkey() {
|
||||||
|
step "写入 Cloudflare CA 公钥 → $CA_PUB_FILE"
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
info "[DRY-RUN] 将写入 CA 公钥到 $CA_PUB_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 幂等:检查是否已包含相同公钥
|
||||||
|
if [[ -f "$CA_PUB_FILE" ]]; then
|
||||||
|
if grep -qF "$CA_PUBKEY" "$CA_PUB_FILE" 2>/dev/null; then
|
||||||
|
info "CA 公钥已存在于 $CA_PUB_FILE(跳过)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# 文件存在但内容不同,追加
|
||||||
|
info "$CA_PUB_FILE 已存在,追加新公钥"
|
||||||
|
echo "$CA_PUBKEY" >> "$CA_PUB_FILE"
|
||||||
|
else
|
||||||
|
echo "$CA_PUBKEY" > "$CA_PUB_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod 644 "$CA_PUB_FILE"
|
||||||
|
info "CA 公钥已写入"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 配置 sshd_config -----
|
||||||
|
configure_sshd() {
|
||||||
|
step "配置 $SSHD_CONFIG"
|
||||||
|
|
||||||
|
if [[ ! -f "$SSHD_CONFIG" ]]; then
|
||||||
|
err "$SSHD_CONFIG 不存在"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 备份
|
||||||
|
local backup="${SSHD_CONFIG}.${BACKUP_SUFFIX}"
|
||||||
|
cp "$SSHD_CONFIG" "$backup"
|
||||||
|
info "已备份: $backup"
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
|
info "[DRY-RUN] 将修改 $SSHD_CONFIG"
|
||||||
|
info "[DRY-RUN] PubkeyAuthentication yes"
|
||||||
|
info "[DRY-RUN] TrustedUserCAKeys $CA_PUB_FILE"
|
||||||
|
if [[ "$ALLOW_ALL_PRINCIPALS" == true ]]; then
|
||||||
|
info "[DRY-RUN] AuthorizedPrincipalsCommand (allow all for $LOGIN_USER)"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local changed=false
|
||||||
|
|
||||||
|
# --- PubkeyAuthentication yes ---
|
||||||
|
if grep -qE '^\s*PubkeyAuthentication\s' "$SSHD_CONFIG"; then
|
||||||
|
# 如果存在但不是 yes,替换
|
||||||
|
if ! grep -qE '^\s*PubkeyAuthentication\s+yes' "$SSHD_CONFIG"; then
|
||||||
|
sed -i 's/^\s*PubkeyAuthentication\s.*/PubkeyAuthentication yes/' "$SSHD_CONFIG"
|
||||||
|
info "已修改 PubkeyAuthentication → yes"
|
||||||
|
changed=true
|
||||||
|
else
|
||||||
|
info "PubkeyAuthentication yes 已存在"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# 不存在,添加到文件顶部(跳过注释)
|
||||||
|
sed -i '1i PubkeyAuthentication yes' "$SSHD_CONFIG"
|
||||||
|
info "已添加 PubkeyAuthentication yes"
|
||||||
|
changed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- TrustedUserCAKeys ---
|
||||||
|
local ca_directive="TrustedUserCAKeys $CA_PUB_FILE"
|
||||||
|
if grep -qE '^\s*TrustedUserCAKeys\s' "$SSHD_CONFIG"; then
|
||||||
|
if ! grep -qF "$ca_directive" "$SSHD_CONFIG"; then
|
||||||
|
sed -i "s|^\s*TrustedUserCAKeys\s.*|$ca_directive|" "$SSHD_CONFIG"
|
||||||
|
info "已修改 TrustedUserCAKeys → $CA_PUB_FILE"
|
||||||
|
changed=true
|
||||||
|
else
|
||||||
|
info "TrustedUserCAKeys 已正确配置"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# 添加到 PubkeyAuthentication 之后
|
||||||
|
sed -i "/^PubkeyAuthentication/a $ca_directive" "$SSHD_CONFIG"
|
||||||
|
info "已添加 $ca_directive"
|
||||||
|
changed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 用户名映射(root / 共享账号模式)---
|
||||||
|
if [[ "$ALLOW_ALL_PRINCIPALS" == true ]]; then
|
||||||
|
configure_principals "$LOGIN_USER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 确保 PermitRootLogin 允许公钥登录(仅 root 模式)---
|
||||||
|
if [[ "$LOGIN_USER" == "root" ]]; then
|
||||||
|
ensure_root_login
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$changed" == true ]]; then
|
||||||
|
info "sshd_config 已修改"
|
||||||
|
else
|
||||||
|
info "sshd_config 无需修改"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- 校验 ---
|
||||||
|
validate_and_reload "$backup"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置 AuthorizedPrincipalsCommand,让任意 Access 用户都可以登录指定用户
|
||||||
|
configure_principals() {
|
||||||
|
local user="$1"
|
||||||
|
|
||||||
|
# 标记行,用于幂等检查
|
||||||
|
local marker="# --- Cloudflare Access short-lived cert: $user ---"
|
||||||
|
|
||||||
|
if grep -qF "$marker" "$SSHD_CONFIG" 2>/dev/null; then
|
||||||
|
info "AuthorizedPrincipalsCommand($user)已配置(跳过)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
warn "⚠️ 将允许任意通过 Cloudflare Access 认证的用户以 '$user' 身份登录"
|
||||||
|
warn "⚠️ 请确保你的 Access Policy 已正确限制可访问人员!"
|
||||||
|
|
||||||
|
# 对于 root,使用全局 AuthorizedPrincipalsCommand
|
||||||
|
# 对于其他用户,使用 Match User 块
|
||||||
|
if [[ "$user" == "root" ]]; then
|
||||||
|
cat >> "$SSHD_CONFIG" << EOF
|
||||||
|
|
||||||
|
$marker
|
||||||
|
# 允许任意 Cloudflare Access 短期证书用户以 root 登录
|
||||||
|
# 安全性完全依赖 Cloudflare Access Policy,请务必正确配置!
|
||||||
|
Match User root
|
||||||
|
AuthorizedPrincipalsCommand /bin/bash -c "echo '%t %k' | ssh-keygen -L -f - | grep -A1 Principals"
|
||||||
|
AuthorizedPrincipalsCommandUser nobody
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat >> "$SSHD_CONFIG" << EOF
|
||||||
|
|
||||||
|
$marker
|
||||||
|
Match User $user
|
||||||
|
AuthorizedPrincipalsCommand /bin/bash -c "echo '%t %k' | ssh-keygen -L -f - | grep -A1 Principals"
|
||||||
|
AuthorizedPrincipalsCommandUser nobody
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "已添加 AuthorizedPrincipalsCommand($user)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 确保 root 可以通过公钥登录
|
||||||
|
ensure_root_login() {
|
||||||
|
# PermitRootLogin 需要为 yes 或 prohibit-password 或 without-password
|
||||||
|
if grep -qE '^\s*PermitRootLogin\s+(no|forced-commands-only)\b' "$SSHD_CONFIG"; then
|
||||||
|
sed -i 's/^\s*PermitRootLogin\s.*/PermitRootLogin prohibit-password/' "$SSHD_CONFIG"
|
||||||
|
info "已修改 PermitRootLogin → prohibit-password(允许证书登录,禁止密码)"
|
||||||
|
elif grep -qE '^\s*PermitRootLogin\s' "$SSHD_CONFIG"; then
|
||||||
|
info "PermitRootLogin 当前设置允许公钥登录"
|
||||||
|
else
|
||||||
|
echo "PermitRootLogin prohibit-password" >> "$SSHD_CONFIG"
|
||||||
|
info "已添加 PermitRootLogin prohibit-password"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 校验并 reload -----
|
||||||
|
validate_and_reload() {
|
||||||
|
local backup="$1"
|
||||||
|
|
||||||
|
step "校验 sshd 配置"
|
||||||
|
|
||||||
|
if sshd -t 2>&1; then
|
||||||
|
info "sshd -t 校验通过 ✓"
|
||||||
|
else
|
||||||
|
err "sshd -t 校验失败!正在回滚..."
|
||||||
|
cp "$backup" "$SSHD_CONFIG"
|
||||||
|
info "已回滚到备份: $backup"
|
||||||
|
err "请手动检查 $SSHD_CONFIG 后重试"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
step "重新加载 SSH 服务"
|
||||||
|
if systemctl reload ssh 2>/dev/null || systemctl reload sshd 2>/dev/null; then
|
||||||
|
info "SSH 服务已 reload ✓"
|
||||||
|
else
|
||||||
|
warn "systemctl reload 失败,尝试 service ssh reload..."
|
||||||
|
service ssh reload 2>/dev/null || service sshd reload 2>/dev/null || {
|
||||||
|
err "SSH 服务 reload 失败,请手动执行: systemctl reload ssh"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----- 打印后续手工步骤 -----
|
||||||
|
print_next_steps() {
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}============================================================${NC}"
|
||||||
|
echo -e "${CYAN} 服务器端配置完成!以下是你需要在 Cloudflare 控制台完成的步骤:${NC}"
|
||||||
|
echo -e "${CYAN}============================================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo " 1. 创建 / 确认 Self-hosted Application"
|
||||||
|
echo " → Cloudflare One → Access controls → Applications"
|
||||||
|
echo " → 添加 Self-hosted Application,域名指向你的 SSH 服务"
|
||||||
|
echo ""
|
||||||
|
echo " 2. 开启 Browser Rendering"
|
||||||
|
echo " → 在 Application 设置中,Browser rendering → 选择 SSH"
|
||||||
|
echo ""
|
||||||
|
echo " 3. 生成 Short-lived Certificate(如果你还没生成 CA 公钥)"
|
||||||
|
echo " → Access controls → Service credentials → SSH"
|
||||||
|
echo " → Add a certificate → 选择你的 Application → Generate"
|
||||||
|
echo ""
|
||||||
|
echo " 4. 配置 Access Policy"
|
||||||
|
echo " → 在 Application 中配置谁可以访问(邮箱、域名、组等)"
|
||||||
|
echo ""
|
||||||
|
echo " 5. 测试"
|
||||||
|
echo " → 浏览器访问你配置的域名"
|
||||||
|
echo " → 完成 SSO 登录后,应出现网页 SSH 终端"
|
||||||
|
echo " → 用户名输入: $LOGIN_USER"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$LOGIN_USER" == "root" ]]; then
|
||||||
|
echo -e " ${YELLOW}⚠️ 重要提醒:${NC}"
|
||||||
|
echo -e " ${YELLOW} 你配置的是 root 登录模式,服务器安全性完全依赖 Access Policy。${NC}"
|
||||||
|
echo -e " ${YELLOW} 务必确保 Access Policy 只允许受信任的用户访问!${NC}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$TUNNEL_TOKEN" && "$SKIP_CLOUDFLARED" != true ]]; then
|
||||||
|
echo " ⓘ cloudflared 已安装但 Tunnel 服务未注册。"
|
||||||
|
echo " 如需注册,请在控制台获取 Token 后执行:"
|
||||||
|
echo " sudo cloudflared service install <YOUR_TUNNEL_TOKEN>"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN} 配置文件位置:${NC}"
|
||||||
|
echo " CA 公钥: $CA_PUB_FILE"
|
||||||
|
echo " sshd_config: $SSHD_CONFIG"
|
||||||
|
echo " sshd 备份: ${SSHD_CONFIG}.${BACKUP_SUFFIX}"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# 主流程
|
||||||
|
# =============================================================================
|
||||||
|
main() {
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
|
||||||
|
echo -e "${CYAN}║ Cloudflare Browser SSH + Short-lived Certificates Setup ║${NC}"
|
||||||
|
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
check_root
|
||||||
|
check_os
|
||||||
|
prompt_missing_params
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "配置摘要:"
|
||||||
|
info " 登录用户: $LOGIN_USER"
|
||||||
|
info " 允许任意 principal: $ALLOW_ALL_PRINCIPALS"
|
||||||
|
info " 安装 cloudflared: $( [[ "$SKIP_CLOUDFLARED" == true ]] && echo '跳过' || echo '是' )"
|
||||||
|
info " Tunnel Token: $( [[ -n "$TUNNEL_TOKEN" ]] && echo '已提供' || echo '未提供' )"
|
||||||
|
info " Dry Run: $DRY_RUN"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$DRY_RUN" != true ]]; then
|
||||||
|
read -rp "确认以上配置并继续?[Y/n] " confirm
|
||||||
|
if [[ "${confirm,,}" =~ ^n ]]; then
|
||||||
|
info "已取消"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. cloudflared
|
||||||
|
if [[ "$SKIP_CLOUDFLARED" != true ]]; then
|
||||||
|
install_cloudflared
|
||||||
|
register_cloudflared_service
|
||||||
|
else
|
||||||
|
info "跳过 cloudflared 安装(--skip-cloudflared)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. CA 公钥
|
||||||
|
write_ca_pubkey
|
||||||
|
|
||||||
|
# 3. sshd 配置
|
||||||
|
configure_sshd
|
||||||
|
|
||||||
|
# 4. 后续步骤
|
||||||
|
print_next_steps
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Loading…
x
Reference in New Issue
Block a user