← --library
이과 · 20이과

네트워크 및 정보 보안

단계1단계2단계3단계4단계5

2단계: 분산 합의, P2P 네트워크, 그리고 침투 테스트


들어가며 — 1단계에서 이 단계로

1단계에서 너는 패킷이 OSI 7계층을 타고 전 세계를 오가는 방식, 소켓이 비동기로 연결을 처리하는 방식, 그리고 HTTP/2와 QUIC이 왜 빠른지를 배웠다. 그 모든 지식의 전제는 하나였다. "서버가 존재한다." 요청을 보내면 받아줄 누군가가 있다는 것, 그 중앙의 존재가 데이터를 들고 있다는 것. 그런데 지금 이 단계에서 우리는 그 전제 자체를 부숴볼 것이다. 만약 서버가 없다면? 만약 모두가 동등하게 데이터를 들고 있다면? 그리고 그 상황에서 누군가 악의적으로 거짓말을 한다면? 이 세 가지 질문이 2단계 전체를 관통한다.


1부. 이론적 기초 — 왜 이 문제가 어려운가

중앙화의 함정

우리가 평소에 쓰는 시스템, 예를 들어 Google 드라이브, 카카오톡, 은행 앱은 모두 **중앙 서버(Central Server)**가 있다. 모든 데이터는 그곳을 통해 흐르고, 그곳이 "진실"을 결정한다. 이 방식은 단순하고 빠르다. 그런데 근본적인 취약점이 하나 있다. **단일 실패 지점(Single Point of Failure, SPOF)**이다. 서버가 불타면, 혹은 누군가 그 서버를 해킹하면, 혹은 그 회사가 데이터를 조작하면, 사용자는 아무것도 할 수 없다. 2021년 페이스북의 DNS 설정 오류로 전 세계 수십억 명이 6시간 동안 카카오, 인스타그램, 왓츠앱을 쓰지 못했던 사건이 정확히 이 문제다.

그렇다면 서버를 여러 개로 늘리면 되지 않을까? 맞다. 그런데 여기서 완전히 새로운 문제가 생겨난다. 여러 서버가 동일한 데이터를 들고 있으려면, 서로 "합의(Consensus)"를 이뤄야 한다. 내가 서버 A에 "잔액 = 100만원"을 썼는데 서버 B는 아직 "잔액 = 50만원"이라고 알고 있다면? 그 찰나에 다른 사용자가 서버 B에서 인출을 시도한다면? 이것이 **분산 데이터 일관성 문제(Distributed Consistency Problem)**다.

CAP 정리 — 세 가지를 동시에 가질 수 없다

[노트 기록] 1998년 Eric Brewer가 제안하고 2002년 Seth Gilbert와 Nancy Lynch가 수학적으로 증명한 **CAP 정리(CAP Theorem)**는 분산 시스템이 동시에 세 가지를 모두 보장할 수 없다고 말한다.

C (Consistency, 일관성): 모든 노드가 같은 순간에 동일한 데이터를 본다. A (Availability, 가용성): 어떤 요청도 항상 응답을 받는다 (실패 없이). P (Partition Tolerance, 분할 내성): 네트워크 일부가 끊어져도 시스템은 계속 작동한다.

실제 인터넷에서 네트워크 분할(패킷 유실, 케이블 손상)은 피할 수 없으므로 P는 포기할 수 없다. 따라서 현실에서 분산 시스템은 CP (일관성 + 분할 내성, 가용성 포기) 또는 AP (가용성 + 분할 내성, 일관성 포기) 중 하나를 선택한다. 예를 들어 은행 시스템은 CP를 선택한다. 네트워크가 끊기면 거래를 멈추더라도, 절대 잔액이 틀려서는 안 된다. 반면 DNS는 AP를 선택한다. 데이터가 약간 구버전이더라도 항상 응답해야 한다.

비잔틴 장군 문제 — 악의적인 노드가 있다면

