dartokloning 修订了这个 Gist . 跳至此修订
1 file changed, 269 insertions
debian-post-install.sh(file created)
| @@ -0,0 +1,269 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # | |
| 3 | + | # debian-post-install.sh | |
| 4 | + | # | |
| 5 | + | # Bootstrap Debian fresh install: | |
| 6 | + | # - sudo + add user to sudo group | |
| 7 | + | # - vnStat | |
| 8 | + | # - Vim | |
| 9 | + | # - sync global .bashrc / shell prompt / Fastfetch config | |
| 10 | + | # - UFW firewall | |
| 11 | + | # - Fail2ban for SSH | |
| 12 | + | # | |
| 13 | + | # Jalankan sebagai root setelah: | |
| 14 | + | # su - | |
| 15 | + | # | |
| 16 | + | # Contoh: | |
| 17 | + | # chmod +x bootstrap-debian.sh | |
| 18 | + | # ./debian-post-install.sh | |
| 19 | + | # | |
| 20 | + | # Aman dijalankan ulang (idempotent). | |
| 21 | + | ||
| 22 | + | set -Eeuo pipefail | |
| 23 | + | ||
| 24 | + | # --------------------------------------------------------------------------- | |
| 25 | + | # Configuration | |
| 26 | + | # --------------------------------------------------------------------------- | |
| 27 | + | ||
| 28 | + | ADMIN_USER="${ADMIN_USER:-darto}" | |
| 29 | + | ||
| 30 | + | SYNC_BASHRC_URL="https://gist.darto.id/dartokloning/82f93f1f0a294d55bd5f1a0abcb7f63f/download/HEAD/sync-bashrc-all.sh" | |
| 31 | + | SYNC_BASHRC_FILE="/usr/local/sbin/sync-bashrc-all.sh" | |
| 32 | + | ||
| 33 | + | FAIL2BAN_JAIL="/etc/fail2ban/jail.d/sshd.local" | |
| 34 | + | ||
| 35 | + | # Port web yang biasa dibuka. | |
| 36 | + | ALLOW_HTTP="${ALLOW_HTTP:-yes}" | |
| 37 | + | ALLOW_HTTPS="${ALLOW_HTTPS:-yes}" | |
| 38 | + | ||
| 39 | + | # --------------------------------------------------------------------------- | |
| 40 | + | # Helpers | |
| 41 | + | # --------------------------------------------------------------------------- | |
| 42 | + | ||
| 43 | + | log() { | |
| 44 | + | printf '\n== %s ==\n' "$*" | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | ok() { | |
| 48 | + | printf ' -> %s\n' "$*" | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | die() { | |
| 52 | + | printf 'ERROR: %s\n' "$*" >&2 | |
| 53 | + | exit 1 | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | if [[ "$(id -u)" -ne 0 ]]; then | |
| 57 | + | die "Jalankan script ini sebagai root. Gunakan: su -" | |
| 58 | + | fi | |
| 59 | + | ||
| 60 | + | if [[ ! -r /etc/os-release ]]; then | |
| 61 | + | die "/etc/os-release tidak ditemukan." | |
| 62 | + | fi | |
| 63 | + | ||
| 64 | + | . /etc/os-release | |
| 65 | + | ||
| 66 | + | if [[ "${ID:-}" != "debian" ]]; then | |
| 67 | + | die "Script ini khusus Debian. Sistem terdeteksi: ${PRETTY_NAME:-unknown}" | |
| 68 | + | fi | |
| 69 | + | ||
| 70 | + | if ! id "$ADMIN_USER" >/dev/null 2>&1; then | |
| 71 | + | die "User '$ADMIN_USER' tidak ditemukan." | |
| 72 | + | fi | |
| 73 | + | ||
| 74 | + | export DEBIAN_FRONTEND=noninteractive | |
| 75 | + | ||
| 76 | + | # --------------------------------------------------------------------------- | |
| 77 | + | # 1. Update + packages | |
| 78 | + | # --------------------------------------------------------------------------- | |
| 79 | + | ||
| 80 | + | log "1. Update repository dan install paket dasar" | |
| 81 | + | ||
| 82 | + | apt-get update | |
| 83 | + | ||
| 84 | + | apt-get install -y \ | |
| 85 | + | sudo \ | |
| 86 | + | curl \ | |
| 87 | + | ca-certificates \ | |
| 88 | + | vnstat \ | |
| 89 | + | vim \ | |
| 90 | + | vim-common \ | |
| 91 | + | ufw \ | |
| 92 | + | fail2ban | |
| 93 | + | ||
| 94 | + | ok "Paket dasar sudah terinstall." | |
| 95 | + | ||
| 96 | + | # --------------------------------------------------------------------------- | |
| 97 | + | # 2. Sudo access | |
| 98 | + | # --------------------------------------------------------------------------- | |
| 99 | + | ||
| 100 | + | log "2. Pastikan $ADMIN_USER masuk group sudo" | |
| 101 | + | ||
| 102 | + | if id -nG "$ADMIN_USER" | tr ' ' '\n' | grep -qx sudo; then | |
| 103 | + | ok "$ADMIN_USER sudah menjadi anggota group sudo." | |
| 104 | + | else | |
| 105 | + | usermod -aG sudo "$ADMIN_USER" | |
| 106 | + | ok "$ADMIN_USER ditambahkan ke group sudo." | |
| 107 | + | fi | |
| 108 | + | ||
| 109 | + | printf ' -> Group %s: %s\n' "$ADMIN_USER" "$(id -nG "$ADMIN_USER")" | |
| 110 | + | ||
| 111 | + | # --------------------------------------------------------------------------- | |
| 112 | + | # 3. vnStat | |
| 113 | + | # --------------------------------------------------------------------------- | |
| 114 | + | ||
| 115 | + | log "3. Aktifkan vnStat" | |
| 116 | + | ||
| 117 | + | systemctl enable --now vnstat | |
| 118 | + | systemctl is-active --quiet vnstat \ | |
| 119 | + | && ok "vnstat aktif." \ | |
| 120 | + | || die "vnstat gagal aktif." | |
| 121 | + | ||
| 122 | + | # --------------------------------------------------------------------------- | |
| 123 | + | # 4. Vim | |
| 124 | + | # --------------------------------------------------------------------------- | |
| 125 | + | ||
| 126 | + | log "4. Verifikasi Vim" | |
| 127 | + | ||
| 128 | + | if command -v vim >/dev/null 2>&1; then | |
| 129 | + | ok "Vim tersedia: $(vim --version | head -n1)" | |
| 130 | + | else | |
| 131 | + | die "Vim tidak ditemukan setelah instalasi." | |
| 132 | + | fi | |
| 133 | + | ||
| 134 | + | # --------------------------------------------------------------------------- | |
| 135 | + | # 5. Sync .bashrc / prompt / Fastfetch | |
| 136 | + | # --------------------------------------------------------------------------- | |
| 137 | + | ||
| 138 | + | log "5. Download dan jalankan sync-bashrc-all.sh" | |
| 139 | + | ||
| 140 | + | tmp_sync="$(mktemp)" | |
| 141 | + | trap 'rm -f "$tmp_sync"' EXIT | |
| 142 | + | ||
| 143 | + | curl -fL --silent --show-error "$SYNC_BASHRC_URL" -o "$tmp_sync" | |
| 144 | + | ||
| 145 | + | if [[ ! -s "$tmp_sync" ]]; then | |
| 146 | + | die "sync-bashrc-all.sh hasil download kosong." | |
| 147 | + | fi | |
| 148 | + | ||
| 149 | + | install -o root -g root -m 0755 "$tmp_sync" "$SYNC_BASHRC_FILE" | |
| 150 | + | ||
| 151 | + | ok "sync-bashrc-all.sh disimpan di $SYNC_BASHRC_FILE" | |
| 152 | + | ||
| 153 | + | "$SYNC_BASHRC_FILE" | |
| 154 | + | ||
| 155 | + | ok "Konfigurasi Bash/Fastfetch selesai disinkronkan." | |
| 156 | + | ||
| 157 | + | # --------------------------------------------------------------------------- | |
| 158 | + | # 6. Detect SSH port | |
| 159 | + | # --------------------------------------------------------------------------- | |
| 160 | + | ||
| 161 | + | log "6. Deteksi port SSH" | |
| 162 | + | ||
| 163 | + | SSH_PORT="22" | |
| 164 | + | ||
| 165 | + | if command -v sshd >/dev/null 2>&1; then | |
| 166 | + | detected_port="$(sshd -T 2>/dev/null | awk '$1=="port" {print $2; exit}' || true)" | |
| 167 | + | if [[ "$detected_port" =~ ^[0-9]+$ ]]; then | |
| 168 | + | SSH_PORT="$detected_port" | |
| 169 | + | fi | |
| 170 | + | fi | |
| 171 | + | ||
| 172 | + | ok "Port SSH terdeteksi: $SSH_PORT/tcp" | |
| 173 | + | ||
| 174 | + | # --------------------------------------------------------------------------- | |
| 175 | + | # 7. UFW | |
| 176 | + | # --------------------------------------------------------------------------- | |
| 177 | + | ||
| 178 | + | log "7. Konfigurasi UFW" | |
| 179 | + | ||
| 180 | + | # Jangan reset UFW agar rule custom yang mungkin sudah ada tidak hilang. | |
| 181 | + | ufw allow "${SSH_PORT}/tcp" comment 'SSH' | |
| 182 | + | ||
| 183 | + | if [[ "$ALLOW_HTTP" == "yes" ]]; then | |
| 184 | + | ufw allow 80/tcp comment 'HTTP' | |
| 185 | + | fi | |
| 186 | + | ||
| 187 | + | if [[ "$ALLOW_HTTPS" == "yes" ]]; then | |
| 188 | + | ufw allow 443/tcp comment 'HTTPS' | |
| 189 | + | fi | |
| 190 | + | ||
| 191 | + | # ufw --force enable aman untuk noninteractive. | |
| 192 | + | ufw --force enable | |
| 193 | + | systemctl enable --now ufw | |
| 194 | + | ||
| 195 | + | ok "UFW aktif." | |
| 196 | + | ||
| 197 | + | ufw status verbose | |
| 198 | + | ||
| 199 | + | # --------------------------------------------------------------------------- | |
| 200 | + | # 8. Fail2ban | |
| 201 | + | # --------------------------------------------------------------------------- | |
| 202 | + | ||
| 203 | + | log "8. Konfigurasi Fail2ban" | |
| 204 | + | ||
| 205 | + | mkdir -p /etc/fail2ban/jail.d | |
| 206 | + | ||
| 207 | + | cat > "$FAIL2BAN_JAIL" <<EOF | |
| 208 | + | [sshd] | |
| 209 | + | enabled = true | |
| 210 | + | backend = systemd | |
| 211 | + | port = ${SSH_PORT} | |
| 212 | + | bantime = 4w | |
| 213 | + | maxretry = 2 | |
| 214 | + | banaction = ufw | |
| 215 | + | EOF | |
| 216 | + | ||
| 217 | + | chmod 0644 "$FAIL2BAN_JAIL" | |
| 218 | + | ||
| 219 | + | ok "Konfigurasi dibuat: $FAIL2BAN_JAIL" | |
| 220 | + | ||
| 221 | + | # Validasi konfigurasi sebelum restart. | |
| 222 | + | if ! fail2ban-client -t; then | |
| 223 | + | die "Validasi konfigurasi Fail2ban gagal." | |
| 224 | + | fi | |
| 225 | + | ||
| 226 | + | systemctl enable --now fail2ban | |
| 227 | + | systemctl restart fail2ban | |
| 228 | + | ||
| 229 | + | sleep 1 | |
| 230 | + | ||
| 231 | + | systemctl is-active --quiet fail2ban \ | |
| 232 | + | && ok "Fail2ban aktif." \ | |
| 233 | + | || die "Fail2ban gagal aktif." | |
| 234 | + | ||
| 235 | + | # --------------------------------------------------------------------------- | |
| 236 | + | # 9. Summary | |
| 237 | + | # --------------------------------------------------------------------------- | |
| 238 | + | ||
| 239 | + | log "9. Ringkasan" | |
| 240 | + | ||
| 241 | + | printf 'User admin : %s\n' "$ADMIN_USER" | |
| 242 | + | printf 'Group : %s\n' "$(id -nG "$ADMIN_USER")" | |
| 243 | + | printf 'SSH port : %s/tcp\n' "$SSH_PORT" | |
| 244 | + | printf 'vnStat : %s\n' "$(systemctl is-active vnstat || true)" | |
| 245 | + | printf 'UFW : %s\n' "$(systemctl is-active ufw || true)" | |
| 246 | + | printf 'Fail2ban : %s\n' "$(systemctl is-active fail2ban || true)" | |
| 247 | + | printf 'Fail2ban jail : %s\n' "$FAIL2BAN_JAIL" | |
| 248 | + | printf 'Bash sync : %s\n' "$SYNC_BASHRC_FILE" | |
| 249 | + | ||
| 250 | + | echo | |
| 251 | + | echo "Fail2ban SSH jail:" | |
| 252 | + | fail2ban-client status sshd 2>/dev/null || true | |
| 253 | + | ||
| 254 | + | echo | |
| 255 | + | echo "============================================================" | |
| 256 | + | echo "BOOTSTRAP DEBIAN SELESAI" | |
| 257 | + | echo "============================================================" | |
| 258 | + | echo | |
| 259 | + | echo "PENTING:" | |
| 260 | + | echo "User '$ADMIN_USER' baru memperoleh group sudo pada login session berikutnya." | |
| 261 | + | echo "Disconnect SSH lalu login kembali sebagai '$ADMIN_USER'." | |
| 262 | + | echo | |
| 263 | + | echo "Setelah login ulang, cek:" | |
| 264 | + | echo " sudo -v" | |
| 265 | + | echo " groups" | |
| 266 | + | echo " fastfetch --config /etc/fastfetch/config.jsonc" | |
| 267 | + | echo " sudo ufw status verbose" | |
| 268 | + | echo " sudo fail2ban-client status sshd" | |
| 269 | + | echo | |
更新
更早