Pi-hole + NetworkManager로 기숙사 방에 AP 겸 광고차단 서버 만들기 (1)

kyhw·2026년 9월 4일

pihole

목록 보기
1/4
post-thumbnail

프로그래밍 수업 때문에 산 라즈베리 파이 4가 수업 시간 말고는 서랍에서 놀고 있었다. 동시에 기숙사 방 와이파이는 느렸다. 이 두 가지를 한 번에 풀어보기로 했다.

목표는 세 가지였다.

  1. 파이를 유선에 물려 무선 AP로 세워서 방 속도 문제 해결
  2. Pi-hole로 네트워크 전체 광고, 트래커 차단
  3. DNS 로그를 모아서 나중에 AWS로 보내 이상 트래픽 탐지까지

이 글은 1편으로, 하드웨어 세팅부터 AP가 실제로 트래픽을 잡기 시작할 때까지의 기록이다. 막힌 지점마다 원인을 적어뒀다.

환경: Raspberry Pi 4 (2GB) / Raspberry Pi OS 64-bit (Debian 13, Trixie) / 대학 기숙사 네트워크


0. 왜 라우터가 아니라 파이인가

방에 이더넷 포트는 있는데 노트북에 이더넷 단자가 없었다. 시중 공유기를 사면 되는 것 아닌가 싶지만, 두 가지 이유로 파이를 택했다. 어차피 놀고 있는 장비를 쓰고 싶었고, 공유기는 그 안에서 무슨 일이 일어나는지 안 보인다. 하고 싶은 건 와이파이를 쏘는 것뿐 아니라 그 관문을 지나가는 트래픽을 들여다보는 것이었고, 그러려면 내가 통제하는 리눅스 박스가 필요했다.

만들려는 구조는 이렇다.

이더넷(eth0) ── 라즈베리 파이 4 ── 무선 AP(wlan0)
                    |                    +-- 폰, 노트북
                    +- Pi-hole (DNS 수집, 차단)
                    +- DHCP (주소 배포)
                    +- NAT (인터넷 중계)

1. Pi-hole 설치

OS는 Raspberry Pi Imager로 64비트 버전을 구웠다. SSH만 미리 켜두면 이후 작업은 전부 터미널로 할 수 있어서 모니터가 필요 없다.

설치는 공식 스크립트 한 줄이다.

curl -sSL https://install.pi-hole.net | sudo bash

설치 중 물어보는 것들 가운데 이 프로젝트에서 잘못 고르면 안 되는 두 가지가 있다.

  • Log queries -> Yes
  • Privacy mode -> 0 (Show everything)

이걸 잘못 고르면 도메인이나 클라이언트 정보가 익명화되어 DB에 안 남는다. "어느 기기가 어떤 도메인을 불렀는가"를 분석하는 게 이 프로젝트의 핵심인데 그 데이터가 사라진다. 광고 차단만 할 거면 상관없지만, 로그 분석이 목적이라면 반드시 켜야 한다.

설치가 끝나면 접속 주소와 웹 비밀번호가 뜬다. 비밀번호는 지나가면 다시 못 보니 바로 바꿔둔다.

sudo pihole setpassword

막힌 지점 1. 목록 갱신이 바로 반영되지 않았다

차단이 되는지 확인하는데 실제 IP가 나왔다. 블록리스트에 있는 도메인인데도 차단이 안 됐다.

dig @127.0.0.1 ad-assets.futurecdn.net +short
# 실제 IP가 나옴 (0.0.0.0 이 나와야 정상)

원인은 차단 목록(gravity DB)은 갱신됐는데 FTL 엔진이 그걸 메모리에 다시 안 읽어들인 상태였던 것. 설정을 바꿔도 바로 적용되지 않을 때는 목록을 다시 읽게 해주면 된다.

sudo pihole reloaddns

이걸 한 뒤 다시 확인하니 0.0.0.0이 나왔다. 참고로 예전 자료에 자주 나오는 pihole restartdns는 v6에서 동작하지 않았고, reloaddns가 목록만 다시 읽고 캐시를 비우는 더 가벼운 방법이다.


2. 무선 AP 만들기 (hostapd가 아니라 NetworkManager)

여기서 오래된 튜토리얼과 갈라진다. 검색하면 대부분 hostapd와 dnsmasq를 직접 설치해 설정하라고 나온다. 하지만 최신 Raspberry Pi OS(Trixie)는 NetworkManager가 네트워크를 통합 관리해서, 여기에 hostapd를 따로 올리면 둘이 무선 인터페이스를 서로 차지하려고 충돌한다. NetworkManager 자체의 AP 모드를 쓰는 게 깔끔하다.

