[Anleitung] Gateway aufsetzen mit Ansible für Neulinge

Moin,

@Fungur, @Parad0x, @descilla und ich haben die Münsteraner Ansible-Konfiguration jetzt an einem Punkt, an dem sie eventuell auch für andere interessant wird.

Bisher war sie auf unseren eher komplexen Aufbau mit eigenem, kleinen Backbone ausgelegt, sodass die FFRL-Anbindung und die Endpunkte der Batman-Domänen auf verschiedenen Servern oder VMs lagen. Jetzt ist es auch möglich über eine IPV4 respektive eine VM oder einen Server ohne Virtualisierung eine FFRL-Anbindung und mehrere getrennte Layer-2 Domänen zu managen.

Dies soll also eine Minimalanleitung sein, die sich an kleine Communities richtet, die damit anfangen wollen, eigene Infrastruktur zu betreuen und bisher eher wenige Kenntnisse zur Linuxadministration gesammelt haben.

Ausgangssituation: Ein Server oder eine VM mit Debian 8, einer öffentlichen IPV4 und einer möglichst guten Internetanbindung. (100 Mbit/s werden erfahrungsgemäß schnell voll, besser Gigabit.)
Auf dem Rechner ist ein ssh-Zugang für root vorhanden, in /root/.ssh/authorized_keys ist ein entsprechendes Zertifikat hinterlegt, und python ist für ansible auch installiert.

