1. SELinux 관리
1-1. SELinux란
리눅스의 강력한 보안 시스템이다. Security-Enhanced Linux의 약자. RedHat 계열(Rocky/CentOS)에서 기본으로 켜져 있다.
일반 권한(rwx)만으로는 부족한 부분을 메운다. 예를 들어 웹서버 프로세스는 웹 폴더만 건드릴 수 있다처럼, 프로세스가 뭘 할 수 있는지를 세밀하게 통제한다. 해킹당해도 피해를 최소화하는 안전장치다.
SELinux의 3가지 모드
먼저 모드부터. SELinux는 세 가지 상태로 동작한다.
| Enforcing | 규칙 위반을 차단 (실제 보안 적용) |
| Permissive | 위반을 경고만 하고 허용 (로그만 남김) |
| Disabled | SELinux 완전히 끔 |
setenforce 0 # Permissive로 전환
getenforce # 현재 모드 확인 → Permissive
SELinux Boolean
SELinux 기능을 on/off로 켜고 끄는 스위치다. 동작을 허용할까 말까를 참/거짓으로 정한다.
예를 들어 "FTP가 사용자 홈 디렉토리에 접근해도 되나?" 같은 걸 boolean으로 켜고 끈다.
semanage boolean -l (목록 보기)
semanage boolean -l | grep ftpd
- semanage boolean -l : 모든 boolean 목록
- | grep ftpd : ftpd(FTP) 관련만 필터

getsebool / setsebool (개별 확인·변경)
getsebool ftp_home_dir # 현재값 확인 → off
setsebool -P ftp_home_dir on # on으로 변경 (영구)
getsebool ftp_home_dir # 다시 확인 → on
| getsebool 이름 | boolean 현재값 확인 |
| setsebool 이름 on/off | 값 변경 (임시) |
| setsebool -P 이름 on | 영구 변경 |
⭐ -P 없이 setsebool하면 재부팅 시 원복된다. -P(Permanent)를 붙여야 영구 적용. 이거 빼먹으면 재부팅 후 다시 안 되는 걸로 헤맨다.


1-2. SELinux Context 설정 & 트러블슈팅
Context(컨텍스트)란
모든 파일/폴더에 붙는 SELinux 보안 라벨이다. SELinux는 이 라벨을 보고 프로세스가 이 파일을 건드려도 되나를 판단한다.
- 웹 파일은 httpd_sys_content_t 라벨이 있어야 아파치가 읽을 수 있다
- 라벨이 안 맞으면, 파일이 존재하고 일반 권한(rwx)이 맞아도 SELinux가 막는다
그래서 디렉토리 분명히 만들었고 권한도 맞는데 왜 아파치가 못 읽지? 하는 상황이 생긴다. 라벨(context)이 안 맞아서 그런 경우가 많다
라벨 확인하는 법
먼저 파일에 어떤 라벨이 붙었나 보는 법
ls -Z /home/user1/public_html
- -Z : SELinux 라벨(context) 표시
- 보통 user_home_t 같은 게 붙어있는데, 웹서버가 읽으려면 httpd_*_content_t여야 한다
라벨 바꾸는 두 가지 방법
chcon과 semanage 두 가지가 있는데 차이가 크다.
방법 1: chcon (임시)
chcon -R -t httpd_user_content_t /home/user1/public_html
- chcon : change context. 라벨을 바꾼다
- -R : 하위 폴더까지 전부 (recursive)
- -t 타입 : 이 타입으로 변경
- 대상: 그 폴더
⚠️ chcon은 임시다. 나중에 restorecon을 하거나 파일시스템 재라벨링을 하면 원래대로 돌아간다. 빠르게 테스트할 때만 쓴다.
방법 2: semanage fcontext (영구)
# 라벨 규칙을 영구 등록
semanage fcontext -a -t public_content_t '/home/share(/.*)?'
# 등록한 규칙을 실제 적용
restorecon -RFvv /home/share
- semanage fcontext -a : 라벨 규칙을 영구 등록 (add)
- -t 타입 : 적용할 타입
- '/home/share(/.*)?' : 경로 (정규식. 그 폴더와 하위 전부)
- restorecon : 등록한 규칙대로 실제 파일에 적용
⭐ semanage는 영구다. 규칙을 데이터베이스에 등록해서, 재부팅하거나 restorecon해도 유지된다. 실무에선 이걸 써야 한다.
semanage fcontext 명령들
| semanage fcontext -l | 등록된 라벨 규칙 목록 |
| semanage fcontext -a -t 타입 '경로' | 규칙 추가 |
| restorecon -R 경로 | 규칙대로 라벨 복원·적용 |
restorecon의 역할
restorecon -RFvv /home/share
- 등록된 규칙(기본 정책 + semanage로 추가한 것)에 맞춰 파일 라벨을 올바르게 되돌린다
- -R 하위까지, -F 강제, -v 자세히
semanage로 규칙만 등록하면 아직 파일엔 반영 안 된다. restorecon을 해야 실제 파일에 라벨이 적용된다. semanage(규칙) → restorecon(적용) 세트다.
SELinux 트러블슈팅
SELinux가 뭔가 막았을 때 원인을 찾는 방법이다.
1. 로그 확인
tail -f /var/log/messages
SELinux가 차단하면 여기 로그가 찍힌다. (Rocky는 /var/log/messages, 앞서 배운 계열별 로그)
2. setroubleshoot 설치 + sealert
# 트러블슈팅 도구 설치
dnf install setroubleshoot
# 경고 분석
sealert -l <경고ID>
- setroubleshoot : SELinux 차단을 사람이 읽기 쉽게 분석해주는 도구
- sealert -l ID : 특정 SELinux 경고를 자세히 분석 + 해결 방법까지 제안
sealert가 강력한 이유: 이 파일 라벨이 안 맞아서 막혔고, 이렇게 하면 해결된다고 구체적인 명령까지 알려준다. SELinux 초보자에게 최고의 도구다.
- Context = 파일마다 붙는 SELinux 라벨. 라벨이 안 맞으면 권한 맞아도 막힘
- 라벨 변경 2방법:
- chcon -t 타입 경로 → 임시 (테스트용)
- semanage fcontext -a + restorecon → 영구
- 트러블슈팅:
- tail -f /var/log/messages (로그)
- setroubleshoot 설치 → sealert -l ID (분석 + 해결책 제안)
1-3. 아파치 DocumentRoot SELinux 라벨 실습
아파치 설정에서 DocumentRoot를 /www로 바꿨다 (기본은 /var/www/html). 설정 파일 124번 줄 DocumentRoot "/www"가 그거다.
그런데 /www는 기본 웹 경로가 아니라서, SELinux 라벨이 웹용이 아니다. 그래서 아파치가 접근하려 하면 SELinux가 막고 alert가 뜨는 것 이를 해결하기 위해선 라벨 규칙을 등록해야한다.

