OpenWrt DNS 설정

보안 DNS

기본적으로 dns 쿼리는 53번 포트를 이용해 평문으로 패킷을 전송합니다. 이것은 우리가 웹브라우저를 통해 https 웹사이트에 접속하더라도 dns 쿼리는 여전히 53번포트를 이용해 암호화하지 않고 평문으로 전송되기 때문에 노출되게 되며 정부나 포털, 광고주 또는 악의적인 사람들은 사용자의 접속 정보를 추적하고 수집할 수 있습니다.

이러한 개인 프라이버시 침해를 방지하기 위해 dns 쿼리 및 응답을 평문이 아닌 암호화하기 위해 개발된 표준이 DNS over TLS (DoT)와 DNS over Https (DoH)입니다.

각 표준은 개별로 개발되었으며 RFC 표준이 따로 존재하지만 가장 큰 차이점은 사용하는 포트가 다르다고 보면 됩니다.

구분DNS over TLS (DoT)DNS over HTTPS (DoH)
IETFRFC 7858, 8310RFC 8484
포트853 (고정)443 (가변)
layertransport layerapplication layer
특징사용자 차원에서는 dns 쿼리 및 응답은 암호화 하지만
전용포트를 사용하므로 tls를 통한dns를 사용한다는 것을 알 수 있으므로 차단할 수 있으나
네트워크 관리 차원에서는 전용포트를 사용하므로 악성 트래픽을 차단하거나 모니터링 할 수 있으므로 유용
DoH 쿼리는 일반 https 트래픽에 숨겨져 있으므로 다른 모든 https 트래픽도 차단하지 않고는 쉽게 차단할 수 없어 사용자에게는 더 많은 개인정보보호
네트워크 계층 차이로 인한 많은 코딩, 라이브러리 필요하고
패킷 크기가 DoT보다 크며
약간 더 긴 지연시간 발생
참고google, mozilla 같은 브라우저로 먹고사는 회사에서 밀고 있음

참고로 DoT나 DoH 둘 중에 하나만 설치하면 되며, 먼저 DoT 다음은 DoH 설치방법을 설명합니다.

OpenWrt에 stubby 사용하기 (DoT)

opkg update
opkg install stubby ca-bundle