[노트 기록] 이제 한 층 더 어려운 문제다. **비잔틴 장군 문제(Byzantine Generals Problem)**는 1982년 Leslie Lamport, Robert Shostak, Marshall Pease가 발표한 논문에서 처음 제시되었다. 시나리오는 이렇다. 여러 명의 장군이 군대를 이끌고 도시를 포위하고 있다. 일부 장군은 배신자다. 배신자는 일부에게는 "공격하라", 다른 이에게는 "후퇴하라"고 메시지를 보낼 수 있다. 모든 장군은 전령(메신저)을 통해서만 통신하고, 전령도 가로채질 수 있다. 이 상황에서 충성스러운 장군들만이라도 같은 결정을 내릴 수 있을까?

이것을 컴퓨터 네트워크에 그대로 적용하면 된다. 노드들이 장군이고, 패킷이 전령이다. 그리고 악의적으로 거짓 메시지를 보내는 노드가 비잔틴 장군이다. 단순한 네트워크 장애(충돌, 지연)를 견디는 것은 Paxos와 Raft가 해결한다. 하지만 의도적으로 거짓말하는 악의적 노드를 견디는 것은 PBFT와 블록체인이 해결한다. 이 차이가 이번 단계 전체에서 가장 중요한 분기점이다.


2부. 분산 합의 알고리즘

Paxos — 합의의 원형

Paxos는 Leslie Lamport가 1989년에 논문을 썼지만 너무 어렵다는 이유로 학계에서 무시당했다가 1998년에 재출판된 알고리즘이다. Lamport 자신도 논문 제목을 "The Part-Time Parliament(시간제 의회)"라는 은유로 설명해야 했을 만큼, Paxos는 이해하기 어렵기로 유명하다. 그럼에도 불구하고 Paxos는 Google의 Chubby 락 서비스, Apache Zookeeper의 ZAB 프로토콜의 핵심 사상적 원천이다.

[노트 기록] Paxos에는 세 가지 역할이 있다. Proposer(제안자), Acceptor(수락자), Learner(학습자). 하나의 노드가 여러 역할을 동시에 할 수 있다. 프로토콜은 두 단계로 진행된다.

1단계 — Prepare/Promise: Proposer가 고유 번호 n을 가진 Prepare 메시지를 과반수의 Acceptor에게 보낸다. Acceptor는 n보다 큰 번호의 Prepare를 앞으로 무시하겠다고 약속하고, 자신이 이전에 수락한 제안이 있다면 그것을 함께 돌려준다. 이 단계의 핵심은 **"이미 진행 중인 합의를 방해하지 않겠다는 약속"**을 받아내는 것이다.

2단계 — Accept/Accepted: Proposer가 과반수로부터 Promise를 받으면, Accept 메시지를 보낸다. 이때 보내는 값은 자신이 원하는 값이지만, 만약 Acceptor들이 이미 수락한 값이 있다면 그 중 가장 높은 번호의 값을 대신 사용해야 한다. 이 제약이 Paxos의 안전성 보장의 핵심이다.

왜 과반수인가? 어떤 두 과반수 집합이든 반드시 하나 이상의 공통 원소를 갖는다는 수학적 성질 때문이다 (5개 중 3개와 3개는 반드시 겹친다). 이 공통 원소가 "이전 합의의 증인"이 되어 충돌을 방지한다. Paxos는 이론적으로 완벽하지만, 구현이 매우 어렵다. 리더가 동시에 여럿 생기는 경우, 노드가 중간에 죽는 경우 등 엣지 케이스가 수없이 많다.

Raft — "이해 가능한" 합의

[노트 기록] 2014년 Diego Ongaro와 John Ousterhout는 "In Search of an Understandable Consensus Algorithm"이라는 논문에서 Raft를 발표했다. 논문 제목에 "이해 가능한"이라는 단어가 들어간 것 자체가, Paxos가 얼마나 이해하기 어려웠는지를 보여준다. Raft는 Paxos와 수학적으로 동등한 안전성을 제공하면서도, 의도적으로 개념을 분리하여 이해와 구현을 쉽게 만들었다. 현재 Etcd(Kubernetes의 핵심 저장소), CockroachDB, TiKV 등 수많은 실무 시스템이 Raft를 사용한다.