막힌 지점 2. wlan0가 unavailable

AP를 만들기 전 무선 상태를 확인했는데 인터페이스가 unavailable이었다.

nmcli device status
# wlan0   wifi   unavailable   --

원인은 국가(무선 규제) 코드가 설정되지 않아 생긴 소프트 블록이었다.

rfkill list
# 1: phy0: Wireless LAN
#     Soft blocked: yes

무선 규제는 나라마다 허용 채널과 출력이 달라서, 국가 코드가 없으면 무선을 아예 잠근다. 미국이라 US로 설정했다.

sudo raspi-config nonint do_wifi_country US
sudo rfkill unblock wifi

이걸 몰라서 "설정은 다 맞는데 신호가 안 잡힌다"로 시간을 날리는 경우가 많다. AP 만들기 전 국가 코드부터 넣는 것을 첫 단계로 삼는 게 좋다.

AP 프로필 생성

NetworkManager로 AP 프로필을 만든다. SSID와 비밀번호는 각자 원하는 값으로.

sudo nmcli connection add type wifi ifname wlan0 con-name pi-ap autoconnect yes ssid <SSID>
sudo nmcli connection modify pi-ap 802-11-wireless.mode ap
sudo nmcli connection modify pi-ap 802-11-wireless.band bg
sudo nmcli connection modify pi-ap 802-11-wireless.channel 6
sudo nmcli connection modify pi-ap wifi-sec.key-mgmt wpa-psk
sudo nmcli connection modify pi-ap wifi-sec.proto rsn
sudo nmcli connection modify pi-ap wifi-sec.pairwise ccmp
sudo nmcli connection modify pi-ap wifi-sec.group ccmp
sudo nmcli connection modify pi-ap wifi-sec.psk "<비밀번호>"
sudo nmcli connection modify pi-ap ipv4.method manual ipv4.addresses 10.10.0.1/24
sudo nmcli connection modify pi-ap ipv6.method disabled
sudo nmcli connection up pi-ap

선택의 이유.

  • 채널은 2.4GHz(band bg) 6번. 기숙사는 5GHz가 덜 붐비지만, 파이 4 내장 무선은 AP 모드에서 2.4GHz가 훨씬 안정적으로 붙는다.
  • IPv6는 비활성화. 안 그러면 클라이언트가 IPv6 경로로 DNS를 우회해서 Pi-hole을 안 거칠 수 있다.
  • AP 주소는 10.10.0.1 고정. 클라이언트가 DNS 서버로 바라볼 주소이자 게이트웨이다.

ip addr show wlan0에 10.10.0.1이 찍히면 신호는 뜬 것이고, 이 시점에 폰 와이파이 목록에 SSID가 보인다. 다만 붙어도 인터넷은 안 된다. 아직 주소를 나눠줄 DHCP도, 밖으로 내보낼 NAT도 없기 때문이다.


3. DHCP 설정

DHCP는 새 기기가 네트워크에 붙었을 때 IP 주소를 자동으로 나눠주는 역할이다. 이게 없으면 기기마다 주소를 손으로 지정해야 한다. 폰이 와이파이에 붙자마자 알아서 주소를 받는 건 DHCP 덕분이다.

주소 배포를 별도 dnsmasq로 돌리면 53번 포트를 두고 Pi-hole의 FTL과 싸운다. Pi-hole에 DHCP 기능이 내장돼 있으니 그걸 쓴다.

막힌 지점 3. 학교 네트워크에 DHCP가 새면 안 된다

가장 조심해야 할 부분이었다. DHCP를 그냥 켜면 파이가 업링크(이더넷) 쪽으로도 주소를 뿌릴 수 있다. 그러면 학교 네트워크에 허가받지 않은 DHCP 서버를 띄우는 꼴이 되어 다른 사람들의 연결을 망가뜨린다. 곧바로 포트 차단감이다.

그래서 DNS와 DHCP를 무선 인터페이스에만 묶은 뒤 켜야 한다.

sudo pihole-FTL --config dns.interface wlan0
sudo pihole-FTL --config dns.listeningMode SINGLE

막힌 지점 4. 활성화를 먼저 하면 거부당한다

dhcp.active부터 켰더니 이렇게 나왔다.

