학습일지/K-Digital Traing

[KDT] AIaaS 마스터클래스 5주차 - 리눅스 실습

tierr 2025. 4. 23. 16:31

1. 리눅스 실습 - TCP 통신 CLI 실습

  • TCP 소켓을 이용한 기본 통신 원리를 이해
  • nc(netcat) 도구를 활용하여
    • 서버↔클라이언트 간 메시지 교환, 파일 전송, HTTP 요청 등을 직접 수행해보기
  • 실습용 리눅스 머신(또는 VM) 2대: “서버”, “클라이언트”로 명명
  • 각 머신에 netcat 설치
# Debian/Ubuntu 계열
sudo apt update 
sudo apt install netcat-openbsd

# RHEL/CentOS 계열
sudo yum install -y nc

 

방화벽에서 실습에 사용할 포트(예: 12345)가 열려 있어야 함


1-1. 기본 TCP 연결

서버(리스닝) 실행

# 서버 머신에서 포트 12345로 대기
nc -l -vv 12345

 

클라이언트에서 연결 및 메시지 전송

# 클라이언트 머신에서 서버 IP로 연결
nc <서버_IP> 12345

# telnet으로도 접속해보기
telnet <서버 IP> 12345
# Ctrl + ] 로 빠져나오기

 

메시지 교환

  • 클라이언트 터미널에 입력한 텍스트가 서버 터미널에 출력됨
  • 서버에서도 입력하면 클라이언트에 실시간 전송됨

nc 접속 (우: 서버 / 좌: 클라이언트)
Telnet 접속 (우: 서버 / 좌: 클라이언트)


1-2. 파일 전송

서버 → 클라이언트 (다운로드)

서버 준비

# 서버: 수신 파일을 received.txt로 저장
nc -l 12345 > received.txt

 

클라이언트 전송

# 클라이언트: 전송할 파일 file_to_send.txt 지정
nc <서버_IP> 12345 < file_to_send.txt

파일 전송 (우: 서버 / 좌: 클라이언트)


1-3. HTTP 요청 전송

단순 GET 요청

printf "GET / HTTP/1.1\\r\\nHost: example.com\\r\\nConnection: close\\r\\n\\r\\n" \\
  | nc example.com 80

 

응답 분석

  • HTML 헤더와 바디가 터미널에 출력됨
  • Connection: close 옵션으로 요청 후 자동 종료

1-4. 양방향 채팅 구현

서버: 백그라운드 리스닝(+로그 저장)

#!/bin/bash
# 파일: nc-chat-server.sh

# 1) 임시 FIFO 생성
FIFO_A_TO_B=/tmp/nc_a2b
FIFO_B_TO_A=/tmp/nc_b2a
rm -f $FIFO_A_TO_B $FIFO_B_TO_A
mkfifo $FIFO_A_TO_B $FIFO_B_TO_A

# 2) 백그라운드로 “브로커” 실행
#    - 포트 12345 에서 들어온 데이터 → tee(server.log) → 포트 12346
#    - 그리고 포트 12346 에서 들어온 데이터 → FIFO_A_TO_B
nc -l 12345 < $FIFO_B_TO_A \\
  | tee server.log \\
  | nc -l 12346 > $FIFO_A_TO_B &

# 3) 나머지 방향(포트12345←포트12346) 연결
cat $FIFO_A_TO_B > $FIFO_B_TO_A

# 종료 시 FIFO 정리
rm -f $FIFO_A_TO_B $FIFO_B_TO_A
  • 포트 12345로 들어온 메시지는 server.log에 기록
  • 동시에 12346 포트로 다시 출력

클라이언트 A, B 연결

클라이언트 A:

nc <서버_IP> 12345

 

클라이언트 B:

nc <서버_IP> 12346

 

메시지 주고받기

  • A → 서버(12345) → B(12346)
  • B → 서버(12346) → A(12345)

양방향 채팅 (우: 클라이언트 A / 좌: 클라이언트 B)


1-5. ncat 패키지 활용해보기

# (Ubuntu 계열)
sudo apt update
sudo apt install ncat -y

 

브로커 열기

# 채팅 서버 띄우기
sudo apt install ncat       # (Ubuntu/Debian 계열)
**ncat** --broker -k -l 12345

 

브로커 접근

nc <서버_IP> 12345


1-6. 리스닝‑백업 스크립팅 응용

#!/bin/bash
PORT=12345
while true; do
  echo "[`date '+%F %T'`] Listening on port $PORT..."
  nc -l $PORT
  echo "[`date '+%F %T'`] Connection closed, restarting listener."
done

 

위 스크립트(tcp_listener.sh)에 실행 권한 부여

chmod +x tcp_listener.sh

 

실행

./tcp_listener.sh

 

클라이언트가 연결/종료할 때마다 자동 재시작됨

 

