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:

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.