리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.

리눅스 시스템 기초 44 / 50 · Part 5. 네트워크·보안·SOC
실습 환경: Rocky Linux 9 (10.0.0.200) · ss·ip 출력은 실습 컨테이너의 실제 출력 (실습용 서비스만 발췌)
이전 글: 43. Socket 이해

1. 들어가며

1편에서 서버 상태를 처음 확인할 때 ss -tulnp를 실행했다. 그때는 "열린 포트를 보는 명령" 정도로 넘어갔지만, 41~43편을 거친 지금은 그 출력의 각 칸이 무엇을 뜻하는지 설명할 수 있다.

  • Local Address 는 소켓이 bind()한 주소다(43편).
  • State 는 TCP 상태다(42편).
  • Process 는 /proc/PID/fd의 소켓 inode와 연결한 결과다(43편).

이번 글은 ss와 ip를 관제 현장에서 쓰는 방식 으로 정리한다. 핵심 질문은 두 가지다.

  1. 이 서버는 밖에서 접근 가능한 어떤 서비스를 열어 두었는가?
  2. 이 서버는 지금 누구와 통신하고 있는가?

2. 핵심 개념

2-1. ss 주요 옵션

옵션의미
-t / -u / -xTCP / UDP / Unix 소켓
-l대기(LISTEN) 소켓만. 없으면 연결된 소켓
-a전부
-n이름 변환 없이 숫자로 (빠르고 정확)
-p프로세스 표시 (root로 실행해야 전체가 보임)
-e추가 정보 (uid, inode)
-o타이머 정보 (keepalive, TIME-WAIT 남은 시간)
-s요약 통계

2-2. 바인딩 주소로 노출 판단

Local Address접근 범위판단
127.0.0.1:포트 / [::1]:포트서버 내부에서만외부 노출 없음
0.0.0.0:포트 / [::]:포트 / *:포트모든 인터페이스방화벽이 없으면 외부 노출
10.0.0.200:포트해당 인터페이스만그 네트워크에서 접근 가능

DB(3306, 5432), Redis(6379), Elasticsearch(9200) 같은 내부용 서비스가 0.0.0.0에 열려 있으면 대표적인 설정 취약점이다.

2-3. 필터 문법

ss -tn state established                       # 상태
ss -tn '( dport = :22 or sport = :22 )'        # 포트
ss -tn dst 203.0.113.50                        # 상대 IP
ss -tn src 10.0.0.200 '( dport = :443 )'       # 조합

state에는 established, listening, syn-sent, syn-recv, time-wait 등을 쓴다.

2-4. ip 명령어

명령내용
ip -br addr인터페이스별 IP 요약
ip route / ip route get <IP>라우팅 표 / 특정 목적지의 실제 경로
ip neighARP 이웃 표 (IP ↔ MAC)
ip -s link인터페이스 송수신·에러·드롭 통계

netstat, ifconfig, route, arp는 net-tools 패키지로 최신 배포판에는 기본 설치되지 않는다. 같은 정보를 ss와 ip로 볼 수 있다.


3. 동작 원리

ss -tulnp 한 화면으로 노출 서비스를 판단한다

실습 환경에서 실습용 서비스 네 개를 띄우고 확인한 실제 출력이다.

$ sudo ss -tulnp
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0            0.0.0.0:5514       0.0.0.0:*    users:(("python3",pid=2041,fd=3))
tcp   LISTEN 0      128        127.0.0.1:22         0.0.0.0:*    users:(("sshd",pid=1788,fd=4))
tcp   LISTEN 0      5          127.0.0.1:8080       0.0.0.0:*    users:(("python3",pid=1790,fd=3))
tcp   LISTEN 0      5            0.0.0.0:8081       0.0.0.0:*    users:(("python3",pid=2043,fd=3))
줄판단
udp 5514, 0.0.0.0UDP는 연결 상태가 없어 UNCONN. 모든 인터페이스에서 수신 → 외부 노출
tcp 22, 127.0.0.1sshd가 내부 전용으로 설정됨(실습용 ListenAddress 127.0.0.1)
tcp 8080, 127.0.0.1내부 전용
tcp 8081, 0.0.0.0모든 인터페이스 에 노출. 방화벽 규칙으로 막고 있는지 확인 필요

LISTEN 줄의 Send-Q는 대기열(backlog) 최대 크기 다(sshd 128, 파이썬 5). 연결이 수립된(ESTAB) 소켓에서는 아직 상대가 받지 않은 데이터 양을 뜻한다.

ss는 커널의 netlink 인터페이스 로 소켓 정보를 직접 요청한다. /proc/net/tcp를 문자열로 파싱하던 netstat보다 빠르고, 연결이 수만 개인 서버에서도 쓸 수 있다.


4. 실습

# 1) 노출 서비스 목록 (root 로)
sudo ss -tulnp

