Systemwide Custom DNS Menggunakan systemd-resolved

Telah beberapa kali saya menulis tentang cara memintasi “internet sehat”. Mulai dari menyunting berkas konfigurasi /etc/resolv.conf, menggunakan skrip di firewall AfWall++, menggunakan ProtonVPN, DNS resolver (?) Nebulo, dan lainnya.

Dan kini, saya akan menulis tema yang sama; system wide custom DNS menggunakan systemd-resolved. System wide alias menyeluruh sistem bukan hanya per app sebagaimana DNS over HTTP-nya Firefox.

Langkahnya sederhana saja:

  • Sunting berkas /etc/systemd/resolved.conf dan isikan baris konfigurasi berikut:
    Jika hendak menggunakan DNS dari CloudFlare:
    [Resolve]
    DNS=1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001
    FallbackDNS=1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001
    Domains=~.
    DNSSEC=yes
    DNSOverTLS=yes
    

    Dan jika hendak menggunakan DNS dari Google:

    [Resolve]
    DNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
    FallbackDNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
    Domains=~.
    DNSSEC=yes
    DNSOverTLS=yes
    

    Atau jika hendak menggunakan DNS dari Quad9:

    [Resolve]
    DNS=9.9.9.9 2620:fe::fe
    FallbackDNS=9.9.9.9 2620:fe::fe
    Domains=~.
    DNSSEC=yes
    DNSOverTLS=yes
    
  • Buat tautan resolv.conf
    sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
    
  • Aktifkan layanan systemd-resolved.service
    sudo systemctl enable systemd-resolved.service
    
  • Jalankan layanan yang berkaitan
    sudo systemctl restart systemd-resolved.service
    sudo systemctl restart NetworkManager
    
  • Buka peramban dan kunjungi laman https://www.cloudflare.com/ssl/encrypted-sni/.
    Jika menggunakan DNS CloudFlare mestinya semua parameter akan hijau. Jika tidak, kemungkinan parameter “Secure DNS” hanya akan berwarna jingga walau DNS yang digunakan sebenarnya aman.

Untuk memudahkan berganti DNS atau kembali menggunakan DNS dari operator seluler/ISP, saya pun membuat skrip berikut:

#!/usr/bin/env bash

# Print message in brown.
print_w() {
  printf '\e[33m:: %s\n\e[m' "$@"
}

backup_cfg() {
  if [[ ! -f /etc/systemd/resolved.conf-orig ]]; then
    print_w "Backing up /etc/systemd/resolved.conf."
    sudo mv /etc/systemd/resolved.conf{,-orig}
  else
    print_w "Backup exist at /etc/systemd/resolved.conf-orig."
  fi
}

print_usage() {
  printf '%s\n' "
  ${0##*/} is script to enable systemwide custom DNS by using systemd-resolved service.

  Usage: ${0##*/} OPTION

  OPTION:
    -h   --help        Print this text
    -on                Enable custom DNS (default to CloudFlare DNS)
    -cf  --cloudflare  Enable CloudFlare DNS (1.1.1.1, 1.0.0.1)
    -gg  --google      Enable Google DNS (8.8.8.8, 8.8.4.4)
    -q9  --quad9       Enable Quad9 DNS (9.9.9.9)
    -s   --status      Show link and server status
    -off               Disable custom DNS

  Example:
    - ${0##*/} on
    - ${0##*/} off
"
  exit
}

restart_services() {
  print_w "Restarting services..."
  sudo systemctl restart systemd-resolved.service
  sudo systemctl restart NetworkManager
}

enable_services() {
  print_w "Restarting services..."
  sudo systemctl enable systemd-resolved.service
  restart_services
}

write_config() {
  print_w "Applying $2 DNS..."
  printf '%s\n' "
[Resolve]
DNS=$1
FallbackDNS=$1
Domains=~.
DNSSEC=yes
DNSOverTLS=yes
" | sudo tee /etc/systemd/resolved.conf
}

# MAIN -------------------------------------------------------------------------

if [[ -z $(command -v "systemctl") ]]; then
  print_w "systemctl not found. Perhaps this is not a systemd system?"
  exit
fi

if [[ "$#" -eq 1 ]]; then
  case $1 in
    -on|-cf|--cloudflare)
      backup_cfg
      write_config "1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001" "CloudFlare"
      sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
      enable_services
    ;;
    -gg|--google)
      backup_cfg
      write_config "8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844" "Google"
      enable_services
    ;;
    -q9|--quad9)
      backup_cfg
      write_config "9.9.9.9 2620:fe::fe" "Quad9"
      enable_services
    ;;
    -s|--status)
      systemd-resolve --status
    ;;
    -off)
      if [[ -f /etc/systemd/resolved.conf-orig ]]; then
        print_w "Backup exist at /etc/systemd/resolved.conf-orig."
        print_w "Restoring it back to /etc/systemd/resolved.conf."
        sudo mv /etc/systemd/resolved.conf{-orig,}
      else
        print_w "Backup (/etc/systemd/resolved.conf-orig) is not found."
        print_w "Creating new /etc/systemd/resolved.conf skeleton."
        printf '%s\n' "
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See resolved.conf(5) for details

[Resolve]
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001
# Google:     8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
# Quad9:      9.9.9.9 2620:fe::fe
#DNS=
#FallbackDNS=
#Domains=
#DNSSEC=no
#DNSOverTLS=no
#Cache=yes
#MulticastDNS=yes
#LLMNR=yes
#DNSStubListener=yes
#DNSStubListenerExtra=
#ReadEtcHosts=yes
#ResolveUnicastSingleLabel=no
" | sudo tee /etc/systemd/resolved.conf
      fi
      sudo unlink /etc/resolv.conf
      sudo systemctl disable systemd-resolved.service
      restart_services
    ;;
    -h|--help|*)
      print_usage
    ;;
  esac
fi

Skrip yang lebih mutakhir bisa dilihat di https://github.com/rizaumami/scripts/blob/master/systemdns.