curl localhost —>기본 page :selinux alert 발생
라벨 규칙 등록 (영구)
semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?'
- /www와 그 하위 전부를 **웹 콘텐츠 라벨(httpd_sys_content_t)**로 등록
- -a 추가, (/.*)? 하위 포함하는 정규식
- 규칙만 등록된 상태 (아직 파일엔 반영 전)
실제 적용 (restorecon)
restorecon -RFv /www
Relabeled /www from ...default_t... to ...httpd_sys_content_t...
Relabeled /www/index.html from ...default_t... to ...httpd_sys_content_t...
default_t → httpd_sys_content_t
(기본 라벨) (웹 콘텐츠 라벨)
/www와 /www/index.html 둘 다 웹용 라벨로 바뀌었다. 이제 아파치가 접근할 수 있다.

왜 default_t는 막혔나
바뀌기 전 라벨이 default_t였다. 이건 "특별한 용도가 지정 안 된 기본 파일"이라는 뜻이다. 아파치는 httpd_sys_content_t 같은 웹 전용 라벨만 읽도록 SELinux 정책에 정해져 있어서, default_t는 거부한 거다.
/var/www/html(기본 경로)은 처음부터 httpd_sys_content_t가 붙어있어서 문제없는데, /www처럼 임의 경로를 쓰면 라벨을 직접 맞춰줘야 한다.
1-4. 포트 변경 실습