# 2) 모든 인터페이스에 열린 것만
sudo ss -tulnp | awk 'NR==1 || $5 ~ /^(0\.0\.0\.0|\*|\[::\]):/'

# 3) 현재 수립된 연결 (프로세스 포함)
sudo ss -tnp state established

# 4) 외부(사설 대역이 아닌) 상대와의 연결
sudo ss -tnp state established | awk 'NR>1 {split($4,a,":"); ip=a[1];
  if (ip !~ /^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)/) print}'

# 5) SSH 접속 현황
ss -tn state established '( sport = :22 )'
who; last -n 5          # 로그인 기록과 대조 (10편)

# 6) 상태별 개수 · 요약
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c
ss -s

# 7) ip
ip -br addr; ip route; ip neigh; ip -s link show eth0

5. 결과 분석

아래 출력은 형식 설명용 예시다.

① 기준값과 비교해 새로 생긴 포트

$ diff <(cut -c1-80 baseline_ss.txt) <(sudo ss -tulnp | cut -c1-80)
> tcp   LISTEN 0  128   0.0.0.0:31337   0.0.0.0:*   users:(("kworkerd",pid=7811,fd=5))
단서해석
기준값에 없던 포트 31337새로 열린 대기 포트
0.0.0.0외부에서 접속 가능
이름 kworkerd커널 스레드 [kworker]를 흉내 낸 이름. 진짜 커널 스레드는 소켓을 열지 않는다(4·29편)

→ 바인드 쉘(백도어 대기 포트) 의심. /proc/7811/exe, 부모, 실행 계정을 확인한다.

② 웹 서버 워커의 외부 연결

$ sudo ss -tnp state established dst 203.0.113.50
0  0  10.0.0.200:51844  203.0.113.50:4444  users:(("sh",pid=7900,fd=3))

웹 서버는 요청을 받는 쪽이다. 서버가 외부 IP의 비표준 포트로 먼저 연결 했다면 43편의 리버스 쉘이나 다운로더를 의심한다.


6. 보안 관점

점검위험조치
내부용 서비스가 0.0.0.0DB·캐시 외부 노출 (무인증 접근, 랜섬)bind-address=127.0.0.1 등 설정 + 방화벽
기준값에 없는 LISTEN백도어프로세스 조사 (29·35편)
서버 → 외부 ESTABC2, 데이터 유출프로세스·계정 식별, 차단
-p 없이 본 결과다른 계정 프로세스가 안 보임반드시 sudo
ss 결과 자체변조 가능/proc/net/tcp 직접 대조 (43편), 외부 스캔과 비교

호스트 안의 ss 결과와 밖에서 본 결과는 다를 수 있다. ss는 대기 중인 포트를, 외부 스캔은 방화벽을 통과해 실제로 도달 가능한 포트를 보여준다. 둘 다 확인해야 정확하다.


7. SOC / 보안관제 활용

7-1. 네트워크 스냅샷

{
  date; ip -br addr; ip route
  sudo ss -tulnp
  sudo ss -tnp state established
  sudo ss -tn state syn-sent        # 나가는 연결 실패 (C2 재시도)
} > /root/evidence/net_$(hostname)_$(date +%Y%m%d_%H%M).txt

7-2. 분석 흐름

[Alert]   외부 스캔 결과: 10.0.0.200:31337 open (정기 점검)
   ↓
[ss]      sudo ss -tulnp → 0.0.0.0:31337 kworkerd pid=7811
   ↓
[프로세스] /proc/7811/exe → /var/tmp/.cache/kworkerd (deleted) · PPID 1 · root
   ↓
[지속성]  systemctl · cron · rc 스크립트 확인 (36·38편)
   ↓
[Response] STOP → 증적 → 차단·제거, 기준값 갱신

8. 핵심 정리

  • ss -tulnp = TCP·UDP·대기·숫자·프로세스. root로 실행 해야 전체가 보인다.
  • 127.0.0.1 = 내부 전용, 0.0.0.0·[::]·* = 모든 인터페이스 (실습 출력으로 비교).
  • 필터: state established, '( dport = :22 )', dst <IP>.
  • ip -br addr, ip route, ip neigh, ip -s link가 ifconfig, route, arp를 대체한다.
  • 판단 순서: 노출(0.0.0.0) → 프로세스·계정·경로 → 기준값 비교 → 방화벽 실제 차단 여부.

9. 다음 글

다음 글 「45. SSH 구조 이해」 에서는 관제에서 가장 많이 다루는 원격 접속 서비스 SSH를 본다. 접속 흐름(키 교환 → 인증 → 세션), sshd의 권한 분리 프로세스 구조, 비밀번호와 공개키 인증, sshd_config 보안 설정, 그리고 실습 환경에서 남긴 실제 sshd 로그 를 읽는다.


참고 자료

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글