Skip to content

Commit 982a592

Browse files
baijumclaude
andcommitted
fix: prevent SSH lockout and harden bootstrap for fresh servers
- Replace git clone with curl tarball in tutorial (git not on fresh Debian) - Add SSH lockout guard: skip hardening if deploy has no SSH keys - Grant deploy user passwordless sudo (needed post-hardening) - Replace hardcoded script copy list with glob (auto-include new scripts) - Update verify path to /opt/platform/infrastructure/verify-server.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3818d56 commit 982a592

2 files changed

Lines changed: 20 additions & 11 deletions

File tree

docs/tutorial.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ You should see a shell prompt. If this works, you are ready to bootstrap.
5151

5252
## Step 3: Bootstrap the server
5353

54-
SSH into your server as root and run the bootstrap script. This installs Docker, creates the `deploy` user, starts all platform services, and generates credentials:
54+
SSH into your server as root. Download and run the bootstrap script — no `git` required:
5555

5656
```bash
5757
ssh root@YOUR_SERVER_IP
58-
git clone https://github.com/towlion/platform.git /tmp/platform
58+
mkdir -p /tmp/platform && curl -fsSL https://github.com/towlion/platform/archive/refs/heads/main.tar.gz \
59+
| tar xz --strip-components=1 -C /tmp/platform
5960
sudo ACME_EMAIL=you@example.com bash /tmp/platform/infrastructure/bootstrap-server.sh
6061
```
6162

@@ -68,7 +69,7 @@ sudo ACME_EMAIL=you@example.com bash /tmp/platform/infrastructure/bootstrap-serv
6869
Verify the bootstrap was successful:
6970

7071
```bash
71-
bash /tmp/platform/infrastructure/verify-server.sh
72+
/opt/platform/infrastructure/verify-server.sh
7273
```
7374

7475
All checks should pass. The script creates:

infrastructure/bootstrap-server.sh

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ else
165165
info "User 'deploy' added to docker group"
166166
fi
167167

168+
SUDOERS_FILE="/etc/sudoers.d/deploy"
169+
if [[ -f "$SUDOERS_FILE" ]]; then
170+
info "Sudoers entry for deploy already exists"
171+
else
172+
echo "deploy ALL=(ALL) NOPASSWD: ALL" > "$SUDOERS_FILE"
173+
chmod 440 "$SUDOERS_FILE"
174+
info "Passwordless sudo granted to deploy user"
175+
fi
176+
168177
DEPLOY_SSH_DIR="/home/deploy/.ssh"
169178
if [[ ! -d "$DEPLOY_SSH_DIR" ]]; then
170179
mkdir -p "$DEPLOY_SSH_DIR"
@@ -191,6 +200,9 @@ fi
191200
SSHD_HARDENING="/etc/ssh/sshd_config.d/99-towlion-hardening.conf"
192201
if [[ -f "$SSHD_HARDENING" ]]; then
193202
info "SSH hardening config already exists"
203+
elif [[ ! -s /home/deploy/.ssh/authorized_keys ]]; then
204+
warn "Skipping SSH hardening — deploy user has no SSH keys"
205+
warn "Add keys to /home/deploy/.ssh/authorized_keys, then re-run bootstrap to harden SSH"
194206
else
195207
cat > "$SSHD_HARDENING" <<'EOF'
196208
PermitRootLogin no
@@ -1402,14 +1414,10 @@ fi
14021414
# --- Copy Infrastructure Scripts ---
14031415

14041416
SCRIPT_DIR="/opt/platform/infrastructure"
1405-
for script in create-app-credentials.sh backup-postgres.sh restore-postgres.sh \
1406-
check-alerts.sh update-images.sh usage-report.sh scan-images.sh \
1407-
deploy-blue-green.sh verify-backup.sh rotate-credentials.sh; do
1408-
SRC_SCRIPT="$(dirname "$0")/$script"
1409-
if [[ -f "$SRC_SCRIPT" ]]; then
1410-
cp "$SRC_SCRIPT" "$SCRIPT_DIR/$script"
1411-
chmod +x "$SCRIPT_DIR/$script"
1412-
fi
1417+
for src in "$(dirname "$0")"/*.sh; do
1418+
[[ "$(basename "$src")" == "bootstrap-server.sh" ]] && continue
1419+
cp "$src" "$SCRIPT_DIR/"
1420+
chmod +x "$SCRIPT_DIR/$(basename "$src")"
14131421
done
14141422
chown -R deploy:deploy "$SCRIPT_DIR"
14151423
info "Infrastructure scripts copied to $SCRIPT_DIR"

0 commit comments

Comments
 (0)