설치 실패나 SSH 단절 때 사용할 하이퍼바이저·BMC·시리얼 콘솔 등 대체 접속 경로
RHEL-COMPATIBLE SERVER
Rocky Linux 9 서버 설치와 초기 구성
공식 Rocky Linux 9 ISO의 서명과 체크섬을 검증하고, 설치 대상 디스크를 이중 확인한 뒤 Minimal 서버 설치부터 첫 업데이트·SELinux·firewalld·SSH 검증까지 안전하게 진행합니다.BEFORE YOU START
시작 전에 준비하세요
기존 데이터의 외부 전체 백업과 실제 복원 테스트 결과 또는 신규 VM 스냅샷·복제본
설치 대상 디스크의 모델·시리얼·용량과 보존할 디스크 목록
공식 ISO·CHECKSUM·CHECKSUM.asc·Rocky Linux 9 릴리스 키를 받을 신뢰 가능한 별도 PC
고정 주소를 쓴다면 IP·게이트웨이·DNS·VLAN·호스트명에 대한 승인된 네트워크 정보
첫 패치와 SSH 강화가 끝날 때까지 사설 관리망 또는 상위 방화벽·보안그룹에서 관리자 IPv4 CIDR만 인바운드로 허용하는 경로
권장 대상 Ubuntu와 다른 RHEL 호환 서버 운영 환경이 필요하고, 새 VM이나 전용 디스크에 Rocky Linux 9를 처음 설치하려는 개발자·운영자
FOLLOW THE RECIPE
8단계 구성·점검 레시피
설치 범위와 복구 경로 확정
이 레시피는 Rocky Linux 8에서 9로 올리는 명령이 아니라 새 VM 또는 전용 베어메탈 디스크에 Rocky Linux 9를 새로 설치하는 절차입니다. x86_64는 x86-64-v2 이상, aarch64는 ARMv8.0-A 이상이 최소 기준입니다. 공식 Releases에서 설치 당일 지원 중인 최신 9.x와 알려진 문제를 확인하고, 설치 실패 때 사용할 콘솔과 백업 복구 시간을 먼저 확정합니다.
uname -m기존 OS가 있는 장비에서만 실행합니다. ISO 아키텍처와 일치해야 하며 x86_64와 aarch64를 혼용하지 않습니다.if [ -d /sys/firmware/efi ]; then printf '%s\n' 'UEFI'; else printf '%s\n' 'BIOS 또는 확인 필요'; fiif command -v systemd-detect-virt >/dev/null 2>&1; then systemd-detect-virt || printf '%s\n' 'none 또는 감지되지 않음'; else printf '%s\n' 'systemd-detect-virt 없음'; finone은 베어메탈일 수 있습니다. 결과가 불명확하면 자산 관리 정보와 하이퍼바이저 콘솔에서 확인합니다.LC_ALL=C lscpu | grep -E '^(Architecture|Model name|CPU\(s\)|Virtualization):'
free -hif [ "$(uname -m)" = "x86_64" ] && [ -x /lib64/ld-linux-x86-64.so.2 ]; then /lib64/ld-linux-x86-64.so.2 --help 2>/dev/null | grep -E 'x86-64-v2.*supported' || printf '%s\n' 'x86-64-v2 지원을 확인하지 못함'; else printf '%s\n' 'x86_64가 아니거나 검사 가능한 glibc 로더가 없음'; fix86-64-v2 (supported)가 보여야 하는 보조 검사입니다. 출력이 없다고 즉시 미지원으로 단정하지 말고 CPU 제조사 명세를 확인합니다. VM은 하이퍼바이저가 게스트에 노출하는 CPU 모델도 x86-64-v2를 충족해야 합니다. aarch64는 하드웨어·VM 명세에서 ARMv8.0-A 이상을 확인합니다.- Rocky 공식 Releases에서 현재 지원 중인 최신 9.x와 알려진 문제를 확인했습니다.
- x86_64는 x86-64-v2 이상, aarch64는 ARMv8.0-A 이상이며 VM의 게스트 CPU 모델도 같은 기준을 충족합니다.
- 신규 설치 대상이며 Rocky Linux 8→9 인플레이스 업그레이드가 아님을 확인했습니다.
- 설치 중 네트워크가 끊겨도 접근할 콘솔과 작업 시간을 확보했습니다.
- 베어메탈은 전체 이미지 복원, VM은 스냅샷·복제본 복원 경로를 실제로 확인했습니다.
- 공인망에 바로 노출하지 않고 사설 관리망 또는 상위 방화벽·보안그룹에서 관리자 IPv4 CIDR만 인바운드로 허용했습니다.
x86_64라는 아키텍처 이름만으로 x86-64-v2 호환을 보장할 수 없습니다. CPU 기준을 확인하지 못했거나 기존 데이터 디스크·듀얼 부트·펌웨어 RAID·SAN·multipath가 있거나 콘솔과 복원 경로가 없으면 이 일반 레시피를 중단하고 하드웨어·스토리지별 설치 계획을 별도로 작성합니다.
디스크를 쓰기 전에 보존 대상과 설치 대상을 모델·시리얼·용량으로 식별하고 공식 설치 파일을 검증합니다.
디스크 인벤토리와 공식 ISO 검증
기존 시스템에서는 모든 디스크를 읽기 전용으로 기록합니다. 공식 Rocky 이미지 문서에서 boot·minimal·dvd 중 용도에 맞는 ISO를 고르고, 같은 공식 디렉터리의 CHECKSUM과 CHECKSUM.asc, 별도 공식 키 페이지의 Rocky Linux 9 키 지문으로 서명과 SHA-256을 차례로 검증합니다.
lsblk -e7 -o NAME,SIZE,MODEL,SERIAL,TYPE,FSTYPE,MOUNTPOINTS출력의 모델·시리얼·용량을 자산 정보와 대조합니다. NAME만으로 설치 대상을 정하지 않습니다.findmnt -no SOURCE,TARGET,FSTYPE /
ip -brief address
ip route주소와 경로에는 내부망 정보가 포함될 수 있으므로 외부에 공유하기 전에 가립니다.ls -lh Rocky-9-*.iso CHECKSUM CHECKSUM.asc RPM-GPG-KEY-Rocky-9공식 Rocky 다운로드·키 페이지에서 받은 네 파일을 같은 작업 폴더에 둡니다. ISO는 CHECKSUM에 적힌 버전 포함 파일명 그대로 저장하고, 이름이 다르면 공식 디렉터리에서 다시 확인합니다.gpg --quiet --show-keys --with-fingerprint ./RPM-GPG-KEY-Rocky-9출력이 공식 Rocky 키 페이지의 21CB 256A E16F C54C 6E65 2949 702D 426D 350D 275D와 한 글자라도 다르면 중단합니다.mkdir -p -m 700 ./rocky-gpg-verify
gpg --homedir ./rocky-gpg-verify --import ./RPM-GPG-KEY-Rocky-9
gpg --homedir ./rocky-gpg-verify --verify ./CHECKSUM.asc ./CHECKSUM키 지문을 공식 페이지와 직접 대조한 뒤 실행합니다. Good signature만 보고 지문 확인을 생략하지 않습니다.sha256sum -c CHECKSUM --ignore-missing선택한 ISO가 OK여야 합니다. 서명 또는 체크섬이 실패하면 파일을 사용하지 말고 공식 경로에서 다시 받습니다.- 설치 대상과 보존 대상 디스크를 모델·시리얼·용량으로 각각 기록했습니다.
- 외부 백업 또는 VM 스냅샷에서 복원할 수 있음을 확인했습니다.
- boot ISO는 안정적인 네트워크 설치, minimal ISO는 최소 서버, DVD ISO는 오프라인·사용자 지정 설치용임을 구분했습니다.
- 현재 지원 Rocky Linux 9.x와 대상 아키텍처에 맞는 공식 ISO를 선택했습니다.
- 공식 키 지문, CHECKSUM.asc 서명, ISO SHA-256이 모두 일치했습니다.
CHECKSUM만 같은 서버에서 받아 비교하면 전송 오류는 찾을 수 있지만 배포 주체의 진위까지 단독으로 보장하지 못합니다. 공식 키 지문과 CHECKSUM.asc 서명까지 검증해야 합니다.
검증한 ISO를 권장 도구로 설치 매체에 기록하고 Anaconda에서 대상 디스크를 다시 확인합니다.
설치 매체 검사와 대상 디스크 확정
USB는 Rocky Release Engineering이 권장하는 Fedora Media Writer로 만들고, 부팅 메뉴에서 ‘Test this media & install Rocky Linux’를 선택합니다. Anaconda의 Begin Installation은 선택한 디스크의 파티션·파일시스템을 실제로 변경하는 사실상 되돌릴 수 없는 경계입니다.
lsblk -e7 -o NAME,SIZE,MODEL,SERIAL,TYPE,FSTYPE,MOUNTPOINTS기존 OS에서 확인 가능할 때 사용합니다. 이 가이드는 dd·wipefs·mkfs 같은 복사 가능한 디스크 쓰기 명령을 제공하지 않습니다.if [ -d /sys/firmware/efi ]; then printf '%s\n' 'UEFI'; else printf '%s\n' 'BIOS 또는 확인 필요'; fi기존 OS와 같은 부팅 방식을 유지해야 하는 장비라면 펌웨어 설정과 설치 매체 부팅 항목을 대조합니다.- Fedora Media Writer로 매체를 만들고 ‘Test this media & install Rocky Linux’ 검사를 통과했습니다.
- Installation Destination에 표시된 대상 디스크의 모델·시리얼·용량이 사전 기록과 정확히 일치합니다.
- 보존할 디스크가 선택되지 않았고 외부 백업의 복구 가능성을 마지막으로 확인했습니다.
- 신규 전용 디스크에는 자동 파티션을 사용하고, 기존 데이터·듀얼 부트·RAID·multipath는 이 가이드에서 중단했습니다.
- 설치 시작 뒤 대상 디스크 변경은 되돌릴 수 없으며 전원 차단도 안전한 취소 방법이 아님을 이해했습니다.
설치 프로그램이 디스크를 보지 못하면 임의로 스토리지 모드를 바꾸거나 다른 디스크를 포맷하지 않습니다. RAID·VMD·HBA·가상 디스크 매핑과 펌웨어 호환성을 먼저 확인합니다.
언어·시간·네트워크·소프트웨어·계정·스토리지 요약을 모두 검토한 뒤에만 설치를 시작합니다.
Anaconda 설치 옵션과 관리자 계정 구성
Minimal Install을 기본으로 선택하고 시간대·NTP·호스트명·네트워크를 서비스 기준에 맞춥니다. 일반 사용자를 만들고 관리자 권한을 부여하며 root 계정은 잠근 상태를 권장합니다. 암호화가 필요하면 LUKS 복구 구문을 서버 밖에 백업하고 실제 복구 절차를 문서화합니다.
timedatectl list-timezones | grep <REGION>설치 전 기존 Linux나 설치 후 시스템에서 확인할 수 있습니다. 예: Asia/Seoul, 표준이 UTC면 Etc/UTC.ip -brief address
ip route기존 시스템에서만 참고합니다. Anaconda에 고정 주소를 입력할 때 승인된 IP·prefix·gateway·DNS와 대조합니다.lsblk -e7 -o NAME,SIZE,MODEL,SERIAL,TYPE,FSTYPE,MOUNTPOINTSAnaconda 화면의 대상 모델·용량과 비교하기 위한 읽기 전용 기준입니다. 장치 이름은 부팅마다 달라질 수 있습니다.- Software Selection은 필요한 경우가 아니면 Minimal Install과 최소 애드온으로 제한했습니다.
- 일반 관리자 계정을 만들고 root 직접 사용에 의존하지 않도록 구성했습니다.
- 고정 주소를 사용하면 IP·prefix·gateway·DNS·VLAN을 승인 정보와 대조했습니다.
- 네트워크를 활성화하기 전에 사설 관리망 또는 상위 보안그룹의 관리자 CIDR 제한을 적용했습니다.
- LUKS를 선택했다면 복구 구문을 서버와 분리해 백업하고 콘솔 해제 절차를 준비했습니다.
- Begin Installation 직전에 대상 디스크 모델·시리얼·용량과 외부 백업 복구 상태를 다시 확인했습니다.
XFS는 축소할 수 없으므로 향후 볼륨 재배치가 예상되면 수동 파티션을 즉흥적으로 만들지 말고 LVM 여유 공간과 업무 데이터 분리 계획을 먼저 검토합니다.
설치가 끝나면 매체를 제거하고 관리자 계정으로 첫 부팅한 뒤 저장소와 업데이트 변경 내용을 검토합니다.
첫 부팅과 검토형 업데이트
설치 완료 후 매체를 제거하고 관리자 계정으로 로그인합니다. 활성 저장소와 패키지 상태를 확인한 뒤 자동 동의 옵션 없이 업데이트 트랜잭션을 읽고 승인합니다. 커널 업데이트가 있어도 콘솔·점검창 확인 없이 자동 재부팅하지 않습니다.
cat /etc/rocky-release
cat /etc/os-releasesudo dnf repolist --enabled
sudo dnf checksudo dnf check-update종료 코드 100은 업데이트가 있다는 뜻이며 명령 실패가 아닙니다. 삭제·대규모 교체가 보이면 원인을 확인합니다.sudo dnf upgrade --refresh트랜잭션 요약을 읽고 대화형으로 승인합니다. -y를 붙이지 않고 원격 세션과 콘솔을 유지합니다.if dnf needs-restarting --help >/dev/null 2>&1; then sudo dnf needs-restarting -r; else printf '%s\n' 'needs-restarting 플러그인 없음: 변경 패키지와 실행 커널을 직접 비교'; fi
uname -r
rpm -q kernel --last | head -n 3needs-restarting의 재부팅 필요 결과는 장애가 아닙니다. 콘솔과 점검 시간을 확보한 뒤 별도 단계로 재부팅합니다.- BaseOS·AppStream 등 의도한 공식 저장소만 활성화됐습니다.
- dnf check가 의존성·중복 패키지 오류 없이 끝났습니다.
- 업데이트 트랜잭션을 읽었고 무인 -y 옵션을 사용하지 않았습니다.
- 재부팅 필요 여부와 새 커널 설치 여부를 기록했습니다.
저장소 메타데이터나 GPG 검증이 실패하면 검증을 우회하지 않습니다. 시스템 시간·DNS·프록시·저장소 URL·공식 키 상태를 고친 뒤 다시 확인합니다.
승인된 점검 시간에 재부팅하고 운영체제·스토리지·네트워크·시간·실패 서비스를 실제 상태로 검증합니다.
재부팅 후 시스템 전체 검증
콘솔 복구 경로와 서비스 영향을 확인한 경우에만 재부팅합니다. 다시 접속한 뒤 파일 존재만이 아니라 실행 커널, 마운트, 기본 경로, DNS·시간, 저장소, 실패 unit과 부팅 오류를 함께 판정합니다.
sudo systemctl reboot스냅샷·백업, 콘솔, 서비스 영향, 새 SSH 접속 준비가 끝난 경우에만 단독으로 실행합니다. 업데이트 명령과 연결하지 않습니다.cat /etc/os-release
uname -srmo
who -b
rpm -q kernel --last | head -n 3lsblk -f
findmnt --verify --verbose
df -hTnmcli device status
ip route
getent hosts download.rockylinux.org
timedatectl statussudo dnf repolist --enabled
systemctl --failed --no-pager
sudo journalctl -p err..alert -b --no-pagerjournal에는 내부 호스트명·주소가 포함될 수 있으므로 공유 전 가립니다.- Rocky Linux 9 최신 지원 9.x와 의도한 아키텍처로 부팅했습니다.
- 실행 커널이 설치된 최신 커널이며 이전 커널은 검증이 끝날 때까지 보존했습니다.
- 업무 파일시스템과 swap이 의도한 장치에 마운트됐습니다.
- 기본 경로·DNS·시간 동기화가 정상이며 실패한 systemd unit이 없습니다.
- 재부팅 뒤 관리자 계정의 로컬·콘솔 로그인이 정상입니다.
부팅이 실패하면 반복 재부팅하거나 이전 커널을 지우지 않습니다. 콘솔의 GRUB에서 이전 커널로 부팅하고 마지막 변경과 journal을 수집합니다.
SELinux Enforcing과 firewalld 활성 상태를 유지한 채 SSH 공개키 접속을 별도 세션으로 검증합니다.
SELinux·firewalld·SSH 잠금 방지 보안
SELinux는 Enforcing, firewalld는 active를 유지합니다. 먼저 사설 관리망 또는 상위 방화벽·보안그룹에서 관리자 IPv4 CIDR만 인바운드로 허용했는지 확인합니다. 활성 zone과 NIC를 확인하고 같은 관리자 CIDR의 SSH rich rule만 runtime에 추가한 뒤 공개키 전용 두 번째 새 SSH 세션과 sudo를 성공시킵니다. 그 다음에만 암호·root 로그인을 제한하고 설정 검사 후 reload합니다.
getenforce
sestatusEnforcing이 정상 기준입니다. 문제 해결을 위해 permissive나 disabled로 바꾸지 않습니다.sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-all
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-rich-rules인터페이스가 연결된 실제 zone을 <ACTIVE_ZONE>에 사용합니다. services에 ssh가 이미 있으면 host zone 전체 허용이므로 이 가이드의 CIDR rich rule만으로 좁아지지 않습니다. 상위 ACL이 관리자 CIDR로 제한되지 않았다면 네트워크 노출을 중단하고 콘솔에서 별도 방화벽 변경 계획을 세웁니다.sudo firewall-cmd --zone=<ACTIVE_ZONE> --add-rich-rule='rule family="ipv4" source address="<ADMIN_IPV4_CIDR>" service name="ssh" accept' &&
{
rocky_runtime_services="$(sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-services)" &&
if printf '%s\n' "$rocky_runtime_services" | grep -qw ssh; then
sudo firewall-cmd --zone=<ACTIVE_ZONE> --remove-service=ssh
else
printf '%s\n' 'runtime zone-wide ssh service 없음'
fi
} &&
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-allCIDR rich rule 추가가 성공한 뒤에만 기본 zone-wide ssh service를 runtime에서 제거합니다. 상위 방화벽·보안그룹도 같은 관리자 CIDR만 허용하고 기존 콘솔과 세션을 유지합니다. IPv6 관리 경로 또는 비표준 포트는 이 초기 레시피에서 동시에 바꾸지 않습니다.ssh-copy-id <ADMIN_USER>@<SERVER_IP>
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'두 명령은 관리자 CIDR 안의 공개키를 보관한 로컬 PC에서 실행합니다. 두 번째 명령은 암호·키보드 대화형 fallback을 막아 실제 공개키 성공만 검증합니다. 새 세션과 sudo가 실패하면 이후 로그인 제한을 적용하지 않습니다.if sudo test -e /etc/ssh/sshd_config.d/10-haruspace-hardening.conf; then sudo cp --archive --no-clobber /etc/ssh/sshd_config.d/10-haruspace-hardening.conf /etc/ssh/sshd_config.d/10-haruspace-hardening.conf.<BACKUP_SUFFIX>; else printf '%s\n' '기존 스니펫 없음'; fi<BACKUP_SUFFIX>를 존재하지 않는 값으로 바꿉니다. 기존 파일이 없었다면 그 사실을 작업 기록에 남깁니다.sudoedit /etc/ssh/sshd_config.d/10-haruspace-hardening.conf공개키 두 번째 세션과 콘솔 복구가 성공한 뒤 아래 설정을 저장합니다.sudo sshd -t && sudo systemctl reload sshd.service && sudo sshd -T | grep -E '^(permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication) 'sshd -t가 아무 출력 없이 종료 코드 0일 때만 reload합니다. 기존 세션을 닫지 말고 다시 새 세션을 열어 확인합니다.ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'관리자 CIDR 안의 로컬 PC에서 실행합니다. 암호·root 로그인 제한을 반영한 뒤에도 새 공개키 세션과 sudo가 성공해야 합니다. 기존 세션은 계속 유지합니다.sudo firewall-cmd --zone=<ACTIVE_ZONE> --permanent --add-rich-rule='rule family="ipv4" source address="<ADMIN_IPV4_CIDR>" service name="ssh" accept' &&
{
rocky_permanent_services="$(sudo firewall-cmd --zone=<ACTIVE_ZONE> --permanent --list-services)" &&
if printf '%s\n' "$rocky_permanent_services" | grep -qw ssh; then
sudo firewall-cmd --zone=<ACTIVE_ZONE> --permanent --remove-service=ssh
else
printf '%s\n' 'permanent zone-wide ssh service 없음'
fi
} &&
sudo firewall-cmd --reload &&
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-allruntime CIDR 제한과 공개키 전용 새 세션이 성공한 뒤에만 실행합니다. 영구 rich rule 추가와 zone-wide service 제거가 모두 성공한 경우에만 reload합니다.ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'관리자 CIDR 안에서 실행하고 기존 세션을 유지합니다. 실패하면 콘솔에서 active zone·rich rule·상위 ACL을 확인합니다.PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no기본 SSH 22번 포트를 유지합니다. 새 관리자 공개키 세션과 sudo, 콘솔 복구를 먼저 검증한 경우에만 적용합니다.- SELinux가 Enforcing이며 비활성화하거나 permissive로 바꾸지 않았습니다.
- 첫 패치와 SSH 강화 전부터 사설 관리망 또는 상위 방화벽·보안그룹이 관리자 IPv4 CIDR만 인바운드로 허용합니다.
- firewalld가 active이고 NIC가 연결된 실제 zone을 확인했습니다.
- 암호 fallback을 차단한 공개키 전용 두 번째 새 SSH 세션과 sudo가 성공하기 전에는 암호·root 로그인을 제한하지 않았습니다.
- sshd -t 성공 뒤 reload했고 기존 세션을 유지한 채 새 접속을 다시 검증했습니다.
- firewalld 영구 규칙은 관리자 CIDR의 runtime 접속 성공 뒤 반영했고 zone 전체에 새 SSH service를 열지 않았습니다.
SELinux 거부는 audit 로그와 파일 레이블·허용 정책을 확인해 해결합니다. 접속 문제가 생겨도 SELinux나 firewalld를 끄거나 SSH 허용을 광범위하게 늘리지 않습니다.
설치·업데이트·SSH 중 어느 경계에서 실패했는지 구분하고 준비한 복원 경로만 사용합니다.
설치 경계별 복구와 원복
Begin Installation 전이라면 설치 프로그램을 종료하고 기존 OS 부팅을 확인합니다. 디스크 쓰기가 시작된 뒤에는 DNF 롤백으로 이전 OS를 복구할 수 없습니다. VM 스냅샷·복제본 또는 베어메탈 전체 이미지와 데이터 백업을 복원하거나 승인된 절차로 재설치합니다. 관리자 CIDR을 잘못 입력했다면 기존 SSH 세션 또는 콘솔과 상위 방화벽·보안그룹 제한을 유지한 채 올바른 CIDR을 먼저 검증하고, 마지막에 잘못된 규칙만 제거합니다.
cat /etc/os-release
lsblk -e7 -o NAME,SIZE,MODEL,SERIAL,TYPE,FSTYPE,MOUNTPOINTS
findmnt -no SOURCE,TARGET,FSTYPE /복원·재설치 전에 예상한 시스템과 대상 디스크인지 읽기 전용으로 확인합니다.sudo journalctl -b -1 -p err..alert --no-pager
sudo dnf history list진단용 조회입니다. 전체 설치나 대규모 업데이트에 dnf history undo를 무조건 실행하지 않습니다.printf '%s\n' "$SSH_CONNECTION"
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-all
sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-rich-rules잘못된 관리자 CIDR 때문에 새 접속이 실패한 경우에만 실행합니다. $SSH_CONNECTION에는 내부 IP와 포트가 포함되므로 외부에 공유하지 않습니다. 기존 세션이나 콘솔을 닫지 말고 상위 방화벽·보안그룹의 관리자 CIDR 제한도 유지합니다.sudo firewall-cmd --zone=<ACTIVE_ZONE> --add-rich-rule='rule family="ipv4" source address="<CORRECT_ADMIN_IPV4_CIDR>" service name="ssh" accept' && sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-rich-rules승인된 실제 관리자 출발지의 IPv4 CIDR을 다시 확인해 입력합니다. 기존의 잘못된 규칙은 아직 제거하지 않습니다.ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'올바른 관리자 CIDR 안의 로컬 PC에서 새 세션으로 실행합니다. 실패하면 영구 반영이나 기존 규칙 제거로 넘어가지 않습니다.sudo firewall-cmd --zone=<ACTIVE_ZONE> --permanent --add-rich-rule='rule family="ipv4" source address="<CORRECT_ADMIN_IPV4_CIDR>" service name="ssh" accept' && sudo firewall-cmd --reload && sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-allruntime 규칙과 공개키 전용 새 세션이 성공한 뒤에만 실행합니다. 영구 규칙 추가가 실패하면 reload하지 않습니다.ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -t <ADMIN_USER>@<SERVER_IP> 'id && sudo -v'reload 뒤에도 올바른 관리자 CIDR에서 공개키 전용 새 세션과 sudo가 성공해야 합니다. 기존 세션이나 콘솔은 계속 유지합니다.sudo firewall-cmd --zone=<ACTIVE_ZONE> --remove-rich-rule='rule family="ipv4" source address="<WRONG_ADMIN_IPV4_CIDR>" service name="ssh" accept' && sudo firewall-cmd --zone=<ACTIVE_ZONE> --permanent --remove-rich-rule='rule family="ipv4" source address="<WRONG_ADMIN_IPV4_CIDR>" service name="ssh" accept' && sudo firewall-cmd --reload && sudo firewall-cmd --zone=<ACTIVE_ZONE> --list-all<WRONG_ADMIN_IPV4_CIDR>는 list-rich-rules에서 확인한 잘못된 규칙의 주소와 정확히 같아야 합니다. 올바른 규칙과 reload 뒤 새 세션을 먼저 검증한 경우에만 실행하며, 기존 세션·콘솔과 상위 ACL은 유지합니다.sudo mv /etc/ssh/sshd_config.d/10-haruspace-hardening.conf /etc/ssh/sshd_config.d/10-haruspace-hardening.conf.disabled && sudo sshd -t && sudo systemctl reload sshd.service콘솔에서 이번 레시피가 만든 파일임을 확인하고 disabled 대상이 없을 때만 실행합니다. 기존 설정 백업이 있다면 검증 후 별도 복원합니다.sudo cp --archive /etc/ssh/sshd_config.d/10-haruspace-hardening.conf.<BACKUP_SUFFIX> /etc/ssh/sshd_config.d/10-haruspace-hardening.conf && sudo sshd -t && sudo systemctl reload sshd.service작업 전에 실제로 만든 백업이 있고 내용과 소유권을 확인한 경우에만, 비활성화 분기 대신 실행합니다. 현재 콘솔과 기존 SSH 세션을 유지합니다.cat /etc/os-release
uname -r
systemctl --failed --no-pager
getenforce
sudo firewall-cmd --state- Begin Installation 전 중단인지 디스크 쓰기 이후 복구인지 구분했습니다.
- VM은 정확한 사전 스냅샷·복제본, 베어메탈은 검증된 전체 이미지·데이터 백업으로 복원했습니다.
- 새 커널 부팅 문제는 GRUB에서 이전 커널을 선택하고 정상 확인 전 이전 커널을 제거하지 않았습니다.
- 설치 대상이 아닌 보존 디스크를 추가로 포맷하거나 임의의 디스크 복구 명령을 실행하지 않았습니다.
- 잘못된 관리자 CIDR은 기존 세션·콘솔과 상위 ACL을 유지하고 올바른 runtime 규칙과 공개키 전용 새 세션을 검증한 뒤에만 정확히 제거했습니다.
- 복구 후 OS·커널·마운트·네트워크·SELinux·firewalld·SSH를 다시 검증했습니다.
새 OS 설치는 패키지 단위 변경이 아니므로 패키지 downgrade나 history undo를 전체 복구 수단으로 사용하지 않습니다. 사전 이미지가 없다면 남은 데이터를 보존한 채 전문 복구 절차를 먼저 결정합니다. SSH CIDR 복구는 올바른 규칙 추가 → 공개키 전용 새 세션 검증 → 영구 반영 → 재검증 → 정확한 잘못된 규칙 제거 순서를 바꾸지 않습니다.
복구 결과와 실패 지점, 대상 디스크 식별값, 사용한 백업·스냅샷을 운영 기록에 남긴 뒤 원인을 분리해 재시도합니다.
SECURITY CHECK
운영 전 마지막 보안 점검
- 설치 대상 디스크는 장치 이름이 아니라 모델·시리얼·용량으로 이중 확인합니다.
- 공식 Rocky Linux 9 키 지문과 CHECKSUM.asc 서명, ISO SHA-256, 부팅 매체 검사를 모두 통과합니다.
- SELinux Enforcing과 firewalld active를 유지하고 문제 해결을 위해 끄지 않습니다.
- 공개키 두 번째 SSH 세션과 sudo가 성공하기 전에는 암호·root 로그인을 차단하지 않습니다.
- 첫 패치와 SSH 강화 전부터 사설 관리망 또는 상위 방화벽·보안그룹으로 관리자 IPv4 CIDR 외 인바운드를 차단합니다.
- 업데이트는 -y 없이 트랜잭션을 읽고 재부팅은 콘솔·점검 시간 확보 뒤 별도로 수행합니다.
- LUKS 복구 구문·관리자 키·내부 네트워크 정보는 화면 캡처나 외부 문서에 노출하지 않습니다.
COMMON ERRORS
자주 막히는 지점
Anaconda에 설치 디스크가 보이지 않음
- 증상
- Installation Destination에 기대한 NVMe·SAS·가상 디스크가 나타나지 않습니다.
- 가능한 원인
- RAID·VMD·HBA 드라이버, 펌웨어 설정, VM 디스크 연결 또는 multipath 구성이 맞지 않을 수 있습니다.
- 확인 순서
- 기존 데이터가 있으면 컨트롤러 모드를 바꾸지 말고 설치를 중단합니다. 하드웨어·하이퍼바이저 매핑과 Rocky 지원 여부를 확인합니다.
ISO 서명·체크섬 또는 미디어 검사 실패
- 증상
- GPG 검증, sha256sum 또는 Test this media 단계가 실패합니다.
- 가능한 원인
- 잘못된 아키텍처·미지원 이전 minor·불완전한 다운로드·손상된 USB 또는 공식 키가 아닌 파일일 수 있습니다.
- 확인 순서
- 설치를 중단하고 공식 Releases와 이미지 디렉터리에서 현재 파일을 다시 받아 키 지문부터 재검증합니다. 검증 우회 옵션은 사용하지 않습니다.
boot ISO에서 저장소에 연결하지 못함
- 증상
- 설치 소스가 준비되지 않거나 패키지 메타데이터를 받지 못합니다.
- 가능한 원인
- VLAN·DHCP·DNS·프록시·기본 경로 문제이거나 boot ISO의 네트워크 설치 전제를 충족하지 못할 수 있습니다.
- 확인 순서
- 승인된 네트워크 값을 점검하고 오프라인 환경이면 검증한 DVD ISO로 다시 계획합니다.
첫 부팅 뒤 SSH가 연결되지 않음
- 증상
- timeout, Connection refused 또는 Permission denied가 발생합니다.
- 가능한 원인
- NetworkManager 연결, 주소·경로, sshd, firewalld zone, 공개키 권한 중 하나가 맞지 않을 수 있습니다.
- 확인 순서
- 콘솔에서 nmcli, ip route, systemctl status sshd, sshd -t, firewall-cmd 순으로 확인하고 SELinux·firewalld를 끄지 않습니다.
새 커널에서 부팅이 실패함
- 증상
- 업데이트 후 부팅이 멈추거나 장치·네트워크가 동작하지 않습니다.
- 가능한 원인
- 커널·드라이버·firmware 조합 또는 initramfs·부팅 항목 문제일 수 있습니다.
- 확인 순서
- 콘솔의 GRUB에서 보존한 이전 커널로 부팅하고 journal과 하드웨어 로그를 수집한 뒤 변경을 분리합니다.
SELinux가 서비스를 거부함
- 증상
- 서비스 설정은 맞지만 audit 로그에 AVC denial이 기록됩니다.
- 가능한 원인
- 파일 컨텍스트·비표준 경로·포트 또는 필요한 정책이 서비스 구성과 맞지 않을 수 있습니다.
- 확인 순서
- ausearch와 journal로 거부 원인을 확인하고 올바른 레이블·정책으로 수정합니다. SELinux를 permissive나 disabled로 바꾸지 않습니다.
PRIMARY REFERENCES
공식 문서
- Rocky Linux · Releases and support policy
- Rocky Linux 9.0 · CPU minimum requirements
- Rocky Linux Release Engineering · ISOs and images
- Rocky Linux · GPG key information
- Rocky Linux · DNF package manager
- Rocky Linux · Learning SELinux
- Rocky Linux · firewalld for beginners
- Red Hat Enterprise Linux 9 · Customize installation storage
설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.