Raft에서 각 노드는 세 가지 상태 중 하나다. Follower(기본 상태, 리더의 명령을 따름), Candidate(리더 선출에 입후보한 상태), Leader(모든 쓰기 요청을 처리하는 단 하나의 권위자). Raft는 문제를 세 가지 독립적인 하위 문제로 분리한다.

리더 선출(Leader Election): 모든 Follower는 Heartbeat(심장박동 신호)를 일정 시간(Election Timeout, 보통 150-300ms) 동안 받지 못하면 Candidate로 전환한다. Candidate는 자신의 임기(Term) 번호를 1 증가시키고 투표를 요청한다. 과반수 투표를 받으면 Leader가 된다. Term은 Paxos의 제안 번호와 같은 개념이다. 이 Term 개념이 "누가 더 최신 리더인가"를 결정하는 중재자 역할을 한다.

로그 복제(Log Replication): 클라이언트의 모든 쓰기 요청은 반드시 Leader를 통해야 한다. Leader는 이 요청을 **로그 항목(Log Entry)**으로 기록하고, Follower들에게 복제를 요청한다. 과반수가 "저장했다"고 응답하면, Leader는 해당 항목을 **커밋(Commit)**하고 클라이언트에게 성공을 알린다. 이 순서를 반드시 기억하라. 쓰기 → 복제 → 과반수 확인 → 커밋 → 응답. 이 순서가 보장되어야 서버가 중간에 죽더라도 데이터가 유실되지 않는다.

안전성(Safety): Raft는 오직 최신 로그를 가진 노드만 Leader가 될 수 있도록 투표 규칙을 정해놓는다. Follower는 Candidate의 로그가 자신보다 뒤처져 있다면 투표를 거부한다. 이 한 줄이 "커밋된 로그는 절대 사라지지 않는다"는 핵심 안전성 보장을 만들어낸다.

PBFT — 악의를 견디는 합의

위에서 설명한 비잔틴 장군 문제를 기억하는가. Paxos와 Raft는 노드가 고장나거나 멈추는 **충돌 고장(Crash Fault)**만 처리한다. **PBFT(Practical Byzantine Fault Tolerance)**는 1999년 Miguel Castro와 Barbara Liskov가 MIT에서 발표한 알고리즘으로, 노드가 **의도적으로 거짓 메시지를 보내는 비잔틴 고장(Byzantine Fault)**도 처리한다.

[노트 기록] PBFT의 핵심 수학: f개의 악의적 노드를 견디려면 전체 노드가 최소 3f+1개여야 한다. 왜 3f+1인가? 과반수, 즉 2f+1개 이상이 응답해야 하는데 그 중 f개는 악의적일 수 있으므로, 신뢰할 수 있는 응답 f+1개를 보장하려면 2f+1개의 응답이 필요하고, 여기에 f개의 침묵하는 고장 노드까지 더하면 3f+1이 된다.

PBFT는 Pre-prepare → Prepare → Commit의 3단계 프로토콜을 사용한다. 단계가 하나 더 많은 이유는 "내가 이 메시지를 받았다"는 것을 다른 모든 노드에게도 알리는 과정이 필요하기 때문이다. 악의적인 Primary(리더)가 노드들에게 서로 다른 요청을 보내는 것을 막으려면, 모든 노드가 서로의 상태를 교차 검증해야 한다. 이 때문에 PBFT는 메시지 복잡도가 O(n²)으로 노드가 많아질수록 매우 느려진다. 이것이 블록체인이 PBFT 대신 작업 증명(PoW)이나 지분 증명(PoS) 같은 방법을 사용하는 이유다.


3부. P2P 네트워크와 DHT

P2P 네트워크의 구조