Unable to update dnsmasq configuration: DHCP start address is not valid

주소 범위가 비어 있는 상태에서 활성화를 시도해서 그렇다. 범위를 먼저 넣고 활성화를 맨 마지막에 해야 한다.

sudo pihole-FTL --config dhcp.start 10.10.0.50
sudo pihole-FTL --config dhcp.end 10.10.0.200
sudo pihole-FTL --config dhcp.router 10.10.0.1
sudo pihole-FTL --config dhcp.leaseTime 24h
sudo pihole-FTL --config dhcp.active true
sudo systemctl restart pihole-FTL

이제 폰을 다시 붙이면 10.10.0.x 주소를 받는다. 주소를 받았다는 건 DHCP가 동작한다는 뜻이다.


4. NAT 설정

NAT는 사설 주소(10.10.0.x)를 쓰는 기기들이 바깥 인터넷과 통신할 수 있게 주소를 바꿔주는 역할이다. 폰이 받은 10.10.0.166 같은 주소는 인터넷에서는 못 쓰는 내부용 주소다. 파이가 바깥으로 내보낼 때 자기 이더넷 주소로 바꿔서 대신 내보내고, 응답을 받아 다시 폰에게 돌려준다. 공유기가 늘 하는 일이 이것이다.

# IP 포워딩 활성화
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-ipforward.conf
sudo sysctl -p /etc/sysctl.d/99-ipforward.conf

# nftables로 마스커레이딩
sudo nft add table ip nat
sudo nft 'add chain ip nat postrouting { type nat hook postrouting priority 100 ; }'
sudo nft add rule ip nat postrouting oifname "eth0" masquerade

이 순간 폰에서 인터넷이 됐다.

재부팅해도 살아남게

nftables 규칙은 재부팅하면 사라진다. 그럼 다음에 껐다 켰을 때 인터넷이 안 된다. 규칙을 파일로 저장하고 서비스로 등록해둔다.

sudo apt install nftables -y
sudo systemctl enable nftables
sudo sh -c 'nft list ruleset > /etc/nftables.conf'
sudo systemctl restart nftables

sudo reboot 한 번 하고 폰이 자동으로 붙어 인터넷이 되는지까지 확인해야 끝이다.


5. 결과

방에서 노트북 기준으로 속도를 측정했다.

속도
학교 와이파이 (기존)17 Mbps
파이 AP (유선 백홀)43 Mbps

약 2.5배. 방까지 오는 무선 신호가 약한 게 원인이었고, 파이를 유선에 물려 바로 옆에서 쏘니 그 구간이 사라졌다.

진짜 목적이었던 로그도 확인했다. Pi-hole의 로그 DB를 직접 조회했다.

sudo sqlite3 /etc/pihole/pihole-FTL.db \
"SELECT datetime(timestamp,'unixepoch','localtime'), client, domain, status FROM queries ORDER BY id DESC LIMIT 10;"
...|10.10.0.166|lcdn-locator.apple.com|2
...|10.10.0.166|mask-api.icloud.com|2
...|10.10.0.166|a1366.dscapi6.akamai.net|3

폰이 부르는 도메인이 실시간으로 찍히기 시작했다. 가만히 둔 폰이 몇 초 사이에 얼마나 많은 곳에 접속을 시도하는지 눈에 보인다.

로그를 보다가 하나 배운 것도 있다. mask-api.icloud.com은 iCloud Private Relay인데, 이게 켜져 있으면 폰의 DNS 질의가 암호화되어 Pi-hole을 우회한다. 로그를 온전히 받으려면 해당 네트워크에서 이 기능을 꺼야 한다. 윈도우 노트북이라면 브라우저의 DoH(DNS over HTTPS) 설정이 같은 역할을 하니 함께 꺼주는 게 좋다.


다음 편

여기까지가 토대다.

[완료] Pi-hole DNS 수집, 차단
[완료] 무선 AP (속도 2.5배)
[완료] DHCP + NAT
[완료] 클라이언트 트래픽 로깅
[예정] S3 업로드
[예정] Athena 쿼리
[예정] 이상 트래픽 탐지 + 대시보드

다음 편에서는 이 DNS 로그를 매일 AWS S3로 올리고, Athena로 쿼리하고, 평소 패턴에서 벗어난 이상 트래픽을 잡아내는 파이프라인을 만든다.

읽어주셔서 감사합니다. 질문이나 지적은 언제든 환영합니다.

profile
취업하고싶어요...

0개의 댓글