실습 결과 확인 및 토의

  • 각 실습 단계마다 정상 동작 여부 확인
  • 메시지/파일이 올바르게 전송되었는지 검증
  • HTTP 요청 결과 해석
  • ACL와 보안 그룹으로 포트 조정하면서 차이 알아보기

2. 리눅스 실습 - 보안그룹 없이 방화벽 만들기

실습 개요

클라우드 보안그룹 없이도, 호스트 자체의 방화벽 도구(iptables 또는 nftables)를 이용해 인바운드·아웃바운드 트래픽을 제어하는 방법을 익힙니다.

 

실습 목표

  • 기본 정책(Default Policy) 설정
  • 특정 서비스(SSH, HTTP 등) 포트 허용/차단
  • NAT(포트 포워딩) 설정
  • 로깅 및 부팅 시 방화벽 룰 자동 적용

2-1. 실습 단계

준비 및 초기화

# Ubuntu에서 iptables-persistent 설치
sudo apt update
sudo apt install -y iptables-persistent

# CentOS에서 firewalld 비활성화 및 iptables 설치
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo yum install -y iptables-services

 

기본 정책 설정

  • TCP 12345 포트 차단
sudo iptables -A INPUT -p tcp --dport 12345 -j DROP 

 

확인 (TCP 12345 통신 시도)

  • 서버(리스닝) 실행
# 서버 머신에서 포트 12345로 대기
nc -l -vv 12345
  • 클라이언트에서 연결 및 메시지 전송
# 클라이언트 머신에서 서버 IP로 연결
nc <서버_IP> 12345

# telnet으로도 접속해보기
telnet 210.109.80.11 12345
# Ctrl + ] 로 빠져나오기

차단된 포트에 nc 접속 (메시지 도착 안함) & Telnet 접속 (응답 없음)

 

TCP 12345 포트 다시 열기

# 현재 정책 확인
sudo iptables -L --line-numbers

# TCP 12345 포트 허용
sudo iptables -D INPUT <규칙번호>
sudo iptables -D INPUT -p tcp --dport 12345 -j DROP

 

확인 (TCP 12345 통신 시도)

  • 서버(리스닝) 실행
# 서버 머신에서 포트 12345로 대기
nc -l -vv 12345
  • 클라이언트에서 연결 및 메시지 전송
# 클라이언트 머신에서 서버 IP로 연결
nc <서버_IP> 12345

# telnet으로도 접속해보기
telnet 210.109.80.11 12345
# Ctrl + ] 로 빠져나오기

12345 포틀를 다시 열고 접속 성공

 

SSH 접근 차단 (포트 22)

🔥이걸 하면 쉘 세션이 꺼져요

sudo iptables -A INPUT  -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j DROP
sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED     -j DROP

 

HTTP/HTTPS 허용 (포트 80, 443)

# 기본 정책 DROP 설정
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
for port in 80 443; do
  sudo iptables -A INPUT  -p tcp --dport $port -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
  sudo iptables -A OUTPUT -p tcp --sport $port -m conntrack --ctstate ESTABLISHED     -j ACCEPT
done

 

ICMP 핑(ping) 허용

sudo iptables -A INPUT  -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply   -j ACCEPT

 

포트 포워딩(NAT) 예시

# 커널 패킷 포워딩 활성화
sudo sysctl -w net.ipv4.ip_forward=1

# 외부 포트 80 → 내부 192.168.10.10:8080
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.10.10:8080
sudo iptables -t nat -A POSTROUTING -j MASQUERADE

 

로깅 룰 추가

sudo iptables -N LOG_DROP
sudo iptables -A LOG_DROP -m limit --limit 5/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
sudo iptables -A LOG_DROP -j DROP
sudo iptables -A INPUT   -j LOG_DROP
sudo iptables -A FORWARD -j LOG_DROP

 

설정 저장 및 자동 적용

# Ubuntu
sudo netfilter-persistent save

# CentOS
sudo service iptables save
sudo systemctl enable iptables

2-2. 검증 및 테스트

방화벽 정책 및 NAT 룰 확인

sudo iptables -L -n -v
sudo iptables -t nat -L -n -v

 

외부에서 포트 스캔

nmap -p 22,80,443 <호스트_IP>

 

확장 과제

  • 포트 범위·IP 대역 단위로 세분화된 접근 제어

3. 리눅스 실습 - 사내 NPM 레지스트리 구성하기

개요

사내 프로젝트에서 외부 공개 레지스트리를 사용하지 않고, 자체 NPM 패키지의 배포·관리를 위해 경량 레지스트리인 Verdaccio를 설치·구성해 봅니다. 내부 보안 정책을 준수하면서 사설 패키지 캐싱·호스팅 기능을 익힐 수 있습니다.

  • Verdaccio 포트: 4873

3-1. 실습 절차

Node.js 설치

# Ubuntu (NVM 설치)
curl -o- <https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh> | bash

