Rocky Linux 9 Fresh Install: Every Anaconda Decision That Matters
The Anaconda installer presents everything at once — a summary screen full of spokes, each hiding a decision. Some have safe defaults. Several don't. The ones that don't are the ones that break quietly: a root partition that fills in three weeks, SELinux that gets disabled on the first confusing denial, an IPv6 address appearing on every interface without an IPv6 router in sight, root SSH that's either locked when you need it or open when it shouldn't be. None of these are documented together in one place. This post covers the installation from first boot of the ISO to a clean, SSH-accessible Rocky Linux 9 machine — partition layout, package selection, SELinux posture, network configuration, and access model all set deliberately rather than accepted from defaults.
Boot and Localization
- Boot from the Rocky Linux 9 ISO. At the GRUB menu, select Install Rocky Linux 9.
- At the Welcome screen, select your language and locale. For most setups: English (United States). Click Continue.
- On the Installation Summary screen, click Keyboard. Verify English (US) is listed and add your layout if different. Click Done.
- Click Time & Date. Select your region and city. Enable the NTP toggle — it will sync time automatically if the machine has network access during install. Click Done.
Storage — The Layout That Lives Forever
Anaconda's automatic LVM layout works fine on large disks. On disks under 100GB it routinely produces undersized root partitions because the algorithm doesn't know what you're running and distributes space conservatively, favouring /home — which on a server is irrelevant.
- Click Installation Destination. Select your target disk. Under Storage Configuration, select Custom. Click Done.
- On the Manual Partitioning screen, select LVM from the partition scheme dropdown. LVM is correct for most server uses — it allows resize and snapshot operations later.
- Click the + button to create partitions in this order:
/boot: Standard Partition, 1 GiB, xfs. This sits outside the LVM volume group and must be a standard partition — not a logical volume.swap: LVM Logical Volume. Size: match your RAM up to an 8GiB ceiling. 8GiB RAM → 8GiB swap. 32GiB RAM → 8GiB swap is sufficient./: LVM Logical Volume, xfs. Assign the remaining space explicitly — do not use "Fill to maximum allowed size" if you may want additional volumes later. 50GiB minimum for a machine that will run containers or accumulate logs; 80–100GiB if the disk has it.
- Click Done. Anaconda will warn about a missing
/homepartition — accept the warning. On a server,/homegets no dedicated space. Click Accept Changes.
If Anaconda flags that your /boot partition can't be on LVM, that's expected — it must be a standard partition. The warning is informational.
Package Selection — Start Minimal
- Click Software Selection.
- Select Minimal Install. Do not select a Server environment, any add-on groups, or anything with GUI. Minimal Install gives you: kernel, dnf, systemd, NetworkManager, firewalld, openssh-server, and basic utilities. Nothing else.
- Click Done.
The temptation to select Server "just in case you need something" is worth resisting. Installing what you actually need after first boot is how you know what's on your machine. Minimal Install is not under-equipped — it's correctly scoped for a server baseline.
Network — Hostname, IP Address, and IPv6
- Click Network & Host Name.
- At the bottom of the screen, replace the default hostname with something specific to this machine —
lab-rocky01,srv-dns-01, whatever fits your naming scheme. Click Apply. The hostname set here becomes the system hostname at first boot. - Select your network interface from the left panel. Toggle it On if it isn't already.
- Click Configure to open the connection editor.
- IPv4 Settings tab: If this machine gets a static IP, change Method from Automatic (DHCP) to Manual. Click Add and enter your IP address, netmask, and gateway. Add your DNS server in the DNS Servers field. If DHCP is correct, leave Method as Automatic.
- IPv6 Settings tab: Set Method to Disabled. This is the correct path in Rocky 9 — it creates the NetworkManager connection profile with IPv6 disabled from the start. Do not skip this if your environment has no IPv6 router. An enabled IPv6 stack without a router produces link-local addresses on every interface and occasional service binding surprises. Click Save.
- Click Done.
Root Account and Access Model
The Navigate post covers whether to enable root SSH — this section covers the implementation. Both pieces must be configured: the root password and the SSH permission. Either one without the other produces a broken state.
- Click Root Password.
- Set a strong root password. If this machine is internal and non-internet-exposed and you want direct root SSH access, check Allow root SSH login with password. If this machine is or may become internet-exposed, leave this unchecked. Click Done.
- Click User Creation. Create a named user — this is your standard login account. Check Make this user an administrator to add the account to the wheel group for sudo access. Set a password. Click Done.
The named admin user is not optional even if root SSH is enabled. It's the access model that translates to professional environments, and building the habit here costs nothing.
Review and Start the Install
- On the Installation Summary screen, verify before proceeding:
- Installation Destination shows your disk with custom partitioning selected
- Software Selection shows Minimal Install
- Network & Host Name shows your configured hostname and interface
- Root Password shows a green checkmark
- Click Begin Installation. Installation takes 3–10 minutes depending on disk speed.
- When complete, click Reboot System. Remove the ISO from the boot device if your VM or hardware will otherwise boot from it again.
First-Boot Verification
Log in at the console or SSH in with the named user created during install. Run these checks before installing anything else.
Check firewall state:
systemctl status firewalld
firewall-cmd --list-allDefault zone is public. SSH is open by default in the public zone. Verify nothing else is listed under services unless you added it. Note the active zone — you'll reference this when opening ports for services you add later.
Run the first update:
dnf update -yThere will be packages to update on a fresh install. Let this complete before installing anything else — post-install state diverges from the installed media the moment updates are applied, and it's cleaner to get to current before adding anything.
Verify SSH is running:
systemctl status sshdExpected: active (running). sshd is enabled by default in Rocky 9 Minimal Install. If it's not running: systemctl enable --now sshd.
Verify IPv6 is disabled:
ip -6 addr showExpected: loopback ::1 only. If global IPv6 addresses appear on your network interface, the IPv6 disable in the installer didn't apply cleanly — see the post-install fix in the next section.
Check network state:
ip addr show
ip routeVerify your IP address appears on the expected interface — either the static address you configured or a DHCP assignment. Verify a default route is present pointing to your gateway. If the interface shows no address, check the connection profile: nmcli connection show and nmcli device status.
Verify SELinux is enforcing:
getenforceExpected output: Enforcing. If it returns Permissive or Disabled, check /etc/selinux/config — the SELINUX= line should read enforcing. If it doesn't, edit it, then reboot. Do not proceed with a non-enforcing SELinux baseline if the intent was to run enforcing.
Post-Install: Fixing IPv6 If It Wasn't Disabled in the Installer
If global IPv6 addresses are showing on your interface, disable through NetworkManager directly. The sysctl-only approach still works but bypasses NetworkManager's connection state — use the NetworkManager path to avoid inconsistent behavior when connection profiles are reloaded or interfaces cycled.
cat > /etc/NetworkManager/conf.d/disable-ipv6.conf << 'EOF'
[connection]
ipv6.method=disabled
EOF
nmcli connection reloadThen bring the affected connection down and back up — replacing ens3 with your actual interface name from ip addr show:
nmcli connection down ens3 && nmcli connection up ens3If the interface name doesn't match a connection profile name, use nmcli connection show to find the profile name and use that instead. If bouncing the connection doesn't clear the IPv6 addresses, reboot — the config file takes effect fully at next NetworkManager start.
Post-Install: Enabling Root SSH After the Fact
If you didn't check root SSH during install but want to enable it now, both the sshd_config and the root password must be set. Either one without the other fails silently — SSH accepts the connection attempt and immediately drops it.
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
grep PermitRootLogin /etc/ssh/sshd_config
systemctl reload sshdIf the root password was never set or is locked, set it before testing SSH:
passwd rootCommands Reference
# First-boot verification
getenforce
ip addr show
ip route
ip -6 addr show
systemctl status sshd
systemctl enable --now sshd
dnf update -y
systemctl status firewalld
firewall-cmd --list-all
# Post-install: disable IPv6 via NetworkManager
cat > /etc/NetworkManager/conf.d/disable-ipv6.conf << 'EOF'
[connection]
ipv6.method=disabled
EOF
nmcli connection reload
nmcli connection down ens3 && nmcli connection up ens3
# Post-install: enable root SSH
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
grep PermitRootLogin /etc/ssh/sshd_config
systemctl reload sshd
# Post-install: set root password if locked
passwd root