Profile picture

[Linux] RHCSA v9 취득을 위한 문제 풀이 정리 #2

JaehyoJJAng2025년 10월 20일

24. 웹 서버 설치 및 설정 (Apache)

문제 1: 서버 A에서 다음 작업을 수행하세요.

  • 기본 웹 서버를 설정하여 접속 시 Welcome to the webserver! 라는 메시지를 표시하도록 구성합니다.
  • 방화벽(firewall) 설정을 수정하여 HTTP(포트 80)와 HTTPS(포트 443) 서비스를 허용합니다.

Apache 설치

dnf install -y httpd

부팅 시 Apache 자동 시작 설정

systemctl enable --now httpd

기본 Document root 디렉토리 찾기

grep -i "docu" /etc/httpd/conf/httpd.conf

# 출력 값
DocumentRoot "/var/www/html" # 기본 document root 경로

환영 메시지 포함한 웹 페이지 생성하기

cd /var/www/html
vim /index.html

환영 메시지 추가

Welcome to the webserver!

저장 및 종료: Esc -> :wq -> Enter


apache 재시작

systemctl restart httpd

방화벽 설정

HTTP 및 HTTPS 서비스를 허용해주겠습니다.

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload
  • --zone=public: 기본 공개 영역(public zone)에 규칙을 적용합니다.
  • --add-service=http: HTTP(포트 80) 트래픽 허용
  • --add-service=https: HTTPS(포트 443) 트래픽 허용
  • --permanent: 재부팅 후에도 설정이 유지되도록 영구 적용

웹 서버 테스트

로컬 테스트

curl http://localhost

외부 테스트

웹 브라우저 열고 다음 주소 입력

http://<ServerA_IP_ADDRESS>

25. 파일 찾기 2 (find)

문제 1: /etc 디렉터리 내에서 3MB보다 큰 모든 파일을 찾아, 새로운 디렉터리 /find/3mfiles로 복사하세요.


찾은 파일들을 모아둘 대상 디렉토리 생성하기

mkdir -p /find/3mfiles

3MB 초과 파일 찾기 및 복사

sudo find /etc -size +3M -exec cp {} /find/3mfiles \;

복사된 파일 확인

ls -lh /find/3mfiles

# 출력 값
-r--r--r--. 1 root root  13M 11116:34 hwdb.bin
-rw-r--r--. 1 root root 3.2M 11116:34 policy.34

26. GRUB 부팅 메시지 설정

문제 1: 서버 A에서 부팅 메시지가 숨겨지지 않고 표시되도록 설정하여, 문제 해결(troubleshooting) 시 부팅 과정을 확인할 수 있도록 하세요.


방법 1: GRUB 설정 파일 직접 수정 (영구 적용)

해당 방법은 /etc/default/grub 파일을 수정하여 모든 부팅에 영구적으로 적용하는 방법입니다.


grub 설정 편집

sudo vim /etc/default/grub

시스템이 어떻게 부팅되어야 하는지 제어하는 부팅 매개변수가 포함된 전역 GRUB 설정 파일을 엽니다.


부팅 매개변수 수정

  • GRUB_CMDLINE_LINUX로 시작하는 줄을 찾아서 rhgb quiet을 제거합니다.
    • rhgb (Red Hat Graphical Boot): 상세한 부팅 메시지를 숨기고 그래픽 부팅 화면을 제공합니다.
    • quiet: 대부분의 부팅 메시지를 숨겨 깔끔한 화면을 만듦
  • 이 두 옵션 제거 시 텍스트 기반 부팅 메시지가 활성화되어 문제 해결에 용이함.

업데이트된 GRUB 설정 생성

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

이 명령은 변경 사항을 부트로더에 적용하기 위해 GRUB 설정을 다시 생성 합니다.


시스템 재부팅

sudo reboot

시스템을 다시 시작하여 업데이트된 GRUB 설정을 적용합니다.


방법 2: 커널 명령줄 직접 업데이트 (현재 커널에만 적용)

이 방법은 grubby 명령어를 사용하여 현재 사용 중인 커널에만 변경 사항을 적용합니다.


커널 명령줄 수정

sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --remove-args="rhgb quiet"
  • grubby 명령은 /etc/default/grub 파일을 수정하지 않고도 현재 커널의 부팅 매개변수를 업데이트합니다. 이 변경 사항은 다음 재부팅 시 적용됩니다.
  • --update-kernel=/boot/vmlinuz-$(uname -r): 현재 사용 중인 커널 버전을 지정합니다.
  • --remove-args="rhgb quiet": rhgb와 quiet 인수를 제거하여 상세한 부팅 메시지를 활성화합니다.

시스템 재부팅

sudo reboot

27. bash 스크립트

문제 1: 서버 A에서 다음 작업을 수행하세요.

/script.sh라는 Bash 스크립트를 생성하고, 이 스크립트가 두 개의 인자(argument) 로 실행될 때

