- Born2beRoot2025년 08월 05일 18시 53분 21초에 업로드 된 글입니다.작성자: kugorang728x90728x90
들어가며
1 서클에서 암기량이 가장 많았던 과제여서 덜덜 떨며 평가를 받았다. 이번에 다룰 과제는
Born2beroot
과제이다. 나는 시간이 없어 아쉽게도 Debian으로 과제를 수행했지만, 과제 정리만큼은 Rocky Linux의 핵심 개념을 정리해보고자 한다.Born2beroot
과제를 수행하기 위해 Rocky Linux를 사용하는 경우 필요한 주요 사전 지식은 다음과 같다.- LVM(Logical Volume Manager): 디스크 파티셔닝과 유연한 스토리지 관리 기법
- UFW(Uncomplicated Firewall): 방화벽 설정 및 네트워크 보안
- SSH 보안 설정: 원격 접속 보안 강화 및 설정 방법
- Sudo와 사용자 관리: 권한 관리 및 보안 설정
- SELinux: 시스템 보안 정책 및 적용 방법
- Hostname 및 네트워크 설정: 서버의 네트워크 환경 구성
- 기본적인 서비스 관리(systemd, journald 등): 서비스와 로그 관리
이제 Rocky Linux 환경을 기반으로 위 내용을 깊이 이해하여, 과제를 수행하는 데 필요한 핵심 개념과 실습 방법을 정리해보자.
LVM(Logical Volume Manager)
개념 및 구조: LVM은 물리 저장장치를 추상화하여 유연한 스토리지 관리를 가능하게 하는 스토리지 가상화 계층이다[1]. LVM에서는 실제 디스크 파티션이나 전체 디스크를 Physical Volume(PV)로 삼고, 하나 이상의 PV를 묶어 Volume Group(VG)을 구성한다[1]. VG의 저장 공간은 필요에 따라 Logical Volume(LV)으로 할당되며, LV는 일반 디스크처럼 포맷하여 파일시스템을 생성하거나 애플리케이션의 저장소로 사용할 수 있는 가상 블록 디바이스이다[1]. 요약하면 PV → VG → LV의 계층으로 이루어져 있으며, LV 위에 실제 파일시스템이나 데이터가 저장된다.
동적 스토리지 관리: LVM을 사용하면 실행 중인 시스템에서도 저장 용량을 유동적으로 조절할 수 있다. 예를 들어 디스크를 추가로 연결한 후 PV로 초기화하여 기존 VG에 편입하고,
lvextend
등으로 LV 크기를 늘린 뒤 파일시스템을 확장함으로써 다운타임 없이 용량 증설이 가능하다[1]. LVM은 물리 장치 위에 가상 볼륨을 만들기 때문에 디스크 공간을 논리적으로 분할/확장/축소할 수 있고, 이는 전통적인 파티션 관리보다 유연하다. 이처럼 LVM은 디스크 추가, VG 확장, LV 확장 등의 작업을 통해 시스템 운영 중에도 저장소 구성을 변경할 수 있다는 장점이 있다.LVM 스냅샷과 백업: LVM의 스냅샷 기능은 특정 시점의 LV 상태를 복제하여 읽기 전용 또는 읽기-쓰기 가능한 스냅샷 볼륨을 만드는 기술이다[2]. 스냅샷 생성 시 서비스 중단 없이도 LV를 보던 시점 그대로의 시점 복사(point-in-time copy)를 얻을 수 있다[3]. 스냅샷 생성 후 원본 LV에 변경이 발생하면, 변경 이전의 원본 데이터 블록을 스냅샷 영역에 기록(copy-on-write)하여 스냅샷이 당시 상태를 유지하도록 한다[2]. 스냅샷은 원본 데이터 중 변경된 부분만을 저장하므로 효율적이며, 일반적으로 원본 크기의 몇 퍼센트 정도 공간으로도 관리 가능하다[3]. 이 스냅샷 볼륨을 이용하면 백업 시점을 고정한 채 백업을 수행할 수 있어 백업 도중 원본 데이터가 변경되는 문제를 피할 수 있다[2,3]. 예를 들어 스냅샷을 만든 후, 그 스냅샷을 읽어서 별도의 백업 매체로 복사하고 백업이 끝나면 스냅샷을 삭제하는 방식으로 서비스 가동 중 실시간 백업이 가능하다. 다만 LVM 스냅샷 자체가 백업 데이터의 영구 보관을 의미하는 것은 아니므로, 스냅샷을 이용해 얻은 데이터를 별도로 안전하게 저장해야 한다.
UFW(Uncomplicated Firewall)
기본 개념과 역할: UFW는 Ubuntu 등에서 기본 제공되는 간편 방화벽 설정 도구로, 리눅스의 iptables(넷필터) 방화벽을 쉽게 다룰 수 있게 해주는 프론트엔드이다[4]. 복잡한 방화벽 규칙 작성을 단순화하여 초보자도 쉽게 방화벽 정책을 관리할 수 있도록 설계되었다[4]. UFW는 기본적으로 비활성화되어 있으며(사용자가 명시적으로 켜야 함), 활성화 시 기본 정책으로 모든 들어오는 트래픽을 거부하고 나가는 트래픽은 허용하는 규칙을 적용한다[5]. 즉 UFW를 켜는 순간부터 외부에서 들어오는 연결은 특별히 허용(
allow
)하지 않는 한 차단되며, 로컬에서 나가는 연결은 기본 허용된다. 이러한 기본 설정 위에 사용자가 필요한 서비스를 열거나 막는 등의 세부 규칙을 추가하게 된다.UFW 명령어 및 설정: UFW는 명령행에서
ufw
명령으로 설정한다. 대표적인 사용법은 다음과 같다.sudo ufw enable
: UFW 방화벽을 활성화한다 (기본 정책이 적용되어 수신 차단: 모든, 송신 허용: 모든 상태가 됨)[4]. 방화벽 상태는sudo ufw status
로 확인할 수 있다.sudo ufw disable
: UFW 방화벽을 비활성화하여 방화벽 규칙을 모두 끈다.sudo ufw allow <포트/서비스>
: 지정한 포트 번호 또는 서비스 이름에 대한 들어오는 트래픽을 허용한다. 예를 들어sudo ufw allow 22
또는sudo ufw allow ssh
명령은 SSH 서비스(포트 22)를 허용하는 규칙을 추가한다[5]. UFW는 서비스 이름에 해당하는 포트를 자동으로 인식하며, 프로파일이 있는 경우 v6 규칙까지 함께 추가한다.sudo ufw deny <포트/서비스>
: 지정한 포트/서비스에 대한 트래픽을 차단한다 (기본정책이 이미 수신 차단이므로 필요시 사용).sudo ufw delete <규칙번호>
: 설정된 방화벽 규칙을 제거한다. (sudo ufw status numbered
로 번호 확인)- 그 외
sudo ufw status verbose
(상세 상태 출력),sudo ufw app list
(미리 정의된 서비스 프로파일 목록) 등의 명령이 있다.
방화벽 규칙 추가 및 특정 서비스 제어: UFW를 사용하면 서비스명이나 포트 번호로 손쉽게 규칙을 추가할 수 있다. 예를 들어
sudo ufw allow 80/tcp
는 TCP 80번 포트를 열어 웹서버(HTTP)를 허용하고,sudo ufw allow https
는 미리 정의된 HTTPS 서비스(443/TCP)를 허용한다[5]. 또한 특정 IP에 대해서만 허용/차단하거나 특정 네트워크 대역만 허용하는 것도 가능하다. 예를 들어sudo ufw allow from 192.168.0.100 to any port 22
명령은 해당 IP에서 오는 SSH(22번 포트) 접속만 허용하고 그 외 주소의 SSH 접속은 차단한다[5]. UFW는 이러한 규칙들을/etc/ufw/
이하의 설정파일과 iptables 규칙으로 관리하며,sudo ufw status
로 현재 적용된 규칙 목록을 확인할 수 있다. UFW를 설정한 후에는sudo ufw enable
로 방화벽을 켜야 규칙이 실제로 적용된다.SSH 보안 설정
SSH 및 설정 파일: SSH는 원격 접속을 위한 보안 프로토콜로, 서버 측 데몬 설정은 보통
/etc/ssh/sshd_config
파일을 통해 관리된다[6]. 이 파일에서 포트 번호, 인증 방식, 접근 제어 등의 옵션을 설정할 수 있으며, SSH 데몬(sshd
)은 시작 시 이 설정파일을 읽어들인다. Rocky Linux와 같은 RHEL 계열에서도 OpenSSH 서버 설정은 동일한 경로를 사용한다. 기본적으로 SSH 데몬은 22번 포트를 사용하고, 루트 계정 접속이 허용되는 등 기본 설정이 되어 있는데, 보안을 강화하기 위해 여러 설정을 변경하는 것이 권장된다[7,8].1) SSH 포트 변경: 브루트포스 공격 등 자동화된 공격으로부터 덜 노출되도록 기본 포트 번호(22번)를 다른 포트로 변경할 수 있다.
/etc/ssh/sshd_config
에서Port 22
지시자를 찾아 임의의 높은 포트 번호(예: 2222 등)로 바꾸고 설정을 저장한 뒤 SSH 서비스를 재시작하면 해당 포트를 통해서만 SSH 접속이 가능해진다[6,7]. 포트 변경 시에는 방화벽에서 새로운 포트를 열어주고, SELinux 보안 정책에 그 포트를 SSH 서비스 포트로 추가로 허용해야 한다. RHEL 계열에서는semanage port -a -t ssh_port_t -p tcp <포트번호>
명령으로 SELinux에 새로운 SSH 포트를 등록할 수 있다[8]. 또한 UFW나 firewalld 방화벽 사용 시 변경한 포트를 허용하도록 규칙을 추가해야 접속이 끊기지 않는다.2) 루트 사용자 SSH 로그인 제한: 보안상 위험이 큰 root 계정의 직접 SSH 로그인은 비활성화하는 것이 좋다.
sshd_config
파일에서PermitRootLogin yes
로 되어 있는 값을no
로 변경하면 이후부터는 root로 SSH 접속을 할 수 없게 된다[6,7,8]. 이렇게 하면 설령 공격자가 root 비밀번호를 알아내도 직접 SSH 로그인은 막히게 되고, 대신 일반 사용자로 로그인한 후sudo
를 통해 권한을 상승시키는 방식만 허용된다. (기본적으로 Rocky Linux의 root SSH 로그인은 허용되어 있으므로 보안을 위해 꼭 변경해야 한다.)3) 공개 키 기반 인증 설정: 패스워드 대신 SSH 공개키/개인키 인증을 사용하면 무차별 대입 공격에 대한 안전성이 크게 높아진다. 이를 위해
PasswordAuthentication no
로 설정하여 비밀번호 인증을 아예 끄고 공개키만으로 로그인하도록 설정할 수 있다[6,7]. 이 경우 SSH 클라이언트는 사용자 PC의 개인 키를 사용하여 인증하고, 서버는 사전에 등록된 공개 키(/home/<사용자>/.ssh/authorized_keys
)로 클라이언트를 검증한다. 공개키 인증을 설정하려면 사용자가ssh-keygen
으로 키쌍(개인키/공개키)을 생성한 뒤, 서버의 해당 사용자 홈 디렉토리에 공개키를 등록해야 한다. 편의를 위해ssh-copy-id
명령으로 공개키를 서버에 복사할 수 있다. 공개키 인증을 활성화한 후에는 앞서 언급한대로/etc/ssh/sshd_config
에서PasswordAuthentication no
로 설정하여 비밀번호로는 로그인 불가하도록 하고 SSH 데몬을 재시작한다. 이렇게 하면 인증 강도가 높아져 무작위 패스워드 공격을 원천 차단할 수 있다.4) Fail2ban으로 SSH 공격 방어: Fail2ban은 반복적인 로그인 실패를 감지해 공격으로 판단될 경우 해당 IP를 일정 시간 차단하는 보안 도구이다[9]. SSH 같이 인터넷에 공개된 서비스는 무차별 대입(bruteforce) 시도가 흔한데, Fail2ban을 사용하면 로그를 모니터링하여 다수의 실패 발생 시 자동으로 방화벽 규칙을 추가해 해당 IP를 일시적으로 막아준다[10]. Rocky Linux에는 Fail2ban이 기본 설치되어 있지 않지만 EPEL 저장소를 통해 설치 가능하며[9,10], 설치 후
/etc/fail2ban/jail.local
에서[sshd]
섹션을 활성화하고 원하는 임계값(예: 5회 실패 시 10분 차단 등)을 설정할 수 있다. Fail2ban이 동작하면/var/log/secure
등의 SSH 인증 로그를 실시간으로 검사하여 규칙에 부합하는 과도한 실패 시도가 발생하면 해당 원격 IP를 UFW나 firewalld를 통해 차단한다[9]. 이를 통해 무차별 대입 공격을 능동적으로 완화하고 서버를 보호할 수 있다. (차단된 IP 목록은fail2ban-client status sshd
명령 등으로 확인 가능하다.)Sudo와 사용자 관리
사용자 계정 및 그룹 관리: Rocky Linux에서 새로운 사용자 계정을 추가하려면
useradd
(또는 편의용adduser
) 명령을 사용하고, 비밀번호는passwd
로 설정한다. 생성된 사용자에게 관리자 권한을 주고 싶다면 wheel 그룹에 추가해야 한다. RHEL 계열에선 wheel 그룹에 속한 사용자에게 sudo 권한을 부여하는 것이 일반적이다[11]. 예를 들어 사용자 example를 추가하고 관리자권한을 주는 과정은 다음과 같다.# useradd example # 새 사용자 추가 # passwd example # 해당 사용자 비밀번호 설정 # usermod -aG wheel example # 사용자 example을 wheel 그룹에 추가
이렇게 하면
/etc/sudoers
파일에서 정의된 wheel 그룹 규칙에 따라 sudo 사용이 가능해진다. 변경사항을 적용하려면 해당 사용자가 새로 로그인해야 한다.id example
명령으로 사용자가 속한 그룹을 확인하면10(wheel)
등으로 wheel 그룹 포함 여부를 알 수 있다[11].sudo 권한 설정과 보안:
/etc/sudoers
파일은 어떤 사용자/그룹에게 어떤 명령을 루트로 실행 허가할지를 정의하는 설정이다[12]. 기본 설정에서는%wheel ALL=(ALL) ALL
라인이 주석 없이 존재하여, wheel 그룹 사용자에게 모든 명령을 루트 권한으로 실행할 수 있는 sudo 권한을 부여한다[11,12]. 따라서 앞서 언급한 대로 사용자를 wheel 그룹에 넣으면 별도 설정 변경 없이 sudo가 가능해진다. 다만 보안을 위해 sudo 권한은 필요한 사용자에게만 최소한으로 부여해야 한다. 또한 기본 설정에서는 sudo 실행 시 사용자 자신의 비밀번호를 요구하여 권한 오남용을 억제하는데, 이를 유지하는 것이 권장된다[12]. 절대로/etc/sudoers
파일을 직접 에디터로 열어 수정하지 말고, 항상visudo
명령을 사용해야 한다.visudo
는 편집 내용에 문법 오류가 없는지 검증하여 잘못된 sudoers 설정으로 인한 잠금(lockout)을 방지한다[12]. 만약 특정 사용자에 대해서만 일부 명령에 대한 sudo를 허용하거나 무비밀번호(nopasswd) 설정 등 세분화가 필요하면, sudoers 파일에 별도 규칙을 추가하면 된다. (예:%dev ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart httpd
등). 원칙적으로 최소 권한의 원칙(Least Privilege)을 따라 sudo 권한을 제한하고, 필요 이상으로 root 계정을 직접 사용하지 않는 관리 전략이 중요하다.비밀번호 정책 설정: 강력한 사용자 비밀번호 정책은 리눅스 서버 보안의 기본이다. Rocky Linux에서는 PAM의
pwquality
모듈을 통해 암호 복잡도 규칙을 enforcing할 수 있다[13]./etc/security/pwquality.conf
파일에서 최소 암호 길이(minlen
), 대문자 최소 개수(ucredit
음수값으로 설정), 소문자(lcredit
), 숫자(dcredit
), 특수문자(ocredit
) 요구사항 등을 지정할 수 있다[13]. 예를 들어minlen=10
,ucredit=-1
,dcredit=-1
,ocredit=-1
로 설정하면 최소 10자 길이에 대문자, 숫자, 특수문자를 각각 1개 이상 포함하도록 암호 규칙을 강화할 수 있다[13]. 또한 이전 암호와의 유사도 제한(difok
), 연속 문자열 제한 등 추가 옵션도 지원된다. 이러한 정책을 설정해 두면 사용자가passwd
명령으로 새 비밀번호를 정할 때 정책을 만족하지 않으면 거부되므로 강제적으로 복잡한 암호 사용을 구현할 수 있다.비밀번호 유효기간(만료) 정책도 설정하는 것이 좋다.
/etc/login.defs
파일에서 전역 기본값을 조정할 수 있는데,PASS_MAX_DAYS
는 암호 최대 사용일수를,PASS_MIN_DAYS
는 변경 최소 주기,PASS_WARN_AGE
는 만료 경고 일수를 정의한다[14]. 예를 들어 다음과 같이 설정하면 암호는 90일간 유효하고, 7일 이상 사용해야 변경 가능하며, 만료 5일 전부터 경고한다[14].PASS_MAX_DAYS 90 PASS_MIN_DAYS 7 PASS_WARN_AGE 5
이 설정은 새로 생성되는 계정에 적용되며, 기존 계정에는
chage
명령으로 개별 설정할 수 있다[14].chage -l <사용자명>
으로 해당 사용자의 현재 암호 만료 설정을 조회하거나,chage -M 90 -m 7 -W 5 <사용자명>
으로 직접 설정 가능하다[14]. 조직 보안 정책에 따라 90일 이내로 만료를 강제하거나, 최근 암호 재사용 금지 등의 추가 정책도 고려할 수 있다. 이러한 비밀번호 정책을 통해 주기적인 암호 변경과 강력한 암호 구성을 시스템 차원에서 강제하여 보안을 향상시킨다.SELinux(Security-Enhanced Linux)
SELinux 개념과 정책: SELinux는 리눅스 커널에 구현된 강화된 접근 제어(MAC) 시스템으로, 사용자와 프로세스가 시스템 리소스에 접근할 수 있는지를 정책에 따라 허용 또는 거부한다[15]. 일반 리눅스의 DAC(Discretionary Access Control)이 소유자와 권한 비트로 접근 통제를 하는 반면, SELinux는 모든 파일, 프로세스 등에 보안 컨텍스트(label)를 부여하고 사전 정의된 정책 규칙에 따라 접근을 제어한다. 예를 들어 Apache 웹서버 프로세스(httpd)가
/var/www
이외 디렉토리에 접근하려 하면 정책에 어긋나 차단되는 식이다. RHEL 및 Rocky Linux의 기본 SELinux 정책은 "대상(Targeted) 정책"으로 불리며, 주요 시스템 데몬(예: httpd, sshd, named 등 선택된 대상만)을 엄격하게 격리하고 일반 사용자 프로세스에 대해서는 비교적 관대하게 동작한다[16]. 이렇게 함으로써 시스템 서비스들이 침해되더라도 지정된 범위를 벗어나지 못하게 피해를 최소화한다.SELinux 모드 설정: SELinux에는 세 가지 동작 모드가 있다[16].
- Enforcing(강제) 모드: SELinux 정책을 적용하여 규칙에 어긋나는 모든 접근을 차단하고 로그로 기록한다. (시스템 기본 모드)
- Permissive(허용) 모드: 정책을 적용하되 차단하지 않고 경고 로그만 기록한다. 즉 실제 접근은 허용되지만 만약 Enforcing이었다면 막혔을 이벤트를 로그로 남겨 추적할 수 있다[16,17]. 이 모드는 SELinux로 인한 문제를 트러블슈팅할 때 유용하다.
- Disabled(비활성) 모드: SELinux를 아예 끈 상태로, 어떠한 정책 검사가 이루어지지 않는다[16].
현재 SELinux 모드는
sestatus
명령으로 확인할 수 있으며, "Current mode:" 항목으로 표시된다 (enabled상태에서 Enforcing/Permissive 중 하나)[16]. 일시적으로 모드를 변경하려면setenforce 0
(Permissive로 전환) 또는setenforce 1
(Enforcing으로 재전환) 명령을 사용한다[16]. 이 변경은 재부팅 전까지만 유효하므로, 영구적으로 모드를 바꾸려면/etc/selinux/config
파일을 편집하여SELINUX=enforcing|permissive|disabled
로 설정하고 재부팅해야 한다[16]. 일반적으로 SELinux를 완전히 끄는 것은 권장되지 않으며, 일시적 문제 해결 시에만 Permissive를 쓰고 다시 Enforcing으로 돌려놓는 것이 바람직하다.SELinux 로그 확인 및 문제 해결: SELinux에 의해 어떤 액션이 차단되면 AVC(Access Vector Cache) Denial 로그가 생성된다[15]. SELinux 경고/차단 메시지는 기본적으로 Audit 로그에 남기는데, auditd 데몬이 활성화된 경우
/var/log/audit/audit.log
파일에서 관련 내역을 확인할 수 있다[15]. (auditd가 꺼져 있다면/var/log/messages
에 기록) 로그에는 "AVC denied" 등의 키워드로 무엇이 어떻게 차단됐는지 정보를 담고 있다. 예를 들어avc: denied { write } for pid=1234 comm="httpd" name="data.txt" ... scontext=httpd_t tcontext=user_home_t ...
와 같이, 어떤 프로세스가 어떤 타입의 리소스에 대해 어떤 동작을 시도했고 거부되었는지 나타낸다. 이러한 로그를 해석하여 문제가 되는 SELinux 규칙을 파악한 뒤, 필요하면 정책 예외를 추가하는 식으로 문제를 해결한다.SELinux 문제 해결에는 몇 가지 방법이 있다. Permissive 모드로 전환하면 해당 호스트에서 SELinux는 로그만 남기므로, 문제 발생 시도를 재현하여 어떤 AVC가 뜨는지 확인할 수 있다. 그 후
audit2why
나audit2allow
도구를 사용하면 로그를 기반으로 왜 차단되었는지 원인을 설명해주거나, 해당 로그를 허용하는 정책 모듈(.te)을 생성해주기도 한다[17]. 생성된 정책 모듈을semodule -i
로 삽입하면 특정 예외를 허용할 수 있다. 다만 이런 커스텀 정책 추가는 신중해야 하며, SELinux Booleans라 불리는 토글 옵션으로 해결 가능한 경우 (getsebool -a
로 확인) 우선 활용하는 것이 좋다. 예를 들어 Apache가 홈 디렉토리를 서비스하도록 허용하려면httpd_enable_homedirs
Boolean을 On으로 켜주면 별도 정책 추가 없이 허용된다.SELinux는 초반 학습 난이도가 있지만 일단 환경에 맞게 설정해두면 강력한 보안 장치를 제공하므로, 운영 중에는 Enforcing 모드 유지를 권장한다. SELinux 관련 문제 발생 시는 로그를 분석해 원인을 찾고, 공식 가이드나 커뮤니티 도움을 받아 올바른 해결책(정책 조정이나 Boolean 활용 등)을 적용하는 것이 바람직하다.
Hostname 및 네트워크 설정
호스트네임 설정 변경(Rocky Linux): 시스템의 호스트네임은
hostnamectl
명령으로 쉽게 변경할 수 있다. 예를 들어sudo hostnamectl set-hostname new-hostname
명령을 실행하면 영구적으로 호스트이름을 변경한다[18]. 이 명령은 시스템의 Static hostname (영구 호스트네임)을 설정하며, pretty-hostname이나 transient-hostname도 함께 갱신한다[18]. 변경 후 즉시hostnamectl status
로 새로운 호스트명이 반영됐는지 확인할 수 있다. 대부분의 현대 리눅스 배포판(Rocky Linux 포함)은hostnamectl
을 권장하는데, 이는/etc/hostname
파일을 직접 편집하는 것과 동일한 효과를 주며, 추가로 systemd의 hostnamed 서비스를 통해 즉각적인 적용을 도와준다[18]. 호스트네임을 바꾼 후에는 필요에 따라/etc/hosts
파일도 수정해야 한다. 예를 들어 기존 호스트네임이 localhosts에 등록되어 있었다면 새로운 이름으로 업데이트하여 로컬 이름 해석에 문제가 없도록 해야 한다./etc/hosts
와 로컬 이름 해석:/etc/hosts
파일은 호스트명과 IP 주소의 정적 매핑을 담고 있다. 시스템이 부팅될 때 또는 네트워크 초기화 시, DNS 서버를 조회하기 전에 우선/etc/hosts
를 참조하여 자주 사용하는 호스트들의 이름-주소 대응을 해석한다[19]. 예를 들어 인터넷에 나가기 전 자체적으로 알아야 할 루프백 주소localhost
등이 여기에 정의된다./etc/hosts
에 한 줄당<IP주소> <호스트이름> <별칭...>
형식으로 기재하며, 이 파일에 존재하는 이름은 DNS를 거치지 않고 해당 IP로 바로 해석된다[19]. 따라서 내부 네트워크에서만 통하는 독자적인 호스트명이나 DNS 서버 설정이 어려운 환경에서 로컬 hosts 파일을 이용해 간단히 이름 해결을 할 수 있다. 단, 이 파일은 모든 시스템에 개별적으로 관리되므로 호스트가 많아지면 일관성 유지가 어렵고, DNS를 대체하지는 못한다. Rocky Linux 기본 hosts에는 보통127.0.0.1 localhost
와127.0.1.1 <현재호스트명>
정도가 들어가 있으며, 필요시 여기에 추가 엔트리를 넣으면 된다. 예를 들어 사설망의 파일서버fileserver.local
이 192.168.1.10이면 각 서버의/etc/hosts
에192.168.1.10 fileserver.local fileserver
식으로 등록해 두면 DNS 없이 이름으로 접근할 수 있다./etc/resolv.conf
설정 이해:/etc/resolv.conf
파일은 DNS 클라이언트(리졸버)의 설정을 담고 있다[20]. 여기에는 시스템이 어떤 DNS 서버를 이용할지, 그리고 도메인 검색 순서를 어떻게 할지 등이 기록된다. 가장 흔한 지시어는nameserver
로, 뒤에 IP 주소를 지정하면 해당 IP의 DNS 서버를 조회하도록 설정하는 것이다[20]. 여러 개의 nameserver가 나열되어 있으면 첫 번째 응답이 없을 때 순차적으로 다음 서버를 사용한다. 또한search
지시어로 기본 검색 도메인을 지정할 수 있는데[20], 예를 들어search example.com mydomain.com
이라고 하면 호스트명을 질의할 때 순수 이름으로 질의가 실패하면호스트명.example.com
,호스트명.mydomain.com
순으로도 조회해보는 식이다. Rocky Linux에서는 이 파일을 수동 편집하기보다는 NetworkManager 등이 자동 생성하는 경우가 많다. DHCP를 통해 DNS 설정을 받으면/etc/resolv.conf
가 자동으로 업데이트되며, systemd-resolved를 사용하는 경우 이 파일이 심볼릭 링크로 대체되기도 한다[20]. 만약 수동으로 설정하려면 해당 파일에nameserver <DNS서버IP>
형식으로 원하는 DNS 서버를 넣고,options timeout:2 attempts:2
같은 옵션으로 타임아웃 등을 조절할 수 있다. 요약하면,/etc/resolv.conf
는 DNS 조회를 위한 설정 (DNS 서버 목록, 검색 도메인 등)을 담고 있으며, 네트워크가 정상 동작하려면 이 파일에 유효한 DNS 서버 주소(예: 8.8.8.8)가 포함되어 있어야 한다.네트워크 인터페이스와 방화벽의 관계: Rocky Linux의 기본 방화벽 데몬은 firewalld이며, 네트워크 인터페이스를 "Zone(영역)"이라는 개념으로 분리하여 관리한다. 방화벽 Zone이란 해당 영역에 속한 인터페이스에 적용할 일련의 규칙들의 집합으로, firewalld는 인터페이스별로 서로 다른 신뢰 수준과 규칙을 적용할 수 있게 한다[21]. 예를 들어 firewalld 기본 public 존은 신뢰도가 낮은 네트워크를 위한 규칙(최소한의 포트만 허용)이고, home 존은 비교적 신뢰할 수 있는 사설망을 위한 규칙(몇 가지 서비스 허용)으로 되어 있다. 각 네트워크 인터페이스(예:
eth0
,wlan0
)는 하나의 존에 할당되며, 그 인터페이스로 들어오고 나가는 패킷에는 해당 존의 방화벽 규칙이 적용된다[21]. 일반적으로 초기 상태에서는 모든 인터페이스가 기본 존(public)에 속하지만, 관리자는firewall-cmd --zone=<zone> --change-interface=<인터페이스>
명령 등을 통해 특정 인터페이스를 내부망용 internal 존이나 DMZ 존 등에 배치할 수 있다[21]. 이렇게 하면 예를 들어 두 개의 NIC가 있는 서버에서 하나는 외부망(인터넷)에 연결되어 external 존 규칙(매우 제한적 허용)으로 보호하고, 다른 하나는 내부망에 연결되어 internal 존 규칙(내부 서비스 허용)으로 동작하게 할 수 있다[21]. UFW를 사용하는 경우에도ufw allow in on eth0 to any port 80
등의 형태로 인터페이스별 규칙 지정이 가능하지만, firewalld의 존 개념이 보다 높은 추상화로 쓰인다. 요약하면 방화벽은 네트워크 인터페이스와 밀접한 관련이 있으며, 어떤 인터페이스를 어떤 보안영역으로 분류하느냐에 따라 허용/차단되는 트래픽이 달라진다.추가로, 네트워크 인터페이스 설정은 nmtui (텍스트 UI)나
nmcli
명령으로 IP, 게이트웨이, DNS 등을 관리할 수 있다. 인터페이스 설정 변경 후에는 해당 연결을 재시작해야 적용되며, 방화벽 존 변경 시에도--permanent
옵션 사용 시firewall-cmd --reload
를 해야 한다. 네트워크와 방화벽 설정은 유기적으로 동작하므로, 예를 들어 새로운 서비스 오픈 시 네트워크 인터페이스 IP 설정, DNS 설정(/etc/resolv.conf
), hosts, 방화벽 포트 허용 등을 종합적으로 고려하여 구성해야 한다.기본적인 서비스 관리(systemd, journald 등)
Systemd 개념과 주요 명령어: Rocky Linux를 포함한 최신 리눅스 배포판은 systemd를 init 시스템으로 사용한다. Systemd는 부팅 시 각종 시스템 서비스(데몬)들을 관리하고 의존성을 조정하는 동시에, 런레벨을 대체하는 target 개념을 통해 시스템 상태를 관리한다. Systemd의 관리 도구인
systemctl
은 전통적인 SysVinit의service
스크립트와chkconfig
기능을 통합한 주요 관리 명령어이다[22]. Systemd에서는 서비스, 소켓, 타이머 등 관리 대상들을 모두 "Unit"이라는 단위로 추상화하여 취급하며, 이들을 관리하는 표준 명령이systemctl
이다[22]. 자주 사용하는systemctl
서브커맨드는 다음과 같다[22,23].systemctl start <서비스>
: 지정한 서비스를 즉시 시작한다 (예:systemctl start sshd.service
로 SSH 데몬 시작)[22].systemctl stop <서비스>
: 서비스를 즉시 중지한다[22].systemctl restart <서비스>
: 서비스를 재시작(중지 후 즉시 시작)한다[22]. 변경된 설정을 반영하려면 보통 restart가 필요하다.systemctl reload <서비스>
: 서비스가 지원할 경우 설정 파일만 다시 불러오도록 요청한다[22]. (nginx
나httpd
등은 reload를 지원)systemctl status <서비스>
: 서비스의 현재 상태를 확인한다. (Active/running 여부, Main PID, 마지막 로그 메시지 등을 출력)[22].systemctl enable <서비스>
: 해당 서비스가 부팅 시 자동으로 시작되도록 설정한다[22]. 이 명령은/etc/systemd/system/
에 서비스의 .service 유닛에 대한 symbolic link를 생성하여 부팅 시 관련 target에서 이 서비스를 끌어올리도록 한다.systemctl disable <서비스>
: 서비스의 부팅 시 자동 시작을 해제한다[22]. (enable의 반대 동작)systemctl is-enabled <서비스>
: 해당 서비스의 부팅 자동실행 여부를 출력한다[22].systemctl list-units --type=service --state=running
: 현재 활성화되어 실행 중인 서비스들을 나열한다[22]. (모든 unit은list-units
, 설치된 모든 유닛 파일은list-unit-files
사용)systemctl daemon-reload
: 수동으로 유닛 파일을 수정한 경우 systemd에게 변경사항을 재인식시킨다.
이 외에도 systemd는 타이머 유닛(
.timer
를 이용한 cron 대체), 대상 유닛(.target
을 통한 runlevel 관리), 슬라이스(.slice
를 통한 cgroups 자원제한) 등 고급 기능을 제공한다. 예를 들어systemctl get-default
로 현재 기본 target (예: multi-user.target)을 확인하고,systemctl set-default graphical.target
으로 부팅시 GUI모드를 기본으로 설정할 수 있다[23]. 또한systemctl isolate rescue.target
으로 단일 사용자 모드(Rescue 모드)로 전환하는 등 런레벨 변경에 상응하는 명령도 사용할 수 있다[23].서비스 등록 및 관리: 새로운 서비스(Unit)을 등록하려면 일반적으로
/etc/systemd/system/
에 유닛 파일을 작성한 후systemctl daemon-reload
로 인식시킨다. 또는systemctl edit --full <서비스>
명령으로 사용자 정의 유닛을 작성할 수도 있다[22]. 서비스 유닛 파일에는[Unit]
(설명, 의존성 등),[Service]
(실행 명령, 실행 사용자, 리스타트 정책 등),[Install]
(WantedBy=로 어떤 target에서 활성화될지) 섹션 등이 포함된다. 예를 들어/etc/systemd/system/myapp.service
를 만들어 커스텀 애플리케이션을 등록하고systemctl enable myapp
하면 부팅 시 자동시작하게 할 수 있다.Systemd는 각 서비스의 의존 관계(dependency)를 관리하여 부팅 순서를 최적화한다. 가능한 한 병렬로 서비스를 올리되,
After=
나Requires=
지시어로 순서를 정의한 것은 지켜준다[22]. 또한 systemd는 서비스가 종료되었을 때 자동 재시작(Restart=
옵션) 같은 고급 기능,systemctl mask <서비스>
로 특정 서비스를 완전히 사용 불능 처리(mask)하는 기능도 제공한다[22]. Rocky Linux의 많은 핵심 서비스(sshd, crond, NetworkManager 등)들은 기본적으로 systemd 서비스로 동작하며, SysV init 스크립트 호환 레이어도 존재하므로service <name> start
같은 옛 명령도 내부적으로 systemd를 호출하여 동작한다.Journald를 이용한 로그 관리: Systemd에는 journald라는 자체 로그 데몬이 포함되어 있다.
systemd-journald
는 커널 메시지, 부팅 초기 메시지(initrd 단계), 표준 출력/에러로 출력되는 서비스 로그 등 모든 유형의 로그를 수집하여 중앙 집계한다[24]. Journald는 수집한 로그를 이진 포맷의 저널 파일로 저장하고 색인화하여 효율적인 조회를 지원한다[24]. 전통적인 rsyslog 텍스트 로그와 달리, journald는 구조화된 메타데이터(예: 어느 유닛에서 나온 로그인지 등)를 포함하기 때문에 특정 서비스나 시간 등으로 편리하게 필터링할 수 있다. Journald에 기록된 로그는journalctl
명령으로 조회한다[24].journalctl
: 시스템의 모든 저널 로그를 시간순으로 출력한다 (부팅 이후 로그).journalctl -u <서비스명>
: 특정 서비스(Unit)의 로그만 필터링해서 출력한다. 예를 들어journalctl -u sshd.service
로 SSH 데몬 관련 로그만 볼 수 있다[24].journalctl -f
: 실시간으로 로그 팔로우(tail) 한다. 새 로그가 생길 때 계속 화면에 출력하여 모니터링할 때 유용하다[24].journalctl -b
: 현재 부팅 이후의 로그만 표시한다. (시스템이 재부팅되었을 경우 이전 부팅의 로그와 구분)journalctl --since "2023-09-01 00:00:00" --until "2023-09-01 23:59:59"
: 지정한 시간 범위의 로그만 조회한다[24].journalctl -k
: 커널 메시지(dmesg) 로그만 출력한다.
이처럼 journalctl을 사용하면
/var/log/messages
등을 일일이 열어 grep하는 것보다 효율적으로 로그를 찾아볼 수 있다. 특히 서비스 이름 단위로 보는 기능은 운영상 매우 편리하다.Journald의 로그 저장 방식은 기본적으로 메모리 내지 임시파일(tmpfs)에 저장된다. Rocky Linux에서는 초기 설정상
/run/log/journal/
에 로그가 있으며, 이는 메모리에 존재하므로 재부팅 시 로그가 사라질 수 있다[25,26]. 로그를 디스크에 영구 보존하려면/etc/systemd/journald.conf
설정 파일에서Storage=persistent
로 변경하고/var/log/journal
디렉토리를 만들어줘야 한다[26]. 그렇게 설정하면 저널 로그가/var/log/journal/
아래 바이너리 파일로 저장되어 재부팅 후에도journalctl -b -1
등으로 이전 부팅 로그를 조회할 수 있다. Journald는 권한상 root 및systemd-journal
그룹만 로그를 읽을 수 있으므로, 필요한 경우 개발자 계정 등을systemd-journal
그룹에 추가하여 특정 서비스 로그를 보게 할 수도 있다.마지막으로 journald는 syslog와 통합되어 동작한다. 전통적인
/var/log/secure
,/var/log/messages
등은 rsyslog 서비스가 journald로부터 로그를 받아 별도로 남기는 것이며, journald 자체만으로 운영해도 무방하다. Rocky Linux 기본 설정에서는 journald와 rsyslog가 같이 동작하여 이중으로 로그를 기록하지만, 원하는 경우 rsyslog를 비활성화하고 journald만 사용해도 된다. journald 로그 확인은journalctl
이 표준 방법이며, 로그 파일을 직접 열어보는 방식은 사용하지 않는다.마치며
이상의 지식을 종합하면, Rocky Linux 환경에서 Born2beRoot 과제를 수행하기 위한 핵심 개념들은 LVM을 통한 유연한 디스크 관리, UFW로 대표되는 방화벽 사용, SSH 서비스 보안 강화, 관리자권한과 사용자 계정관리, SELinux 보안 정책 이해, 호스트네임/네트워크 기본 설정, 그리고 systemd 기반 서비스/로그 관리로 요약된다. 각각에 대해 공식 문서와 업계 표준을 참고하여 실습하면, 안전하고 효율적인 서버 구축이 가능할 것이다. 이 글을 보시는 미래의 카뎃들에게 도움이 많이 되었으면 좋겠다.
참고 문헌
[1] Configuring and managing logical volumes | Red Hat Product Documentation. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_logical_volumes/index
[2] 3.3.6. Snapshot Volumes | Red Hat Product Documentation. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/6/html/logical_volume_manager_administration/snapshot_volumes
[3] SLES 12 SP5 | Storage Administration Guide | LVM Volume Snapshots. https://documentation.suse.com/sles/12-SP5/html/SLES-all/cha-lvm-snapshots.html
[4] UFW - Community Help Wiki. https://help.ubuntu.com/community/UFW
[5] UFW Essentials: Common Firewall Rules and Commands | DigitalOcean. https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands
[6] sshd_config - How to Configure the OpenSSH Server? https://www.ssh.com/academy/ssh/sshd_config
[7] Configuring a Secure SSH Server on Rocky Linux - JumpCloud. https://jumpcloud.com/blog/how-to-configure-secure-ssh-server-rocky-linux
[8] Initial Steps to Secure Rocky Linux 8 | Vultr Docs. https://docs.vultr.com/initial-steps-to-secure-rocky-linux-8
[9] How To Protect SSH with Fail2Ban on Rocky Linux 8 | DigitalOcean. https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-rocky-linux-8
[10] CIQ | Installing fail2ban to Protect Rocky Linux from SSH Attacks. https://ciq.com/blog/installing-fail2ban-to-protect-rocky-linux-from-ssh-attacks
[11] How to enable sudo on Red Hat Enterprise Linux | Red Hat Developer. https://developers.redhat.com/blog/2018/08/15/how-to-enable-sudo-on-rhel
[12] Chapter 11. Managing sudo access | Red Hat Product Documentation. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-sudo-access_configuring-basic-system-settings
[13] How to enhance Linux user security with Pluggable Authentication Module settings. https://www.redhat.com/en/blog/linux-security-pam
[14] How to set user password expirations on Linux. https://www.redhat.com/en/blog/password-expiration-date-linux
[15] How to read and correct SELinux denial messages. https://www.redhat.com/en/blog/selinux-denial2
[16] HowTos/SELinux. https://wiki.centos.org/HowTos/SELinux
[17] Troubleshooting SELinux - SUSE Documentation. https://documentation.suse.com/en-us/sle-micro/6.0/html/Micro-setroubleshoot/index.html
[18] Chapter 18. Changing a hostname | Red Hat Product Documentation. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/assembly_changing-a-hostname_configuring-and-managing-networking
[19] The /etc/hosts file. https://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap9sec95.html
[20] resolv.conf - Wikipedia. https://en.wikipedia.org/wiki/Resolv.conf
[21] CIQ | How to Manage Firewall Zones in Rocky Linux. https://ciq.com/blog/how-to-manage-firewall-zones-in-rocky-linux
[22] About systemd - Documentation. https://docs.rockylinux.org/books/admin_guide/16-about-sytemd/
[23] System Startup - Documentation. https://docs.rockylinux.org/zh/books/admin_guide/10-boot/
[24] Enabling and Using Journald for System Logging on Rocky Linux 9 | Reintech media. https://reintech.io/blog/enabling-using-journald-system-logging-rocky-linux
[25] System Journal messages on console - Rocky Linux Help & Support. https://forums.rockylinux.org/t/system-journal-messages-on-console/11968
[26] Where is "journalctl" data stored? - Ask Ubuntu. https://askubuntu.com/questions/864722/where-is-journalctl-data-stored
728x90728x90'프로그래밍 > 42 Gyeongsan' 카테고리의 다른 글
ft_printf - ft_putnbr()과 ft_putstr()만으로는 충분하지 않기 때문에 (0) 2025.07.20 Get Next Line - 한 줄씩 읽는 것은 너무 지루하다 (0) 2025.03.16 Libft - 나만의 첫 번째 라이브러리 (0) 2025.03.12 다음글이 없습니다.이전글이 없습니다.댓글