1단계에서 너는 클라이언트-서버 모델에서 소켓 연결이 어떻게 이루어지는지 배웠다. P2P(Peer-to-Peer) 네트워크는 그 구조를 뒤집는다. 모든 참여자가 동시에 클라이언트이자 서버다. 이를 **피어(Peer)**라고 부른다. P2P 네트워크는 크게 세 가지 유형으로 분류된다.

비구조적 P2P(Unstructured P2P): 초기 Gnutella(파일 공유 프로그램)가 이 방식이다. 피어들이 임의로 서로 연결되고, 파일을 찾으려면 연결된 모든 피어에게 "이 파일 있어?"라고 묻고, 그 피어들이 또 자신의 이웃에게 묻는 Flooding 방식을 쓴다. 단순하지만 검색이 O(n)으로 확장성이 최악이다.

하이브리드 P2P(Hybrid P2P): BitTorrent가 이 방식이다. 중앙 트래커(Tracker) 서버가 "이 파일을 가진 피어 목록"만 알려주고, 실제 파일 전송은 피어끼리 직접 한다. 검색의 효율성과 P2P의 분산성을 절충한다.

구조적 P2P(Structured P2P): **DHT(Distributed Hash Table)**를 사용하여 피어들이 체계적으로 조직된다. 파일 검색이 O(log N)에 가능하다. 현재 가장 성숙한 P2P 기술이다.

일관된 해싱 — DHT의 핵심 아이디어

[노트 기록] DHT를 이해하려면 먼저 **일관된 해싱(Consistent Hashing)**을 이해해야 한다. 일반 해싱의 문제를 생각해보자. 서버가 5개인 시스템에서 hash(key) % 5로 데이터를 분배한다면, 서버가 하나 추가되어 6개가 되는 순간 거의 모든 데이터의 위치가 바뀐다. 이것은 분산 시스템에서 대재앙이다.

일관된 해싱은 이 문제를 우아하게 해결한다. 0부터 2^m-1까지의 숫자를 원형으로 배치한 **해시 링(Hash Ring)**을 상상하라. 노드들도 이 링 위의 위치를 hash(node_id)로 배정받는다. 데이터 키 k는 hash(k)를 계산한 후 링 위에서 시계 방향으로 가장 가까운 노드에 저장된다. 이제 노드 하나가 추가되거나 제거될 때, 재배치해야 하는 데이터는 그 노드와 인접한 노드들의 데이터뿐이다. 전체 데이터의 약 1/N만 이동하면 된다.

Chord와 Kademlia

Chord는 2001년 MIT에서 발표된 DHT 프로토콜이다. 각 노드는 Finger Table을 유지한다. 이 테이블에는 링 위에서 2^1, 2^2, 2^3, ..., 2^(m-1) 거리만큼 떨어진 노드들의 주소가 저장된다. 이 지수적 점프 덕분에 어떤 키의 담당 노드도 O(log N) 번의 홉(hop)으로 찾을 수 있다. 160비트 링에서 100만 개의 노드가 있어도 20번의 메시지 교환으로 원하는 노드를 찾는다.

Kademlia는 2002년 발표된 DHT로, 현재 BitTorrent와 Ethereum에서 실제로 사용된다. Chord와의 핵심 차이는 거리 계산 방법이다. Kademlia는 두 ID의 XOR 연산 결과를 거리로 정의한다. 1010 XOR 1100 = 0110 = 6. 이 XOR 거리는 대칭적이고(A→B 거리 = B→A 거리), 삼각 부등식을 만족하여 수학적으로 다루기 쉽다. 각 노드는 k-bucket이라는 라우팅 테이블을 유지하고, 여기에 XOR 거리 기준으로 가까운 k개의 노드를 저장한다.


4부. 침투 테스트 방법론과 도구

공격자의 사고방식

앞서 분산 합의와 P2P에서 우리는 "어떻게 시스템을 안전하게 설계하는가"를 배웠다. 이제 관점을 완전히 뒤집는다. **침투 테스트(Penetration Testing, Pentest)**는 권한을 부여받은 상태에서 공격자처럼 생각하고 행동하여 시스템의 취약점을 먼저 발견하는 작업이다. 법적으로 명확한 권한(서면 승인)이 없는 침투 테스트는 범죄다. 이것을 반드시 먼저 기억하라.