첫 번째 인자 뒤에 두 번째 인자를 출력하는 것이 아니라, 두 번째 인자 다음에 첫 번째 인자를 출력하도록 하세요.


예를 들어, 다음과 같이 실행 시

./script.sh test1 test2

출력 결과는 다음과 같아야 합니다.

test2 test1

스크립트 파일 생성

vim /script.sh

다음 스크립트 작성

#!/usr/bin/bash

# 파일에 들어온 매개변수 체크
if [ $# -eq 2 ]; then
  echo "$2 $1"
else
  echo "Usage: $0 argument1 argument2"
  exit 1
fi
  • if [ $# -eq 2 ]; then: 정확히 두 개의 인수가 제공되었는지 확인합니다. $#는 전달된 인수의 개수를 나타내는 특수 변수입니다.
  • echo "$2 $1": 두 개의 인수가 제공되었다면, 이 줄은 두 번째 인수($2) 다음에 첫 번째 인수($1) 를 공백으로 구분하여 출력합니다. (인수 순서를 뒤집어 출력)

스크립트 테스트

chmod u+x ./script.sh
bash ./script.sh argument1 argument2

# 출력 값
argument2 argument1

28. 비밀번호 유효기간 설정

문제 1: 서버 A에서 모든 사용자 비밀번호에 대해 다음 정책을 적용하세요.

  • 비밀번호 유효기간을 90일로 설정하여, 90일이 지나면 비밀번호를 반드시 변경하도록 합니다.
  • 비밀번호 최소 길이를 8자 이상으로 설정합니다.

1. 시스템 전반의 로그인 설정 파일 편집

sudo vim /etc/login.defs

암호 만료를 포함하여 시스템 전반의 로그인 정책이 구성되는 파일인 /etc/login.defs를 엽니다.


PASS_MAX_DAYS 구성

vim 내에서 PASS_MAX_DAYS 줄을 찾거나 없으면 추가합니다.

PASS_MAX_DAYS 90

PASS_MAX_DAYS를 90으로 설정하면 90일 암호 만료 정책이 적용되어, 사용자들은 약 3개월마다 암호를 업데이트해야 합니다.


2. 최소 암호 길이 8자로 설정


암호 품질 구성 파일 열기

sudo vim /etc/security/pwquality.conf

이 파일은 /libpwquality 라이브러리에 의해 관리되며, RHEL 9에서 암호 복잡성과 길이 요구사항을 담당합니다.


minlen 구성

vim 내에서 minlen 줄을 찾거나 없으면 추가합니다.

minlen = 8

이는 모든 새 암호 및 업데이트된 암호에 대해 최소 길이 8자 를 강제하여, 약한 암호의 가능성을 줄여 보안을 강화합니다.


29. 파일 소유권 설정 (sticky bit)

문제 1: 서버 A에서 다음 조건에 맞게 사용자, 그룹, 디렉터리 및 권한을 설정하세요

사용자 및 그룹 구성

  • 그룹
    • admins
    • developers
  • 사용자
    • amr, biko -> admins 그룹 구성원
    • carlos, david -> developers 그룹 구성원

디렉터리 구성

  • /admins
    • 소유자(owner): biko
    • 그룹: admins
    • 접근 권한: 오직 소유자와 admins 그룹 구성원만 접근 가능
  • /developers
    • 소유자(owner): carlos
    • 그룹: developers
    • 접근 권한: 오직 developers 그룹 구성원만 접근 가능

파일 소유권 및 권한 요구사항

  • /admins/developers 디렉터리 내에서 새로 생성되는 파일은 해당 디렉터리의 그룹 소유권을 자동으로 상속받아야 함.
  • 파일 생성자만 자신의 파일을 삭제할 수 있어야 함.


단계 1: 사용자 및 그룹 생성

그룹 생성하기

sudo groupadd admins
sudo groupadd developers

adminsdevelopers 그룹을 생성하여, 특정 권한을 가진 사용자들을 조직화할 겁니다.


사용자 생성 및 그룹 추가

useradd amr && usermod -aG admins amr
useradd biko && usermod -aG admins biko
useradd carlos && usermod -aG developers carlos
useradd david && usermod -aG developers david

각 사용자를 생성하고 적절한 그룹에 추가합니다.


단계 2: 디렉토리 생성 및 구성

디렉토리 생성

mkdir -p /{admins,developers}

그룹별 리소스를 분리하기 위해서 /admins/developers 디렉터리를 생성합니다.


/admins에 대한 소유권 설정하기

디렉토리 소유권 설정

chown biko:admins /admins

디렉토리 접근 권한 설정

chmod 770 /admin

소유자와 그룹에게는 읽기, 쓰기, 실행 권한을 부여하고, 다른 사용자(other)에게는 모든 접근을 차단합니다.


/admins에 대한 sticky bit 설정하기

chmod -t,g+s /admins
  • chmod g+s: Setgid 비트를 활성화하여, 이 디렉토리에 생성되는 파일들이 admins 그룹 소유권을 상속받도록 보장합니다.
  • chmod -t: Sticky 비트를 설정하여, /admins 디렉토리 내에서 파일 생성자(또는 root)만이 파일을 삭제할 수 있도록 제한합니다.

/developers에 대한 소유권 설정하기

디렉토리 소유권 설정

chown carlos:developers /developers

디렉토리 접근 권한 설정

chmod 770 /developers

소유자와 그룹에게는 접근 권한을 제공하고, 다른 사용자들은 제외합니다.


/developers에 대한 sticky bit 설정하기

chmod +t,g+s /developers

단계 3: 테스트 (검증)

ls -ld /admins /developers

# 출력 값
drwxrws--T. 2 biko   admins     6 11117:35 /admins
drwxrws--T. 2 carlos developers 6 11117:30 /developers
  • rwxrws--T: 소유자 및 그룹에 대한 읽기, 쓰기, 실행 권한이 부여되었음을 확인합니다.
  • s: Setgid 비트가 설정되었음을 확인하고, T는 Sticky 비트가 설정되었음을 보여줍니다.

30. cron job 설정

문제 1: 서버 A에서 다음 작업을 수행하세요.

매주 평일(월~금) 정오 12시(12 PM)에 시스템 로그 파일 /var/lob/messagesGet Ready! 라는 메시지를 기록하도록

cron 작업을 설정하세요.


또한 이 작업은 적절한 권한으로 실행되어야 하며,

문제 발생 시 추적이 가능하도록 로그 기록이 남도록 구성해야 합니다.


단계 1: root crontab 접근

sudo crontab -e

root 사용자의 크론탭 파일을 엽니다. 이를 통해 /var/log/messages에 기록하는 데 필수적인 root 권한으로 작업 예약이 가능합니다.


단계 2: 메시지를 기록하는 Cron 작업 추가

작업 예약을 위해 crontab에 다음 줄 추가

* 12 * * 1-5 /usr/bin/logger -t "GetReadyCron" "Get Ready!" 2>&1 | tee -a /tmp/cron_jobs.log
  • 2>&1: 표준 출력(Standard Output)과 표준 오류(Standard Error)를 단일 스트림으로 리다이렉션(redirection)합니다.

단계 3: Cron 작업 확인

  • Esc를 누르고 :wq를 입력한 후 Enter를 누릅니다.
  • 예약된 cron 작업 목록이 정상적인지 확인합니다.
    • sudo crontab -l


31. tar 아카이브 파일 생성

문제 1: 요구사항에 맞는 tar 아카이브 파일을 생성하세요

서버 A에서 /usr/local 디렉터리와 그 안의 모든 내용을 포함하는 압축된 tar 아카이브 파일을 생성하세요.

아카이브 파일의 이름은 /root/local.tgz로 하며, 적절한 권한이 설정되어 있고, 생성된 아카이브의 무결성을 검증해야 합니다.


1. 압축된 아카이브 생성

sudo tar -cvzf /root/local.tgz /usr/local
  • c: 새로운 아카이브 생성
  • v: 처리되는 파일들 상세 표시하는 Verbose mode
  • z: 효율적인 저장을 위한 gzip 압축
  • f: 출력 파일 지정

2. 아카이브 무결성 확인

sudo gzip -t /root/local.tgz

.tgz 파일의 무결성을 검사하여 오류나 손상이 없는지 확인.


3. 아카이브 권한 확인

ls -l /root/local.tgz

아카이브 파일의 소유권 및 권한 확인.


32. 스왑 파티션 생성

문제 1: 다음 요구사항에 맞게 스왑 파티션을 생성하세요.

서버 A에서 /dev/sdb를 사용하여 200MB 크기의 스왑 파티션 을 생성하세요.

이 스왑 영역은 시스템 부팅 시 자동으로 활성화되도록 설정해야 합니다.


1. /dev/sdb에서 새 파티션 생성

fdisk /dev/sdb

# 파티션 생성 과정은 생략 ...
# n -> p -> 2 (파티션 번호) -> Enter -> +200M 파티션 크기 지정

2. 파티션 유형 변경 (스왑)

fdisk /dev/sdb

# t -> 2 (파티션 번호) -> 82 (스왑 타입 번호)

3. 커널 파티션 정보 업데이트

sudo partprobe /dev/sdb

커널에 새 파티션 테이블 알림으로써 재부팅 없이 즉시 접근할 수 있도록 함.


4. 파티션을 스왑으로 포맷

sudo mkswap /dev/sdb2

/dev/sdb1를 스왑 공간으로 포맷하여 활성화 준비


5. fstab 구성을 위한 UUID 가져오기

sudo blkid /dev/sdb2

새 스왑 파티션의 고유 식별자(UUID)를 검색하여, 부팅 시 자동 마운트를 위한 일관성 보장


6. /etc/fstab에서 자동 마운트 설정

sudo vim /etc/fstab

UUID=... swap  swap  defaults 0 0

7. 스왑 파티션 활성화

sudo swapon /dev/sdb2

8. 검증

free -m

33. root ssh no password

문제 1: 서버 A에서 서버 B의 root 계정으로 비밀번호 없이 SSH 원격 접속이 가능하도록 설정하세요.


1. OpenSSH 설치 및 상태 확인

dnf install -y openssh-server
systemctl enable --now sshd

2. ServerB에서 Root 로그인 허용

# SSH 설정 편집
vim /etc/ssh/sshd_config

# PermitRootLogin을 yes로 설정
PermitRootLogin yes
:wq # 저장하고 나오기

# 적용 위해 SSH 재시작
systemctl restart sshd

3. 서버 A에서 SSH 키 생성

openssh client 설치 (원격 ssh 연결에 필요한 ssh-keygenssh-copy-id와 같은 도구 포함)

dnf install -y openssh-client

4. 서버 A에서 SSH 키 쌍 생성

ssh-keygen -t rsa -b 4096

새로운 SSH 키 쌍을 생성


5. 공개 키를 서버 B로 복사

ssh-copy-id root@ServerB

이 명령은 서버 A의 공개 키를 서버 B의 Root 계정의 ~/.ssh/authorized_keys 파일로 복사하여, Root의 암호 없는 접근을 허용합니다.


34. SSH 로그인 시도 횟수 설정

문제 1: 서버 A에서 SSH 로그인 시도 횟수의 최대값을 2회로 설정하시오.


1. SSH 설정 파일 편집

vim /etc/ssh/sshd_config

이 파일에서 인증 및 보안 관련 설정 수정이 가능합니다.


2. MaxAuthTries 매개변수 설정

# MaxAuthTries 매개변수 값을 2로 변경
MaxAuthTries 2

SSH를 통해 허용되는 연속적인 로그인 실패 시도 횟수를 2회로 제한하며, 2회를 초과하면 클라이언트 연결을 끊습니다.


3. SSH 서비스 재시작

systemctl restart sshd

35. Rootless Quadlet 기반 Redis (Podman)

💡 참고: Quadlet 기능은 RHEL 9.2 이상 버전에서 사용 가능한 최신 표준입니다.

만약 실습 환경이 RHEL 9 초기 버전이라면, “Alternative Method” 섹션에 있는 podman generate systemd 방식을 사용해야 합니다.


문제 1: 서버 A에서 rootless systemd 서비스로 관리되는 redis 컨테이너를 구성하세요. 이 서비스는 Quadlet을 사용하여 선언적으로 정의되어야 합니다.


  • Quadlet 파일 경로
    • ~/.config/containers/systemd/redis.container
  • Quadlet 파일 내용 요건
    • containerNameredis로 설정할 것
    • 이미지: docker.io/library/redis를 사용하고, 로컬에서는 localhost/myredis로 태깅할 것
    • 호스트 포트 6379를 컨테이너 포트 6379에 매핑할 것
    • 사용자의 홈 디렉토리에 redis-data라는 디렉토리를 생성하고, 이를 컨테이너의 /data 경로에 영구 볼륨으로 마운트할 것
    • 컨테이너 실패 시 자동으로 재시작되도록 설정할 것
  • 사용자 세션은 linger(지속 실행) 모드로 설정되어야 함
    • loginctl enable-linger <username>
  • SELinux는 Enforcing 모드로 유지해야 함.
    • 만약 접근 거부(denial)가 발생한다면, 적절한 SELinux boolean을 영구적으로 설정하여 해결해야 한다.

1. 필수 도구 설치

sudo dnf install -y podman skopeo

podman 및 skopeo (컨테이너 이미지 관리 도구)를 설치합니다.


Redis 이미지 풀(Pull) 및 태그 지정

podman pull docker.io/library/redis
podman tag docker.io/library/redis localhost/myredis

Docker hub에서 공식 redis 이미지를 가져와서 localhost/myredis 라는 이름의 이미지로 태깅합니다.


영구 볼륨을 위한 호스트 디렉토리 생성

mkdir -p ~/redis-data

Redis 데이터가 컨테이너가 재시작되어도 유지되도록 ~/redis-data 디렉토리를 생성합니다.


2. 시스템 필수 조건 구성

현재 사용자에 대한 링거링(Lingering) 활성화

sudo loginctl enable-linger $(whoami)

링거링을 활성화하여 현재 사용자가 로그아웃한 후에도 사용자 세션의 시스템드 서비스(예: 컨테이너)가 계속 실행되도록 합니다.


필수 SELinux Bool 영구 설정

sudo setsebool -P container_manage_cgroup on

컨테이너가 cgroup을 관리할 수 있도록 SELinux 부울 값을 영구적(-P)으로 설정합니다.


3. Quadlet 유닛 파일 생성

사용자 Quadlet 파일 디렉토리가 존재하는지 확인

mkdir -p ~/.config/containers/systemd

Quadlet .container 파일 생성 (절대 경로 사용)

cat <<EOF > ~/.config/containers/systemd/redis.container
[Unit]
Description=Redis Quadlet Container

[Container]
ContainerName=redis
Image=localhost/myredis
PublishPort=6379:6379
Volume=$HOME/redis-data:/data:Z

[Service]
Restart=always

[Install]
WantedBy=default.target
EOF

4. 서비스 활성화 및 검증

Quadlet 파일로부터 서비스를 생성하기 위해 systemd 데몬 리로드

systemctl --user daemon-reload

문제 해결 참고: "Unit file redis.service does not exist"

위 오류가 발생하면 Quadlet 생성기가 시스템에 올바르게 등록되지 않은 것입니다.

  1. 실행 파일 존재 여부 확인: ls /usr/libexec/podman/quadlet
  2. 누락된 링크 생성: `sudo ln -s /usr/libexec/pdoman/quadlet /usr/lib/systemd/system-generators/
  3. 두 데몬 모두 재로드: sudo systemctl daemon-reload 실행 후 systemctl --user daemon-reload를 실행
  4. 로그인 시 시작하도록 서비스 활성화 및 즉시 시작: systemctl --user enable --now redis.service
  5. 서비스 및 컨테이너가 올바르게 실행 중인지 확인
    1. systemctl --user status redis.service
    2. podman ps | grep redis

정리 (선택 사항)

# 서비스 중지 및 로그인 시 시작 비활성화
systemctl --user disable --now redis.service

# 컨테이너, Quadlet 파일 및 데이터 디렉터리 제거
podman rm -f redis
rm -f ~/.config/containers/systemd/redis.container
sudo rm -rf ~/redis-data

36. 쉘 스크립트 작성

문제 1: 서버 A에서 /etc/passwd 파일로부터 사용자 이름과 해당 기본 그룹 이름을 추출하여 명확하게 출력하는 간결하고 효율적인 셸 스크립트를 /names.sh라는 이름으로 작성히세요.

  • 잘 정리된 형식 갖출 것.
  • 쉘 스크립트 작성의 모범 사례(best practice)를 따를 것
  • 이해를 돕는 주석 포함할 것

1. /names.sh 스크립트 생성

vim /names.sh

<br.

2. 스크립트 작성

#!/usr/bin/bash


cut -d: -f1,4 /etc/passwd \
        | while IFS=: read user group_id; \
        do \
                group_name=$(getent group "$group_id" | cut -d: -f1); echo "$user : $group_name"; \
        done

2. 스크립트 실행 권한 부여

chmod u+x /names.sh

3. 스크립트 실행

bash /names.sh

# 출력 값

root : root
bin : bin
...
...

문제 2: ServerA에서 /etc/passwd 파일을 참고하여 사용자 이름(username)과 해당 사용자의 로그인 쉘(login shell) 목록을 생성하는 스크립트를 /users_shells.sh 라는 이름으로 작성하세요.


1. /users_shells.sh 스크립트 생성

vim users_shells.sh

2. 스크립트 작성

#!/usr/bin/bash

cut -d: -f 1,7 /etc/passwd

3. 스크립트 실행

chmod u+x users_shells.sh
bash users_shells.sh

# 출력 값

root:/bin/bash
daemon:/usr/sbin/nologin
bin:/usr/sbin/nologin
sys:/usr/sbin/nologin
sync:/bin/sync
...
...

문제 3: ServerA에서 /home 디렉터리 및 그 하위 디렉터리 내에서, 첫 번째 인자로 전달된 패턴과 일치하는 일반 파일(regular file) 의 개수를 세는 쉘 스크립트를 작성하세요.

  • 스크립트의 이름은 /find.sh 여야 하며, 오류 처리(error handling) 와 안내 메시지(informative output)를 포함하고, 사용성과 안정성 측면에서 모범 사례(best practices)를 따르도록 작성해야 합니다.

1. /find.sh 스크립트 생성

vim /find.sh

2. 스크립트 작성

#!/usr/bin/bash


if [ -z $1 ];then
        echo "Error: 인자 1개 필수"
        exit 1
fi

if [ ! -d /home ]; then
        echo "Error: /home 디렉토리 없음"
        exit 1
fi

find /home -type f -name "$1" 2>/dev/null | wc -l

3. 스크립트 실행

chmod u+x /find.sh
bash /find.sh *.txt

# 출력 값
16

문제 4: ServerA에서 /trim.sh 라는 이름의 다목적이고 안내 메시지가 포함된 쉘 스크립트를 작성하세요.

  • 이 스크립트는 입력으로 전달된 각 인자(argument) 에서 모음 문자 "a", "i", "e", "o", "u" 를 모두 제거해야 합니다.

1. 스크립트 작성

#!/usr/bin/bash


if [[ $# -eq 0 ]]; then
        echo "하나 이상의 인자 입력"
        exit 1
fi

for arg in "$@"; do
        trimmed="$(echo $arg | tr -d 'aeiou')"
        echo $trimmed
done

2. 스크립트 실행

chmod u+x trim.sh
bash trim.sh "Hello World"

# 출력 값
Hll Wrld

37. MBR 백업파일 생성

문제 1: ServerA의 /dev/sda디스크에 위치한 MBR(Master Boot Record)을 적절한 명령어를 사용하여서 백업 파일로 생성하세요.

  • 백업 파일은 /backup/mbr.img로 저장해야 하며, 다음 조건을 충족해야 합니다.
    • 블록 크기 (Block size): 512 byte
    • 블록 개수 (Number of Blocks): 1
    • 검증: 백업이 정상적으로 생성되었는지 확인

1. 백업 디렉토리 생성

mkdir -p /backup

2. MBR 백업 수행

sudo dd if=/dev/sdb of=/backup/mbr.img bs=512 count=1 status=progress
  • if=/dev/sda: 입력 파일을 지정합니다. MBR이 위치한 첫 번째 하드 디스크 전체를 의미합니다.
  • of=/backup/mbr.img: 출력 파일을 지정합니다. MBR 백업이 저장될 위치입니다.
  • bs=512: 블록 크기를 MBR의 정확한 크기와 일치하는 512바이트로 설정합니다.
  • count=1: MBR 전체를 캡처하기에 충분한 1개의 블록만 복사하며, 디스크의 추가 데이터를 복사하지 않습니다.
  • status=progress: 백업 진행 상황을 표시하여, 명령어의 작동 상태를 볼 수 있게 합니다.

3. MBR 백업에 대한 보안 권한 설정

sudo chmod 600 /backup/mbr.img

600 권한을 사용하는가?

  • 권한을 600으로 설정 시, 소유자(root)만이 백업 파일을 읽고 쓸 수 있음.

4. 백업 생성 확인

ls -l /backup/mbr.img

38. Autofs 설정 (2)


문제 1: ServerA에서 사용자 Tom과 Sam의 홈 디렉토리를 ServerB로부터 NFS를 통해 자동 마운트되도록 구성하세요.

ServerB에서 해당 사용자들의 홈 디렉토리는 각각 /home/tom, /home/sam에 위치하며, 사용자 ID는 Tom:1010, Sam:1020입니다.


ServerA에서는 이 디렉토리들이 로컬의 /home 디렉토리 아래에 마운트되도록 설정해야 하며,

읽기/쓰기 권한이 가능해야 하고, 시스템 자원을 효율적으로 사용하며,

사용자가 자연스럽게 사용할 수 있도록 원활한 마운트가 이루어져야 합니다.


1. ServerB를 NFS로 설정하기

ServerB를 NFS 서버로 구성하는 과정은 일반적으로 RHCSA 범위에 포함되어 있지 않지만,

실습 환경을 동일하게 구성하기 위해서 다음과 같이 NFS를 설정해보도록 하겠습니다.


nfs 관련 패키지 설치 및 서비스 시작

dnf install -y nfs-utils
systemctl enable --now nfs-server rpcbind

방화벽 설정하기

firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload

Tom과 Sam 계정 생성하기 (UID 지정)

useradd -m -s /bin/bash -u 1010
useradd -m -s /bin/bash -u 1020
  • -m: 유저가 생성될 때 유저명에 맞는 홈 디렉토리 자동 생성
  • -s /bin/bash: 유저 기본 쉘 지정
  • -u: 유저 UID 지정

NFS 공유 디렉토리 설정

/etc/exports 파일에 다음 내용을 추가하겠습니다.

/home/tom 192.168.219.102(rw,sync,no_root_squash)
/home/sam 192.168.219.102(rw,sync,no_root_squash)
  • 192.168.219.102: ServerA IP
  • rw: 읽기/쓰기 허용
  • sync: 데이터가 디스크에 기록된 후 응답
  • no_root_squash: ServerA의 root 계정도 root 권한 유지.

공유 설정 적용

exportfs -arv

공유 내역 확인

# showmount -e ServerB
$ showmount -e localhost

Export list for localhost:
/home/sam 192.168.219.102
/home/tom 192.168.219.102

2. ServerA에서 Autofs 구성하여 자동 마운트 설정하기

ServerA에서 autofs를 사용하면,

사용자가 디렉토리를 실제로 접근할 때만 NFS 마운트가 이루어져 시스템 자원을 효율적으로 사용할 수 있게 된다.


필요한 패키지 설치

dnf install -y nfs-utils autofs

ServerA에 사용자 계정 생성

useradd -M -u 1010 tom
useradd -M -u 1020 sam
  • -M: 로컬 홈 디렉토리를 생성하지 않는다.
  • -> Tom과 Sam의 홈 디렉토리는 NFS로 가져올 것이므로 서버에 생성할 필요 없음.

중요!!

UID(1010, 1020)는 ServerB와 반드시 동일해야 권한 문제가 발생하지 않는다.


autofs 구성하기

/etc/auto.master 편집

vim /etc/auto.master

# 아래와 같이 입력
/home /etc/auto.home --timeout=60

/etc/auto.home 파일 생성

vim /etc/auto.home

# 아래와 같이 입력
# * -fstype=nfs,rw,sync ServerB:/home/&
* -fstype=nfs,rw,sync 192.168.219.199:/home/&
  • 192.168.219.199: ServerB IP
  • *: 와일드카드로 어떤 사용자 이름이든 자동 매칭
  • ServerB:/home/&: &가 자동으로 사용자명(tom,sam)으로 변환됨.
  • -> 즉 사용자가 tom이면 자동으로 -> ServerB:/home/tom 마운트

autofs 서비스 활성화 및 시작

systemctl restart autofs
systemctl enable --now autofs

동작 테스트

  • ServerA에서 테스트

tom 사용자로 전환

$ su - tom
$ ls -l /home
$ pwd # /home/tom이 출력되어야 함

39. podman - apache 컨테이너 생성

문제 1: 아래 요구사항에 맞춰서 Apache 컨테이너를 생성하세요.

ServerA에서 사용자 sam으로 작업하여 다음 조건을 만족하는 영구적(persistent)이고 루트 권한을 사용하지 않는(rootless) Apache HTTP 웹 서버 컨테이너를 생성하세요.


컨테이너 이미지는 registry.redhat.io 레지스트리에서 가져오며, 보안성과 효율성 측면의 모범 사례를 준수해야 합니다.


구성 조건은 다음과 같습니다.

  • 컨테이너 태그
    • httpd-24
  • 컨테이너 이름
    • httpd
  • 레지스트리 인증 정보
    • 사용자 이름: admin
    • 비밀번호: administrator
  • 영구 저장소
    • 호스트의 ~/www-data/ 디렉토리를 컨테이너 내부의 /var/www/html 경로에 마운트할 것
  • 초기 웹 콘텐츠
    • ~/www-data/ 디렉토리에 index.html 파일 생성
    • 파일 내용: Hello World!
  • 포트 매핑
    • 호스트 8080 -> 컨테이너 8080
  • 환경 변수 설정
    • HTTPD_USER=test
    • HTTPD_PASSWORD=test
  • systemd 관리
    • systemd를 사용하여 컨테이너가 지속적으로 동작하고, 자동으로 시작하도록 구성할 것.

1. 컨테이너 도구 설치 확인

컨테이너를 관리하기 위해 필요한 도구들이 설치되어 있는지 확인합시다.

dnf install -y container-tools

2. sam 사용자 생성

시스템에 sam 사용자가 없는 경우 아래와 같이 게정을 생성하고 비밀번호를 설정합니다.

useradd -m -s /bin/bash sam
passwd sam

3. sam 사용자 전환

컨테이너 설정 작업은 sam 사용자로 진행해야 합니다.

ssh sam@localhost

4. 이미지 레지스트리 로그인

제공된 계정 정보로 Red Hat 레지스트리에 인증합니다.
(실습 환경의 경우 Red Hat 레지스트리 인증에 어려움이 있으므로, Docker hub 레지스트리로 대체합니다.)

podman login https://registry.hub.docker.com
Username: admin
Password: administrator

5. Apache HTTP 이미지 다운로드

먼저 apache 관련 컨테이너 이미지를 검색해봅니다.

$ podman search httpd
NAME                                                                DESCRIPTION
registry.redhat.io/ubi8/httpd-24                                    Platform for running Apache httpd 2.4 or bui...
registry.redhat.io/rhel9/httpd-24                                   Platform for running Apache httpd 2.4 or bui...
registry.redhat.io/ubi9/httpd-24                                    Platform for running Apache httpd 2.4 or bui...

요구사항대로 라면 registry.redhat.io/rhel9/httpd-24 요 이미지를 다운로드해야 합니다.


그러나 저는 registry.redhat.com가 아닌 registry.docker.hub로 로그인하였으므로 도커 허브 이미지를 찾아봐야 합니다.

docker.io/library/httpd                                             The Apache HTTP Server Project

요 이미지로 다운로드 해보겠습니다.


docker.io/library/httpd 이미지를 도커 레지스트리에서 가져옵시다.

(실제 시험환경에서는 요구사항에 맞는 레지스트리에서 컨테이너 이미지를 가져와야 합니다!)

podman pull docker.io/library/httpd

6. 이미지에 로컬 태그를 추가합니다.

이미지를 보다 쉽게 사용하기 위해 로컬에서 간단한 태그를 붙입니다.

podman tag docker.io/library/httpd:latest httpd-24

7. 영구 저장용 디렉토리 생성

컨테이너에서 사용할 웹 콘텐츠를 저장할 디렉토리를 생성합니다.

mkdir ~/www-data

8. 초기 웹 페이지 생성

기본 제공될 index.html 파일을 생성합시다.

echo "<h1>Hello World!</h1>" > ~/www-data/index.html

9. 컨테이너 실행

환경 변수, 포트 매핑, 볼륨 마운트(:Z 포함) 등 조건에 맞춰 컨테이너를 생성해봅시다.

podman run -d -it \
--name httpd \
-p 8080:8080 \
-v ~/www-data:/var/www/html:Z \
-e HTTPD_USER=test -e HTTPD_PASSWORD=test \
localhost/httpd-24
  • -p 127.0.0.1:8080:8080
    • → 컨테이너의 8080 포트를 localhost로만 제한하여 바인딩함.
    • 외부 접근 차단 → 보안 강화.
  • 만약 외부에서 접근 가능하게 하고 싶다면 127.0.0.1을 제거한다.
    • 예: -p 8080:8080

위 명령을 실행하여 컨테이너를 실행하고 상태도 확인해봅니다.

$ podman ps

CONTAINER ID  IMAGE                      COMMAND           CREATED             STATUS             PORTS                   NAMES
e157472ae4df  localhost/httpd-24:latest  httpd-foreground  About a minute ago  Up About a minute  0.0.0.0:8080->8080/tcp  httpd

10. systemd 유닛 파일 생성

컨테이너를 systemd로 관리하기 위해 unit 파일을 자동으로 생성해줍시다.

$ podman generate systemd -f -n httpd --new

/root/www-data/container-httpd.service

11. Lingering 활성화 (선택)

sam 사용자가 로그아웃해도 서비스가 계속 실행되도록 하려면 lingering을 활성화합니다.

loginctl enable-linger sam

# 활성 상태 확인
loginctl show-user sam

12. systemd로 컨테이너 확인

systemd를 통해 컨테이너가 자동으로 실행되도록 설정합니다.

systemctl --user enable --now /root/www-data/container-httpd.service

13. 컨테이너 상태 확인

systemctl --user status container-httpd.service

14. curl 명령으로 웹 페이지가 정상 로드되는지 확인합니다.

curl http://localhost:8080

40. 아파치 웹 서버 콘텐츠 제공 오류

-> 해당 실습은 실습 서버에 아파치(httpd)가 동작하고 있다는 가정하에 진행합니다.


문제 1: 아래 요구사항을 참조하여 현재 아파치 웹 서버가 정상적으로 콘텐츠를 제공하지 못하는 원인을 해결하세요.


  • 웹 서버 기능 정상화
    • /var/www/html 디렉토리에 있는 모든 HTML 파일들이 정상적으로 서비스되어야 합니다.
  • 비표준 포트 사용
    • 웹 서버는 8888번 포트에서 동작합니다.
  • 자동 시작 구성
    • 시스템 부팅 시 웹 서버가 자동으로 시작되도록 구성해야 합니다.

1. 점검 리스트

서비스 상태 확인

sudo systemctl status httpd

웹 서버가 실행 중인지 확인해야 합니다.


오류 로그 확인

less /var/log/httpd/error.log

오류 로그를 통해 파일 접근에 문제, 설정 오류 등 웹 서버 기능에 영향을 주는 원인이 있는지 파악해야 합니다.


SELinux 보안 컨텍스트 확인

ls -Z /var/www/html/*

/var/www/html 안의 파일들이 정상적으로 서비스되려면 SELinux 컨텍스트가 httpd_sys_content_t여야 합니다.

잘못되어 있으면 apache에서 접근을 못해요.


포트 리스닝 상태 확인

ss -nltpu | grep -E httpd|8888

웹 서버가 실제로 포트 8888에서 리스닝 중인지 확인합니다.


방화벽 설정 확인

firewall-cmd --list-all

방화벽에서 8888 접속을 막고있지 않은지 확인합니다.


2. 문제 검증

SELinux 보안 컨텍스트 수정 (필요할 경우)

SELinux 컨텍스트 문제인 경우 다음과 같이 컨텍스트를 변경해줍니다.

semanage fcontext -m -t httpd_sys_content_t "/var/www/html(/.*)?"
restorecon -R -v /var/www/html

/var/www/html과 그 내부 파일들에 웹 서버 접근용 SELinux 컨텍스트를 설정하여, Apache가 HTML 파일을 읽을 수 있게 합니다.


비표준 포트(8888) 사용을 SELinux에 허용

SELinux에 포트 8888을 웹 포트로 추가합니다.

semanage port -a -t http_port_t -p tcp 8888

Apache는 기본적으로 80,443만 허용되어 있습니다.

따라서 8888번 같은 비표준 포트를 사용하려면 SELinux에 추가해줘야 해요.


포트 충돌 여부 검증

ss -nltpu | grep 8888

다른 서비스가 8888 포트를 점유하고 있지는 않은지 확인합니다.


방화벽 8888 포트 허용

firewall-cmd --permanent --add-port=8888/tcp
firewall-cmd --reload

외부 클라이언트가 port 8888로 접근할 수 있도록 방화벽에서 허용합니다.

    Tag -

Loading script...