Wiki source code of proxmox

Version 11.7 by Kevin Wiki on 2026/05/18 15:42

Show last authors
1 (% class="row" %)
2 (((
3 (% class="col-xs-12 col-sm-8" %)
4 (((
5 {{children/}}
6
7
8 = Getting Started with Proxmox VE LXC and VM Templates =
9
10 Proxmox VE (PVE) allows users to create and manage both LXC containers and KVM virtual machines (VMs). This guide walks you through the process of downloading, importing, and creating templates for both.
11
12 == LXC Templates ==
13
14 LXC containers are lightweight and ideal for running Linux services with minimal overhead.
15
16 === List Available Templates ===
17
18 To view the available LXC templates:
19
20 {{code language="bash"}}
21 pveam list
22 {{/code}}
23
24 === Download Templates ===
25
26 Use the pveam download command to import templates to the local storage:
27
28 {{code language="bash"}}
29 pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.gz
30 pveam download local ubuntu-24.04-standard_24.04-1_amd64.tar.zst
31 pveam download local debian-12-standard_11.7-1_amd64.tar.zst
32 {{/code}}
33
34 Once downloaded, these templates can be used to create new LXC containers from the Proxmox web interface or via CLI.
35
36 == VM Template from Ubuntu Cloud Image ==
37
38 KVM VMs are ideal when you need full virtualization, for instance, to run Windows or more complex Linux systems.
39
40 === Download Ubuntu Cloud Image ===
41
42 Download the official Ubuntu 24.04 cloud [[image:]]
43
44 {{code language="bash"}}
45 wget http://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img
46 {{/code}}
47
48 === Create the Virtual Machine ===
49
50 Create a new VM with ID 910 (you can pick any unused ID):
51
52 {{code language="bash"}}
53 qm create 910 -name template-ubuntu-jammy -memory 2048 -net0 virtio,bridge=vmbr0 -cores 2 -sockets 1
54 {{/code}}
55
56 === Import and Attach the Disk ===
57
58 Choose the correct storage (replace nvme if you use a different storage name):
59
60 {{code language="bash"}}
61 qm importdisk 910 ubuntu-24.04-server-cloudimg-amd64.img nvme
62 qm set 910 -scsihw virtio-scsi-pci -virtio0 nvme:vm-910-disk-0
63 {{/code}}
64
65 === Configure the VM ===
66
67 {{code language="bash"}}
68 qm set 910 -serial0 socket
69 qm set 910 -boot c -bootdisk virtio0
70 qm set 910 -agent 1
71 qm set 910 -hotplug disk,network,usb
72 qm set 910 -vcpus 1
73 qm set 910 -vga qxl
74 qm set 910 -ide2 nvme:cloudinit
75 qm resize 910 virtio0 +8G
76 {{/code}}
77
78
79 If your disk is using SCSI instead of virtio, resize like this:
80
81 {{code language="bash"}}
82 qm resize 910 scsi0 +8G
83 {{/code}}
84
85 === Convert the VM into a Template ===
86
87 {{code language="bash"}}
88 qm template 910
89 {{/code}}
90
91 Now you can use this template to clone new VMs instantly.
92
93 == Bash Script to Automate Setup ==
94
95 Install the above using bash script below
96
97 === setup_proxmox_templates.sh ===
98
99 {{code language="bash"}}
100 #!/bin/bash
101
102 # Exit on errors
103 set -e
104
105 echo "Downloading LXC templates..."
106 pveam download nvme ubuntu-22.04-standard_22.04-1_amd64.tar.zst
107 pveam download nvme ubuntu-24.04-standard_24.04-2_amd64.tar.zst
108 pveam download nvme alpine-3.21-default_20241217_amd64.tar.xz
109 pveam download nvme debian-12-standard_12.7-1_amd64.tar.zst
110
111 echo "Downloading Ubuntu cloud image..."
112 wget -N http://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img
113
114 echo "Creating VM Template..."
115 qm create 910 -name template-ubuntu-jammy -memory 2048 -net0 virtio,bridge=vmbr0 -cores 2 -sockets 1 && 1
116
117 # qm importdisk 910 ubuntu-24.04-server-cloudimg-amd64.img nvme
118 # qm set 910 -scsihw virtio-scsi-pci -scsi0-virtio0 nvme:910/vm-910-disk-0
119 qm set 910 -scsihw virtio-scsi-pci -scsi0 nvme:0,import-from=/mnt/nvmestorage/template/iso/ubuntu-24.04-server-cloudimg-amd64.img
120
121 qm set 910 -serial0 socket
122 qm set 910 -boot c -bootdisk virtio0
123 qm set 910 -agent 1
124 qm set 910 -hotplug disk,network,usb
125 qm set 910 -vcpus 1
126 qm set 910 -vga qxl
127 qm set 910 -ide2 nvme:cloudinit
128 # qm resize 910 scsi0 +8G
129
130 read -p "Confirm converting to template by pressing Enter"
131 qm template 910
132
133 echo "Templates setup complete."
134 {{/code}}
135
136
137 = VM runtime setup =
138
139 After creating the VM and before making it into a template there are some programs and settings we want to ensure exists always.
140
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
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
152 **qemu-guest-agent** is for allowing proxmox to query information from the VM such as IP address, shutdown commands, etc
153
154 {{code language="bash"}}
155 sudo apt update
156 sudo apt upgrade -y
157 sudo apt install qemu-guest-agent -y
158
159 sudo systemctl enable qemu-guest-agent.service
160 sudo systemctl start qemu-guest-agent.service
161 {{/code}}
162
163 **reset machine-id** to not have overlapping ids from same template
164
165 {{code language="bash"}}
166 cat /dev/null > /etc/machine-id
167 cat /dev/null > /var/lib/dbus/machine-id
168 {{/code}}
169
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.
171
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
177 {{code language="bash"}}
178 cloud-init clean
179 {{/code}}
180
181 This is a debian example of what we are looking for:
182
183 {{code language="yaml"}}
184 # The top level settings are used as module
185 # and system configuration.
186 # A set of users which may be applied and/or used by various modules
187 # when a 'default' entry is found it will reference the 'default_user'
188 # from the distro configuration specified below
189
190 # If this is set, 'root' will not be able to ssh in and they
191 # will get a message to login instead as the default $user
192 disable_root: true
193
194 # This will cause the set+update hostname module to not operate (if true)
195 preserve_hostname: false
196
197 apt:
198 # This prevents cloud-init from rewriting apt's sources.list file,
199 # which has been a source of surprise.
200 preserve_sources_list: true
201
202 # manually managed resolv
203 manage_resolv_conf: false
204
205 package_update: true
206 packages:
207 - qemu-guest-agent
208
209 # The modules that run in the 'init' stage
210 cloud_init_modules:
211 - seed_random
212 - bootcmd
213 - write-files
214 - growpart
215 - resizefs
216 - disk_setup
217 - mounts
218 - set_hostname
219 - update_hostname
220 - update_etc_hosts
221 - ca-certs
222 - rsyslog
223 - users-groups
224 - ssh
225
226 # The modules that run in the 'config' stage
227 cloud_config_modules:
228 - keyboard
229 - locale
230 - set-passwords
231 - grub-dpkg
232 - apt-pipelining
233 - apt-configure
234 - ntp
235 - timezone
236 - disable-ec2-metadata
237 - runcmd
238
239 # The modules that run in the 'final' stage
240 cloud_final_modules:
241 - package-update-upgrade-install
242 - write-files-deferred
243 - scripts-vendor
244 - scripts-per-once
245 - scripts-per-boot
246 - scripts-per-instance
247 - scripts-user
248 - ssh-authkey-fingerprints
249 # - keys-to-console
250 - install-hotplug
251 # - phone-home
252 - final-message
253 - power-state-change
254
255 runcmd:
256 - systemctl enable qemu-guest-agent.service
257
258 # System and/or distro specific settings
259 # (not accessible to handlers/transforms)
260 system_info:
261 # This will affect which distro class gets used
262 distro: debian
263 # Other config here will be given to the distro class and/or path classes
264 paths:
265 cloud_dir: /var/lib/cloud/
266 templates_dir: /etc/cloud/templates/
267 package_mirrors:
268 - arches: [default]
269 failsafe:
270 primary: https://deb.debian.org/debian
271 security: https://deb.debian.org/debian-security
272 ssh_svcname: ssh
273 {{/code}}
274
275 Cleanup script:
276
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 # =============================================================================
298
299 set -euo pipefail
300
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'
304
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
695
696 )))
697
698 (% class="col-xs-12 col-sm-4" %)
699 (((
700 (% class="box" %)
701 (((
702 |=Site|[[Proxmox>>https://proxmox.com]]
703 |=Dashboard|
704 |=Servers|1200 €
705 |=Image|[[Credits>>https://commons.wikimedia.org/wiki/File:FalabellaFestivo.jpg]]
706 )))
707
708 (% class="box" %)
709 (((
710 **Contents**
711
712 {{toc/}}
713 )))
714 )))
715 )))