2. 네트워크 관리
2-1. IP 주소 클래스 (A/B/C Class)
IP 주소의 구조
IP 주소는 4개의 숫자로 돼 있다 (예: 192.168.0.1). 이걸 두 부분으로 나눈다.
- Network 주소 : 어느 네트워크인지 (동네)
- Host 주소 : 그 네트워크 안의 어느 장비인지 (집)
클래스로 나누는 이유
네트워크 규모가 제각각이다. 큰 기관은 호스트가 수백만 개 필요하고, 작은 곳은 몇 개면 된다. 그래서 네트워크/호스트 비율을 다르게 나눈 게 클래스다.
A / B / C 클래스
| 클래스 | 첫 비트 | 첫 숫자 범위 | Network | Network |
| A | 0 | 0~127 | 1byte | 3byte (호스트 많음) |
| B | 10 | 128~191 | 2byte | 2byte |
| C | 110 | 192~223 | 3byte | 1byte (호스트 적음) |
같은 망에 존재하는 호스트들은 네트워크 주소는 같지만 호스트 주소는 다르다
A: 00000000 ~ 01111111 = 0 ~ 127
B: 10000000 ~ 10111111 = 128 ~ 191
C: 11000000 ~ 11011111 = 192 ~ 223
| Network 주소 | 네트워크를 대표하는 주소 (호스트 부분 전부 0) |
| Host 주소 | 실제 장비에 붙는 주소 |
| Netmask/Subnetmask | 네트워크/호스트 경계를 나누는 값 |
| Broadcast | 그 네트워크 전체에 한 번에 보내는 주소 (호스트 부분 전부 1) |
사설 IP란
외부 인터넷에 안 나가고, 내부 네트워크에서만 쓰는 IP다. 집이나 회사 내부에서만 통하는 주소다. 공인 IP(인터넷용)와 구분된다. => 외우는 게 좋다
| A | 10.0.0.0 ~ 10.255.255.255 | 10.x.x.x |
| B | 172.16.0.0 ~ 172.31.255.255 | 172.16~31.x.x |
| C | 192.168.0.0 ~ 192.168.255.255 | 192.168.x.x |
2-2. 클래스별 호스트 개수 & 서브넷의 필요성
호스트 개수 계산법
각 클래스가 몇 대의 장비를 담을 수 있는지는 Host 주소 비트 수로 정해진다.
공식: 2^(호스트 비트 수) - 2
A class: Host 3byte(24비트) → 2²⁴ - 2 = 약 1,677만 대
B class: Host 2byte(16비트) → 2¹⁶ - 2 = 65,534 대
C class: Host 1byte(8비트) → 2⁸ - 2 = 254 대
2를 빼는 이유
호스트 주소 2개는 특수 용도로 예약돼서 실제 장비엔 못 쓴다.
| 첫 번째 (호스트 부분 전부 0) | Network 주소 (네트워크 대표) |
| 마지막 (호스트 부분 전부 1) | Broadcast 주소 (전체 전송) |
그래서 실제 쓸 수 있는 건 전체 - 2다. 앞 슬라이드에서 본 Network/Broadcast가 여기서 빠지는 거다.
예시 (C class, 192.168.0.x)
- 192.168.0.0 → Network 주소 (예약)
- 192.168.0.1 ~ 192.168.0.254 → 실제 장비 (254대)
- 192.168.0.255 → Broadcast (예약)
하지만 B class 하나 = 65,534대. 근데 한 네트워크에 6만 대를 다 몰아넣으면 문제가 생긴다.
- 브로드캐스트 폭주: 한 대가 전체에 뭘 보내면 6만 대가 다 받는다 → 네트워크 마비
- 관리 불가: 6만 대를 한 덩어리로 관리 못 함
- 낭비: 실제론 100대만 필요한데 6만 개 주소를 통째로 받으면 나머지 낭비
따라서 서브넷(Subnet)을 사용한다. 서브넷은 큰 네트워크를 작은 여러 개로 쪼개는 것이다.
큰 네트워크 하나 (65534대)
↓ 서브넷으로 분할
작은 네트워크 여러 개 (예: 254대씩)
Subnet Mask가 등장하는 이유
이렇게 쪼개려면 어디까지가 네트워크고 어디부터가 호스트인지 경계를 정해야 한다. 그 경계를 정하는 게 Subnet Mask(서브넷 마스크)다.
- 호스트 개수 = 2^(호스트 비트) - 2
- A: 2²⁴-2 (약 1677만) / B: 2¹⁶-2 (65534) / C: 2⁸-2 (254)
- -2 이유: Network 주소 + Broadcast 주소는 예약이라 못 씀
- 문제: B class 하나(6만대)는 너무 커서 브로드캐스트 폭주,관리불가,낭비
- 해결: 서브넷 = 큰 네트워크를 작게 쪼갬 (격리·관리·절약)
- 쪼개는 도구 = Subnet Mask
네트워크 IP 설정 & 상태 확인
# 동적 (DHCP 자동 할당)
dhclient eth0 # IP 받기
dhclient eth0 -r # IP 반납
# 정적 (수동) - 요즘 방식
ip a add 10.1.2.100/24 dev eth0 # IP 설정
ip link set eth0 up # 인터페이스 켜기
ip route add default via 192.168.100.254 dev eth0 # 게이트웨이
ifconfig/route는 구식, ip는 신식. 실무는 ip로 통일하는 추세다.
⚠️ 이 설정은 임시(재부팅 시 사라짐). 영구는 nmcli나 설정 파일(우분투는 /etc/netplan/).
인터페이스 상태 확인: ip -s link show
ip -s link show ens160
- -s : 통계(RX/TX) 포함
- 요즘 인터페이스 이름은 eth0 대신 ens160, enp3s0 형식
| UP + LOWER_UP | 인터페이스 켜짐 + 케이블 연결 (정상) |
| link/ether 00:0c:29:... | MAC 주소 (하드웨어 고유 번호, IP와 다름) |
| RX | 수신(받은) 데이터 |
| TX | 송신(보낸) 데이터 |
| errors / dropped | 0이면 정상, 늘어나면 물리적 문제 |
2-3. nmcli
NetworkManager를 명령줄로 제어하는 도구다. 앞서 GUI(nm-connection-editor)가 화면 없어서 안 됐을 때 대안으로 쓰는 그거다. 설정이 .nmconnection 파일에 영구 저장된다.
nmcli는 두 개념을 다룬다.
| con (connection) | 설정 프로필 (IP, DNS 등을 담은 설정 묶음) |
| dev (device) | 실제 하드웨어 (ens160 같은 네트워크 카드) |
con = 설정서, dev = 실제 장비. 하나의 dev에 여러 con(설정)을 만들어두고 갈아끼울 수 있다.
1) 조회 (show / status)
# 연결(설정) 목록 보기
nmcli con show
# 특정 연결 상세 보기
nmcli con show mynet
# 장치(하드웨어) 목록/상태
nmcli dev status
# 장치 상세
nmcli dev show ens160
| nmcli con show | 설정 프로필 목록 |
| nmcli con show 이름 | 특정 설정 상세 |
| nmcli dev status | 장치 상태 (연결됨/끊김) |
| nmcli dev show | 장치 상세 정보 |
2) 추가 (add)
nmcli con add type ethernet con-name mynet2 ifname ens160 \
ipv4.addresses 192.168.10.50/24 \
ipv4.gateway 192.168.10.1 \
ipv4.dns 8.8.8.8 \
ipv4.method manual
새 연결 프로필을 처음부터 만드는 명령이다.
| add | 새 연결 생성 |
| type ethernet | 유선 타입 |
| con-name mynet2 | 연결 이름 |
| ifname ens160 | 어느 장치에 |
| ipv4.addresses | IP/서브넷 |
| ipv4.gateway | 게이트웨이 |
| ipv4.dns | DNS 서버 |
| ipv4.method manual | 정적(manual)/자동(auto) |
mod(수정)는 기존 걸 고치는 거고, add는 새로 만드는 거다. 인터페이스에 새 설정 프로필을 통째로 추가할 때 쓴다.
DHCP(자동)로 만들려면
nmcli con add type ethernet con-name mynet3 ifname ens160 \
ipv4.method auto
method auto면 DHCP로 IP 자동 할당. 정적이면 manual + IP 지정.
수정 (mod)
# IP 교체
nmcli con mod mynet ipv4.addresses 192.168.10.100/24
# IP 추가 (+ 붙이면 추가!)
nmcli con mod mynet +ipv4.addresses 10.0.0.10/24
# IP 삭제 (- 붙이면 삭제)
nmcli con mod mynet -ipv4.addresses 10.0.0.10/24
# 게이트웨이/DNS 변경
nmcli con mod mynet ipv4.gateway 192.168.10.1
nmcli con mod mynet ipv4.dns 8.8.8.8
# 정적↔동적 전환
nmcli con mod mynet ipv4.method manual # 정적
nmcli con mod mynet ipv4.method auto # DHCP
| (없음) | 교체 |
| + | 추가 |
| - | 삭제 |
앞서 본 +ipv4.addresses의 +가 추가였다. -는 삭제, 아무것도 없으면 교체. 이 세 기호 구분이 중요하다.
적용 (up / down)
# 연결 활성화 (적용)
nmcli con up mynet
# 연결 비활성화
nmcli con down mynet
# 설정 파일 다시 읽기 (파일 직접 수정했을 때)
nmcli con reload
⚠️ mod로 수정한 건 up 해야 적용된다. 수정만 하면 파일에만 저장되고 실제 반영 안 됨. 앞서 계속 나온 "설정 → 적용" 패턴이다.
삭제 (delete)
# 연결 프로필 삭제
nmcli con delete mynet2
장치 제어 (dev)
# 장치 연결
nmcli dev connect ens160
# 장치 끊기
nmcli dev disconnect ens160
# 와이파이 목록 (무선인 경우)
nmcli dev wifi list
| 연결 목록 | nmcli con show |
| 장치 상태 | nmcli dev status |
| 새 연결 생성 | nmcli con add type ethernet con-name 이름 ... |
| IP 교체 | nmcli con mod 이름 ipv4.addresses IP |
| IP 추가 | nmcli con mod 이름 +ipv4.addresses IP |
| IP 삭제 | nmcli con mod 이름 -ipv4.addresses IP |
| 적용 | nmcli con up 이름 |
| 삭제 | nmcli con delete 이름 |
실습 과정






