map¶
Diese Dokumentation behandelt das Aufsetzen von https://map.freifunk-suedholstein.de

Vorraussetzungen¶
Wie für all unsere Service Server verwenden wir Ubuntu als Basis. Als Hardware verwenden für den gesammten Stack eine VM von Hetzner (CPX21) 2vCores 4GB RAM 40GB disk. Für unsere Community reicht dieses Setup bisher aus.
yanic¶
yanic sammelt von den Knoten Daten, welche dann auf einer Karte angezeigt werden können, früher wurde hierfür Alfred benutzt. yanic ist in go geschrieben also installieren wir eine neue Version von go. golang
wget https://dl.google.com/go/go1.17.5.linux-amd64.tar.gz
# Bitte sha256 vergleichen https://golang.org/dl/
tar -C /usr/local -xzf go1.17.5.linux-amd64.tar.gz
rm go1.17.5.linux-amd64.tar.gz
In ~/.bashrc
GOPATH=/opt/go
PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
Hier musst du dich einmal abmelden und neu anmelden damit die Variablen auch gesetzt werden.
Nach dem Anmelden kann man prüfen ob die Variablen korrekt gesetzt wurden.
echo $GOPATH
/opt/go
Mit whereis
go prüfen ob go gefunden wird:
go: /usr/local/go /usr/local/go/bin/go
Dann wird yanic installiert.
go get -v -u github.com/FreifunkBremen/yanic
Die Konfiguration von Yanic wird in /etc/yanic.conf
angelegt:
[respondd]
enable = true
synchronize = "1m"
collect_interval = "1m"
[respondd.sites.ffsh]
domains = ["ffsh", "ffod", "ffrz"]
[respondd.sites.ffod]
domains = []
[respondd.sites.ffrz]
domains = []
[[respondd.interfaces]]
ifname = "bat0"
[[respondd.interfaces]]
ifname = "bat0"
multicast_address = "ff02::2:1001"
[webserver]
enable = false
bind = "127.0.0.1:8080"
webroot = "/var/www/html/meshviewer"
[nodes]
state_path = "/var/lib/yanic/state.json"
prune_after = "14d"
save_interval = "2m"
offline_after = "10m"
[[nodes.output.geojson]]
enable = true
path = "/var/www/map/data/nodes.geojson"
[[nodes.output.meshviewer-ffrgb]]
enable = true
path = "/var/www/map/data/meshviewer.json"
[nodes.output.meshviewer-ffrgb.filter]
no_owner = true
blacklist = ["f4f26d4a2ecc"]
[[nodes.output.meshviewer]]
enable = true
version = 2
nodes_path = "/var/www/map/data/nodes.json"
graph_path = "/var/www/map/data/graph.json"
[nodes.output.meshviewer.filter]
no_owner = true
blacklist = ["f4f26d4a2ecc"]
[[nodes.output.nodelist]]
enable = true
path = "/var/www/map/data/nodelist.json"
[nodes.output.nodelist.filter]
no_owner = true
blacklist = ["f4f26d4a2ecc"]
[database]
delete_after = "30d"
delete_interval = "1h"
[[database.connection.influxdb]]
enabled = true
address = "http://localhost:8086"
database = "ffsh"
username = ""
password = ""
[database.connection.influxdb.tags]
[[database.connection.graphite]]
enable = false
address = "localhost:2003"
prefix = "freifunk"
[[database.connection.respondd]]
enable = false
type = "udp6"
address = "stats.bremen.freifunk.net:11001"
[[database.connection.logging]]
enable = false
path = "/var/log/yanic.log"
Wir können testen ob yanic funktioniert in dem wir eine manuelle Anfrage stellen hier an das Gateway Hopfenbach:
yanic query --wait 5 br-ffsh "fddf:bf7:80::48:1"
Damit yanic auch als Deamon läuft legen wir noch einen Service an.
sudo cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/yanic.service
sudo systemctl daemon-reload
influxdb¶
Influxdb dient als Datenbank für yanic
Achtung hier wird Influxdb 1.x (aktuell 1.8.10) installiert, die aktuelle version ist 2.0 (diese wird aktuell nicht von yanic unterstützt).
wget -qO- https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/lsb-release
echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
sudo apt install influxdb influxdb-client
Nun sichern wir die influxdb ab /etc/influxdb/influxdb.conf
Hier werden nur die empfohlenen Anpassungen beschrieben: Noch vor der
[meta]
Sektion setzen wir, sonst wäre der port 8088 überall offen.
bind-address = "localhost:8088"
Weiter unten bei [admin]
das gleiche:
bind-address = "localhost:8083"
kurz danach in [http]
bind-address = "localhost:8086"
systemctl restart influxdb
Nun sollte influxdb nur noch auf localhost erreichbar sein, prüfen kann
man dies mit netstat -tlpn
Grafana¶
Grafana kann Graphen erstellen welche im meshviewer eingebunden werden können. Hier wird Grafana über eine Repository installiert.
deb https://packagecloud.io/grafana/stable/debian/ stable main
curl https://packagecloud.io/gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install grafana
Da Grafana bei uns hinter einem Proxy laufen soll, setzen wir auch hier alle IPs auf localhost
.
Am besten einmal am Ende prüfen ob alles richtig konfiguriert ist mit netstat -tlpn
.
Ein wichtiger Punkt ist der öffentliche Zugang, damit die Statistiken auch von Besuchern abgerufen werden können.
#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
enabled = true
# specify organization name that should be used for unauthenticated users
org_name = Freifunk Südholstein
# specify role for unauthenticated users
org_role = Viewer
Die Organisation kann man als Admin in Grafana anlegen.
meshviewer¶
Für den Meshviewer installieren wir als erstes nodejs und yarn
nodejs¶
Wir brauchen ein aktuelles nodejs das finden wir auf nodejs.org Wir benutzen die LTS Variante 16.x
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
meshviewer-rgb¶
Nun installieren wir den meshviewer
selbst. Im web Verzeichnis /var/www/
git clone https://github.com/ffsh/meshviewer.git
cd meshviewer
yarn
Nun muss die Konfiguration in meshviewer/config.js
eventuell noch
angepasst werden.
Danach yarn run gulp
Nun muss nur noch ein Webserver meshviewer/build
ausliefern.
Tile-cache mit nginx¶
Für den Meshviewer benötigt man einen Tile-Server, der die Karte als einzelne Kacheln ausliefert. Wir verwenden dabei das kostenlose und freie Angebot von OpenStreetMap. Damit die Server von OpenStreetMap weniger stark belastet werden verwenden wir einen Tile-Cache. Bei einer Anfrage für eine Karten-Kachel fragt der Browser den Cache, hat dieser die Datei bereits, so liefert er sie direkt aus. Hat er sie nicht, so fragt er bei den OpenStreetMap Servern und speichert die Datei in seinem Cache. Für die einfache Umsetzung haben ein paar Freifunker an einer Konfiguration für nginx gearbeitet, welche genau das umsetzt.
Voraussetzungen: - nginx erreichbar unter der entsprechenden Domain - TLS mit gültigem Zertifikat (Let’s Encrypt) - ein wenig Speicherplatz
#
# Nginx >= 1.9.15 - 1.10.1 recommended
#
# Thanks to https://github.com/cbricart
proxy_cache_path /var/www/tilecache/osm
levels=1:2 inactive=7d
keys_zone=tilecache:64m
max_size=500M;
upstream osm_tiles {
server a.tile.openstreetmap.org;
server b.tile.openstreetmap.org;
server c.tile.openstreetmap.org;
keepalive 16;
}
server {
listen 80;
listen [::]:80;
server_name tiles.freifunk-suedholstein.de;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /etc/ssl/dhparam.pem;
server_name tiles.freifunk-suedholstein.de;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/tiles.freifunk-suedholstein.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tiles.freifunk-suedholstein.de/privkey.pem;
root /var/www/tilecache/html;
location / {
try_files $uri @osm;
}
location @osm {
proxy_pass http://osm_tiles;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding "";
proxy_set_header User-Agent "Mozilla/5.0 (compatible; OSMTileCache/1.0; +mailto:noc@freifunk-suedhosltein.de; +https://map.freifunk-suedholstein.de/)";
proxy_set_header Host tile.openstreetmap.org;
proxy_temp_path /var/www/tilecache/temp;
proxy_cache tilecache;
proxy_store off;
proxy_cache_key $uri$is_args$args;
proxy_ignore_headers Expires Cache-Control;
proxy_cache_valid 200 301 302 7d;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_403 http_404;
proxy_cache_use_stale error timeout updating invalid_header http_500 http_502 http_503 http_504 http_403 http_404;
proxy_hide_header Via;
proxy_hide_header X-Cache;
proxy_hide_header X-Cache-Lookup;
expires 7d;
}
}
Grafna cache mit nginx¶
Da Grafana ab Version 7.0 das rendern der images, welche wir auf der Karte einbetten, anders rendert als früher mussten wir einen Cache einrichten. Siehe https://github.com/ffrgb/meshviewer/issues/304
Basierend auf den Kommentaren haben wir auch eine Konfiguration zusammengestellt.
proxy_cache_path /var/cache/nginx/grafana
keys_zone=grafana:10m
max_size=128m;
server {
listen 80;
listen [::]:80;
server_name grafana.freifunk-suedholstein.de;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/grafana.freifunk-suedholstein.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/grafana.freifunk-suedholstein.de/privkey.pem;
server_name grafana.freifunk-suedholstein.de;
location / {
proxy_pass http://127.0.0.1:3000;
}
location /render/ {
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:3000/render/;
proxy_cache grafana;
proxy_cache_valid 300s;
proxy_cache_lock on;
proxy_cache_lock_age 60s;
proxy_cache_lock_timeout 60s;
proxy_hide_header Cache-Control;
proxy_hide_header Expires;
proxy_hide_header Pragma;
proxy_ignore_headers Cache-Control Expires;
expires 150s;
}
}