/etc/config/stubby를 다음과 편집합니다.

  • ipv4 루프백 인터페이스의 포트 5453에서 stubby가 수신하도록합니다. (127.0.0.1#5453)
  • ipv6은 주석처리 합니다. (현재 국내 isp는 ipv6 서비스를 하지 않습니다.) (0::[email protected])
  • option manual '1'로 설정하면 /etc/config/stubby의 설정은 모두 무시하고 원래 stubby 설정화일인 json 형식의 /etc/stubby/stubby.yml 화일을 설정화일로 인식하여 서비스를 구동하게 되며, option manual '0'으로 설정하면 OpenWrt 통합설정인터페이스인 uci 형식의 /etc/config/stubby로 설정을 구성하고 서비스를 구동합니다. 아래 구성은 uci를 통한 구성의 예입니다.(json 형식이 원래 stubby의 설정화일이라 그런지 좀 더 정교한 설정이 가능하다고 하는데 사실 uci 형식과 구성의 차이는 없습니다.)
  • 본 예제처럼 upstream resolver는 cloudflare dns 1.1.1.1 및 1.0.0.1을 사용할 경우 idle_time을 9000으로 설정합니다.
config stubby 'global'
        option manual '0'
        option trigger 'wan'
        option triggerdelay '2'
        list dns_transport 'GETDNS_TRANSPORT_TLS'
        option tls_authentication '1'
        option tls_query_padding_blocksize '128'
        option appdata_dir '/var/lib/stubby'
        option edns_client_subnet_private '1'
        option idle_timeout '9000'
        option round_robin_upstreams '1'
        list listen_address '[email protected]'
#       list listen_address '0::[email protected]'
        option tls_min_version '1.3'
#       option tls_max_version '1.3'

# Upstream resolvers are specified using 'resolver' sections.
config resolver
        option address '1.1.1.1'
        option tls_auth_name 'cloudflare-dns.com'

config resolver
        option address '1.0.0.1'
        option tls_auth_name 'cloudflare-dns.com'

/etc/config/network를 다음을 추가 및 편집합니다. 그리고 설정하는 김에 ipv6 대한 설정을 죽입니다.

...
config interface 'lan'
        ...
        option ipv6 '0'

config interface 'wan'
        ...
        option peerdns '0'
        option dns '127.0.0.1'
        option ipv6 '0'

config interface 'wan6'
        ...
        option peerdns '0'
        option dns '0::1'
        option auto '0'
...

dnssec 사용을 위해 dnsmasq패키지를 제거하고 dnsmasq-full 패키지를 설치합니다.

opkg install dnsmasq-full --download-only && opkg remove dnsmasq && opkg install dnsmasq-full --cache . && rm *.ipk

/etc/config/dhcp를 다음과 같이 추가 및 편집합니다.

config dnsmasq
        ...
        option noresolv '1'
        option dnssec '1'
        option dnsseccheckunsigned '1'
        list server '127.0.0.1#5453'
#       list server '0::1#5453'
        list server '/openwrt.pool.ntp.org/1.1.1.1'

config dhcp 'lan'
        ...
        option dhcpv6 'disabled'
...

서비스 재시작 (아래 network 재시작은 ssh 연결이 끊기므로 ssh 재접속 해야 합니다.)

/etc/init.d/stubby restart
/etc/init.d/dnsmasq restart
/etc/init.d/odhcpd stop
/etc/init.d/odhcpd disable
/etc/init.d/network restart

dnssec 유효성 검사 작동 확인을 위해 dig 명령으로 확인합니다. flags: qr rd ra ad; 부분에서 ad플래그는 dnssec 유효성 검사가 작동 중임을 나타냅니다. 해당 플래그가 없으면 dnssec 유효성 검사가 작동하지 않는 것 입니다.

opkg install bind-dig
dig qquack.org +dnssec +multi @127.0.0.1

; <<>> DiG 9.16.6 <<>> qquack.org +dnssec +multi @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14736
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;qquack.org.            IN A

;; ANSWER SECTION:
qquack.org.             300 IN A 104.24.106.41
qquack.org.             300 IN A 104.24.107.41
qquack.org.             300 IN A 172.67.214.156
qquack.org.             300 IN RRSIG A 13 2 300 (
                                20201101035709 20201030015709 34505 qquack.org.
                                xUSjpHO9vKhOlj3Dbw3IFFxSpwXYyg1Dwf9m8nr6H+kF
                                bB2RaUirMeemaaazEt38g/yuUgYLUlph4Hl72vuBNg== )

;; Query time: 130 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Oct 31 11:57:09 KST 2020
;; MSG SIZE  rcvd: 233

OpenWrt에 https-dns-proxy 사용하기 (DoH)

https-dns-proxy 패키지를 설치하고 설치를 완료하면 자동으로 서비스를 시작하는데 일단 서비스를 종료시킵니다. (필요한 경우 luci-app-https-dns-proxy를 설치하면 luci를 통해 설정을 할 수 있습니다.)

opkg update
opkg install https-dns-proxy ca-bundle
/etc/init.d/https-dns-proxy stop

/etc/config/https-dns-proxy를 다음과 같이 수정합니다. 저는 구글 dns는 주석처리하여 cloudflare dns만을 이용하고, option update_dnsmasq_config 는 '*" 에서 '-'로 수정하여 https-dns-proxy 데몬이 시작시 /etc/config/https-dns-proxy 설정을 스크립트에 의해 자동으로 /etc/config/dhcp화일에 반영하고 dnsmasq 데몬을 재시작하는데 이를 방지하였습니다.

config main 'config'
        option update_dnsmasq_config '-'

#config https-dns-proxy
#       option bootstrap_dns '8.8.8.8,8.8.4.4'
#       option resolver_url 'https://dns.google/dns-query'
#       option listen_addr '127.0.0.1'
#       option listen_port '5053'
#       option user 'nobody'
#       option group 'nogroup'

config https-dns-proxy
        option bootstrap_dns '1.1.1.1,1.0.0.1'
        option resolver_url 'https://cloudflare-dns.com/dns-query'
        option listen_addr '127.0.0.1'
        option listen_port '5054'
        option user 'nobody'
        option group 'nogroup'

/etc/config/network를 다음을 추가 및 편집합니다. 그리고 설정하는 김에 ipv6 대한 설정을 죽입니다. (위의 stubby의 설정과 같음)

...
config interface 'lan'
        ...
        option ipv6 '0'

config interface 'wan'
        ...
        option peerdns '0'
        option dns '127.0.0.1'
        option ipv6 '0'

config interface 'wan6'
        ...
        option peerdns '0'
        option dns '0::1'
        option auto '0'
...

dnssec 사용을 위해 dnsmasq패키지를 제거하고 dnsmasq-full 패키지를 설치합니다.

opkg install dnsmasq-full --download-only && opkg remove dnsmasq && opkg install dnsmasq-full --cache . && rm *.ipk

/etc/config/dhcp를 다음과 같이 추가 및 편집합니다.

config dnsmasq
        ...
        option noresolv '1'
        option dnssec '1'
        option dnsseccheckunsigned '1'
        list server '127.0.0.1#5054'
        list server '/openwrt.pool.ntp.org/1.1.1.1'

config dhcp 'lan'
        ...
        option dhcpv6 'disabled'
...

서비스 재시작 (아래 network 재시작은 ssh 연결이 끊기므로 ssh 재접속 해야 합니다.)

/etc/init.d/https-dns-proxy start
/etc/init.d/dnsmasq restart
/etc/init.d/odhcpd stop
/etc/init.d/odhcpd disable
/etc/init.d/network restart

위의 stubby 처럼 dig 명령으로 dnssec 테스트를 해보시기 바랍니다.

DNS hijacking/redirect

라우터 하부 lan에 물려있는 개별 장치의 dns 설정은 라우터의 dns설정을 우선하기 때문에 lan 하부 장치의 dns 설정 주소가 라우터 주소(192.168.1.1)가 아니거나 자동으로 받기가 아니라면 아무리 라우터에 dns를 안전하게 구성하다라도 lan 하부 장치의 dns트래픽은 라우터를 거쳐갈뿐 라우터 dns를 이용하지 않습니다. lan 하부 장치들에게 라우터 dns 이용을 강제하고 싶다면 dns 트래픽을 가로채기(하이재킹)를 구성합니다. vi편집기로 아래와 같이 방화벽 설정화일을 수정합니다. (단 클라이언트가 브라우저나 별도 프로그램으로 DoT, DoH를 수행하도록 설정된 경우 요청을 리디렉션하지 않습니다.)

vi /etc/config/firewall

...
config redirect
        option name 'DNS-hijacking'
        option src 'lan'
        option src_dport '53'
        option proto 'tcp udp'
        option target 'DNAT'

방화벽 재시작

/etc/init.d/firewall restart

참고사이트

Comments

No comments yet. Why don’t you start the discussion?

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다

1  ×    =  10