# 설치 확인
nvm --version
nvm install --lts
nvm use --lts

node -v   # v22.x.x
npm -v    # 10.x.x

 

Verdaccio 설치

# 설치
npm install -g verdaccio

# 설치 확인
verdaccio --version

 

Verdaccio 기본 실행

# 바로 실행
verdaccio

# 브라우저에서 확인
http://<서버_IP>:4873

 

주소 설정

vi /home/ubuntu/verdaccio/config.yaml

# listen을 **0.0.0.0**:4837 으로 수정

 

Systemd 서비스로 자동 기동

  1. /etc/systemd/system/verdaccio.service 파일 생성
[Unit]
Description=Verdaccio NPM Registry
After=network.target

[Service]
Type=simple
User=ubuntu
ExecStart=/usr/bin/verdaccio
Restart=on-failure

[Install]
WantedBy=multi-user.target

 

서비스 등록 및 기동

sudo systemctl daemon-reload
sudo systemctl enable verdaccio
sudo systemctl start verdaccio
sudo systemctl status verdaccio

 

사용자 계정 생성

npm adduser --registry <http://localhost:4873>

# 입력 예시
Username: devuser
Password: ****
Email: devuser@company.com

 

내부 패키지 발행·설치 테스트

# 샘플 패키지 생성 및 발행
mkdir ~/test-pkg && cd ~/test-pkg
npm init -y
echo "module.exports = () => console.log('Hello from internal pkg');" > index.js
npm publish --registry <http://localhost:4873>
# 클라이언트 측 설치
mkdir ~/client-app && cd ~/client-app
npm init -y
npm set registry http://<서버_IP>:4873
npm install test-pkg
node -e "require('test-pkg')();"

 

심화 과제

  • npm publish 후 내부 레지스트리에 패키지가 업로드되는지 확인
  • Systemd 서비스 재시작 후에도 자동 기동 검증
  • 특정 스코프(@company/*)만 발행 가능하도록 권한을 제한해 보세요.
  • config.yaml의 uplinks 섹션을 수정하여 공개 npmjs.org 패키지를 자동 캐싱하도록 구성해 보세요.

4. 리눅스 실습 - (과제) 자신만의 CLI 프로그램 만들어보기

자신만의 CLI 프로그램을 만들어보는 과제다. 나는 logpeek 이란 프로그램을 만들기로 했다. 로그 파일에서 마지막 50줄을 읽어 GPT에 전달하고, 어떤 내용인지 요약해서 한국어로 설명해주는 도구다.  커맨드창에서 긴 영어 로그를 확인하는 것은 여간 번거로운 일이 아니기 때문에, 로그 내용을 요약해주는 도구가 있으면 좋겠다는 생각으로 만들어봤다. 

 

< 깃허브 주소 >

https://github.com/ncb-yji/testRepo/tree/main/0403

 

testRepo/0403 at main · ncb-yji/testRepo

for practice. Contribute to ncb-yji/testRepo development by creating an account on GitHub.

github.com

 

logpeek 사용법
logpeek 실행 결과

 

< 테스트용 시나리오>

아래 명령어를 입력하면 총 6개의 테스트파일을 생성할 수 있다. 

각각 오류 내용이 다른 로그이므로 logpeek을 사용해서 테스트해보면 다른 결과를 확인할 수 있다.

#테스트 시나리오
#1. 일반적인 SSH 로그인 실패 (보안 테스트)
echo -e "Apr 23 10:01:00 ubuntu sshd[1234]: Failed password for root from 192.168.0.10 port 45123 ssh2" > test1.log
#2. CPU soft lockup (시스템 오류)
echo -e "Apr 23 10:02:10 ubuntu kernel: [12345.678901] CPU0: soft lockup - CPU#0 stuck for 22s! [kworker/0:1:1234]" > test2.log
#3. 웹 서버 실행 실패 (서비스 장애)
echo -e "Apr 23 10:03:21 ubuntu apache2[5678]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message" > test3.log
#4. Nginx 설정 오류 (구문 에러)
echo -e "Apr 23 10:04:01 ubuntu nginx[9123]: nginx: [emerg] unexpected \"}\" in /etc/nginx/sites-enabled/default:45" > test4.log
#5. 디스크 공간 부족 (운영 이슈)
echo -e "Apr 23 10:05:12 ubuntu systemd[1]: Starting Daily apt download activities...\nApr 23 10:05:12 ubuntu systemd[1]: apt-daily.service: Failed to run 'start-pre' task: No space left on device" > test5.log
#6. 정상 작동 로그 (비교용)
echo -e "Apr 23 10:06:30 ubuntu systemd[1]: Started nginx - high performance web server.\nApr 23 10:06:30 ubuntu systemd[1]: Reached target Multi-User System." > test6.log

본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 (B-log) 리뷰로 작성 되었습니다.