침투 테스터는 방어자보다 더 창의적이어야 한다. 방어자는 알려진 모든 취약점을 막아야 하지만, 공격자는 단 하나의 구멍만 찾으면 된다. 이 비대칭성이 보안을 어렵게 만든다.

방법론 — PTES와 OWASP

[노트 기록] 침투 테스트는 즉흥적 해킹이 아니라 체계적 방법론을 따른다. 가장 널리 사용되는 표준은 **PTES(Penetration Testing Execution Standard)**와 OWASP Testing Guide다. 전체 과정은 6단계로 구성된다.

1단계 — 사전 교전(Pre-engagement): 범위(Scope)를 정의한다. 어떤 IP 범위, 어떤 도메인, 어떤 시간대에 테스트할 것인가. 이 문서가 법적 보호막이다.

2단계 — 정보 수집(Reconnaissance): 공격 전에 최대한 많은 정보를 모은다. **수동적 정찰(Passive)**은 대상 시스템에 직접 접촉하지 않고 공개된 정보를 수집한다 (OSINT: Open Source Intelligence). WHOIS 조회, 소셜 미디어, Shodan(인터넷에 연결된 모든 장치를 스캔하는 검색엔진) 등이 사용된다. **능동적 정찰(Active)**은 직접 탐침을 보낸다. 1단계에서 배운 TCP/IP를 생각해보라. Nmap이 보내는 SYN 패킷 하나가 포트의 상태를 알려준다.

3단계 — 스캐닝 & 열거(Scanning & Enumeration): 어떤 포트가 열려있는지, 어떤 서비스가 실행 중인지, 어떤 버전인지를 파악한다. 버전 정보가 중요한 이유는 CVE(Common Vulnerabilities and Exposures) 데이터베이스에서 해당 버전의 알려진 취약점을 검색할 수 있기 때문이다.

4단계 — 취약점 분석(Vulnerability Analysis): 발견된 정보를 바탕으로 실제 공격 가능한 취약점을 식별한다. 자동화 도구와 수동 분석을 병행한다.

5단계 — 익스플로잇(Exploitation): 취약점을 실제로 공격하여 접근 권한을 획득한다. 이 단계에서 Payload(악성 코드 조각)와 Exploit(취약점을 이용하는 코드)을 사용한다.

6단계 — 사후 작업 & 보고(Post-exploitation & Reporting): 얼마나 깊이 침투했는지 확인하고, 발견한 모든 취약점을 명확한 리포트로 작성한다. 리포트는 임원을 위한 요약(Executive Summary)과 엔지니어를 위한 기술 상세(Technical Details) 두 파트로 구성한다.

주요 도구

[노트 기록] 도구는 방법론을 보조할 뿐이다. 도구를 아는 것보다 왜 이 도구가 이 단계에서 사용되는지 이해하는 것이 더 중요하다.

Nmap(Network Mapper): 정보 수집 및 스캐닝 단계의 표준 도구. nmap -sV -O 192.168.1.1은 해당 IP에서 실행 중인 서비스 버전(-sV)과 운영체제(-O)를 탐지한다. 내부적으로는 1단계에서 배운 TCP 3-way handshake의 변형들(SYN scan, FIN scan 등)을 사용한다.

Wireshark: 1단계의 패킷 분석 도구를 기억하는가. Pentest에서는 내부 네트워크의 트래픽을 캡처하여 평문 전송되는 패스워드나 민감한 데이터를 찾는 데 사용한다.

Metasploit Framework: 익스플로잇 단계의 대표 도구. 수천 개의 알려진 CVE 익스플로잇이 모듈 형태로 내장되어 있다. search, use, set, exploit의 간단한 명령어로 취약한 서비스를 공격할 수 있다. 단, Metasploit을 "만능 해킹 툴"로 오해하면 안 된다. 패치된 시스템에는 아무 소용이 없다.

