How-to: DNS-Server wechseln - so funktioniert es wirklich

  • 8 Antworten
  • Letztes Antwortdatum
C

Carl

Ambitioniertes Mitglied
9
Vorwort:
Da mein Router über kein NAT-Loopback verfügt, brauche ich zu hause einen eigenen DNS-Server um auch von innerhalb über die normale URL auf meinen (owncloud) Web-Server zuzugreifen.
Klappt wunderbar, nur mit Android war die Umstellung auf diesen DNS-Server schwierig - daher möchte ich hier darüber berichten, vielleicht nutzt es ja jemandem was. :)


Zunächst sei gesagt: Ja, es gibt diverse Root-Apps, die behaupten, jenes bewerkstelligen zu können. Bei mir funktionierte keine einzige. Ich vermute, es liegt daran, dass man normalerweise schlicht nicht merkt, ob man DNS Server A oder DNS Server B benutzt.


Tatsächlich half mir folgender Eintrag bei XDA-Developers:
[Q] How to change dns in android 4.3 - Post #7 - XDA

Ich werde das zunächst mal auf Deutsch und vereinfacht darstellen und dann erklären, warum ausgerechnet diese Vorgehensweise so gut ist.

So geht es:
benötigtes Zubehör: Ein Root-File-Browser und Editor, z.B. Root-Explorer:
https://play.google.com/store/apps/details?id=com.speedsoftware.rootexplorer&hl=de

Vorgehensweise:
Man begebe sich zu und öffne /etc/dhcpcd/dhcpcd-hooks/20-dns.conf und erstelle sicherheitshalber ein Backup dieser Datei.
Normalerweise sieht diese wie folgt aus:
Code:
set_dns_props()
{
    case "${new_domain_name_servers}" in
    "")   return 0;;
    esac

    count=1
    for i in 1 2 3 4; do
        setprop dhcp.${intf}.dns${i} ""
    done

    count=1
    for dnsaddr in ${new_domain_name_servers}; do
        setprop dhcp.${intf}.dns${count} ${dnsaddr}
        count=$(($count + 1))
    done

    separator=" "
    if [ -z "$new_domain_name" ]; then
       separator=""
    else
        if [ -z "$new_domain_search" ]; then
            separator=""
        fi
    fi
    setprop dhcp.${interface}.domain "${new_domain_name}$separator${new_domain_search}"
}
In der Variable new_domain_name_servers befindet sich eine Liste von DNServer, welche durch den DHCP mitgeteilt wurden.
Um einen eigenen DNS zu benutzen, muss man diesen der Liste also nur voranstellen. Man muss dazu ganz am Anfang der Funktion set_dns_props() die Variable entsprechend erweitern:
Code:
new_domain_name_servers="192.168.2.99 8.8.8.8 $new_domain_name_servers"
In diesem Beispiel wurden ein eigener, interner DNS mit IP 192.168.2.99 (mein Szenario, Achtung! Für eigene Verhältnisse anpassen oder weglassen!) mit Priorität 1 hinzugefügt und der Google DNS 8.8.8.8 mit Priorität 2, mit Priorität 3 und niedriger folgt die ursprüngliche durch den DHCP mitgeteilte Liste ($ liest den Inhalt der Variable aus.).
Natürlich geht auch nur ein einziger DNS oder drei, getrennt werden müssen diese jeweils durch Leerzeichen.


Insgesamt sieht die Datei dann also so aus:
Code:
set_dns_props()
{
new_domain_name_servers="192.168.2.99 8.8.8.8 $new_domain_name_servers"
    case "${new_domain_name_servers}" in
    "")   return 0;;
    esac

    count=1
    for i in 1 2 3 4; do
        setprop dhcp.${intf}.dns${i} ""
    done

    count=1
    for dnsaddr in ${new_domain_name_servers}; do
        setprop dhcp.${intf}.dns${count} ${dnsaddr}
        count=$(($count + 1))
    done

    separator=" "
    if [ -z "$new_domain_name" ]; then
       separator=""
    else
        if [ -z "$new_domain_search" ]; then
            separator=""
        fi
    fi
    setprop dhcp.${interface}.domain "${new_domain_name}$separator${new_domain_search}"
}
Verbindung neu aufbauen oder Gerät neu starten, fertig! :)
Die eigenen DNS werden jetzt mit höchster Priorität verwendet, die per DHCP mitgeteilten mit niedrigerer Priorität.

Warum ist speziell dieses Vorgehen so gut?

1. Es ist im Unterschied zu diversen anderen Lösungen permanent. Einmal eingestellt, muss man nichts mehr machen.
2. Im Unterschied zu anderen Lösungen wird die Liste der per DHCP mitgeteilten DNS nicht verworfen, sondern nur mit einer niedrigeren Priorität verwendet. Das ist sehr nützlich, wenn der selbst definierte DNS mal nicht zur Verfügung steht.
3. Da das Interface in jenem Script als Variable geführt wird, muss man sich nicht darum kümmern, welches denn nun das wirklich verwendete ist. (Wer eine Übersicht der Interfaces sehen will, gebe mal "ip link" in ein Terminal auf dem Android Gerät ein..)


