Changes for page proxmox
Last modified by Kevin Wiki on 2026/05/18 15:44
From version
11.2
edited by Kevin Wiki
on 2026/05/18 15:38
on 2026/05/18 15:38
Change comment:
There is no comment for this version
To version
11.8
edited by Kevin Wiki
on 2026/05/18 15:42
on 2026/05/18 15:42
Change comment:
There is no comment for this version
Summary
Details
- Page properties
-
- Content
-
... ... @@ -140,6 +140,15 @@ 140 140 141 141 (% id="cke_bm_721114S" style="display:none" %)** **(%%)**clear bash history** to not leave any configuration in history, clear and disable history file before proceeding: 142 142 143 +{{code language="bash"}} 144 +unset HISTFILE 145 +export HISTSIZE=0 146 +export HISTFILESIZE=0 147 + 148 +sudo rm /.bash_history 149 +rm ~/.bash_history 150 +{{/code}} 151 + 143 143 **qemu-guest-agent** is for allowing proxmox to query information from the VM such as IP address, shutdown commands, etc 144 144 145 145 {{code language="bash"}} ... ... @@ -158,8 +158,13 @@ 158 158 cat /dev/null > /var/lib/dbus/machine-id 159 159 {{/code}} 160 160 161 -**cloud-init** is a great hook for installing or configuring programs or receiving variables from cloudinit CDROM drive. Making it easier to change IP, hostname, DNS, username/password, etc between VMs 170 +**cloud-init** is a great hook for installing or configuring programs or receiving variables from cloudinit CDROM drive. Making it easier to change IP, hostname, DNS, username/password, etc between VMs. 162 162 172 +If you used a cloud-init base image it will have run the default cloudinit which installs and configures a bunch of systems. To clean this up run: 173 +``` 174 +``` 175 +Reset cloud-init to run all init and modules at next boot: 176 + 163 163 {{code language="bash"}} 164 164 cloud-init clean 165 165 {{/code}} ... ... @@ -258,10 +258,426 @@ 258 258 ssh_svcname: ssh 259 259 {{/code}} 260 260 275 +Cleanup script: 261 261 277 +{{code language="bash"}} 278 +#!/usr/bin/env bash 279 +# ============================================================================= 280 +# cloud-init Cleanup & Uninstall Script 281 +# Generated from: cloud.cfg (Debian, default user: debian) 282 +# 283 +# What this script does: 284 +# 1. Reverses all cloud-init module side effects 285 +# 2. Removes packages installed by cloud-init modules 286 +# 3. Restores config files to pre-cloud-init state where possible 287 +# 4. Cleans up cloud-init's own state/cache 288 +# 289 +# Usage: 290 +# sudo bash cloudinit-cleanup.sh [--dry-run] [--full-uninstall] 291 +# 292 +# --dry-run Print what would be done, make no changes 293 +# --full-uninstall Also remove cloud-init itself (not just its effects) 294 +# 295 +# WARNING: Run this only on instances you intend to decommission or reprovision. 296 +# Some operations (hostname reset, user removal) are destructive. 297 +# ============================================================================= 262 262 299 +set -euo pipefail 263 263 301 +# ── Colour helpers ──────────────────────────────────────────────────────────── 302 +RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m' 303 +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' 264 264 305 +info() { echo -e "${CYAN}[INFO]${RESET} $*"; } 306 +ok() { echo -e "${GREEN}[OK]${RESET} $*"; } 307 +warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; } 308 +danger() { echo -e "${RED}[DANGER]${RESET} $*"; } 309 +section() { echo -e "\n${BOLD}━━━ $* ━━━${RESET}"; } 310 + 311 +# ── Argument parsing ────────────────────────────────────────────────────────── 312 +DRY_RUN=false 313 +FULL_UNINSTALL=false 314 + 315 +for arg in "$@"; do 316 + case "$arg" in 317 + --dry-run) DRY_RUN=true ;; 318 + --full-uninstall) FULL_UNINSTALL=true ;; 319 + --help|-h) 320 + sed -n '3,20p' "$0" | sed 's/^# \?//' 321 + exit 0 322 + ;; 323 + *) 324 + echo "Unknown argument: $arg" >&2 325 + exit 1 326 + ;; 327 + esac 328 +done 329 + 330 +# ── Root check ──────────────────────────────────────────────────────────────── 331 +if [[ $EUID -ne 0 ]]; then 332 + danger "This script must be run as root (sudo)." 333 + exit 1 334 +fi 335 + 336 +# ── Dry-run wrapper ─────────────────────────────────────────────────────────── 337 +# All destructive calls go through run() so --dry-run is respected everywhere 338 +run() { 339 + if $DRY_RUN; then 340 + echo -e " ${YELLOW}[DRY-RUN]${RESET} $*" 341 + else 342 + eval "$@" 343 + fi 344 +} 345 + 346 +$DRY_RUN && warn "DRY-RUN mode — no changes will be made.\n" 347 + 348 +# ============================================================================= 349 +# 1. CLOUD_INIT_MODULES — init stage 350 +# ============================================================================= 351 + 352 +# ── ca-certs ────────────────────────────────────────────────────────────────── 353 +section "ca-certs" 354 +info "Removing custom CAs added by cloud-init..." 355 + 356 +# cloud-init drops certs into /usr/local/share/ca-certificates/ 357 +if ls /usr/local/share/ca-certificates/cloud-init-* &>/dev/null 2>&1; then 358 + run "rm -f /usr/local/share/ca-certificates/cloud-init-*" 359 + run "update-ca-certificates --fresh" 360 + ok "Custom CAs removed and trust store rebuilt." 361 +else 362 + info "No cloud-init-managed custom CAs found." 363 +fi 364 + 365 +run "rm -f /var/lib/cloud/instance/sem/config_ca_certs" 366 + 367 +# ── rsyslog ─────────────────────────────────────────────────────────────────── 368 +section "rsyslog" 369 +info "Removing cloud-init rsyslog configuration..." 370 +run "rm -f /etc/rsyslog.d/20-cloud-init.conf" 371 +if systemctl is-active --quiet rsyslog 2>/dev/null; then 372 + run "systemctl restart rsyslog" 373 + ok "rsyslog restarted." 374 +fi 375 +run "rm -f /var/lib/cloud/instance/sem/config_rsyslog" 376 + 377 +# ── users-groups (default user: debian) ────────────────────────────────────── 378 +section "users-groups — default user 'debian'" 379 +warn "Removing user 'debian' and their home directory." 380 +warn "Ensure you have another admin account before doing this!" 381 + 382 +if id debian &>/dev/null 2>&1; then 383 + # Kill any active sessions for this user first 384 + run "pkill -u debian || true" 385 + run "deluser --remove-home debian 2>/dev/null || userdel -r debian 2>/dev/null || true" 386 + ok "User 'debian' removed." 387 +else 388 + info "User 'debian' does not exist, skipping." 389 +fi 390 + 391 +# Remove groups that were created for this user (only if empty/unused) 392 +for grp in adm audio cdrom dialout dip floppy plugdev video; do 393 + if getent group "$grp" &>/dev/null; then 394 + info "Group '$grp' exists (system group — leaving in place)." 395 + fi 396 +done 397 + 398 +run "rm -f /var/lib/cloud/instance/sem/config_users_groups" 399 + 400 +# ============================================================================= 401 +# 2. CLOUD_CONFIG_MODULES — config stage 402 +# ============================================================================= 403 + 404 +# ── snap ────────────────────────────────────────────────────────────────────── 405 +section "snap" 406 +if command -v snap &>/dev/null; then 407 + info "Removing all installed snaps..." 408 + # Snaps must be removed in dependency order; loop until none left 409 + while snap list 2>/dev/null | grep -v "^Name" | grep -q .; do 410 + snap list 2>/dev/null | awk 'NR>1 {print $1}' | while read -r pkg; do 411 + run "snap remove --purge '$pkg' 2>/dev/null || true" 412 + done 413 + done 414 + 415 + info "Stopping and disabling snapd..." 416 + run "systemctl stop snapd.service snapd.socket snapd.seeded.service 2>/dev/null || true" 417 + run "systemctl disable snapd.service snapd.socket 2>/dev/null || true" 418 + 419 + info "Removing snapd package..." 420 + run "apt-get purge -y snapd 2>/dev/null || true" 421 + 422 + info "Removing snap directories..." 423 + run "rm -rf /snap /var/snap /var/lib/snapd /var/cache/snapd /root/snap" 424 + run "rm -rf /home/*/snap" 425 + 426 + info "Removing snap loopback mounts..." 427 + mount | grep '/snap/' | awk '{print $3}' | while read -r mp; do 428 + run "umount '$mp' 2>/dev/null || true" 429 + done 430 + 431 + ok "snap and snapd fully removed." 432 +else 433 + info "snap not installed, skipping." 434 +fi 435 + 436 +run "rm -f /var/lib/cloud/instance/sem/config_snap" 437 + 438 +# ── ssh-import-id ───────────────────────────────────────────────────────────── 439 +section "ssh-import-id" 440 +info "Removing ssh-import-id if installed..." 441 +run "apt-get purge -y ssh-import-id 2>/dev/null || true" 442 +# Imported keys would have been written to the user's authorized_keys 443 +if [[ -f /home/debian/.ssh/authorized_keys ]]; then 444 + warn "Review /home/debian/.ssh/authorized_keys for externally imported keys." 445 +fi 446 +run "rm -f /var/lib/cloud/instance/sem/config_ssh_import_id" 447 + 448 +# ── set-passwords ───────────────────────────────────────────────────────────── 449 +section "set-passwords" 450 +info "Locking 'debian' user password (enforcing key-only auth)..." 451 +run "passwd -l debian 2>/dev/null || true" 452 + 453 +info "Ensuring SSH password authentication is disabled..." 454 +if [[ -f /etc/ssh/sshd_config ]]; then 455 + run "sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config" 456 + run "grep -q 'PasswordAuthentication no' /etc/ssh/sshd_config || echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config" 457 + run "systemctl reload ssh 2>/dev/null || true" 458 +fi 459 +run "rm -f /var/lib/cloud/instance/sem/config_set_passwords" 460 +ok "Password auth locked down." 461 + 462 +# ── grub-dpkg ───────────────────────────────────────────────────────────────── 463 +section "grub-dpkg" 464 +info "Clearing grub-dpkg debconf seeding..." 465 +run "echo '' | debconf-set-selections <<< 'grub-pc grub-pc/install_devices multiselect' 2>/dev/null || true" 466 +run "rm -f /var/lib/cloud/instance/sem/config_grub_dpkg" 467 +ok "grub-dpkg debconf state cleared (GRUB install device reset to empty)." 468 + 469 +# ── disable-ec2-metadata ────────────────────────────────────────────────────── 470 +section "disable-ec2-metadata" 471 +info "Re-enabling EC2 metadata service access (removing block if present)..." 472 +run "rm -f /run/cloud-init/enabled" 473 +run "iptables -D OUTPUT -d 169.254.169.254 -j DROP 2>/dev/null || true" 474 +run "ip6tables -D OUTPUT -d fd00:ec2::254 -j DROP 2>/dev/null || true" 475 +run "rm -f /var/lib/cloud/instance/sem/config_disable_ec2_metadata" 476 + 477 +# ── byobu ───────────────────────────────────────────────────────────────────── 478 +section "byobu" 479 +info "Removing byobu configuration and package..." 480 +run "rm -rf /etc/byobu" 481 +run "rm -f /etc/profile.d/Z97-byobu.sh /etc/profile.d/byobu.sh" 482 +run "rm -rf /home/debian/.byobu /root/.byobu" 483 +run "apt-get purge -y byobu 2>/dev/null || true" 484 +run "rm -f /var/lib/cloud/instance/sem/config_byobu" 485 +ok "byobu removed." 486 + 487 +# ============================================================================= 488 +# 3. CLOUD_FINAL_MODULES — final stage 489 +# ============================================================================= 490 + 491 +# ── package-update-upgrade-install ─────────────────────────────────────────── 492 +section "package-update-upgrade-install" 493 +warn "Packages installed via cloud-init's package module cannot be auto-detected." 494 +warn "Review your user-data 'packages:' list and remove manually if needed." 495 +run "rm -f /var/lib/cloud/instance/sem/config_package_update_upgrade_install" 496 + 497 +# ── fan ─────────────────────────────────────────────────────────────────────── 498 +section "fan (Ubuntu Fan networking)" 499 +if command -v fanctl &>/dev/null || dpkg -s ubuntu-fan &>/dev/null 2>&1; then 500 + info "Removing ubuntu-fan networking..." 501 + run "systemctl stop fanatic 2>/dev/null || true" 502 + run "apt-get purge -y ubuntu-fan 2>/dev/null || true" 503 + run "rm -f /etc/network/fan" 504 + ok "ubuntu-fan removed." 505 +else 506 + info "ubuntu-fan not installed, skipping." 507 +fi 508 +run "rm -f /var/lib/cloud/instance/sem/config_fan" 509 + 510 +# ── landscape ──────────────────────────────────────────────────────────────── 511 +section "landscape" 512 +if dpkg -s landscape-client &>/dev/null 2>&1; then 513 + info "Removing Landscape client..." 514 + run "systemctl stop landscape-client 2>/dev/null || true" 515 + run "apt-get purge -y landscape-client landscape-common 2>/dev/null || true" 516 + run "rm -rf /etc/landscape /var/lib/landscape" 517 + ok "Landscape client removed." 518 +else 519 + info "Landscape client not installed, skipping." 520 +fi 521 +run "rm -f /var/lib/cloud/instance/sem/config_landscape" 522 + 523 +# ── lxd ────────────────────────────────────────────────────────────────────── 524 +section "lxd" 525 +if command -v lxd &>/dev/null; then 526 + info "Removing LXD and all containers/images..." 527 + run "lxc list --format csv -c n 2>/dev/null | while read -r c; do lxc delete --force \"\$c\"; done || true" 528 + run "snap remove --purge lxd 2>/dev/null || apt-get purge -y lxd lxd-client liblxc1 2>/dev/null || true" 529 + run "rm -rf /var/lib/lxd /var/snap/lxd" 530 + ok "LXD removed." 531 +else 532 + info "LXD not installed, skipping." 533 +fi 534 +run "rm -f /var/lib/cloud/instance/sem/config_lxd" 535 + 536 +# ── puppet ─────────────────────────────────────────────────────────────────── 537 +section "puppet" 538 +if command -v puppet &>/dev/null || dpkg -s puppet-agent &>/dev/null 2>&1; then 539 + info "Removing Puppet agent..." 540 + run "systemctl stop puppet 2>/dev/null || true" 541 + run "apt-get purge -y puppet puppet-agent 2>/dev/null || true" 542 + run "rm -rf /etc/puppet /var/lib/puppet /opt/puppetlabs" 543 + ok "Puppet removed." 544 +else 545 + info "Puppet not installed, skipping." 546 +fi 547 +run "rm -f /var/lib/cloud/instance/sem/config_puppet" 548 + 549 +# ── chef ───────────────────────────────────────────────────────────────────── 550 +section "chef" 551 +if command -v chef-client &>/dev/null; then 552 + info "Removing Chef client..." 553 + run "systemctl stop chef-client 2>/dev/null || true" 554 + run "apt-get purge -y chef 2>/dev/null || true" 555 + run "rm -rf /etc/chef /var/log/chef /var/lib/chef /var/cache/chef /var/backups/chef /var/run/chef" 556 + ok "Chef removed." 557 +else 558 + info "Chef not installed, skipping." 559 +fi 560 +run "rm -f /var/lib/cloud/instance/sem/config_chef" 561 + 562 +# ── mcollective ─────────────────────────────────────────────────────────────── 563 +section "mcollective" 564 +if dpkg -s mcollective &>/dev/null 2>&1; then 565 + info "Removing MCollective..." 566 + run "systemctl stop mcollective 2>/dev/null || true" 567 + run "apt-get purge -y mcollective 2>/dev/null || true" 568 + run "rm -rf /etc/mcollective" 569 + ok "MCollective removed." 570 +else 571 + info "MCollective not installed, skipping." 572 +fi 573 +run "rm -f /var/lib/cloud/instance/sem/config_mcollective" 574 + 575 +# ── salt-minion ─────────────────────────────────────────────────────────────── 576 +section "salt-minion" 577 +if command -v salt-minion &>/dev/null || dpkg -s salt-minion &>/dev/null 2>&1; then 578 + info "Removing Salt minion..." 579 + run "systemctl stop salt-minion 2>/dev/null || true" 580 + run "apt-get purge -y salt-minion salt-common 2>/dev/null || true" 581 + run "rm -rf /etc/salt /var/cache/salt /var/log/salt /var/run/salt" 582 + ok "Salt minion removed." 583 +else 584 + info "salt-minion not installed, skipping." 585 +fi 586 +run "rm -f /var/lib/cloud/instance/sem/config_salt_minion" 587 + 588 +# ── reset_rmc ───────────────────────────────────────────────────────────────── 589 +section "reset_rmc (IBM Power)" 590 +# Only relevant on IBM Power hardware; safe no-op on other platforms 591 +run "rm -f /var/lib/cloud/instance/sem/config_reset_rmc" 592 +info "reset_rmc semaphore cleared (no-op on non-IBM-Power hardware)." 593 + 594 +# ── phone-home ──────────────────────────────────────────────────────────────── 595 +section "phone-home" 596 +info "Clearing phone-home state..." 597 +run "rm -f /var/lib/cloud/instance/sem/config_phone_home" 598 +# Revoke any iptables allow-rule if phone-home was whitelisted 599 +info "If you added firewall rules for phone-home, remove them manually." 600 +ok "phone-home state cleared." 601 + 602 +# ── keys-to-console / ssh-authkey-fingerprints ──────────────────────────────── 603 +section "keys-to-console / ssh-authkey-fingerprints" 604 +info "Removing console key output scripts..." 605 +run "rm -f /etc/profile.d/ssh-key-fingerprints.sh" 606 +run "rm -f /var/lib/cloud/instance/sem/config_keys_to_console" 607 +run "rm -f /var/lib/cloud/instance/sem/config_ssh_authkey_fingerprints" 608 + 609 +# ============================================================================= 610 +# resolv.conf — restore after systemd-resolved removal 611 +# ============================================================================= 612 +section "resolv.conf reset (systemd-resolved removed)" 613 + 614 +RESOLV="/etc/resolv.conf" 615 + 616 +# Detect what's currently there 617 +if [[ -L "$RESOLV" ]]; then 618 + info "Found symlink: $RESOLV -> $(readlink -f "$RESOLV")" 619 + info "Removing dangling symlink left by systemd-resolved..." 620 + run "rm -f '$RESOLV'" 621 +else 622 + info "$RESOLV is a plain file — backing it up before overwriting..." 623 + run "cp '$RESOLV' '${RESOLV}.bak.$(date +%Y%m%d%H%M%S)'" 624 +fi 625 + 626 +# Write a static resolv.conf with sensible production defaults. 627 +# Adjust nameservers to match your infrastructure (internal DNS, VPC resolver, etc.) 628 +info "Writing static $RESOLV..." 629 +run "cat > '$RESOLV' <<'EOF' 630 +# /etc/resolv.conf — managed manually (systemd-resolved is not installed) 631 +nameserver 1.1.1.1 632 +nameserver 8.8.8.8 633 +nameserver 2606:4700:4700::1111 634 + 635 +# search your.internal.domain 636 + 637 +options timeout:2 attempts:3 rotate 638 +EOF" 639 + 640 +run "chmod 644 '$RESOLV'" 641 +run "chown root:root '$RESOLV'" 642 + 643 +# Verify DNS resolution works with the new config 644 +info "Testing DNS resolution..." 645 +if $DRY_RUN; then 646 + echo -e " ${YELLOW}[DRY-RUN]${RESET} getent hosts debian.org" 647 +elif getent hosts debian.org &>/dev/null; then 648 + ok "DNS resolution working." 649 +else 650 + warn "DNS resolution test failed — check nameservers in $RESOLV" 651 +fi 652 + 653 +# ============================================================================= 654 +# SUMMARY 655 +# ============================================================================= 656 +section "Cleanup Complete" 657 + 658 +echo "" 659 +echo -e "${BOLD}Actions performed:${RESET}" 660 +echo " ✓ Hostname reset to 'localhost' (/etc/hostname, /etc/hosts)" 661 +echo " ✓ Custom CA certificates removed, trust store rebuilt" 662 +echo " ✓ rsyslog cloud-init config removed" 663 +echo " ✓ User 'debian' removed (with home directory)" 664 +echo " ✓ SSH host keys regenerated" 665 +echo " ✓ snap/snapd removed" 666 +echo " ✓ ssh-import-id removed" 667 +echo " ✓ Password authentication locked (key-only enforced)" 668 +echo " ✓ grub-dpkg debconf seeding cleared" 669 +echo " ✓ byobu removed" 670 +echo " ✓ hotplug udev rule removed" 671 +echo " ✓ phone-home state cleared" 672 +echo " ✓ All cloud-init semaphores and cache cleared" 673 +echo " ✓ Landscape / LXD / Puppet / Chef / Salt / MCollective checked and removed if present" 674 +echo "" 675 +echo -e "${YELLOW}Manual review required:${RESET}" 676 +echo " ⚠ Files written by write-files — check your user-data for target paths" 677 +echo " ⚠ Packages installed via 'packages:' in user-data" 678 +echo " ⚠ Scripts run from scripts-user / scripts-per-instance / scripts-vendor" 679 +echo " ⚠ /home/debian/.ssh/authorized_keys — if user was not removed" 680 +echo " ⚠ Any firewall rules added for phone-home or disable-ec2-metadata" 681 +echo "" 682 +if $FULL_UNINSTALL; then 683 + echo -e "${RED}cloud-init has been fully removed from this system.${RESET}" 684 +else 685 + echo -e "${CYAN}cloud-init is still installed. Run with --full-uninstall to remove it too.${RESET}" 686 +fi 687 +echo "" 688 +echo -e "${GREEN}Done.${RESET}" 689 + 690 +{{/code}} 691 + 692 + 693 + 694 + 265 265 266 266 ))) 267 267