diff --git a/README.md b/README.md
index d61db2d..c87e4be 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,21 @@
# ansible.fftdf.supernode
Ansible yml file to manage Freifunk Troisdorf supernodes
+
+At this time you have to start it explicit with the target server
+example: ansible-playbook install.sn.yml --extra-vars "target=troisdorf5"
+
+You need this information in your hosts (/etc/ansible/hosts) file:
+#example, I hope self explaining
+[troisdorf5]
+78.46.233.212
+
+[troisdorf5:vars]
+sn_hostname=troisdorf5
+sn_dhcp_range=10.188.115.1 10.188.115.254
+sn_dhcp_dns=10.188.1.100, 10.188.1.23
+sn_dhcp_router=10.188.255.5
+sn_mesh_IPv6=fda0:747e:ab29:7405:255::5
+sn_mesh_IPv4=10.188.255.5
+sn_mesh_MAC=a2:8c:ae:6f:f6:05
+sn_fqdn=freifunk-troisdorf.de
+sn_l2tp_tb_port=53844
diff --git a/files/authorized_keys b/files/authorized_keys
new file mode 100644
index 0000000..7cc6678
--- /dev/null
+++ b/files/authorized_keys
@@ -0,0 +1,13 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAgEAos0JvQsyAsP3FcsqDCBTDqzUGBeoxMKDj/SSRoy5MBDPUaWm37b93Lqmg1wMj0qvUURBKpWsRiRUzzRAaQrIdhcZjo0Gkw4vv7tpFQCmvWqxUpzH00GDKjLrMvNfcv+5b0Ctl06Bo+e4nb2SVsFhjaP9MLIjHiKpgivIPx9aKwxKx/VjsW920eWOG+VaDKIJTxPGUYedaUgIktvhutAbOyRR/OJlIZ3Qs0cnyT4KTM4pe4br2p3+mNs6J7G+z8Lw99WiUBfUwsRLVO68nJA2PKlJNEUGJycngqV06iQpcDfei88DFRMetN9bhVYxWFIzCQfjjqs8dkomEhfFQwfOTYiOouhaycZABwU4pPmQwZIkp1q4KduodU/KYsf78WitYgavHVInWBQuAUljafwQpTLHy8AI6M3XmbKi5rvNZiy4hoxfaT7rYJGuBoTwsZEHI7Sf26XsyQKJdu29mmIYPpzPKP7VAyjAVLqruLX1Yy0oZuM22YFFj5MHuoEN3WdXOYymvZyOM05xXeQk6gVh3EE6MpbK8CFz1KPNEjd+vce1zUyACDvqdt6ZIjqmUdivBsvHDTqMgH9mSxjjjwLy+Sd7snXx0bqksTdPChAlXN9vs3ez8FJl0P4inzjza8l8zGqaa2A1CsO8dRcyojohczLYoTHWQTB3tVIdcj55UIE= Roman
+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDM0d9uUUdkK80fYEAz+IwxbhQO2qsr87Q4uxxwqQCvjVWryL+IuKMBJJGroWDMz2d9UJcIXEYdMz4436U0DoPJuoXe5iDsVvum3Vz3276My+tqx1bZWCktPa8Isft7mO/wfELNjRNQduUiwh2y712s7/3GQI+5Rs/65HuLHTnpLKrlfptqmsmYw+IUFDzGwBLJ6sqP90ywjKkperPCAH3IWcTsQwnW3EJFPToMg6BrQslZlxx/z+co3e6jCWzUuuIRP9jp4SmNVfYaVGb1cOFdL1p1P0qWHBHdGUnXHZ+c773VKVSj+spUBxKGqNC1EhRCYTsPDLVrYrhKl2BRLcgB stefan@Stefan-Linux
+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUlPYUqsisJoBT5iDOc7OQXadZyFgI2Z+n+ARPg7OLgkw4SCORAOd53x6KYQZFhq9LP6Dv+kNkk3Qvd/uIr8avG3nxRcHWSIU9ICUmGzEp+W7dT1ExzhVkFxQG7f219ifjRO95xeQNI45MdVKBytQoQGNMoNLXTOZfW5mYr5yQWePa2OmdJLPWrAoHpS2PgrcqWzqdSBuKLdPQgr8KKHGvn9Wf/t9/6/foYfBlzf+emfxZY0M7vJUcCkpK+m66ECE2/eu9aE3m4oBOImivy9/yCta2BASJKCycYoTijRlihcllT3zSt2AGlK7OKpZRDlvFOPuL4yw1LsreBRkkdcAZ reka
+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDb1l5B82IeYYmapacMPR1KQV7r24Qc7K9v33Wtfyi3GuF6sz/Z014ZvtI6TwodvjWH5yx0yh+zY8BQzgb29zQm6vCjnAzDX2QdJJtAruNcl3Ib8rnp4dIRtSRwxwTP/QSltuSokMMoCoKI3Zl0i4MvlCCezjSVWzmfeTr8OA9pDz1eJ9hZn87IaBghVIOIpZYvoxhE7GAbctqA+Jx3XUoWyY4LJpgMA4Y2q9YjQ9bWNyQb5FuwCp4akapwDFEvbTDY0DyAHKmm7txv+5q5RkxfFq3K/DtcILbm0wtAsqM7VZu2TYOj+KiEHJmJMAq+yYNEWzMTsnr7mjqz8I5uOA0V jan@gefion
+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNx2LqPdxwg26i4PytNUIbabqf7eb9gIp6dgwwIqFUnqbnTcilzxlm1FZoH+yMKvYY0G+ZNPG9Zs59QWE/m+mPBOjmrf5N4EH3BW3L/VRLesFMokXHtxkXZzX8CD7c+C0DGmcWfQNMD9tOYsKVm3No3Yr1Hy/WmVQbdEjpkowGpl/y1GFjZqa0dGBhVwAzdHjxsKkpbbVJDDzBwY6WReV+b6Ychgk4S58caJWXAZhkv/2bnaGW1SloHST+GBZrFa+JYbS0D1eortfpPsSR0AMqReJ+NSBKopOYC+WbqEFk9V5VJgbIsT27hRLk3Ctn8MuBUCP1vzn6gyPK91o/ZZqH jan@odin
+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCVxoI2GdqqnK0eKsx5xXiYca19toxB+s9lHb9u9gdmJ52tsl75XZVT2R44o5Yu8KciSPx+khzj7vL3RWieVTrPGhlbYQnOuK73x420rGejjAyDFPQWQxw98Bx0a7VHBsSUpndcnlLBMPe6bIOLI8j7c/sV26rEOAF7LshuONq4E5SMUTL4bp2dhfBgC8SjGdevBpwR1rCBIt51jhvS/asBIUZNrabG3NPwNoaRLELUbFZm7vLF777GWuBzM0G41iImb8nuC1q9WSt66ShhSxLthvl1wdyvixgCgY5yM3eOVJHheMWR6mwE2ZdAeLAFjfXKBqoH5My7a4K96wyUMptD nodeadmin@update1
+
+ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAgEA5OYOF+VBtXXxv/wZkT5K3P7QAUJaM88zJqeGh8NJCO7EDg9jLoWLzAP7LnM9XEA4ycWdl8HX1+EUKqVXAbSNItTZZkO9LCbIiIe1w8oJd2j9hY0IpxPqbz9ePPZh0JtxAZMh3NgOoSiND0leAeOt0lTlDPh4g3G4KvR33d9PIj5ZerU47ceLyy4xEwNbZDKD04+frpq1W+lDqglR0jV/h/pcoQTAEBflbmGLeXIXRsR6zq/of4Wx/MlX18VD9SXPLGXvQ5c4lt5PvV/oeHz4gEjPv2hrI3s3fyWakadAuI9ah48CaEgpVReUGjtYDc0PskvjAH/+slqIHW1D5El+R1Z/2wn/aEGokFHUc0SiFb3NAOwxWvMtUHhXi9ZiTHt0p/0FwWZ1pxqRzODvK8uZ7LAJRGe6q9NYQkIax6SLOfWm4MFWDpDLgWz5MSbPqo+Kfo0614z1mxA3vpY53lUqEGRx4I6z/PDaOHMFd3sxhSMPGvmMvAOLTRofFppwUq1YqQkd6embsJjBN0gU9AilpL5Q2il0OoW4g0rUR8HPJczuDzmHZTXpPU2dY6MhAJ0sbNmk0XhmyoEH9/A1zPEHmirTcBMmbFUsYmR6+MnHEhxnRu5PQpXqcu2vN+JAeasgJShRl7g+rHIdutswHUAWWyfgaD0GF3f6zuOLooz1XQU= localadmin@tst-ansible
diff --git a/files/bataddif.sh.j2 b/files/bataddif.sh.j2
new file mode 100644
index 0000000..4dde305
--- /dev/null
+++ b/files/bataddif.sh.j2
@@ -0,0 +1,7 @@
+#!/bin/bash
+INTERFACE="$3"
+
+ip link set address {{ sn_mesh_MAC }} dev $INTERFACE
+
+ip link set dev $INTERFACE up mtu 1312
+/usr/sbin/batctl if add $INTERFACE
diff --git a/files/batdelif.sh b/files/batdelif.sh
new file mode 100644
index 0000000..dbe3614
--- /dev/null
+++ b/files/batdelif.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+INTERFACE="$3"
+
+/usr/sbin/batctl if del $INTERFACE
diff --git a/files/collectd.conf.j2 b/files/collectd.conf.j2
new file mode 100644
index 0000000..6c91e0c
--- /dev/null
+++ b/files/collectd.conf.j2
@@ -0,0 +1,922 @@
+# Config file for collectd(1).
+#
+# Some plugins need additional configuration and are disabled by default.
+# Please read collectd.conf(5) for details.
+#
+# You should also read /usr/share/doc/collectd-core/README.Debian.plugins
+# before enabling any more plugins.
+
+Hostname "{{ sn_hostname }}"
+FQDNLookup true
+BaseDir "/var/lib/collectd"
+PluginDir "/usr/lib/collectd"
+#TypesDB "/usr/share/collectd/types.db" "/etc/collectd/my_types.db"
+Interval 100
+Timeout 2
+ReadThreads 5
+LoadPlugin write_graphite
+
+
+ Host "10.188.1.27"
+ Port "2003"
+ Prefix "collectd.gateways."
+ StoreRates true
+ AlwaysAppendDS false
+ EscapeCharacter "_"
+
+
+
+LoadPlugin syslog
+LoadPlugin interface
+LoadPlugin cpu
+LoadPlugin df
+LoadPlugin disk
+LoadPlugin entropy
+LoadPlugin irq
+LoadPlugin load
+LoadPlugin memory
+LoadPlugin openvpn
+LoadPlugin processes
+LoadPlugin swap
+LoadPlugin rrdtool
+LoadPlugin users
+
+
+ DataDir "/var/lib/collectd/rrd"
+# CacheTimeout 120
+# CacheFlush 900
+# WritesPerSecond 30
+# RandomTimeout 0
+#
+# The following settings are rather advanced
+# and should usually not be touched:
+# StepSize 10
+# HeartBeat 20
+# RRARows 1200
+# RRATimespan 158112000
+# XFF 0.1
+
+
+#
+# LogLevel "info"
+# File STDOUT
+# Timestamp true
+# PrintSeverity false
+#
+
+
+
+ LogLevel info
+
+
+ Interface "eth0"
+ Interface "bat0"
+ Interface "fastd-tro"
+ Interface "mullvad"
+ IgnoreSelected false
+
+
+#####################################################################
+#LoadPlugin amqp
+#LoadPlugin apache
+#LoadPlugin apcups
+#LoadPlugin ascent
+#LoadPlugin battery
+#LoadPlugin bind
+#LoadPlugin conntrack
+#LoadPlugin contextswitch
+
+#LoadPlugin cpufreq
+#LoadPlugin csv
+#LoadPlugin curl
+#LoadPlugin curl_json
+#LoadPlugin curl_xml
+#LoadPlugin dbi
+
+#LoadPlugin dns
+#LoadPlugin email
+
+#LoadPlugin ethstat
+#LoadPlugin exec
+#LoadPlugin filecount
+#LoadPlugin fscache
+#LoadPlugin gmond
+#LoadPlugin hddtemp
+
+#LoadPlugin ipmi
+#LoadPlugin iptables
+#LoadPlugin ipvs
+
+#LoadPlugin java
+#LoadPlugin libvirt
+
+#LoadPlugin madwifi
+#LoadPlugin mbmon
+#LoadPlugin md
+#LoadPlugin memcachec
+#LoadPlugin memcached
+
+#LoadPlugin multimeter
+#LoadPlugin mysql
+#LoadPlugin netlink
+#LoadPlugin network
+#LoadPlugin nfs
+#LoadPlugin nginx
+#LoadPlugin notify_desktop
+#LoadPlugin notify_email
+#LoadPlugin ntpd
+#LoadPlugin numa
+#LoadPlugin nut
+#LoadPlugin olsrd
+
+#
+# Globals true
+#
+#LoadPlugin pinba
+#LoadPlugin ping
+#LoadPlugin postgresql
+#LoadPlugin powerdns
+
+#LoadPlugin protocols
+#
+# Globals true
+#
+#LoadPlugin rrdcached
+
+#LoadPlugin sensors
+#LoadPlugin serial
+#LoadPlugin snmp
+
+#LoadPlugin table
+#LoadPlugin tail
+#LoadPlugin tcpconns
+#LoadPlugin teamspeak2
+#LoadPlugin ted
+#LoadPlugin thermal
+#LoadPlugin tokyotyrant
+#LoadPlugin unixsock
+#LoadPlugin uptime
+
+#LoadPlugin uuid
+#LoadPlugin varnish
+#LoadPlugin vmem
+#LoadPlugin vserver
+#LoadPlugin wireless
+
+#LoadPlugin write_http
+#LoadPlugin write_mongodb
+
+#
+#
+# Host "localhost"
+# Port "5672"
+# VHost "/"
+# User "guest"
+# Password "guest"
+# Exchange "amq.fanout"
+# RoutingKey "collectd"
+# Persistent false
+# StoreRates false
+#
+#
+
+#
+#
+# URL "http://localhost/server-status?auto"
+# User "www-user"
+# Password "secret"
+# VerifyPeer false
+# VerifyHost false
+# CACert "/etc/ssl/ca.crt"
+# Server "apache"
+#
+#
+#
+# URL "http://some.domain.tld/status?auto"
+# Host "some.domain.tld"
+# Server "lighttpd"
+#
+#
+
+#
+# Host "localhost"
+# Port "3551"
+#
+
+#
+# URL "http://localhost/ascent/status/"
+# User "www-user"
+# Password "secret"
+# VerifyPeer false
+# VerifyHost false
+# CACert "/etc/ssl/ca.crt"
+#
+
+#
+# URL "http://localhost:8053/"
+#
+# ParseTime false
+#
+# OpCodes true
+# QTypes true
+# ServerStats true
+# ZoneMaintStats true
+# ResolverStats false
+# MemoryStats true
+#
+#
+# QTypes true
+# ResolverStats true
+# CacheRRSets true
+#
+# Zone "127.in-addr.arpa/IN"
+#
+#
+
+#
+# DataDir "/var/lib/collectd/csv"
+# StoreRates false
+#
+
+#
+#
+# URL "http://finance.google.com/finance?q=NYSE%3AAMD"
+# User "foo"
+# Password "bar"
+# VerifyPeer false
+# VerifyHost false
+# CACert "/etc/ssl/ca.crt"
+# MeasureResponseTime false
+#
+# Regex "]*> *([0-9]*\\.[0-9]+) *"
+# DSType "GaugeAverage"
+# Type "stock_value"
+# Instance "AMD"
+#
+#
+#
+
+#
+## See: http://wiki.apache.org/couchdb/Runtime_Statistics
+#
+# Instance "httpd"
+#
+# Type "http_requests"
+#
+#
+#
+# Type "http_request_methods"
+#
+#
+#
+# Type "http_response_codes"
+#
+#
+## Database status metrics:
+#
+# Instance "dbs"
+#
+# Type "gauge"
+#
+#
+# Type "counter"
+#
+#
+# Type "bytes"
+#
+#
+#
+
+#
+#
+# Host "my_host"
+# Instance "some_instance"
+# User "collectd"
+# Password "thaiNg0I"
+# VerifyPeer true
+# VerifyHost true
+# CACert "/path/to/ca.crt"
+#
+#
+# Type "magic_level"
+# InstancePrefix "prefix-"
+# InstanceFrom "td[1]"
+# ValuesFrom "td[2]/span[@class=\"level\"]"
+#
+#
+#
+
+#
+#
+# Statement "SELECT 'customers' AS c_key, COUNT(*) AS c_value \
+# FROM customers_tbl"
+# MinVersion 40102
+# MaxVersion 50042
+#
+# Type "gauge"
+# InstancePrefix "customer"
+# InstancesFrom "c_key"
+# ValuesFrom "c_value"
+#
+#
+#
+#
+# Driver "mysql"
+# DriverOption "host" "localhost"
+# DriverOption "username" "collectd"
+# DriverOption "password" "secret"
+# DriverOption "dbname" "custdb0"
+# SelectDB "custdb0"
+# Query "num_of_customers"
+# Query "..."
+#
+#
+
+#
+# Device "/dev/sda1"
+# Device "192.168.0.2:/mnt/nfs"
+# MountPoint "/home"
+# FSType "ext3"
+# IgnoreSelected false
+# ReportByDevice false
+# ReportReserved false
+# ReportInodes false
+#
+
+#
+# Disk "hda"
+# Disk "/sda[23]/"
+# IgnoreSelected false
+#
+
+#
+# Interface "eth0"
+# IgnoreSource "192.168.0.1"
+# SelectNumericQueryTypes false
+#
+
+#
+# SocketFile "/var/run/collectd-email"
+# SocketGroup "collectd"
+# SocketPerms "0770"
+# MaxConns 5
+#
+
+#
+# Interface "eth0"
+# Map "rx_csum_offload_errors" "if_rx_errors" "checksum_offload"
+# Map "multicast" "if_multicast"
+# MappedOnly false
+#
+
+#
+# Exec user "/path/to/exec"
+# Exec "user:group" "/path/to/exec"
+# NotificationExec user "/path/to/exec"
+#
+
+#
+#
+# Instance "foodir"
+# Name "*.conf"
+# MTime "-5m"
+# Size "+10k"
+# Recursive true
+# IncludeHidden false
+#
+#
+
+#
+# MCReceiveFrom "239.2.11.71" "8649"
+#
+#
+# Type "swap"
+# TypeInstance "total"
+# DataSource "value"
+#
+#
+#
+# Type "swap"
+# TypeInstance "free"
+# DataSource "value"
+#
+#
+
+#
+# Host "127.0.0.1"
+# Port 7634
+#
+
+#
+# Interface "eth0"
+# IgnoreSelected false
+#
+
+#
+# Sensor "some_sensor"
+# Sensor "another_one"
+# IgnoreSelected false
+# NotifySensorAdd false
+# NotifySensorRemove true
+# NotifySensorNotPresent false
+#
+
+#
+# Chain "table" "chain"
+#
+
+#
+# Irq 7
+# Irq 8
+# Irq 9
+# IgnoreSelected true
+#
+
+#
+# JVMArg "-verbose:jni"
+# JVMArg "-Djava.class.path=/usr/share/collectd/java/collectd-api.jar"
+#
+# LoadPlugin "org.collectd.java.GenericJMX"
+#
+# # See /usr/share/doc/collectd/examples/GenericJMX.conf
+# # for an example config.
+#
+#
+
+#
+# Connection "xen:///"
+# RefreshInterval 60
+# Domain "name"
+# BlockDevice "name:device"
+# InterfaceDevice "name:device"
+# IgnoreSelected false
+# HostnameFormat name
+# InterfaceFormat name
+#
+
+#
+# Interface "wlan0"
+# IgnoreSelected false
+# Source "SysFS"
+# WatchSet "None"
+# WatchAdd "node_octets"
+# WatchAdd "node_rssi"
+# WatchAdd "is_rx_acl"
+# WatchAdd "is_scan_active"
+#
+
+#
+# Host "127.0.0.1"
+# Port 411
+#
+
+#
+# Device "/dev/md0"
+# IgnoreSelected false
+#
+
+#
+#
+# Server "localhost"
+# Key "page_key"
+#
+# Regex "(\\d+) bytes sent"
+# ExcludeRegex ""
+# DSType CounterAdd
+# Type "ipt_octets"
+# Instance "type_instance"
+#
+#
+#
+
+#
+# Socket "/var/run/memcached.sock"
+# or:
+# Host "127.0.0.1"
+# Port "11211"
+#
+
+#
+#
+# Host "database.serv.er"
+# Port "3306"
+# User "db_user"
+# Password "secret"
+# Database "db_name"
+# MasterStats true
+#
+#
+#
+# Host "localhost"
+# Socket "/var/run/mysql/mysqld.sock"
+# SlaveStats true
+# SlaveNotifications true
+#
+#
+
+#
+# Interface "All"
+# VerboseInterface "All"
+# QDisc "eth0" "pfifo_fast-1:0"
+# Class "ppp0" "htb-1:10"
+# Filter "ppp0" "u32-1:0"
+# IgnoreSelected false
+#
+
+#
+# # client setup:
+# Server "ff18::efc0:4a42" "25826"
+#
+# SecurityLevel Encrypt
+# Username "user"
+# Password "secret"
+# Interface "eth0"
+#
+# TimeToLive "128"
+#
+# # server setup:
+# Listen "ff18::efc0:4a42" "25826"
+#
+# SecurityLevel Sign
+# AuthFile "/etc/collectd/passwd"
+# Interface "eth0"
+#
+# MaxPacketSize 1024
+#
+# # proxy setup (client and server as above):
+# Forward true
+#
+# # statistics about the network plugin itself
+# ReportStats false
+#
+# # "garbage collection"
+# CacheFlush 1800
+#
+
+#
+# URL "http://localhost/status?auto"
+# User "www-user"
+# Password "secret"
+# VerifyPeer false
+# VerifyHost false
+# CACert "/etc/ssl/ca.crt"
+#
+
+#
+# OkayTimeout 1000
+# WarningTimeout 5000
+# FailureTimeout 0
+#
+
+#
+# SMTPServer "localhost"
+# SMTPPort 25
+# SMTPUser "my-username"
+# SMTPPassword "my-password"
+# From "collectd@main0server.com"
+# # on .
+# # Beware! Do not use not more than two placeholders (%)!
+# Subject "[collectd] %s on %s!"
+# Recipient "email1@domain1.net"
+# Recipient "email2@domain2.com"
+#
+
+#
+# Host "localhost"
+# Port 123
+# ReverseLookups false
+#
+
+#
+# UPS "upsname@hostname:port"
+#
+
+#
+# Host "127.0.0.1"
+# Port "2006"
+# CollectLinks "Summary"
+# CollectRoutes "Summary"
+# CollectTopology "Summary"
+#
+
+#
+# StatusFile "/etc/openvpn/openvpn-status.log"
+# ImprovedNamingSchema false
+# CollectCompression true
+# CollectIndividualUsers true
+# CollectUserCount false
+#
+
+#
+# IncludeDir "/my/include/path"
+# BaseName "Collectd::Plugins"
+# EnableDebugger ""
+# LoadPlugin Monitorus
+# LoadPlugin OpenVZ
+#
+#
+# Foo "Bar"
+# Qux "Baz"
+#
+#
+
+#
+# Address "::0"
+# Port "30002"
+#
+# Host "host name"
+# Server "server name"
+# Script "script name"
+#
+#
+
+#
+# Host "host.foo.bar"
+# Host "host.baz.qux"
+# Interval 1.0
+# Timeout 0.9
+# TTL 255
+# SourceAddress "1.2.3.4"
+# Device "eth0"
+# MaxMissed -1
+#
+
+#
+#
+# Statement "SELECT magic FROM wizard WHERE host = $1;"
+# Param hostname
+#
+#
+# Type gauge
+# InstancePrefix "magic"
+# ValuesFrom "magic"
+#
+#
+#
+#
+# Statement "SELECT COUNT(type) AS count, type \
+# FROM (SELECT CASE \
+# WHEN resolved = 'epoch' THEN 'open' \
+# ELSE 'resolved' END AS type \
+# FROM tickets) type \
+# GROUP BY type;"
+#
+#
+# Type counter
+# InstancePrefix "rt36_tickets"
+# InstancesFrom "type"
+# ValuesFrom "count"
+#
+#
+#
+#
+# Host "hostname"
+# Port 5432
+# User "username"
+# Password "secret"
+#
+# SSLMode "prefer"
+# KRBSrvName "kerberos_service_name"
+#
+# Query magic
+#
+#
+#
+# Interval 60
+# Service "service_name"
+#
+# Query backend # predefined
+# Query rt36_tickets
+#
+#
+
+#
+#
+# Collect "latency"
+# Collect "udp-answers" "udp-queries"
+# Socket "/var/run/pdns.controlsocket"
+#
+#
+# Collect "questions"
+# Collect "cache-hits" "cache-misses"
+# Socket "/var/run/pdns_recursor.controlsocket"
+#
+# LocalSocket "/opt/collectd/var/run/collectd-powerdns"
+#
+
+#
+# Process "name"
+# ProcessMatch "foobar" "/usr/bin/perl foobar\\.pl.*"
+#
+
+#
+# Value "/^Tcp:/"
+# IgnoreSelected false
+#
+
+#
+# ModulePath "/path/to/your/python/modules"
+# LogTraces true
+# Interactive true
+# Import "spam"
+#
+#
+# spam "wonderful" "lovely"
+#
+#
+
+#
+# DaemonAddress "unix:/var/run/rrdcached.sock"
+# DataDir "/var/lib/rrdcached/db/collectd"
+# CreateFiles true
+# CollectStatistics true
+#
+
+
+
+#
+# SensorConfigFile "/etc/sensors3.conf"
+# Sensor "it8712-isa-0290/temperature-temp1"
+# Sensor "it8712-isa-0290/fanspeed-fan3"
+# Sensor "it8712-isa-0290/voltage-in8"
+# IgnoreSelected false
+#
+
+# See /usr/share/doc/collectd/examples/snmp-data.conf.gz for a
+# comprehensive sample configuration.
+#
+#
+# Type "voltage"
+# Table false
+# Instance "input_line1"
+# Scale 0.1
+# Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1"
+#
+#
+# Type "users"
+# Table false
+# Instance ""
+# Shift -1
+# Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0"
+#
+#
+# Type "if_octets"
+# Table true
+# InstancePrefix "traffic"
+# Instance "IF-MIB::ifDescr"
+# Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
+#
+#
+#
+# Address "192.168.0.2"
+# Version 1
+# Community "community_string"
+# Collect "std_traffic"
+# Inverval 120
+#
+#
+# Address "192.168.0.42"
+# Version 2
+# Community "another_string"
+# Collect "std_traffic" "hr_users"
+#
+#
+# Address "192.168.0.3"
+# Version 1
+# Community "more_communities"
+# Collect "powerplus_voltge_input"
+# Interval 300
+#
+#
+
+#
+# ReportByDevice false
+#
+
+#
+#
+# Instance "slabinfo"
+# Separator " "
+#
+# Type gauge
+# InstancePrefix "active_objs"
+# InstancesFrom 0
+# ValuesFrom 1
+#
+#
+# Type gauge
+# InstancePrefix "objperslab"
+# InstancesFrom 0
+# ValuesFrom 4
+#
+#
+#
+
+#
+#
+# Instance "exim"
+#
+# Regex "S=([1-9][0-9]*)"
+# DSType "CounterAdd"
+# Type "ipt_bytes"
+# Instance "total"
+#
+#
+# Regex "\\"
+# ExcludeRegex "\\.*mail_spool defer"
+# DSType "CounterInc"
+# Type "counter"
+# Instance "local_user"
+#
+#
+#
+
+#
+# ListeningPorts false
+# LocalPort "25"
+# RemotePort "25"
+#
+
+#
+# Host "127.0.0.1"
+# Port "51234"
+# Server "8767"
+#
+
+#
+# Device "/dev/ttyUSB0"
+# Retries 0
+#
+
+#
+# ForceUseProcfs false
+# Device "THRM"
+# IgnoreSelected false
+#
+
+#
+# Host "localhost"
+# Port "1978"
+#
+
+#
+# SocketFile "/var/run/collectd-unixsock"
+# SocketGroup "collectd"
+# SocketPerms "0660"
+# DeleteSocket false
+#
+
+#
+# UUIDFile "/etc/uuid"
+#
+
+#
+#
+# CollectCache true
+# CollectBackend true
+# CollectConnections true
+# CollectSHM true
+# CollectESI false
+# CollectFetch false
+# CollectHCB false
+# CollectSMA false
+# CollectSMS false
+# CollectSM false
+# CollectTotals false
+# CollectWorkers false
+#
+#
+#
+# CollectCache true
+#
+#
+
+#
+# Verbose false
+#
+
+
+
+#
+#
+# User "collectd"
+# Password "secret"
+# VerifyPeer true
+# VerifyHost true
+# CACert "/etc/ssl/ca.crt"
+# Format "Command"
+# StoreRates false
+#
+#
+
+#
+#
+# Host "localhost"
+# Port "27017"
+# Timeout 1000
+# StoreRates false
+#
+#
+
+Include "/etc/collectd/filters.conf"
+Include "/etc/collectd/thresholds.conf"
diff --git a/files/dhcpd.conf.j2 b/files/dhcpd.conf.j2
new file mode 100644
index 0000000..f644e28
--- /dev/null
+++ b/files/dhcpd.conf.j2
@@ -0,0 +1,14 @@
+ddns-update-style none;
+option domain-name "fftdf";
+default-lease-time 300;
+max-lease-time 3600;
+log-facility local7;
+subnet 10.188.0.0 netmask 255.255.0.0 {
+authoritative;
+range {{ sn_dhcp_range }};
+option domain-name-servers {{ sn_dhcp_dns }};
+option routers {{ sn_dhcp_router }};
+interface bat0;
+
+}
+
diff --git a/files/gre_backbone.sh b/files/gre_backbone.sh
new file mode 100644
index 0000000..ab3635e
--- /dev/null
+++ b/files/gre_backbone.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# Server name ending must be a single digit number
+communityname="troisdorf"
+server="troisdorf1 troisdorf2 troisdorf3 troisdorf4 troisdorf5 troisdorf6"
+domain="freifunk-troisdorf.de"
+mtu=1500
+# community MAC address, without the last Byte (:)!
+communitymacaddress="a2:8c:ae:6f:f6"
+# Network part of the network, without the trailing dot
+communitynetwork="10.188"
+# IPv6 network
+communitynetworkv6="fda0:747e:ab29:7405:255::"
+# Third octet from the server range
+octet3rd="255"
+# CIDR muss /16 sein
+localserver=$(hostname)
+
+for i in $server; do
+
+(
+ for j in $server; do
+
+ if [ $i != $j ]; then
+ if [ $i = $(hostname) ]; then
+ ip link add $j type gretap local $(hostname -I | cut -f1 -d' ') remote $(dig +short $j.$domain) dev eth0 nopmtudisc
+ ip link set dev $j mtu $mtu
+ ip link set address $communitymacaddress:${i#$communityname}${j#$communityname} dev $j
+ ip link set $j up
+ batctl if add $j
+ fi
+ fi
+
+ done
+)
+
+done
+
+# configure bat0
+ip link set address $communitymacaddress$:0{localserver#$communityname} dev bat0
+ip link set up dev bat0
+ip addr add $communitynetwork.$octet3rd.${localserver#$communityname}/16 broadcast $communitynetwork.255.255 dev bat0
+ip -6 addr add fda0:747e:ab29:7405:255::${localserver#$communityname}/64 dev bat0
+alfred -i bat0 > /dev/null 2>&1 &
+batadv-vis -i bat0 -s > /dev/null 2>&1 &
diff --git a/files/keepalive.sh b/files/keepalive.sh
new file mode 100644
index 0000000..c83d734
--- /dev/null
+++ b/files/keepalive.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+INTERFACE=eth0 # Set to name of VPN interface
+shopt -s nullglob
+
+# Test whether gateway is connected to the outer world via VPN
+ping -q -I $INTERFACE 8.8.8.8 -c 4 -i 1 -W 5 >/dev/null 2>&1
+
+if test $? -eq 0; then
+ NEW_STATE=server
+else
+ NEW_STATE=off
+fi
+
+# Iterate through network interfaces in sys file system
+for MESH in /sys/class/net/*/mesh; do
+# Check whether gateway modus needs to be changed
+OLD_STATE="$(cat $MESH/gw_mode)"
+[ "$OLD_STATE" == "$NEW_STATE" ] && continue
+ echo $NEW_STATE > $MESH/gw_mode
+ echo 92MBit/92MBit > $MESH/gw_bandwidth
+ logger "batman gateway mode changed to $NEW_STATE"
+
+ # Check whether gateway modus has been deactivated
+ if [ "$NEW_STATE" == "off" ]; then
+ # Shutdown DHCP server to prevent renewal of leases
+ /usr/sbin/service isc-dhcp-server stop
+ fi
+
+ # Check whether gateway modus has been activated
+ if [ "$NEW_STATE" == "server" ]; then
+ # Restart DHCP server
+ /usr/sbin/service isc-dhcp-server start
+ fi
+ exit 0
+done
+
+if [ "$NEW_STATE" == "server" ]; then
+ /usr/sbin/service isc-dhcp-server status 2>&1> /dev/null
+ if $? -ne 0
+ then
+ /usr/sbin/service isc-dhcp-server restart
+ fi
+fi
+if [ "$NEW_STATE" == "off" ]; then
+ /usr/sbin/service isc-dhcp-server status 2>&1> /dev/null
+ if $? -eq 0
+ then
+ /usr/sbin/service isc-dhcp-server stop
+ fi
+fi
diff --git a/files/l2tp_broker.cfg.j2 b/files/l2tp_broker.cfg.j2
new file mode 100644
index 0000000..c9a0cf8
--- /dev/null
+++ b/files/l2tp_broker.cfg.j2
@@ -0,0 +1,51 @@
+[broker]
+; IP address the broker will listen and accept tunnels on
+address={{ ansible_default_ipv4.address }}
+; Ports where the broker will listen on
+port={{ sn_l2tp_tb_port }}
+; Interface with that IP address
+interface=eth0
+; Maximum number of cached cookies, required for establishing a
+; session with the broker
+max_cookies=1024
+; Maximum number of tunnels that will be allowed by the broker
+max_tunnels=100
+; Tunnel port base
+port_base=15000
+; Tunnel id base
+tunnel_id_base=100
+; Tunnel timeout interval in seconds
+tunnel_timeout=60
+; Should PMTU discovery be enabled
+pmtu_discovery=false
+; Namespace (for running multiple brokers); note that you must also
+; configure disjunct ports, and tunnel identifiers in order for
+; namespacing to work
+namespace=troisdorf
+
+[log]
+; Log filename
+filename=/var/log/tunneldigger-broker.log
+; Verbosity
+verbosity=DEBUG
+; Should IP addresses be logged or not
+log_ip_addresses=false
+
+[hooks]
+; Arguments to the session.{up,pre-down,down} hooks are as follows:
+;
+;
+;
+; Arguments to the session.mtu-changed hook are as follows:
+;
+;
+;
+
+; Called after the tunnel interface goes up
+session.up=/srv/tunneldigger/bataddif.sh
+; Called just before the tunnel interface goes down
+session.pre-down=/srv/tunneldigger/batdelif.sh
+; Called after the tunnel interface goes down
+session.down=
+; Called after the tunnel MTU gets changed because of PMTU discovery
+session.mtu-changed=
diff --git a/files/start-broker.sh b/files/start-broker.sh
new file mode 100644
index 0000000..22450e0
--- /dev/null
+++ b/files/start-broker.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+WDIR=/srv/tunneldigger
+VIRTUALENV_DIR=/srv/tunneldigger
+
+cd $WDIR
+source $VIRTUALENV_DIR/bin/activate
+
+bin/python broker/l2tp_broker.py l2tp_broker.cfg
diff --git a/files/tunneldigger.service b/files/tunneldigger.service
new file mode 100644
index 0000000..e6ec88a
--- /dev/null
+++ b/files/tunneldigger.service
@@ -0,0 +1,9 @@
+[Unit]
+Description = Start tunneldigger L2TPv3 broker
+After = network.target
+
+[Service]
+ExecStart = /srv/tunneldigger/start-broker.sh
+
+[Install]
+WantedBy = multi-user.target
diff --git a/install.sn.yml b/install.sn.yml
new file mode 100644
index 0000000..b7aa9f3
--- /dev/null
+++ b/install.sn.yml
@@ -0,0 +1,230 @@
+# First install ssh-key at remote computer
+# In case of python error start:
+# ansible troisdorf4 -u root -m raw -a "apt-get update && apt-get install python -y"
+# Version 3.1, gre-backbone
+
+- name: Install Freifunk Troisdorf super node
+# hosts: FreifunkSupernodesL2TP
+ hosts: '{{ target }}'
+ sudo: False
+ user: root
+ gather_facts: False
+ vars:
+ common_required_packages:
+ - git
+ - make
+ - gcc
+ - build-essential
+ - pkg-config
+ - libgps-dev
+ - libnl-3-dev
+ - libjansson-dev
+ - isc-dhcp-server
+# - openvpn
+ - collectd
+ - libcap-dev
+ - iproute
+ - libnetfilter-conntrack3
+ - python-dev
+ - libevent-dev
+ - ebtables
+ - python-virtualenv
+ - iptables-persistent
+ - batctl
+ - iftop
+ - screen
+ - bridge-utils
+ - tcpdump
+ modules_required:
+ - batman-adv
+ - nf_conntrack_netlink
+ - nf_conntrack
+ - nfnetlink
+ - l2tp_netlink
+ - l2tp_core
+ - l2tp_eth
+ tunneldigger_scripts:
+ - start-broker.sh
+ - batdelif.sh
+ tunneldigger_service:
+ - tunneldigger.service
+# openvpn_files:
+# - mullvad_linux.conf
+# - mullvad.key
+# - mullvad.crt
+# - ca.crt
+# - crl.pem
+# openvpn_scripts:
+# - up.sh
+# - down.sh
+ check_gw_script:
+ - keepalive.sh
+ backbone_script:
+ - gre_backbone.sh
+ system_startup:
+ - "# Routing einschalten"
+ - /sbin/sysctl -w net.ipv6.conf.all.forwarding=1
+ - /sbin/sysctl -w net.ipv4.ip_forward=1
+# - "# Routing Tabelle 42 fuer Freifunk anlegen, wenn noch nicht vorhanden"
+# - #/bin/grep 42 /etc/iproute2/rt_tables || echo '42 42' >> /etc/iproute2/rt_tables"
+# - "# Freifunk Daten sollen mit 0x1 markiert werden"
+# - /sbin/iptables -t mangle -A PREROUTING -i bat0 -j MARK --set-xmark 0x1
+# - "# Erstmal unreachable melden, ausser OpenVPN ist aufgebaut"
+# - "#/sbin/ip route add unreachable default table 42"
+# - "# Alles was mit 0x1 markiert ist soll nach Routing Tabelle 42 behandelt werden"
+# - "/sbin/ip rule add from all fwmark 0x1 table 42 priority 4"
+ - "#NAT auf eth0 aktivieren"
+ - /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
+ - "#GRE Backbone aufbauen"
+ - /opt/freifunk/gre_backbone.sh
+ authorized_keys:
+ - authorized_keys
+
+ tasks:
+ - name: Remove cdrom in sources.list
+ raw: "sed -i '/deb cdrom/c\\#' /etc/apt/sources.list"
+ - name: Make this server ansible compatible
+ raw: "apt-get update && apt-get install python -y"
+ - name: Add backport repo to source list #target: /etc/apt/sources.list.d
+ apt_repository: repo='deb http://http.debian.net/debian jessie-backports main' state=present
+ - name: Update apt cache
+ apt: update_cache=yes
+# - name: Install new kernel
+# apt: name=linux-image-4.2.0-0.bpo.1-amd64 state=present
+# register: kernel4
+ - name: Gathering facts
+ setup:
+ - name: Set IPv4 in hostfile
+ lineinfile: dest=/etc/hosts regexp='^{{ ansible_default_ipv4.address }}' line='{{ ansible_default_ipv4.address }} {{ sn_hostname }}.{{ sn_fqdn }} {{ sn_hostname }}' owner=root group=root mode=0644 state=present
+ - name: Set IPv6 in hostfile
+ lineinfile: dest=/etc/hosts regexp='^{{ ansible_default_ipv6.address }}' line='{{ ansible_default_ipv6.address }} {{ sn_hostname }}.{{ sn_fqdn }} {{ sn_hostname }}' owner=root group=root mode=0644 state=present
+ when: ansible_default_ipv6.address is defined
+ - name: set hostname
+ hostname: name='{{ sn_hostname }}'
+ register: hostname
+ - name: Reboot the server
+ shell: sleep 2 && shutdown -r now "Ansible updates triggered"
+ async: 1
+ poll: 0
+ ignore_errors: true
+ when: hosts.changed
+ when: hostname.changed
+ - name: waiting for server to come back
+ local_action:
+ wait_for
+ host={{ inventory_hostname }}
+ port=22
+ delay=15
+ timeout=300
+ when: hosts.changed
+ when: hostname.changed
+ - name: Install common required packages
+ apt: state=installed pkg={{ item }}
+ with_items: common_required_packages
+ register: apt_updates
+ - name: Install Linux headers
+ shell: "apt-get install linux-headers-$(uname -r) -y"
+ when: apt_updates.changed
+ - name: Add modules
+ lineinfile: dest=/etc/modules line={{ item }}
+ with_items: modules_required
+ register: modules_req
+ - name: Load modules
+ modprobe: name={{ item }}
+ with_items: modules_required
+ when: modules_req.changed
+ - name: Get Tunneldigger
+ git: repo=https://github.com/wlanslovenija/tunneldigger.git
+ dest=/srv/tunneldigger
+ register: tunneldigger
+ - name: Configure tunneldigger
+ command: "{{item}}"
+ with_items:
+ - virtualenv /srv/tunneldigger/ -p python2.7
+ when: tunneldigger.changed
+ - name: Tunneldigger requirements
+ pip: requirements=/srv/tunneldigger/broker/requirements.txt virtualenv=/srv/tunneldigger/
+ when: tunneldigger.changed
+ - name: Copy l2tp broker config template
+ template: src=./files/l2tp_broker.cfg.j2 dest=/srv/tunneldigger/l2tp_broker.cfg owner=root group=root mode=0444
+ when: tunneldigger.changed
+ - name: Copy tunneldigger script template
+ template: src=./files/bataddif.sh.j2 dest=/srv/tunneldigger/bataddif.sh owner=root group=root mode=0500
+ when: tunneldigger.changed
+ - name: Copy tunneldigger scripts
+ copy: src=./files/{{ item }} dest=/srv/tunneldigger owner=root group=root mode=0500
+ with_items: tunneldigger_scripts
+ when: tunneldigger.changed
+ - name: Copy tunneldigger service file
+ copy: src=./files/{{ item }} dest=/etc/systemd/system/tunneldigger.service owner=root group=root mode=0444
+ with_items: tunneldigger_service
+ when: tunneldigger.changed
+ - name: Tunneldigger reload
+ command: "{{item}}"
+ with_items:
+ - systemctl daemon-reload
+ - systemctl enable tunneldigger.service
+ when: tunneldigger.changed
+ - name: Check if alfred is installed
+ command: dpkg-query -W alfred
+ register: alfred_check_deb
+ failed_when: alfred_check_deb.rc > 1
+ changed_when: alfred_check_deb.rc == 1
+ - name: Download alfred
+ get_url:
+ url="https://firmware.freifunk-wuppertal.net/deb/alfred_2015.0_amd64.deb"
+ dest="/tmp/alfred_2015.0_amd64.deb"
+ when: alfred_check_deb.rc == 1
+ - name: Install alfred
+ apt: deb="/tmp/alfred_2015.0_amd64.deb"
+ sudo: False
+ when: alfred_check_deb.rc == 1
+# - name: copy openvpn files
+# copy: src=./files/{{ item }} dest=/etc/openvpn owner=root group=root mode=0400
+# with_items: openvpn_files
+# - name: copy openvpn scripts
+# copy: src=./files/{{ item }} dest=/etc/openvpn owner=root group=root mode=0500
+# with_items: openvpn_scripts
+ - name: Create freifunk directory
+ file: path=/opt/freifunk state=directory mode=0755
+ - name: Check gateway / keepalive script
+ copy: src=./files/{{ item }} dest=/opt/freifunk owner=root group=root mode=0500
+ with_items: check_gw_script
+ register: check_gw
+ - name: Add cron job with check gateway script
+ cron: name=check_gw job="/opt/freifunk/keepalive.sh > /dev/null 2>&1" user="root"
+ when: check_gw.changed
+ - name: Copy dhcpd template file
+ template: src=./files/dhcpd.conf.j2 dest=/etc/dhcp/dhcpd.conf owner=root group=root mode=0444
+ - name: Copy backbone script
+ copy: src=./files/{{ item }} dest=/opt/freifunk owner=root group=root mode=0500
+ with_items: backbone_script
+ - name: Collectd template file
+ template: src=./files/collectd.conf.j2 dest=/etc/collectd/collectd.conf owner=root group=root mode=0444
+ - name: configure rc.local 1st
+ lineinfile: dest=/etc/rc.local line="{{ item }}" state=present
+ with_items: system_startup
+ register: rc
+ - name: configure rc.local 2nd
+ lineinfile: dest=/etc/rc.local line="exit 0" state=absent
+ when: rc.changed
+ - name: configure rc.local 3rd
+ lineinfile: dest=/etc/rc.local line="exit 0" state=present
+ when: rc.changed
+ - name: SSH authorized_keys
+ copy: src=./files/{{ item }} dest=/root/.ssh owner=root group=root mode=0400
+ with_items: authorized_keys
+ - name: Reboot the server finally
+ shell: sleep 2 && shutdown -r now "Ansible updates triggered"
+ async: 1
+ poll: 0
+ ignore_errors: true
+ when: tunneldigger.changed
+ - name: waiting for server to come back
+ local_action:
+ wait_for
+ host={{ inventory_hostname }}
+ port=22
+ delay=15
+ timeout=300
+ when: tunneldigger.changed