non-interactive --yes: ask() assumes prompt default (no read); timezone defaults UTC; --username implies force-create; create-user name defaults to mk under --yes
This commit is contained in:
parent
34137d185e
commit
8930e7aa76
@ -2,9 +2,15 @@
|
||||
# prompt.sh — plain y/N prompts.
|
||||
|
||||
# ask "prompt?" [default y|n] -> sets REPLY
|
||||
# Under ${ALL:-0} (the --yes flag) assume the stated default without
|
||||
# reading stdin, so a fully non-interactive run never blocks on a read.
|
||||
ask() {
|
||||
local p="$1" d="${2:-y}" hint
|
||||
if [[ "$d" == "y" ]]; then hint="[Y/n]"; else hint="[y/N]"; fi
|
||||
if (( ${ALL:-0} )); then
|
||||
REPLY="$d"
|
||||
return
|
||||
fi
|
||||
read -rp "$p $hint " REPLY
|
||||
[[ -z "$REPLY" ]] && REPLY="$d"
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
# - Root + no SUDO_USER + Debian/Ubuntu -> ask y/N (optional, apt works as root).
|
||||
# - --create-user flag -> force prompt regardless.
|
||||
# - --username NAME -> override default name, no prompt.
|
||||
# - --yes (no --username) -> default to 'mk' silently (no stall).
|
||||
#
|
||||
# Passwordless, no user password (NOPASSWD). Idempotent: re-runs re-sync
|
||||
# authorized_keys + sudoers rather than failing.
|
||||
@ -40,7 +41,8 @@ run_create_user() {
|
||||
_handle_direct_root() {
|
||||
local should_create=0
|
||||
|
||||
if (( CREATE_USER )); then
|
||||
if (( CREATE_USER )) || [[ -n "${USERNAME_ARG:-}" ]]; then
|
||||
[[ -n "${USERNAME_ARG:-}" ]] && log "--username given: forcing user creation"
|
||||
should_create=1
|
||||
elif [[ "$DISTRO" == "arch" ]]; then
|
||||
# AUR/makepkg cannot run as root — we genuinely need a non-root sudoer.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# 50-hardening — system defaults. Each sub-step y/N, all idempotent.
|
||||
|
||||
step_name="hardening"
|
||||
step_desc="ssh, ufw, updates, unattended, tz, hostname, swap, locale, fail2ban, angie config"
|
||||
step_desc="ssh, ufw, updates, unattended, tz, hostname, swap, locale, fail2ban, angie config + built-in ACME"
|
||||
step_run="run_hardening"
|
||||
|
||||
run_hardening() {
|
||||
@ -15,6 +15,7 @@ run_hardening() {
|
||||
_h_locale
|
||||
_h_fail2ban
|
||||
_h_angie_config
|
||||
_h_angie_acme
|
||||
ok "hardening pass complete"
|
||||
}
|
||||
|
||||
@ -104,8 +105,12 @@ _h_tz_hostname() {
|
||||
if command -v timedatectl >/dev/null 2>&1; then
|
||||
if yn "Set timezone (default UTC)?" y; then
|
||||
local tz="${REPLY_TZ:-}"
|
||||
read -rp " timezone [UTC]: " tz
|
||||
[[ -z "$tz" ]] && tz="UTC"
|
||||
if (( ${ALL:-0} )); then
|
||||
tz="UTC"; ok "--yes: timezone defaulting to UTC"
|
||||
else
|
||||
read -rp " timezone [UTC]: " tz
|
||||
[[ -z "$tz" ]] && tz="UTC"
|
||||
fi
|
||||
sudo_ timedatectl set-timezone "$tz" && ok "timezone set to $tz"
|
||||
fi
|
||||
else
|
||||
@ -367,4 +372,86 @@ if command -v angie >/dev/null 2>&1; then
|
||||
fi
|
||||
EOF
|
||||
sudo_ chmod +x /usr/local/bin/angie-enable /usr/local/bin/angie-disable
|
||||
}
|
||||
|
||||
# ── angie built-in ACME (Let's Encrypt) ────────────────────────────────────
|
||||
# No certbot: Angie ships http_acme and fetches/renews certs itself.
|
||||
# Bootstrap can't know your domain/email, so we ship an example TLS server
|
||||
# target + an `angie-issue` helper that creates the live acme_client on demand.
|
||||
_h_angie_acme() {
|
||||
if ! command -v angie >/dev/null 2>&1; then
|
||||
echo " skip angie ACME (angie not installed)"; return
|
||||
fi
|
||||
if ! yn "Ship Angie built-in ACME template + angie-issue helper?" y; then
|
||||
echo " skip angie ACME"; return
|
||||
fi
|
||||
|
||||
local d=/etc/angie
|
||||
# example TLS server target — NOT auto-enabled (.example, so angie-enable won't glob it)
|
||||
if [[ ! -f "$d/targets/example-https.conf.example" ]]; then
|
||||
sudo_ tee "$d/targets/example-https.conf.example" >/dev/null <<'EOF'
|
||||
# Template for a TLS host using Angie built-in ACME.
|
||||
# Use it via the helper: angie-issue <domain> [you@email]
|
||||
# Or by hand: copy to targets/<domain>.conf, fill <DOMAIN>, then: angie-enable <domain>
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
server_name <DOMAIN>;
|
||||
|
||||
acme default; # add this server_name to the shared 'default' ACME certificate
|
||||
ssl_certificate $acme_cert_default;
|
||||
ssl_certificate_key $acme_cert_key_default;
|
||||
|
||||
# http -> https redirect
|
||||
if ($scheme = http) { return 301 https://$host$request_uri; }
|
||||
|
||||
location / {
|
||||
# replace with your app / proxy_pass upstream;
|
||||
return 200 "angie + builtin ACME ok\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
sudo_ tee /usr/local/bin/angie-issue >/dev/null <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
# angie-issue <domain> [email] — create a TLS host backed by Angie built-in ACME.
|
||||
# First call (needs email) writes /etc/angie/modules/http/acme.conf with the
|
||||
# shared 'default' acme_client; every call writes targets/<domain>.conf and enables it.
|
||||
# All enabled domains using `acme default` share one cert covering all their server_names.
|
||||
set -euo pipefail
|
||||
domain="${1:-}"; email="${2:-}"
|
||||
[ -n "$domain" ] || { echo "usage: angie-issue <domain> [email]" >&2; exit 2; }
|
||||
acme_conf=/etc/angie/modules/http/acme.conf
|
||||
|
||||
if [ ! -f "$acme_conf" ]; then
|
||||
[ -n "$email" ] || { echo "first-time: also pass your email for Let's Encrypt" >&2; exit 2; }
|
||||
cat > "$acme_conf" <<ACME
|
||||
# managed by angie-issue — Angie built-in ACME (Let's Encrypt)
|
||||
# resolver is required by the acme_client directive (http context).
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s ipv6=off;
|
||||
acme_client default https://acme-v02.api.letsencrypt.org/directory email=${email};
|
||||
ACME
|
||||
echo "wrote $acme_conf (email=${email})"
|
||||
else
|
||||
echo "_existing $acme_conf (shared default client)"
|
||||
fi
|
||||
|
||||
target=/etc/angie/targets/${domain}.conf
|
||||
sed -e "s|<DOMAIN>|${domain}|g" /etc/angie/targets/example-https.conf.example > "$target"
|
||||
echo "wrote $target"
|
||||
ln -sfn "../targets/${domain}.conf" /etc/angie/_on/${domain}.conf
|
||||
echo "enabled: $domain"
|
||||
sudo angie -t
|
||||
sudo systemctl reload angie && echo "angie reloaded — certificate is obtained automatically."
|
||||
EOF
|
||||
sudo_ chmod +x /usr/local/bin/angie-issue
|
||||
|
||||
ok "angie ACME ready: example host at $d/targets/example-https.conf.example"
|
||||
echo " issue a cert: angie-issue <domain> you@email"
|
||||
echo " then reload picks it up; Angie renews automatically before expiry."
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user