Wie gesagt, vielleicht nützt es ja jemandem. :)
 
  • Danke
Reaktionen: magicw und Otandis_Isunos
In der Tat sehr nützlich, wenn man externe DNS-Server wie OpenDNS benutzt bspw.

Allerdings und das wundert mich in der Tat: Bei mir hat die simple App: SetDNS immer funktioniert.

Aber: Ich habe auch kein Android 4.3 ;) Mir scheint es nämlich, als kämen die Apps eben mit jener Android-Version und neuer nicht zurecht, wozu man eben hier händisch arbeiten muss ;)
 
Ja, damit probierte ich es auch, klappte aber nicht.
Ich habe auch Android 4.4.2, und die App-Beschreibung sagt ja auch schon, dass es mit 4.3 nicht funktioniert, insofern wohl auch nicht mit 4.4.
 
Zwei Ergänzungen:

1. WICHTIG!
Wenn Du - wie ich zuvor vorgeschlagen habe - Root Explorer verwendest um die 20-dns.conf Datei zu editieren, wird Root Explorer eine backup Datei namens 20-dns.conf-bak anlegen.Diese Datei wird ebenfalls berücksichtigt! Du musst also diese Backup-Datei löschen wenn Du doppelte Zuordnungen vermeiden willst...

(Ich bemerkte das, als mein eigener DNSMASQ Server 192.168.2.99 sowohl als dns1 als auch als dns2 auftauchte...)

2.Um zu vermeiden in anderen WLANs als dem eigenen auf den Timeout für den nicht vorhandenen DNS zu warten, wollte ich, dass diese Änderung nur im eigenen WLAN angewendet wird. Da die 20-dns.conf so eine Art bash-Skript ist, muss man mit den Werkzeugen der bash arbeiten, ich schaute also mal, was man mit Hilfe des bash Befehls "getprop" so herausfinden kann. Leider nicht die SSID, aber etwas, was fast genauso gut ist: Die Domain!

Tippe in ein Terminal auf Deinem Android Gerät:
Code:
$ getprop | grep domain
[dhcp.wlan0.domain]: [Speedport_W_921V_1_35_000]
(bei mir.)

Also veränderte ich die /etc/dhcpcd/dhcpcd-hooks/20-dns.conf so, dass die zusätzliche DNS Einstellung nur auf dieser Domain angewendet wird:

Code:
# Set net.<iface>.dnsN properties that contain the
# DNS server addresses given by the DHCP server.

if [[ $interface == p2p* ]]
    then
    intf=p2p
    else
    intf=$interface
fi

set_dns_props()
{
    if [ "$new_domain_name" == "Speedport_W_921V_1_35_000" ]
       then new_domain_name_servers="192.168.2.99 ${new_domain_name_servers}"
    fi

    case "${new_domain_name_servers}" in
    "")   return 0;;
    esac

    count=1
    for i in 1 2 3 4; do
        setprop dhcp.${intf}.dns${i} ""
    done

    count=1
    for dnsaddr in ${new_domain_name_servers}; do
        setprop dhcp.${intf}.dns${count} ${dnsaddr}
        count=$(($count + 1))
    done

    separator=" "
    if [ -z "$new_domain_name" ]; then
       separator=""
    else
        if [ -z "$new_domain_search" ]; then
            separator=""
        fi
    fi
    setprop dhcp.${interface}.domain "${new_domain_name}$separator${new_domain_search}"
}

unset_dns_props()
{
    for i in 1 2 3 4; do
        setprop dhcp.${intf}.dns${i} ""
    done

    setprop dhcp.${interface}.domain ""
}

case "${reason}" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT)       set_dns_props;;
EXPIRE|FAIL|IPV4LL|RELEASE|STOP)                unset_dns_props;;
esac
(Siehe die if-Bedingung mit der Domain, die ich hinzufügte......)

Du kannst die Einstellung mit
Code:
$ getprop | grep dns
abrufen. Änderungen werden nach Neuaufbau einer Verbindung angewandt.
 
Viel zu kompliziert und unzuverlässig. Nimm einfach iptables.
 
Also zuverlässig ist es zu 100%, und "kompliziert" ist offenbar subjektiv: Ich verstehe diese IPTABLES Geschichte überhaupt nicht. Was müsste man denn dort konkret eintragen? Und wäre es damit auch möglich, nur im Heimnetzwerk einen anderen DNS Server zu benutzen?
 
