DNS als Weiche zwischen zwei Servern verwenden

OP Persönliche Seite #5162291
Lesenswert?

Hallo

Ich habe folgende Ausgangslage:

1) Ich habe ein Embedded Linux Gerät mit einem Webserver am laufen 
(Server).

2) Zusätzlich habe ich ein weiteres Gerät (Client) welches über Ethernet 
meistens direkt am Server angeschlossen ist, kann aber auch über 
Switches etc. weiter entfernt sein.


Auf dem Client läuft ebenfalls ein Embedded Linux. Der Client hat nur 
einen Touchscreen, keine weiteren Bedienmöglichkeiten. Darauf ist ein 
Browser installiert (voraussichtlich Chromium) welcher im Kiosk-Mode 
läuft, hat also keinerlei zusätzliche Bedienung.

Wenn der Client keine Verbindung zum Server aufbauen kann, soll dies dem 
Benutzer optisch ansprechend mittels einer Webseite gezeigt werden. Auf 
keinen Fall darf jemals eine Fehlerseite z.B. ERR_NAME_NOT_RESOLVED des 
Browsers angezeigt werden. Denn ohne F5 Taste zum aktualisieren kommt 
man von einer solchen Seite nie wieder weg. Stattdessen soll eine andere 
lokal auf dem Client gespeicherte Webseite angezeigt werde z.B. mittels 
eines weiteren lokalen Mini-Webservers auf dem Client.

Meine Idee ist es nun, auf dem Client einen DNS-Dienst so zu 
konfigurieren, dass dieser die Anfragen des Browsers an den Server 
weitergibt falls dieser erreichbar ist. Falls nicht, leitet er diese auf 
den lokalen Webserver weiter. Der DNS-Dienst muss zwingend alle Anfragen 
auflösen, damit der Browser immer eine Webseite zur Anzeige bekommt und 
nie eine Fehlerseite anzeigt.


Da ich mich mit Netzwerken nicht so gut auskenne ist nun meine Frage an 
euch, ob jemand einen eleganteren Weg kennt wie man ein solches Problem 
lösen könnte.


Danke im Voraus und Grüsse
Philipp
#5162305
Lesenswert?

Philipp K. schrieb:
> Wenn der Client keine Verbindung zum Server aufbauen kann, soll dies dem
> Benutzer optisch ansprechend mittels einer Webseite gezeigt werden. Auf
> keinen Fall darf jemals eine Fehlerseite z.B. ERR_NAME_NOT_RESOLVED des
> Browsers angezeigt werden. Denn ohne F5 Taste zum aktualisieren kommt
> man von einer solchen Seite nie wieder weg.

Und wie kommst du von der Fehlerseite wieder weg?
Was willst du denn überhaupt machen? Eine Webseite anzeigen und 
periodisch neu laden, ohne sonstige Eingriffsmöglichkeiten des 
Benutzers? Dann lade den Seiteninhalt über JavaScript und schaue nach, 
ob was sinnvolles zurückkommt.
Gast #5162307
Lesenswert?

DNS Anfragen werden üblicherweise vom Betriebssystem gecacht.
Das bedeutet Du machst eine Auflösung, Dein Server ist gerade da, gibt 
dem Client seine IP zurück und beim nächsten Aufruf der Seite macht der 
Client nicht nochmal eine DNS-Anfrage weil er die Antwort ja schon 
kennt.

Was Jan vorschlägt klingt vernünftiger ...
Gast #5162318
Lesenswert?

Das wird so nicht zuverlässig funktionieren. Wenn der Browser die IP 
hat, fragt er nie wieder beim DNS nach. Beim Browserstart funktioniert 
alles. Eine Stunde später fällt der Server aus. Und dein Browser benutzt 
weiter die alte IP.

Ich würde es direkt im HTML/Javascript machen. Entweder traditionell mit 
Frames. Nur der innere Frame wird neu geladen. Die Navigation bleibt 
stehen. Kannst auch einen Javascript-Mechanismus bauen; wenn sich der 
innere Frame nicht bei der Navigation anmeldet, wird nach einem Timeout 
eine Fehlerseite geladen.