2-4. 라우팅 실습 과정 정리 ⭐
윈도우(192.168.120.1) → 로키(라우터) → 우분투(10.0.0.11)
192.168.120.128
10.0.0.10
서로 다른 대역(192.168.120 ↔ 10.0.0)을 로키가 중간에서 연결하는 구조. 로키가 라우터(다리) 역할을 한다.
1) 윈도우 - 가는 길 설정
route ADD 10.0.0.0 MASK 255.255.255.0 192.168.120.128 METRIC 3 IF 10
10.0.0.x로 가려면 로키(128)를 거쳐야하는 것 설정 이때 10은 인터페이스 번호
IF 번호 확인하는 법
10번이 어느 카드인지 확인하려면:
route PRINT
맨 위에 인터페이스 목록이 번호와 함께 나온다:
인터페이스 목록
10 ... VMware Network Adapter VMnet8 ← 10번이 이거!
6 ... Wi-Fi
...
2) 로키 - 패킷 전달 켜기
sysctl -w net.ipv4.ip_forward=1
라우터 역할하려면 필수. 받은 패킷을 다른 대역으로 넘겨줌.
3) 우분투 - 돌아가는 길 설정
ip route add default via 10.0.0.10
응답을 로키(10.0.0.10) 거쳐 윈도우로 보내는 길.
실패했던 원인들
- route 게이트웨이 IP가 실제 로키 IP와 불일치 → 일치시켜야 함
- 로키 ip_forward 꺼짐 → 1로 켜기
- 우분투에 return route 없음 → default route 추가
- (방화벽이 막으면 firewalld/ufw 확인)
| 윈도우 | route ADD 10.0.0.0 MASK 255.255.255.0 192.168.120.128 |
| 로키 | sysctl -w net.ipv4.ip_forward=1 |
| 우분투 | ip route add default via 10.0.0.10 |
| 확인 | ping 10.0.0.11 |



