diff --git a/inventory/group_vars/ffmwu-monitoring b/inventory/group_vars/ffmwu-monitoring
index 971fbd0..0f0588a 100644
--- a/inventory/group_vars/ffmwu-monitoring
+++ b/inventory/group_vars/ffmwu-monitoring
@@ -10,6 +10,7 @@ common_repos:
http_meshviewer_prefix: map
http_grafana_prefix: stats
+http_lookingglass_prefix: lg
prometheus_conf_main: prometheus/prometheus.yml.j2
prometheus_opts: "--web.listen-address=localhost:9090"
diff --git a/playbooks/gateways.yml b/playbooks/gateways.yml
index b811933..41883dc 100755
--- a/playbooks/gateways.yml
+++ b/playbooks/gateways.yml
@@ -31,6 +31,7 @@
- service-bird
- service-bird-icvpn
- service-bird-ffrl
+ - service-bird-lg
- service-bind-slave
- service-respondd
- service-nullmailer
diff --git a/playbooks/monitoring.yml b/playbooks/monitoring.yml
index f6b9120..458c36f 100755
--- a/playbooks/monitoring.yml
+++ b/playbooks/monitoring.yml
@@ -29,5 +29,6 @@
- service-fastd
- service-fastd-backbone
- service-bird
+ - service-bird-lg
- service-respondd
- service-nullmailer
diff --git a/roles/service-bird-lg/README.md b/roles/service-bird-lg/README.md
new file mode 100644
index 0000000..7745b51
--- /dev/null
+++ b/roles/service-bird-lg/README.md
@@ -0,0 +1,13 @@
+# Ansible role service-bird-lg
+
+Diese Ansible role installiert und konfiguriert bird-lg.
+
+## Benötigte Variablen
+
+- Variable `http_lookingglass_prefix`
+- Variable `git_path`
+- Liste `meshes`
+- Variable `lg_path` (Rollen-Variable)
+- Variable `lg_user `(Rollen-Variable)
+- Variable `lg_url_external` (Rollen-Variable)
+- Variable `lg_url_internal `(Rollen-Variable)
diff --git a/roles/service-bird-lg/handlers/main.yml b/roles/service-bird-lg/handlers/main.yml
new file mode 100644
index 0000000..064c701
--- /dev/null
+++ b/roles/service-bird-lg/handlers/main.yml
@@ -0,0 +1,19 @@
+---
+- name: reload systemd
+ systemd:
+ daemon_reload: yes
+
+- name: restart bird-lg-proxy
+ systemd:
+ name: bird-lg-proxy
+ state: restarted
+
+- name: restart bird-lg-webservice
+ systemd:
+ name: bird-lg-webservice
+ state: restarted
+
+- name: restart nginx
+ systemd:
+ name: nginx
+ state: restarted
diff --git a/roles/service-bird-lg/meta/main.yml b/roles/service-bird-lg/meta/main.yml
new file mode 100644
index 0000000..35e84d4
--- /dev/null
+++ b/roles/service-bird-lg/meta/main.yml
@@ -0,0 +1,4 @@
+---
+dependencies:
+ - { role: service-bird }
+ - { role: service-nginx }
diff --git a/roles/service-bird-lg/tasks/lg-proxy.yml b/roles/service-bird-lg/tasks/lg-proxy.yml
new file mode 100644
index 0000000..87b4b04
--- /dev/null
+++ b/roles/service-bird-lg/tasks/lg-proxy.yml
@@ -0,0 +1,24 @@
+---
+- name: write lgproxy.cfg
+ template:
+ src: lgproxy.cfg.j2
+ dest: "{{ lg_path }}/lgproxy.cfg"
+ notify:
+ - restart bird-lg-proxy
+
+- name: write systemd unit
+ template:
+ src: bird-lg-proxy.service.j2
+ dest: "/etc/systemd/system/bird-lg-proxy.service"
+ owner: root
+ group: root
+ mode: 0644
+ notify:
+ - reload systemd
+ - restart bird-lg-proxy
+
+- name: configure systemd unit
+ systemd:
+ name: bird-lg-proxy
+ enabled: yes
+ state: started
diff --git a/roles/service-bird-lg/tasks/lg-webservice.yml b/roles/service-bird-lg/tasks/lg-webservice.yml
new file mode 100644
index 0000000..bf338da
--- /dev/null
+++ b/roles/service-bird-lg/tasks/lg-webservice.yml
@@ -0,0 +1,33 @@
+---
+- name: write lg.cfg
+ template:
+ src: lg.cfg.j2
+ dest: "{{ lg_path }}/lg.cfg"
+ notify:
+ - restart bird-lg-webservice
+
+- name: write vhost lookingglass.conf
+ template:
+ src: lookingglass_vhost.conf.j2
+ dest: /etc/nginx/conf.d/lookingglass.conf
+ owner: root
+ group: root
+ mode: 0644
+ notify: restart nginx
+
+- name: write systemd unit
+ template:
+ src: bird-lg-webservice.service.j2
+ dest: "/etc/systemd/system/bird-lg-webservice.service"
+ owner: root
+ group: root
+ mode: 0644
+ notify:
+ - reload systemd
+ - restart bird-lg-webservice
+
+- name: configure systemd unit
+ systemd:
+ name: bird-lg-webservice
+ enabled: yes
+ state: started
diff --git a/roles/service-bird-lg/tasks/main.yml b/roles/service-bird-lg/tasks/main.yml
new file mode 100644
index 0000000..73d7973
--- /dev/null
+++ b/roles/service-bird-lg/tasks/main.yml
@@ -0,0 +1,42 @@
+---
+- name: clone repo
+ git:
+ repo: "https://github.com/sileht/bird-lg.git"
+ dest: "{{ lg_path }}"
+ version: master
+ force: yes
+
+- name: install dependencies
+ package:
+ name: "{{ item }}"
+ state: present
+ loop:
+ - python-flask
+ - python-dnspython
+ - python-pydot
+ - python-memcache
+ - graphviz
+ - whois
+ - traceroute
+
+- name: create system user
+ user:
+ name: "{{ lg_user }}"
+ home: "{{ lg_path }}"
+ groups: bird
+ shell: /bin/false
+
+- name: create log dir
+ file:
+ path: "/var/log/bird-lg"
+ state: directory
+ owner: "{{ lg_user }}"
+ group: "{{ lg_user }}"
+
+- name: configure lg-proxy
+ when: ffmwu_server_type == "gateway"
+ include_tasks: lg-proxy.yml
+
+- name: configure lg-webservice
+ when: ffmwu_server_type == "monitoring"
+ include_tasks: lg-webservice.yml
diff --git a/roles/service-bird-lg/templates/bird-lg-proxy.service.j2 b/roles/service-bird-lg/templates/bird-lg-proxy.service.j2
new file mode 100644
index 0000000..fb7511d
--- /dev/null
+++ b/roles/service-bird-lg/templates/bird-lg-proxy.service.j2
@@ -0,0 +1,31 @@
+# Copyright (C) 2015-2018 Alsace Réseau Neutre
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+# Debian GNU/Linux: store this in /etc/systemd/system/
+
+
+[Unit]
+Description=BIRD Looking-Glass proxy
+After=bird.service bird6.service
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/python {{ lg_path }}/lgproxy.py
+User={{ lg_user }}
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/service-bird-lg/templates/bird-lg-webservice.service.j2 b/roles/service-bird-lg/templates/bird-lg-webservice.service.j2
new file mode 100644
index 0000000..a1d31cc
--- /dev/null
+++ b/roles/service-bird-lg/templates/bird-lg-webservice.service.j2
@@ -0,0 +1,31 @@
+# Copyright (C) 2015-2018 Alsace Réseau Neutre
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+# Debian GNU/Linux: store this in /etc/systemd/system/
+
+
+[Unit]
+Description=BIRD Looking-Glass service
+After=nginx.service
+
+[Service]
+Type=simple
+User={{ lg_user }}
+ExecStart=/usr/bin/python {{ lg_path }}/lg.py
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/service-bird-lg/templates/lg.cfg.j2 b/roles/service-bird-lg/templates/lg.cfg.j2
new file mode 100644
index 0000000..c913b57
--- /dev/null
+++ b/roles/service-bird-lg/templates/lg.cfg.j2
@@ -0,0 +1,34 @@
+DEBUG = False
+LOG_FILE="/var/log/bird-lg/lg-webservice.log"
+LOG_LEVEL="WARNING"
+
+DOMAIN = "ffmwu.org"
+
+BIND_IP = "127.0.0.1"
+BIND_PORT = 5001
+
+PROXY = {
+{% for host in groups["ffmwu-gateways"] %}
+ "{{ host.rsplit('.freifunk-mwu.de')[0] }}" : 5000,
+{% endfor %}
+}
+
+# Used for bgpmap
+ROUTER_IP = {
+{% for host in groups["ffmwu-gateways"] %}
+ "{{ host.rsplit('.freifunk-mwu.de')[0] }}" : [ "{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}", "{{ bgp_ipv6_transfer_net | ipaddr('net') | ipsubnet(64, 0) | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}" ],
+{% endfor %}
+}
+
+AS_NUMBER = {
+{% for host in groups["ffmwu-gateways"] %}
+ "{{ host.rsplit('.freifunk-mwu.de')[0] }}" : "65037",
+{% endfor %}
+}
+
+#WHOIS_SERVER = "whois.foo.bar"
+
+# DNS zone to query for ASN -> name mapping
+ASN_ZONE = "asn.cymru.com"
+
+SESSION_KEY = '\xd77\xf9\xfa\xc2\xb5\xcd\x85)`+H\x9d\xeeW\\%\xbe/\xbaT\x89\xe8\xa7'
diff --git a/roles/service-bird-lg/templates/lgproxy.cfg.j2 b/roles/service-bird-lg/templates/lgproxy.cfg.j2
new file mode 100644
index 0000000..028578a
--- /dev/null
+++ b/roles/service-bird-lg/templates/lgproxy.cfg.j2
@@ -0,0 +1,16 @@
+DEBUG=False
+
+LOG_FILE="/var/log/bird-lg/lg-proxy.log"
+LOG_LEVEL="WARNING"
+
+BIND_IP = "{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(magic) | ipaddr('ip') }}"
+BIND_PORT = 5000
+
+ACCESS_LIST = [ {% for host in groups["ffmwu-monitoring"] %}"{{ bgp_ipv4_transfer_net | ipaddr('net') | ipaddr(hostvars[host]['magic']) | ipaddr('ip') }}"{% if not loop.last %}, {% endif %}{% endfor %} ]
+
+# ???
+IPV4_SOURCE = "10.207.0.37"
+IPV6_SOURCE = "fec0::a:cf:0:25"
+
+BIRD_SOCKET="/var/run/bird/bird.ctl"
+BIRD6_SOCKET="/var/run/bird/bird6.ctl"
diff --git a/roles/service-bird-lg/templates/lookingglass_vhost.conf.j2 b/roles/service-bird-lg/templates/lookingglass_vhost.conf.j2
new file mode 100644
index 0000000..c111042
--- /dev/null
+++ b/roles/service-bird-lg/templates/lookingglass_vhost.conf.j2
@@ -0,0 +1,23 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ lg_url_external }} {{ lg_url_internal }};
+
+ include /etc/nginx/snippets/redirect-to-ssl.conf;
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ server_name {{ lg_url_external }} {{ lg_url_internal }};
+
+ ssl_certificate /etc/nginx/ssl/{{ inventory_hostname_short }}.{{ http_domain_external }}/fullchain.pem;
+ ssl_certificate_key /etc/nginx/ssl/{{ inventory_hostname_short }}.{{ http_domain_external }}/privkey.pem;
+
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+
+ location / {
+ proxy_pass http://127.0.0.1:5001;
+ }
+}
diff --git a/roles/service-bird-lg/vars/main.yml b/roles/service-bird-lg/vars/main.yml
new file mode 100644
index 0000000..b5a7070
--- /dev/null
+++ b/roles/service-bird-lg/vars/main.yml
@@ -0,0 +1,6 @@
+---
+lg_path: "{{ git_path }}/bird-lg"
+lg_user: "lookingglass"
+
+lg_url_external: "{{ http_lookingglass_prefix }}.{{ http_domain_external }}"
+lg_url_internal: "{{ http_lookingglass_prefix }}.{{ http_domain_internal }}"