Oder du machst es modern als Single-Page-Webapp. Es wird nur eine 
einzige Htmp-Seite geladen. Die holt nur Rohdaten vom Server und ändert 
mit Javascript ihren Inhalt.
Gast #5162326
Lesenswert?

Das könnte man gut mit Python lösen, mal schnell "hingerotzt":

-------- snippet on ----------
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3

4
import urllib2, os
5

6
while 1
7

8
    try:
9
        seite = urllib2.urlopen(http://pfad/zum/server/seite.htm).read()
10
    except:
11
        seite = open(/home/user/hilfsseite.htm).read()
12

13
    os.system("/usr/bin/chromium")
-------- snippet off ----------

Die Hilfsseite liegt auf dem Client, Dein Browser fragt immer nur die 
lokale Hilfsseite ab. Wird komplizierter bei mehreren Seiten, dann 
müsste die Hauptseite auf dem Server absolute Pfade zu den anderen 
Seiten auf dem Server enthalten anstelle von relativen Pfaden.
OP Persönliche Seite #5162351
Lesenswert?

Hallo zusammen

Dass das mit DNS nicht so richtig funktioniert leuchtet mir nun ein.
Die Python Lösung hat meiner Meinung nach den Nachteil, dass diese nicht 
mehr greift, sobald die Verbindung einmal zustande gekommen ist.

Bei der Javascript/Frames Lösung habe ich ein bisschen bedenken, da die 
Webseite auf dem Server bereits diverse Javascripts & AJAX verwendet. Ob 
das Konfliktfrei funktionieren wird weiss ich nicht.

Die Variante mit einem Proxy gefällt mir bis jetzt am besten. Ich werde 
das mal mit squid versuchen, oder gibt es etwas einfacheres?
Gast #5162362
Lesenswert?

Noch einer schrieb:
> Das wird so nicht zuverlässig funktionieren. Wenn der Browser die IP
> hat, fragt er nie wieder beim DNS nach.

Der Browser wird keine IPs cachen, das macht das Betriebssystem - bei 
Windows abzufragen mit "ipconfig /displaydns".

Ich hoffe doch, dass dieser Cache die Lifetime "TTL" berücksichtigt, der 
DNS also eine TTL von nur wenigen Sekunden liefern sollte.
Gast #5162471
Lesenswert?

noch eine Lösung:

bluppdidupp schrieb:
> Mindestens Chrome cached definitiv selbst DNS-Einträge unabhängig vom
> Betriebssystem.

Nö, gerade ausprobiert:

mit Chromium www.mikrocontroller.net aufgerufen, Seite reloaded: geht

/etc/hosts manipuliert:
127.0.0.1 www.mikrocontroller.net

Seite reloaded: geht nicht

/etc/hosts manipuliert (auskommentiert):
# 127.0.0.1 www.mikrocontroller.net

Seite reloaded: geht nicht

Daraus folgt: wenn man per Programm in einer Dauerschleife (z.B. alle 30 
Sekunden) die /etc/hosts manipuliert (abhängig, ob Server erreichbar 
oder nicht), kann das vom TE erstellt Problem gelöst werden.
Gast #5162609
Lesenswert?

Der dnsmasq vom Android liest die /system/etc/hosts genau
einmal beim Starten. Danach kann Mann da schreiben was Mann will...

Was zuverlaessig funktioniert, ist per iptables den Request
im Fehlerfall an die passende Adresse zu schicken.
Im Beispiel lauscht lokal auf dem Androiden ein Webserver
auf dem Port 1080.
1
su -c iptables -t nat -A OUTPUT -p tcp -d 1.0.0.1 --dport 80 -j DNAT --to-destination 127.0.0.1:1080

Das su muss Mann sich selber kompilieren. Die su aus Androidpaketen
kennen die Option "-c" oft nicht.

Ein:
1
su -c iptables -t nat -D OUTPUT 1

stellt die normalen Verhaeltnisse wieder her.
Ein Script das die Erreichbarkeit des richtigen Servers
pollt, schaltet dann dazwischen um.
Gast #5162646
Lesenswert?

trostpreis schrieb:
> Das könnte man gut mit Python lösen, mal schnell "hingerotzt":
>
1
> 
2
> #!/usr/bin/python
3
> # -*- coding: utf-8 -*-
4
> 
5
> import urllib2, os
6
> 
7
> while 1
8
> 
9
>     try:
10
>         seite = urllib2.urlopen(http://pfad/zum/server/seite.htm).read()
11
>     except:
12
>         seite = open(/home/user/hilfsseite.htm).read()
13
> 
14
>     os.system("/usr/bin/chromium")
15
> 
16
>

ich würde das ähnlich machen - an der netzwerkconfig rum zu schrauben 
ist keine gute idee, denn das netzwerk ist nicht der grund warum der 
server nicht erreichbar ist.
es ist, wie es in obigem code beschrieben wird: eine resource soll 
geladen werden, und wenn das nicht funktioniert soll eine meldung 
ausgegeben werden. wenn es ein normales GUI programm wäre, und eine 
datei geöffnet werden sollte, würde auch keiner auf die idee kommen im 
fehlerfall fix mal einen hardlink zu setzen um die nicht ladbare datei 
durch eine dummy datei zu ersetzen.

meine idee wäre lokal auf dem client einen http-server mit php zu haben, 
die index.php hat im html-header "reload alle 10 sec" stehen (genaue 
syntax weiß ich nicht auswendig, bin kein web entwickler :).
im php-script wird versucht die externe resource zu laden, und wenn das 
nicht funktioniert, wird eine interne resource geladen, oder 
fehlermeldung ausgegeben.
der browser auf dem client lädt die index.php einmal, und dann halt 
immer wieder - der inhalt der seite wird durch das php-script bestimmt.

und noch was zu obigem code: es wäre von vorteil wenn man der 
urllib-klasse sagen könnte wie lange der timeout sein darf, nicht dass 
das laden der server-seite 30 sekunden lange versucht wird.
Gast #5162679
Lesenswert?

trostpreis schrieb:
> c.m. schrieb:
>> und noch was zu obigem code: es wäre von vorteil wenn man der
>> urllib-klasse sagen könnte wie lange der timeout sein darf, nicht dass
>> das laden der server-seite 30 sekunden lange versucht wird.
>
> urllib2 kann ein timeout:
> https://stackoverflow.com/questions/2712524/handling-urllib2s-timeout-python

hab ich mir gedacht, ist ja auch sinnvoll :)
Gast #5162701
Lesenswert?

Abgesehen davon das ich $irgendwas mit Chrom nicht mehr instinktiv als 
embedded ansehen würde (vielleicht haben sich die Zeiten ja geändert).

Möchte ich nochmal die Lösung mit den Proxy ansprechen. Klar kann man 
das sicher auch in Python machen und das wäre wahrscheinlich auch mein 
erster ansatz das mit den try/except umzusetzen.
Aber wenn es ein Produkt werden soll, wäre meine Empfehlung den Nginx, 
alternativ den lighttpd als Proxy auf den Client zu installieren.
Beide habe ich schon erfolgreich in embedded Projekten eingesetzt und 
hätten im Vergleich zu der Python Lösung den charmanten Vorteil nur noch 
Konfiguriert werden müssen.
Beide vor allen aber der Nginx haben sich schon 1000 Fach als Proxy 
bewährt. Bei der Python Lösung fängst du von 0 an und musst selbst 
erstmals alle Fehler und Fallen finden und beheben.
Abgesehen davon hat so eine Proxylösung, egal ob Homebrew Python oder 
Nginx denn Vorteil das auch fälle wie DNS geht, Webserver weg gleich mit 
gecovert werden.
Gast #5162714
Lesenswert?

> an der netzwerkconfig rum zu schrauben

Das tut es ja nicht.
Der Request wird von der nat/Output-Regel nur an ein anderes Ziel
geschickt. Das funktioniert in einer anderen Anwendung schon heute
bestens und zuverlaessig.
An der Netzwerkkonfiguration wird dadurch nichts geaendert.
Irgendwelche Cachingprobleme treten dabei nicht auf.
Die Dummy/Fehler-Webseite muss natuerlich auch passende
http-Parameter zurueckgeben.

Kommerzielle Loadbalancer machen das auch nicht viel anders.

Wer aber nur in PHP frickeln kann, wird es wohl damit versuchen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren