소개
이 실습에서는 SELinux 정책과 방화벽 규칙을 관리하여 Red Hat Enterprise Linux(RHEL)에서 Apache 웹 서버(httpd)를 보호하는 방법을 배웁니다. httpd가 비표준 포트에서 수신하도록 구성하고, SELinux와 방화벽 시스템이 이러한 구성에 대한 보안을 어떻게 관리하는지 실습을 통해 알아봅니다. 이 과정은 RHEL 환경에서 일반적인 보안 관리 작업을 직접 경험할 수 있도록 설계되었습니다.
먼저 httpd 서비스를 사용자 지정 포트에서 실행하도록 구성하고 SELinux 적용 하에서 어떻게 동작하는지 관찰합니다. semanage 명령어를 사용하여 SELinux 포트 레이블을 이해하고 관리하며, 적절한 보안 규정 준수를 보장합니다. 그런 다음 firewall-cmd를 사용하여 시스템 방화벽에서 이 사용자 지정 포트를 엽니다. 마지막으로 웹 서버에 액세스할 수 있는지 확인하여 보안 구성이 올바르게 적용되었는지 검증합니다.
사용자 지정 포트에서 httpd 구성 및 SELinux 컨텍스트 이해
이 단계에서는 Apache 웹 서버(httpd)를 비표준 포트에서 실행하도록 구성하고 SELinux가 포트 액세스를 관리하는 방식을 배웁니다. 포트 8081을 사용하여 실습하며, 일부 구성에서 서비스가 성공적으로 시작되더라도 SELinux 포트 관리가 어떻게 이루어지는지 살펴봅니다.
필요한 패키지(httpd, policycoreutils-python-utils, firewalld)는 설정 단계에서 이미 설치되었습니다. policycoreutils-python-utils 패키지는 이후 단계에서 사용할 semanage 명령어를 제공합니다.
먼저 기본 httpd 구성을 수정하여 비표준 포트인 8081에서 수신하도록 설정하겠습니다. httpd의 메인 구성 파일은 /etc/httpd/conf/httpd.conf에 위치합니다. nano 편집기를 사용하여 수신 포트를 변경합니다.
sudo nano /etc/httpd/conf/httpd.conf
nano 편집기 내에서 화살표 키를 사용하여 아래로 스크롤하여 Listen 80이라고 적힌 줄을 찾습니다. 이 줄을 다음과 같이 변경합니다.
Listen 8081
파일을 저장하고 nano를 종료하려면 Ctrl+X를 누른 다음 Y를 눌러 변경 사항을 확인하고, 마지막으로 Enter를 눌러 파일에 씁니다.
구성이 변경되었으므로 httpd 서비스를 시작해 보겠습니다. 이 컨테이너 환경에서는 systemctl을 사용할 수 없으므로 httpd 데몬을 직접 시작합니다.
설정 단계에서 기본 SSL 가상 호스트가 이미 비활성화되어 있으므로, 인증서 파일 오류 없이 일반 HTTP 실습을 시작할 수 있습니다.
sudo /usr/sbin/httpd
서버의 정규화된 도메인 이름(FQDN)에 대한 경고 메시지가 나타날 수 있지만, 이는 정상이며 무시해도 됩니다.
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe02:1a1e%eth0. Set the 'ServerName' directive globally to suppress this message
httpd 프로세스를 확인하여 서비스가 실행 중인지 확인합니다.
ps aux | grep httpd
여러 개의 httpd 프로세스가 실행 중인 것을 볼 수 있으며, 이는 웹 서버가 성공적으로 시작되었음을 나타냅니다.
root 4813 0.0 0.2 23364 7736 ? Ss 09:32 0:00 /usr/sbin/httpd
apache 4814 0.0 0.1 23020 5092 ? S 09:32 0:00 /usr/sbin/httpd
apache 4815 0.0 0.4 1441064 14620 ? Sl 09:32 0:00 /usr/sbin/httpd
apache 4816 0.0 0.5 1441064 18736 ? Sl 09:32 0:00 /usr/sbin/httpd
apache 4837 0.0 0.4 1572200 16872 ? Sl 09:32 0:00 /usr/sbin/httpd
labex 4996 0.0 0.0 6408 2176 pts/3 S+ 09:32 0:00 grep --color=auto httpd
httpd 오류 로그를 확인하여 시작 중에 어떤 일이 있었는지 살펴보겠습니다.
sudo tail /var/log/httpd/error_log
서버가 정상적으로 작동 중임을 나타내는 일반적인 시작 메시지가 표시되어야 합니다.
[Tue Jun 17 09:32:46.374275 2025] [core:notice] [pid 4812:tid 4812] SELinux policy enabled; httpd running as context system_u:system_r:unconfined_service_t:s0
[Tue Jun 17 09:32:46.377265 2025] [suexec:notice] [pid 4812:tid 4812] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Tue Jun 17 09:32:46.394284 2025] [lbmethod_heartbeat:notice] [pid 4813:tid 4813] AH02282: No slotmem from mod_heartmonitor
[Tue Jun 17 09:32:46.399433 2025] [mpm_event:notice] [pid 4813:tid 4813] AH00489: Apache/2.4.62 (Red Hat Enterprise Linux) configured -- resuming normal operations
[Tue Jun 17 09:32:46.399458 2025] [core:notice] [pid 4813:tid 4813] AH00094: Command line: '/usr/sbin/httpd'
흥미롭게도 httpd 서비스는 SELinux 문제 없이 시작되었습니다. 감사 로그에 SELinux 거부 기록이 있는지 확인해 보겠습니다.
sudo grep AVC /var/log/audit/audit.log | grep httpd
결과가 없다면 SELinux가 httpd 서비스가 포트 8081에 바인딩되는 것을 차단하지 않았음을 의미합니다. 이는 다음과 같은 이유일 수 있습니다.
- 일부 구성에서는 포트 8081이 기본적으로 HTTP 서비스에 대해 이미 허용되어 있을 수 있습니다.
- httpd 프로세스가 제한되지 않은(unconfined) 컨텍스트에서 실행 중일 수 있습니다.
- 포트 8081이 이미 SELinux 정책에 정의되어 있을 수 있습니다.
현재 SELinux 모드를 확인해 보겠습니다.
getenforce
SELinux가 "Enforcing" 모드에 있음을 확인할 수 있으며, 이는 정책을 적극적으로 시행하고 있음을 의미합니다. httpd가 성공적으로 시작되었다는 사실은 포트 8081에 이미 적절한 SELinux 레이블이 지정되어 있거나, 로그 메시지에 표시된 것처럼 서비스가 제한되지 않은 컨텍스트에서 실행 중임을 나타냅니다. 이 학습 실습을 위해 다음 단계로 넘어가 SELinux 포트 관리를 살펴보고 적절한 구성을 보장하겠습니다.
semanage를 사용한 SELinux 포트 레이블 이해 및 관리
이 단계에서는 semanage 명령어를 사용하여 SELinux 포트 레이블을 관리하는 방법을 배웁니다. 현재 httpd 서비스가 포트 8081에서 실행 중이지만, 보안과 규정 준수를 위해 SELinux 포트 정책을 올바르게 구성하는 방법을 이해하는 것이 중요합니다. 현재 포트 구성을 살펴보고 사용자 지정 포트에 올바른 SELinux 유형을 명시적으로 할당하는 방법을 배웁니다.
먼저 웹 서버 포트에 대한 올바른 SELinux 유형을 찾아야 합니다. semanage port -l 명령어는 SELinux에 알려진 모든 포트 정의를 나열합니다. 이 출력을 grep으로 파이프하여 http와 관련된 유형을 찾을 수 있습니다.
sudo semanage port -l | grep http
출력에는 여러 포트 유형이 표시됩니다. 표준 웹 서버와 가장 관련이 깊은 유형은 http_port_t입니다.
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
보시다시피 http_port_t는 80 및 443과 같은 표준 HTTP/HTTPS 포트에 할당되어 있습니다. SELinux 정책은 httpd_t 유형(웹 서버)을 가진 프로세스가 http_port_t로 레이블이 지정된 모든 포트에 바인딩할 수 있도록 허용합니다. 포트 8081이 이 목록에 이미 있는지 확인해 보겠습니다.
포트 8081이 현재 http_port_t 아래에 나열되어 있지 않은 것을 알 수 있습니다. 그러나 일부 RHEL 구성에서는 이 포트가 이미 SELinux 정책에 정의되어 있을 수 있습니다. 적절한 SELinux 규정 준수를 위해 semanage port -a 명령어를 사용하여 명시적으로 추가해 보겠습니다.
-a옵션은 "add(추가)"를 의미합니다.-t http_port_t옵션은 할당할 유형을 지정합니다.-p tcp옵션은 프로토콜을 지정합니다.
sudo semanage port -a -t http_port_t -p tcp 8081
"Port tcp/8081 already defined, modifying instead"라는 메시지가 표시될 수 있는데, 이는 해당 포트가 이미 구성되어 있었음을 의미합니다. 이것이 이전 단계에서 httpd가 성공적으로 시작된 이유입니다. 현재 구성을 확인하려면 http_port_t 정의를 다시 나열하십시오.
sudo semanage port -l | grep '^http_port_t'
이제 목록에 포트 8081이 포함된 것을 볼 수 있습니다.
http_port_t tcp 8081, 80, 81, 443, 488, 8008, 8009, 8443, 9000
SELinux 정책이 명시적으로 업데이트되었으므로 포트 8081은 이제 공식적으로 HTTP 포트로 인식됩니다. httpd 서비스는 문제없이 계속 실행될 것이며, 적절한 SELinux 규정 준수를 보장했습니다.
프로세스가 여전히 실행 중인지 확인해 보겠습니다.
ps aux | grep httpd
웹 서버가 적절한 SELinux 포트 레이블과 함께 성공적으로 실행되고 있음을 나타내는 여러 httpd 프로세스가 계속 표시되어야 합니다.
root 4813 0.0 0.2 23364 7736 ? Ss 09:32 0:00 /usr/sbin/httpd
apache 4814 0.0 0.1 23020 5092 ? S 09:32 0:00 /usr/sbin/httpd
apache 4815 0.0 0.4 1441064 14620 ? Sl 09:32 0:00 /usr/sbin/httpd
apache 4816 0.0 0.5 1441064 18736 ? Sl 09:32 0:00 /usr/sbin/httpd
apache 4837 0.0 0.4 1572200 16872 ? Sl 09:32 0:00 /usr/sbin/httpd
labex 5215 0.0 0.0 6408 2176 pts/3 S+ 09:33 0:00 grep --color=auto httpd
SELinux 정책을 성공적으로 구성하여 httpd 서비스가 포트 8081에서 실행되도록 명시적으로 허용하고 적절한 보안 규정 준수를 보장했습니다.
firewall-cmd를 사용하여 방화벽에서 사용자 지정 포트 열기
이 단계에서는 시스템 방화벽을 구성하여 사용자 지정 포트 8081에서 웹 서버로의 외부 연결을 허용합니다. SELinux 정책 변경 덕분에 httpd 서비스가 올바르게 실행되고 있지만, 네트워크 트래픽 규칙을 관리하는 firewalld 서비스는 기본적으로 이 비표준 포트로 들어오는 요청을 차단하고 있을 가능성이 높습니다.
firewalld 패키지는 설정 단계에서 이미 설치되었습니다. 하지만 먼저 firewalld 서비스를 시작해야 합니다. 현재 상태를 확인하고 필요하면 시작해 보겠습니다.
sudo firewall-cmd --list-all
"FirewallD is not running"이 표시되면 firewalld 데몬을 시작해야 합니다. 이 컨테이너 환경에서는 firewalld 데몬을 직접 시작합니다. 끝에 있는 &는 프로세스를 백그라운드에서 실행합니다.
sudo /usr/sbin/firewalld &
서비스가 초기화될 때까지 잠시 기다린 후 실행 중인지 확인합니다.
sudo firewall-cmd --list-all
이제 기본 영역(public)에 대한 현재 방화벽 구성을 볼 수 있습니다.
curl을 사용하여 명령줄에서 웹 서버에 대한 액세스를 테스트해 보겠습니다. 이 명령어는 포트 8081의 localhost에 연결을 시도합니다.
curl http://localhost:8081
테스트 페이지의 HTML 콘텐츠가 표시되어야 하며, 이는 웹 서버에 로컬로 액세스할 수 있음을 의미합니다. firewalld는 일반적으로 기본적으로 localhost 트래픽을 허용하므로 이는 예상된 결과입니다.
그러나 외부 액세스와 적절한 보안 구성을 위해서는 사용자 지정 포트에 대해 방화벽을 올바르게 구성해야 합니다. localhost 연결은 일반적으로 방화벽 규칙과 관계없이 작동하지만, 다른 머신에서의 외부 연결은 적절한 방화벽 구성 없이는 차단됩니다.
먼저 기본 영역(public)에 대한 현재 규칙을 검사합니다.
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
이제 포트 8081에서 TCP 트래픽을 허용하는 새 규칙을 추가합니다. 이 명령어를 실행하기 전에 firewalld가 실행 중인지 확인하십시오.
--add-port=8081/tcp는 열 포트와 프로토콜을 지정합니다.--permanent는 재부팅이나 방화벽 다시 로드 후에도 규칙이 유지되도록 합니다.
sudo firewall-cmd --permanent --add-port=8081/tcp
"FirewallD is not running"이 표시되면 이전 단계에서 firewalld 데몬을 시작했는지 확인하고 초기화될 때까지 잠시 기다리십시오.
firewalld가 올바르게 실행 중이면 명령어는 success를 반환해야 합니다.
success
영구 규칙은 다시 로드될 때까지 활성 방화벽 구성에 적용되지 않습니다. 방화벽을 다시 로드하여 새 규칙을 적용하겠습니다.
sudo firewall-cmd --reload
이 명령어 또한 success를 반환해야 합니다.
success
규칙을 다시 나열하여 포트가 이제 열려 있는지 확인합니다.
sudo firewall-cmd --list-all
이제 ports: 섹션에 8081/tcp가 표시되어야 합니다.
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: cockpit dhcpv6-client ssh
ports: 8081/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
방화벽을 성공적으로 구성했습니다. 마지막 단계는 웹 서버에 액세스할 수 있는지 테스트하는 것입니다.
표준 및 사용자 지정 웹 서버 포트에 대한 액세스 확인
이 마지막 단계에서는 수행한 모든 변경 사항이 웹 서버가 로컬 및 외부 액세스 모두에 대해 올바르게 구성되었는지 확인합니다. SELinux 정책을 구성하고 방화벽에서 필요한 포트를 열었습니다. 이제 구성을 확인하기 위해 포괄적인 테스트를 수행합니다.
먼저 간단한 테스트 페이지를 만들어 연결 시 사용자 지정 메시지가 표시되도록 하겠습니다. httpd의 기본 문서 루트는 /var/www/html입니다. 해당 디렉토리에 index.html 파일을 생성합니다. 이 위치에 쓰려면 sudo 권한이 필요합니다.
echo "Success! Web server on custom port 8081 is working." | sudo tee /var/www/html/index.html
이 명령어는 성공 메시지를 index.html 파일에 넣습니다. 여기서 tee 명령어를 사용하는 이유는 파이프를 사용하면서 sudo 권한이 필요한 파일에 쓸 수 있게 해주기 때문입니다. 확인을 위해 터미널에 메시지가 출력되는 것을 볼 수 있습니다.
Success! Web server on custom port 8081 is working.
실습을 완료하기 위해 표준 HTTP 포트 80에 액세스를 시도하여 대조를 보여드리겠습니다. 서버가 8081에서만 수신하도록 구성되어 있으므로 이 요청은 실패해야 합니다.
curl http://localhost:80
예상대로 해당 포트에서 수신 중인 서비스가 없기 때문에 연결이 거부됩니다.
curl: (7) Failed to connect to localhost port 80: Connection refused
이는 서버가 구성한 사용자 지정 포트에서만 독점적으로 실행되고 있음을 확인해 줍니다. 이 실습을 통해 RHEL 서비스에 대한 중요한 문제 해결 워크플로우를 배웠습니다.
- 서비스 상태 및 로그 확인.
- 감사 로그에서 SELinux 거부 조사.
semanage를 사용하여 SELinux 정책 수정.firewall-cmd를 사용하여 방화벽 규칙 구성.- 연결 확인.
요약
이 실습에서는 사용자 지정 포트에서 웹 서버를 구성하고 SELinux 보안 정책을 관리하는 방법을 배웠습니다. Apache 웹 서버(httpd), policycoreutils-python-utils, firewalld 패키지가 미리 설치된 상태에서 SELinux 포트 관리와 방화벽 구성에 집중했습니다. httpd.conf 파일을 수정하여 웹 서버의 수신 포트를 비표준 포트인 8081로 변경했습니다.
포트 8081이 이미 SELinux 정책에 올바르게 구성되어 있었기 때문에 httpd 서비스가 사용자 지정 포트에서 성공적으로 시작되었음을 발견했습니다. 이는 SELinux 포트 관리를 탐색하고 semanage가 적절한 포트 레이블을 유지하기 위해 어떻게 작동하는지 이해할 기회를 제공했습니다. 또한 firewall-cmd를 사용하여 방화벽 규칙을 관리하고 보안 규정 준수와 액세스 가능성을 모두 보장하는 방법을 배웠습니다. httpd가 제한되지 않은 컨텍스트에서 실행되었더라도, 이 실습은 프로덕션 환경을 위해 적절한 SELinux 및 방화벽 구성이 얼마나 중요한지 보여주었습니다.



