macvlan으로 docker-pi-hole 설치하기
앞서 설명한 macvlan으로 도커 네트워크를 생성하는 것을 이해하고 잘 따라왔다면 docker-pi-hole의 설치는 어렵지 않습니다. 지금까지는 docker 명령어를 썼지만 pi-hole 설치에는 docker-compose를 써보도록 하겠습니다.
저는 /volume1/docker 아래에 docker-compose.yml과 .env를 만들고 설정 파일들도 모두 한 곳에서 관리합니다.
이걸 기준으로 예를 들어보겠습니다.
docker-compose.yml 내용
version: '3.5' services: pihole: container_name: pihole image: pihole/pihole:latest restart: always logging: # 시놀로지 도커에서는 logging-driver를 json-file로 강제 지정해서 SSH에서 로그 확인 가능 'docker logs 컨테이너이름' driver: json-file networks: macvlan: ipv4_address: ${PIHOLE_IP} hostname: pihole mac_address: d0:ca:ab:cd:ef:01 # pi-hole이 제공하는 DHCP를 사용한다면 아래 두 줄 주석 제거 # cap_add: # - NET_ADMIN ports: - 53/tcp - 53/udp # - 67/udp # pi-hole이 제공하는 DHCP를 사용한다면 주석 제거 - 80/tcp - 443/tcp environment: - TZ=Asia/Seoul - WEBPASSWORD=${SIMPLE_PASS} # 주석처리하면 랜덤으로 지정됨 - DNS1=1.1.1.1 - DNS2=8.8.8.8 # - IPv6=False - DNSSEC=True - ServerIP=${PIHOLE_IP} - VIRTUAL_HOST=pi.hole - DNSMASQ_LISTENING=local volumes: - ${DOCKER_ROOT}/pihole/etc-pihole:/etc/pihole - ${DOCKER_ROOT}/pihole/etc-dnsmasq.d:/etc/dnsmasq.d networks: macvlan: name: macvlan driver: macvlan driver_opts: parent: eth0 ipam: config: - subnet: 192.168.1.0/24
시놀에다가 올린 docker-compose.yml에서 pi-hole 관련 부분만 발췌하였습니다. 설명을 덧붙이면
1. driver는 macvlan, name도 macvlan, driver_opts.parent는 eth0, subnet은 192.168.1.0/24로 macvlan network를 설정
자신의 환경에 맞게 subnet과 driver_opts.parent 값을 수정해주세요. 공유기 IP가 192.168.0.1인 경우는 192.168.0.0/24로 하는 식으로. 그리고 시놀로지면 driver_opts.parent 값은 eth0가 맞을겁니다. open vswitch가 켜져있으면 이 값이 달라질 수 있으니 SSH에서 ifconfig로 확인 필요.
2. 고정 IP ${PIHOLE_IP}에서 동작하고 upstream DNS가 1.1.1.1/8.8.8.8로 동작하는 pi-hole 컨테이너를 설정
환경 변수가 몇 개 있는데, docker-compose.yml 파일이 저장된 곳에 .env 파일을 아래와 같이 만들어 두면 기본값으로 인식합니다. (가장 첫 그림 확인)
# PATH DOCKER_ROOT=/volume1/docker PIHOLE_IP=192.168.1.77 SIMPLE_PASS=this_is_password
그러니까 저는 192.168.1.77을 pi-hole의 고정 IP로 사용할겁니다. 원하시는 IP로 수정하세요. WEBPASSWORD에 대입되는 SIMPLE_PASSWORD도 수정하세요.
docker-compose.yml에 보면 두 개의 폴더를 볼륨으로 사용한다고 명시해뒀는데 없을테니 만들어주고, pihole 컨테이너를 띄웁니다.
mkdir -p /volume1/docker/{etc-pihole,etc-dnsmasq.d} docker-compose up -d pihole
이렇게 하면 docker-compose가 의존성이 있는 macvlan network도 생성한 다음, 컨테이너를 올려줍니다.
docker-compose logs pihole 명령을 쳐서 컨테이너 로그를 보면,
광고 차단 리스트 불러오는 등 초기 설정을 끝내고 [services.d] done. 까지 나오면 잘 설치된겁니다.
공유기에서도 지정한 IP와 mac_address로 잘 올라가 있습니다.
mac_address 값은 필수는 아니지만 눈으로 확인하기 편해서 지정했습니다. dhcp lease에도 테스트할때 계속 랜덤하게 바뀌는 것보다는 나을 것 같구요. hostname도 비슷하게 보기 편하라고... (근데 공유기 network map에는 안나오네요)
pihole이 DNS단에서 광고 차단을 한다고 했으니 공유기 아래의 모든 기기가 pihole의 IP를 DNS로 가리키도록 해야 혜택을 누릴 수 있습니다. ASUS 멀린펌 기준 LAN > DHCP Server로 가서 아래와 같이 설정합니다.
다른건 그대로 두고 DNS Server 1에 앞에 pihole 컨테이너의 IP를 넣어줍니다. pihole의 기능을 100% 활용하려면 두번째 DNS는 비우고 Advertise router's IP in addition to user-specific DNS도 No로 해줍니다. 다시 말해 유일한 DNS로 pihole만 남기라는건데 이러면 pihole이 죽었을 때 집안 네트워크가 다 먹통이 되는 일이 발생합니다. failover에 대한 대비가 필요한데 이 부분은 저도 알아보고 있는 중...
이제 네트워크 어댑터 상태를 확인해보면
유일한 DNS 서버로 192.168.1.77이 올라와 있네요.
이제 비로소 컨테이너의 환경변수로 줬던 VIRTUAL_HOST=pi.hole으로 pihole webui를 접근할 수 있습니다.
미리 설치해둔거라 통계가 조금 쌓였습니다. 지정한 WEBPASSWORD로 로그인하면 dashboard에
이런 놈들이 광고 도메인이군...하고 확인 가능하고
어떤 기기가 DNS쿼리를 많이 날리나 ~= 인터넷을 많이 쓰나 확인 가능합니다. 저 mijia-clock은 샤오미 알람 시계인데 시간 동기화를 무척 자주 하더군요. 아이패드 미니만큼 요청이 있다니...
query_log도 상세하게 확인 가능
이 정도입니다. 하루이틀 써보니 살짝 체감이 되는 정도인데 오!! 이런게 돌아가고 있군 하는 만족감이 더 큰것 같습니다. ㅎㅎ
더 시도해볼 것 - DNS-over-TLS (DOT)
현재는 pihole을 DNS로 쓰는 기기에서 pihole에게 이 도메인 네임은 뭐여? 라고 물어봤을 때, 기존 요청이 있어서 캐쉬되어 있으면 바로 답을 알려주고, 아니면 연결된 외부 DNS에 요청을 전달해서 도메인 네임을 알려줍니다. 이 외부 DNS가 도커 환경변수로 준 DNS1/DNS2 입니다.
최종 목적지가 되는 이들 DNS는 공개 DNS인데 여기에 별도의 DNS 서버를 하나 더 추가하는 것을 고려해 볼수 있습니다. 그러니까 cloudflare를 예로 들면,
client >>> pihole >>> internal dns server >>> (dns-over-tls/dnssec) >>> cloudflare dns
이런 식인거죠. 굳이 이렇게 하는 목적은 보안인데, 하나를 중간에 더 거치니 성능 하락이 있겠지만 캐싱이 잘 되어 있어서 처음 접속하는 도메인이 아니라면 성능이 꽤 괜찮다고... 사람들은 자기가 가는 사이트만 주로 가니까요.
중간 경유의 internal dns server는 보통 unbound나 stubby를 많이 쓰는데 unbound가 대세인것 같습니다. 공홈에서도 unbound로 설명. https://docs.pi-hole.net/guides/unbound/
도커 이미지로는 https://github.com/qdm12/cloudflare-dns-server 이런게 있는데 이걸 macvlan network로 올리고 (예를 들어 192.168.1.78) pihole의 DNS로 지정하면 위에 적어둔 DNS 쿼리 흐름을 완성할 수 있습니다.
다른 이미지를 쓰지만 이 DNS 구조를 구현하는 예시는 여기서 볼 수 있습니다. https://github.com/chriscrowe/docker-pihole-unbound
더 시도해볼 것 - 라우터에 직접 설치
https://discourse.pi-hole.net/t/run-pihole-directly-on-asus-merlin-dd-wrt-router/182
https://www.snbforums.com/threads/installing-pihole-directly-on-asus-router.57262/page-2
아마 이게 이상적인 방법이 아닐까 싶지만 아직 못해봤습니다.
근데 라우터에 직접 설치하기엔 diversion이 더 낫다는 말도 있더군요.
일단 글은 여기서 마무리하고 더 추가할 것이 있으면 보강해 나가겠습니다.