Burp Suite: 웹 애플리케이션 전문 도구. HTTP 요청과 응답을 가로채고 수정할 수 있는 Proxy 기능이 핵심이다. OWASP Top 10(SQL Injection, XSS, IDOR 등)을 테스트하는 데 사용한다. HTTP/2 프로토콜도 지원한다.

Hydra: 브루트포스(Brute-force) 도구. SSH, FTP, HTTP 등 다양한 프로토콜에 대해 패스워드를 자동으로 시도한다. 이 도구의 존재 자체가 "왜 강력한 패스워드와 계정 잠금 정책이 필요한가"를 설명한다.


5부. 프로젝트 — 40분 분량의 문제

아래 세 프로젝트는 정답 없이 문제만 주어진다. 각 문제를 읽고 스스로 설계하고, 코드를 작성하고, 검증해보아라. 막히는 부분은 앞의 이론으로 돌아가 연결 고리를 찾아라.


프로젝트 1. Raft 리더 선출 시뮬레이터 (Python, 약 15분)

설정: 5개의 노드(n0~n4)가 Raft를 실행한다고 가정하자. 실제 네트워크 통신 없이, Python 딕셔너리와 함수 호출로 메시지 전달을 시뮬레이션한다.

문제 1-1: 각 노드의 상태를 표현하는 데이터 구조를 설계하라. 최소한 포함해야 하는 필드가 무엇인지 Raft 이론에서 도출하고, 이유와 함께 설명하라. (힌트: 현재 상태, 현재 임기, 투표 기록을 생각해보라)

문제 1-2: request_vote(candidate_id, candidate_term, candidate_log_length) 함수를 구현하라. 이 함수는 투표 요청을 받은 노드가 찬성 또는 반대를 결정하는 로직이다. Raft의 안전성 보장을 위해 어떤 두 가지 조건이 모두 만족되어야 찬성표를 던지는가?

문제 1-3: n2 노드가 Election Timeout에 걸려 Candidate가 되는 시나리오를 시뮬레이션하라. n0, n1, n3, n4 각각에게 투표 요청을 보내고, 응답을 처리하여 n2가 Leader가 되는 전체 흐름을 코드로 작성하라. n4가 이미 더 높은 Term에서 다른 후보에게 투표했다는 상황을 인위적으로 만들어, n2가 과반수를 얻지 못하는 시나리오도 함께 테스트하라.

문제 1-4 (도전): Raft에서 Split Vote(분할 투표) 상황이란 무엇인가? 5개 노드 중 2개가 동시에 Candidate가 될 때 어떤 일이 벌어지는가? 이것이 무한루프가 되지 않도록 Raft는 어떻게 설계되어 있는가? 이론적으로 설명하고, 이 상황을 재현하는 코드를 작성하라.


프로젝트 2. 미니 DHT 구현 (Python, 약 15분)

설정: 간단한 Chord 스타일의 DHT를 구현한다. 해시 공간은 0~63(2^6)이고, 노드 ID와 키는 모두 이 범위의 정수다. 실제 SHA-1 대신 주어진 값 그대로 사용한다.

문제 2-1: 다음 6개의 노드가 링에 배치되어 있다: ID = {5, 14, 28, 37, 45, 58}. 각 노드의 Successor(시계 방향으로 가장 가까운 노드)를 구하는 find_successor(node_id, all_nodes) 함수를 작성하라. 링이 원형임을 주의하라(58의 Successor는 5다).

문제 2-2: 각 노드의 Finger Table을 계산하라. 해시 공간이 2^6이므로 각 노드는 6개의 항목을 갖는다. 노드 14의 Finger Table 전체를 손으로 계산하고, 이를 자동으로 생성하는 코드를 작성하라.

문제 2-3: key = 22인 데이터를 저장하는 노드는 어디인가? key = 60은? key = 3은? find_responsible_node(key, all_nodes) 함수를 작성하고, 세 가지 케이스를 테스트하라.

