Migrasi DNS-over-HTTPS dari cloudflared ke dnscrypt-proxy

Beberapa tahun lalu saya menulis cara setup DNS-over-HTTPS dengan cloudflared, memakai perintah cloudflared proxy-dns sebagai resolver DoH lokal. Setup itu bertahan cukup lama, sampai akhirnya berhenti berfungsi.

Ternyata Cloudflare menghapus perintah proxy-dns dari cloudflared. Mulai rilis 2 Februari 2026 fitur ini dihilangkan dari semua rilis baru, dan benar-benar dihapus di versi 2026.2.0 — konon karena ada kerentanan di salah satu library yang dipakai, dan proxy-dns sendiri memang fitur yang tidak pernah didokumentasikan resmi.

Jadi kalau kamu masih pakai setup lama itu, cepat atau lambat DNS akan berhenti jalan setelah cloudflared ter-update. Di tulisan ini saya berbagi penggantinya: dnscrypt-proxy.

Kenapa dnscrypt-proxy?

dnscrypt-proxy adalah resolver DNS lokal yang mendukung DoH (DNS-over-HTTPS), DNSCrypt, dan protokol terenkripsi lainnya. Beberapa alasan saya memilihnya sebagai pengganti langsung:

Install

brew install dnscrypt-proxy

Konfigurasi

Config ada di /opt/homebrew/etc/dnscrypt-proxy.toml. Bagian yang penting kira-kira seperti ini:

# Listen lokal — nanti DNS sistem diarahkan ke 127.0.0.1
listen_addresses = ['127.0.0.1:53', '[::1]:53']

# Upstream DoH/DNSCrypt (lewat 443), dicoba berurutan
server_names = ['cloudflare', 'google', 'quad9-doh-ip4-port443-filter-pri']

doh_servers = true
dnscrypt_servers = true

# Hanya pakai resolver yang DNSSEC dan tidak menyimpan log
require_dnssec = true
require_nolog = true

# Cache lokal biar cepat
cache = true

# Daftar resolver publik yang ditandatangani
[sources]
  [sources.public-resolvers]
  urls = [
    'https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md',
    'https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md'
  ]
  cache_file = '/opt/homebrew/var/dnscrypt-proxy/public-resolvers.md'
  minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
  refresh_delay = 73

Sebelum menjalankan sebagai service, ada baiknya cek dulu konfigurasinya valid:

dnscrypt-proxy -config /opt/homebrew/etc/dnscrypt-proxy.toml -check

Menjalankan sebagai Service

Kalau di setup cloudflared dulu saya membuat file launchd sendiri secara manual, kali ini lebih sederhana — cukup pakai brew services. Karena harus bind ke port 53, jalankan dengan sudo:

sudo brew services start dnscrypt-proxy

Ini otomatis membuat LaunchDaemon yang jalan sebagai root dan restart saat boot.

Setting DNS

Arahkan DNS sistem ke 127.0.0.1. Bisa lewat System Settings, atau langsung dari terminal (ulangi untuk tiap network service yang aktif):

sudo networksetup -setdnsservers Ethernet 127.0.0.1
sudo networksetup -setdnsservers Wi-Fi 127.0.0.1

Verifikasi

Yang sempat membingungkan saya: dig example.com +short menampilkan IP example.com, bukan 127.0.0.1. Itu wajar — +short menampilkan jawaban (IP domain), bukan resolver yang menjawab. Untuk melihat resolvernya, lihat baris SERVER: pada output lengkap:

$ dig example.com

;; ANSWER SECTION:
example.com.    2280  IN  A  172.66.147.243

;; SERVER: 127.0.0.1#53(127.0.0.1)   <- resolver lokal kita

Cek juga flag ad (Authenticated Data) untuk memastikan DNSSEC tervalidasi:

$ dig cloudflare.com +dnssec | grep flags
;; flags: qr rd ra ad; ...

Dan seperti dulu, kita bisa buka https://1.1.1.1/help untuk memastikan koneksi memakai DNS-over-HTTPS.

Membersihkan Setup Lama

Jangan lupa hapus LaunchDaemon cloudflared yang lama, karena proxy-dns sudah tidak ada:

sudo launchctl bootout system /Library/LaunchDaemons/org.andrkrn.cloudflared.plist
sudo rm -f /Library/LaunchDaemons/org.andrkrn.cloudflared.plist

Binary cloudflared-nya sendiri boleh dibiarkan — masih berguna untuk cloudflared tunnel.

Penutup

Kalau butuh mengembalikan ke DNS bawaan jaringan:

sudo networksetup -setdnsservers Ethernet Empty
sudo brew services stop dnscrypt-proxy

Migrasinya ternyata singkat, dan hasilnya malah lebih baik dari sebelumnya: selain DoH lewat 443, sekarang ada validasi DNSSEC, cache lokal, dan pilihan beberapa upstream sekaligus. Fitur yang di-deprecate memang kadang merepotkan, tapi kali ini penggantinya lebih bagus.