Die ersten zwei Zeilen löschen die Regeln, die nächsten zwei setzen sie. Der DNS Server ist 208.67.222.222 (OpenDNS). Kannst du durch deinen ersetzen. Man kann nur einen DNS Server haben. Diese Regeln leiten per Netfilter/Kernel Port 53 auf die angegebene Adresse um. Teste die 4 Kommandos per ADB shell und/oder setze sie direkt in ein init.d Skript. Teste den aktiven DNS mit myresolver.info.
Code:
iptables -t nat -D OUTPUT -p tcp --dport 53 -j DNAT --to-destination 208.67.222.222:53 || true
iptables -t nat -D OUTPUT -p udp --dport 53 -j DNAT --to-destination 208.67.222.222:53 || true

iptables -t nat -I OUTPUT -p tcp --dport 53 -j DNAT --to-destination 208.67.222.222:53
iptables -t nat -I OUTPUT -p udp --dport 53 -j DNAT --to-destination 208.67.222.222:53
 
Erstmal danke für die Antwort und nichts für ungut, ABER:

0. Vermutung: Ausführlichere Beschreibung führt zum Eindruck komplizierter?
Der Thread-Start ist ja nicht gerade kurz, das liegt aber daran, dass

  • die bereits vorhandene und zu bearbeitende Datei 20-dns.conf in ihrer ganzen Länge wiedergegeben wird.
  • Jeder einzelne Schritt genannt wird.
  • Und das Vorgehen auch noch erklärt und begründet wird.
Gleiches kann man beim ersten Beitrag zur iptables-Methode ja nicht gerade sagen... ;-)

1. iptables zum DNS-Wechsel? Kanonen auf Spatzen!
Ich habe mich mal ein wenig kundig gemacht über iptables und dabei festgestellt, dass iptables ein komplexes und mächtiges Werkzeug zur Paketfilterung darstellt. iptables Mag sein, dass dieses mächtige Werkzeug auch zu einem Effekt genutzt werden kann, der einem DNS-Wechsel entspricht, ich würde mich allerdings scheuen so etwas mächtiges anzuwenden, ohne es wirklich zu verstehen. Wer weiß, was man da kaputt knaubt...

2. These: Der Aufwand bei der iptables-Methode ist objektiv höher
Begründung:

  • Bei der 20-dns.conf Methode müssen 64 Zeichen (bei einem festen zusätzlichen DNS auf Priorität 1) bzw. 130 Zeichen (bei einem Domain-spezifischen zusätzlichen DNS auf Priorität 1) in eine ansonsten bereits vorhandene Datei eingefügt werden, bei der iptables Methode sind 174 Zeichen nötig für ein festes Routing.
  • Eine adb-shell ist für die 20-dns.conf Methode nicht nötig, das Smartphone alleine reicht bereits.
  • Für eine dauerhafte Anwendung benötigt die iptables-Methode init.d, was standardmäßig nicht vorhanden ist und erst noch erzeugt und eingerichtet werden muss. Bei der 20-dns.conf Methode ergänzt man einfach nur eine sowieso vorhandene Datei.
3. Die 20-dns.conf Methode ist flexibler
Da es dort möglich ist, Netzwerk(Domain)-spezifische Einstellungen vorzunehmen und die vom DHCP vorgeschlagenen DNS nicht verworfen werden, sondern nur eine niedrigere Priorität erhalten.

4. Android kann sehr wohl mehr als einen DNS verwalten!
Genau genommen nämlich 4 pro Interface. Meist teilt der DHCP nur einen oder zwei mit, daher lässt sich ja auch gut einer oder zwei eigene voranstellen.
Siehe die Ausgabe von "getprop | grep dns" im Terminal:
Code:
$ getprop | grep dns
[dhcp.p2p.dns1]: []
[dhcp.p2p.dns2]: []
[dhcp.p2p.dns3]: []
[dhcp.p2p.dns4]: []
[dhcp.wlan0.dns1]: [192.168.2.99]
[dhcp.wlan0.dns2]: [192.168.2.1]
[dhcp.wlan0.dns3]: []
[dhcp.wlan0.dns4]: []
[net.dns1]: [192.168.2.99]
[net.dns2]: [192.168.2.1]
[net.dns3]: []
[net.dns4]: []
[net.dnschange]: []
[net.p2p-p2p0-0.dns1]: []
[net.p2p-p2p0-0.dns2]: []
[net.rmnet0.dns1]: []
[net.rmnet0.dns2]: []
[net.wlan0.dns1]: []
[net.wlan0.dns2]: []
rmnet0 wird aktiv bei einer Mobilfunkverbindung, net.dns* nimmt immer die Werte der aktuell aktiven Verbindung an.
 
iptables wird ja auch bei diversen Firewalls für Android verwendet ;) AFWall+ bspw.
 

Ähnliche Themen

mtemp
Antworten
2
Aufrufe
133
Klaus986
K
M
Antworten
8
Aufrufe
934
Big11
Big11
D
Antworten
2
Aufrufe
712
chrs267
chrs267
Zurück
Oben Unten