문제 2-4: 노드 28이 네트워크를 이탈한다. 이탈 전에 노드 28이 담당하던 키들은 어떤 노드로 재배치되어야 하는가? 이 재배치 과정에서 이동해야 하는 데이터의 양이 전체 데이터의 약 1/N임을 직접 확인해보아라.

문제 2-5 (도전): Kademlia의 XOR 거리를 기반으로, 노드 ID 0b001010(10진수 10)에서 key 0b110101(10진수 53)을 찾아가는 과정을 시뮬레이션하라. 각 홉에서 어떤 노드를 선택하는지 설명하라.


프로젝트 3. 취약점 스캐너 제작 (Python, 약 10분)

중요 전제: 아래 모든 문제는 localhost(127.0.0.1) 또는 직접 구축한 테스트 서버에 대해서만 실행한다. 외부 시스템에 무단으로 실행하는 것은 불법이다.

설정: Python의 socket 모듈과 http.client 모듈만 사용한다. 외부 라이브러리 없이 구현한다.

문제 3-1: 포트 스캐너를 구현하라. scan_ports(target_ip, port_range) 함수가 지정된 IP의 포트 범위를 스캔하고, 열린 포트 목록을 반환한다. TCP 3-way handshake(connect 성공 여부)로 열린 포트를 판단한다. localhost에서 python -m http.server 8080을 실행한 뒤, 스캐너가 8080번 포트를 열린 것으로 탐지하는지 확인하라. 타임아웃 처리를 반드시 포함하라.

문제 3-2: 위 포트 스캐너에 배너 그래빙(Banner Grabbing) 기능을 추가하라. 열린 포트에 연결한 직후, 서버가 먼저 보내는 응답 메시지(배너)를 읽는다. HTTP 서버에서는 어떤 배너가 나오는가? SSH 서버(포트 22)가 열려있다면 어떤 배너가 나오는가? 배너에서 서비스 종류와 버전을 추출하는 로직을 추가하라.

문제 3-3: 간단한 디렉토리 열거(Directory Enumeration) 기능을 구현하라. 워드리스트(wordlist) — 즉 흔히 쓰이는 경로 이름의 목록(예: /admin, /login, /config, /backup, /api) — 를 이용하여, HTTP 서버에 각 경로로 요청을 보내고 응답 코드를 기록한다. 200(정상), 403(접근 금지), 404(없음), 301/302(리다이렉트)를 구분하여 보고서를 출력하라. localhost:8080에서 실제로 존재하는 경로와 존재하지 않는 경로를 각각 만들어 테스트하라.

문제 3-4 (도전): 스캐너를 통합하여 다음 순서로 동작하는 자동화 파이프라인을 만들어라. ① 포트 스캔 → ② HTTP 포트 탐지 → ③ 디렉토리 열거 → ④ 결과를 JSON 형식의 보안 리포트로 저장. 리포트에는 스캔 시각, 대상 IP, 발견된 포트, 발견된 경로, 각 항목의 위험도(열린 포트 수, 접근 가능한 민감 경로 수 기준)가 포함되어야 한다.


마치며 — 세 주제의 연결

이 단계의 세 주제는 사실 하나의 거대한 그림의 세 조각이다. 분산 합의는 "여러 노드가 합의에 도달하는 방법"이고, P2P와 DHT는 "그 노드들이 중앙 없이 서로를 찾는 방법"이다. 그리고 침투 테스트는 "그렇게 구축한 시스템의 진짜 약점을 찾는 방법"이다. 블록체인은 이 세 가지를 하나로 통합한 가장 유명한 사례다. Kademlia로 피어를 찾고, PBFT의 변형으로 합의하며, 침투 테스터들의 수년간의 공격을 버텨내며 강화되었다. 3단계의 제로 트러스트 아키텍처에서는, 오늘 배운 "악의적 노드를 가정한 설계"가 그대로 기업 네트워크 설계 철학으로 이어진다.

← 단계 1단계 3