Außerdem wird eine separate Linux-Kiste benötigt, um Ansible auszurollen. Dies kann z. B. ein Raspberry Pi sein, aber auch irgendwas angemietetes im Internet, sofern ihr Linux noch nicht als Desktopbetriebssystem nutzt. Dorthin verbindet ihr euch von Windows aus per Putty. Habt ihr schon eine Linuxinstallation auf dem Rechner, mit dem ihr arbeiten wollt, ist das nicht erforderlich.

  • Von wo auch immer ihr arbeitet, zunächst wird Ansible benötigt: http://docs.ansible.com/ansible/intro_installation.html#installing-the-control-machine

  • Zusätzlich zur Core-Installation von Ansible wird noch das Paket netaddr benötigt:

    pip install netaddr

  • Dann unser Ansible-ffms-Repo klonen:

    git clone https://github.com/FreiFunkMuenster/ansible-ffms

    Ggfs. muss vorher git installiert werden, unter Debian und dessen Derivaten geht das mit

    apt-get install git

  • Da wir die Skripte nicht von unserer Konfiguration trennen, müsste das Repo geforked und die hosts, host_vars/* und die group_vars/* geleert werden.

  • Nun müssen ein paar Konfigurationsdateien gesetzt werden, beginnend mit group_vars/all:

Hierbei ist die Einrückung entscheidend. Jede neue Ebene sollte um zwei bis drei Leerzeichen eingerückt sein, damit Ansible die Struktur korrekt erkennt.

domaenen:
  "01":
    name: Münster
    community: Münster
    ffv4_network: 10.43.8.0/21
    ffv6_network: 2a03:2260:115:100::/64
    map_scale: 0.9
    firmware: domaene01/
  "02":
    name: Kreis Coesfeld
    community: Kreis Coesfeld
    ffv4_network: 10.43.16.0/21
    ffv6_network: 2a03:2260:115:200::/64
    map_scale: 1.1
    firmware: domaene02/

routing_table: 42

batman:
  downstream: 1024Mbit
  upstream: 1024Mbit 

dhcp_global:
  mtu: 1280 
  lease_default: 240
  lease_max: 1200 

 ff_network:
   as_number: 65251
   v4_network: 10.43.0.0/16
   v6_network: 2a03:2260:115::/48 

hostname_suffix: ".servers.freifunk-muensterland.de"

administratorenteam:
  - "admin1"
  - "admin2"

Hier müssen pro Domäne (es gehen beliebig viele) ein paar Parameter gesetzt werden, sowie das Administratorenteam festgelegt werden. Jeder Admin braucht einen gleichnamigen admin.pub im keyfiles-Ordner.

  • Als nächstes wird mindestens ein Host benötigt, also eine Datei host_vars/host1 mit folgendem Inhalt anlegen:
vm_id: 2
server_id: 2
server_besitzer: "Name des Eigentümers"

server_ipv4_nat: 185.66.193.51/32
    
ffrl_tun:
- name: dus
  gre_target: 185.66.193.0
  v4_local: 100.64.0.209/31
  v4_remote: 100.64.0.208/31
  v6_local: 2a03:2260:0:6e::2/64
  v6_remote: 2a03:2260:0:6e::1/64
- name: fra
  gre_target: 185.66.194.0
  v4_local: 100.64.0.207/31
  v4_remote: 100.64.0.206/31
  v6_local: 2a03:2260:0:6d::2/64
  v6_remote: 2a03:2260:0:6d::1/64
        
domaenenliste:
   "01":
      dhcp_start: 10.43.96.26
      dhcp_ende: 10.43.99.255
      server_id: 2
   "02":
      dhcp_start: 10.43.104.26
      dhcp_ende: 10.43.107.255
      server_id: 2

Die vm_id muss für alle eure Server und VMs eindeutig sein. Die Server_ID muss pro Domäne eindeutig sein. Die Zahlen können identisch sein und müssen größer eins sein. Den Besitzer notieren wir, damit die Admins wissen, in wessen Namen sie gerade Blödsinn anstellen. Die NAT- und sämtliche Tunnel-IPs erhaltet ihr vom FFRL-Backbone-Team zusammen mit den restlichen Daten für eure Anbindung und müsst diese hier eintragen. Es können beliebig viele Tunnel eingetragen werden, tragt einfach alle ein, die ihr zugewiesen bekommen habt.

Anschließend müssen noch pro Domäne der DHCP-Bereich und die server_id innerhalb der Domäne gesetzt werden. Dies ist gleichzeitig die Freifunk-interne-IP-Adresse auf dem Batman-Interface. Die eins muss frei bleiben, da diese von den Knoten besetzt ist. Die Gateways beginnen mit der zwei am Ende.

  • Anschließend muss noch die Datei hosts bearbeitet werden.
[gateways]
host1             ansible_ssh_host=[IPV4 eures Servers]
  • Wenn ihr collectd und bind (Rolle heißt gateways_bind) noch nicht nutzt, sollten die Zeilen in der gateways.yml zunächst auskommentiert werden, dies geht mit einem vorangestellten #.

  • Nun sollte die Konfiguration stehen und ihr könnt diese ausrollen:

ansible-playbook -i hosts gateways.yml --diff
  • Wenn alles geklappt hat, ist das Gateway nun einsatzbereit und ihr könnte euch eine L2TP-Firmware bauen, die sich mit dem Server verbindet. Wichtig ist es dabei, dass der Port 200XX ist wobei XX die Domänennummer ist. Über diese wird der von uns gepatchte Tunneldigger den Knoten der passenden Domäne zuordnen. Eine Vorlage findet sich z. B. unter Domäne 10 in unserem site-Repo. (Nicht die Domäne 6 benutzen, da diese noch Fastd nutzt, das ist nicht zu diesem System kompatibel.)

  • Wenn ihr auch einen eigenen Kartenserver möchtet, schaut euch die mapserver.yml an. Diese setzt auf einer separaten Maschine den Hoppglass auf und verbindet sich automatisch mit jeder von euch angelegten Domäne per GRETAP.

Da ein Server immer mal abstürzen kann, empfiehlt es sich einen zweiten zu konfigurieren. Ihr könnt dazu die host_vars/host1-Datei auf host_vars/host2 kopieren und die DHCP-Bereiche und die FFRL-Tunnel ändern. Den zweiten Host noch in die hosts-Datei eintragen und auf beide Maschinen Ansible ausrollen. Dann werden zwischen den Domänen automatisch GRETAP-Tunnel gebaut und die beiden Maschinen über iBGP vernetzt.

Diese Anleitung ist noch experimentell und höchst wahrscheinlich unvollständig. Ich deklariere sie als Wiki, jeder der Fehler findet, ist gebeten diese zu korrigieren. Wir haben nur ein historisch gewachsenes System. Was wirklich erforderlich ist, um ein minimales System aufzusetzen, wissen wir nicht genau. Wir wissen aber, dass die Konfiguration einzelner Hosts problemlos durchläuft, es könnte aber fehlende Abhängigkeiten mit dem Kartenserver (services) geben.

Wenn alles funktioniert, solltet ihr eure Konfiguration mit git commit committen und in ein eigenes Repo auf Github oder einem anderen Git-Hoster ablegen.

Viel Spaß beim Freifunken!

Grüße aus dem Münsterland
Matthias

Auf Wunsch den Titel angepasst. Natürlich kann man Gateways auch per Hand, mit Salt, mit Puppet oder sonstigen Werkzeugen zur Serverkonfiguration aufsetzen. Hier wird eine Methode mittels Ansible gezeigt.

18 „Gefällt mir“

Sehr schön! Dann werde ich doch später mal ein neues L2TP-Gateway nach deinem Muster aufsetzen.

1 „Gefällt mir“

Bin gespannt, wie weit es klappt. Geh bitte davon aus, dass es nicht auf Anhieb funktioniert, wir müssen sicherlich die Anleitung noch etwas erweitern ;).

Ìch habe erst einmal mit FFRL Kontakt zwecks Anbindung an das Backbone aufgenommen. Später wäre etwas Unterstützung klasse, denn die Anleitung ist für mich in vielen Punkten noch nicht transparent. Ich leiste aber gerne einen Beitrag um das zu ändern.

1 „Gefällt mir“

Man sollte vielleicht noch irgendwo anmerken, dass hier die Rollen so designt wurden, dass versucht wird SSH auf den Benutzer root zu verbinden, statt (wie es „best practice“ ist) die Privilegieneskalation zu nutzen. Deswegen funktioniert auch die -u option nicht. Bedeutet übrigens auch, das die Abschaltung des root-Zugangs nicht möglich ist, also unbedingt auf zertifikatbasierten Login beschränkt werden sollte.

Wie man Ansible unter Windows nutzen kann ohne größere Installationen zu tätigen, habe ich vor längerer Zeit schon mal auf mein Blog beleuchtet: Ansible on Windows using HyperV and Debian

2 „Gefällt mir“

Ja, leider. Wir wissen auch um diesen Umstand, sind leider noch nicht dazu gekommen es „best practice“ mäßig zu realisieren.

Unbedingt! (Dazu sollte in der sshd config PermitRootLogin auf without-password gesetzt werden, was, soweit ich weiß (bei Debian Installationen) aber auch die Standardeinstellung ist.

1 „Gefällt mir“

Ich habe mal eine kleine Salve von Issues eröffnet, die mir beim testen des Repos aufgefallen sind. Ich habe erst mal versucht nur ein Gateway mit dem Repo aufzusetzen.

Man sollte mehr default-Values hinzufügen um Probleme mit den Rollen zu vermeiden.

1 „Gefällt mir“

Ja super, danke für die Infos. Ich habe die Konfiguration in der letzten Woche auch erstmal für eine fremde Community eingesetzt und da sind mir auch noch ein paar Stolpersteine aufgefallen.

Alles in allem hat es aber doch super funktioniert.

Was mir aufgefallen ist:

  • SSL des nginx auf der service-vm funktioniert nicht. Das ist aber generell so ein Henne-Ei-Problem
  • Es ist nicht klar, was man minimal braucht
  • bat-Interfaces fehlten in der bird-Konfiguration. Mir ist nicht klar, wie es ohne bei uns überhaupt funktioniert, habe es ergänzt
  • Die Service-VM hat ein paar Startschwierigkeiten mit der Karte

Ich hab mir noch nicht überlegt, wie wir die Münsteraner Konfiguration von einer Art Mustervorlage trennen. Eventuell muss ich dafür einfach ein zweites Repo anlegen.

Das einfachste wäre die Roles auszulagern und dann die Beispielconfigs und die Münster in getrennten Repos zu organisieren. Das roles repo kann man dann per Submodule einbinden.

Dadurch könnten dann auch alle Forks regelmäßig updates für die Rollen bekommen.

will man es komplett generalisieren, könnte man noch alle rollen in eigene Repos auslagern, aber das ist aus meiner Sicht übergeneralisiert.

In jedem Fall würde ich mich mal dran setzen die Rollen mit Defaults auszustatten.

1 „Gefällt mir“

Ich werde mal ein generalisiertes Repo anlegen und wenn du mitarbeiten möchtest, kriegst du auch direkt Zugriff drauf.

1 „Gefällt mir“

Ist erledigt: GitHub - FreiFunkMuenster/Ansible-Freifunk-Gateway

Ich hatte noch keine Zeit die Ausgangskonfiguration reinzuschieben, du hast aber auch Zugriff, @Sheogorath

Grüße
Matthias

2 „Gefällt mir“

Bitte korrigiere:

streiche in ca Zeile 25: beginnend mit host_vars/all:
und setze: beginnend mit group_vars/all:

Geändert. Ist aber auch ein Wiki, hättest du sogar direkt machen können.

Ich habe nun alle Daten zusammen und wäre über etwas Unterstützung froh. Gibt es die Möglichkeit, dass mir jemand bei der Repo-Anpassung und der Einrichtung des ersten Gateways zur Seite steht?

Möglicherweise wäre das eine Gelegenheit, alles so anzupassen, dass es auch für andere Communities „out of the box“ benutzbar ist. Die Doku schreibe ich gerne.

Hallo,

ich kann dir gerne dabei helfen. Meld dich mal per PN, dann machen wir einen Termin aus.

Das ist nicht mal eben so gemacht, das sind viele Stunden Arbeit. Wir können aber gerne die Stellen notieren, wo es hängt und dann schon mal als Issues aufnehmen.

@Sheogorath: Wir haben deinen Pullrequest erstmal abgelehnt.

Wenn ich dein Konzept richtig verstehe, möchtest du im [Ansible-Freifunk-Gateway-Repo][1] nur noch die Rollen lagern und dann noch ein separates Repo aufmachen, wo jede Community ihre eigenen Einstellungen speichert, richtig?

Das ansible-ffms-Repo gegen das du den Pullrequest gestellt hast, ist das mit unseren Einstellungen. Da werden wir so erstmal nichts ändern. Wenn du noch ein zweites Repo brauchst, um die Struktur zu vervollständigen, sag das gerne, dann legen wir noch ein weiteres an.

Frage an dich noch, was für eine Struktur müsste in diesem weiteren Repo noch liegen? Oder wollen wir dafür nicht einfach in der Readme erklären, wie das angelegt wird?

Grüße
Matthias
[1]: http://%20https://github.com/FreiFunkMuenster/Ansible-Freifunk-Gateway

Nochmals vielen Dank für deine Unterstützung. Die Firmware ist noch nicht fertig, da mal wieder einige Quellen von Openwrt temporär nicht verfügbar sind. Da hilft nur warten und es öfters probieren.

Kannst du mir jemanden bezüglich Anbindung unseres bestehenden Meshviewers an die neuen Gateways nennen?

Vermutlich ist es einfacher, einen neuen in einer anderen VM einzusetzen und die alte Karte dort mit zu integrieren.

Gibt es zu eurer L2TP-Architektur eine schematische Darstellung?

In etwa so:

l2tpYYYY hängt in brXX hängt in batXX.

@Fungur: Wo in eurem Setup liegt euer Meshviewer-Merge-Script? Könnte man das anpassen - wir möchten z.B. keine Kontaktdaten filtern und auch Gateway-Infos sollen übermittelt werden.

Ein weiterer Ansatz ist der Meshflix. Dieser kann Daten aus mehreren Domänen automatisch mergen. Was aber bei uns nicht funktioniert, was meiner Meinung nach an Alfred-Einstellungen liegen kann.

Wo wird Alfred bei euch aufgerufen? Ist sichergestellt, dass nur EIN Alfred-Master existiert?