2-5. 서비스 포트 확인하기
ss란
소켓(네트워크 연결) 상태를 보는 명령이다. 어떤 포트가 열려있나, 누가 연결돼 있나를 확인한다. 옛날 netstat의 후속으로, 더 빠르다.
ss -tlnp
| -t | TCP 연결 |
| -u | UDP 연결 |
| -l | LISTEN 상태만 (대기 중인 포트) |
| -n | 숫자로 표시 (포트를 이름 대신 번호로) |
| -p | 프로세스 정보 (어느 프로그램인지) |
| -a | 전체 (all) |

3. Openssh
SSH 포트 22를 220으로 변경 실습
# 1. sshd 설정 파일에서 포트 변경
vi /etc/ssh/sshd_config
# Port 220 으로 (앞에 # 있으면 제거)
# 2. SELinux에 포트 등록 (RedHat 필수!)
semanage port -a -t ssh_port_t -p tcp 220
# 3. 방화벽 열기 (firewalld 실행 중일 때만)
firewall-cmd --add-port=220/tcp --permanent
firewall-cmd --reload
# 4. sshd 재시작
systemctl restart sshd
# 5. 확인
ss -tlnp | grep ssh # → 0.0.0.0:220 나오면 성공
이때 방화벽 꺼져있으면 systemctl start firewalld 명령어 사용해서 열기

'{Bootcamp} > KT Cloud Tech up 클라우드 인프라' 카테고리의 다른 글
| [kt cloud] 도커 실습 (1) (0) | 2026.09.15 |
|---|---|
| [kt cloud] 리눅스 관리자 실습 (6) (0) | 2026.09.11 |
| [KT Cloud] 리눅스 관리자 실습 (4) (0) | 2026.09.09 |
| [KT Cloud] 리눅스 관리자 실습 (3) (0) | 2026.09.08 |
| [KT Cloud] 리눅스 관리자 실습 (2) (0) | 2026.09.07 |