From 37728ec27ddf1f23ecdc0bde53d6e61641564ca7 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 20 May 2014 15:54:52 +0200
Subject: [PATCH 01/58] Update bird.conf and peering data

---
 data/peering.yaml                | 32 ++++++++++++++++++++++----------
 templates/etc/bird/bird.conf.erb |  6 +++---
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/data/peering.yaml b/data/peering.yaml
index 202923b..79e4df1 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -61,6 +61,10 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.67
     as: 65529
+  Bremen1:
+    template: peers
+    ip: 10.207.0.196
+    as: 65196
   Chemnitz1:
     template: peers
     ip: 10.207.0.36
@@ -125,9 +129,9 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.66
     as: 65055
-  Kiel4:
+  Kiel2:
     template: peers
-    ip: 10.207.0.58
+    ip: 10.207.0.52
     as: 65525
   Koblenz:
     template: peers
@@ -169,10 +173,6 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.27
     as: 65513
-  Schwarzach1:
-    template: peers
-    ip: 10.207.0.56
-    as: 65527
   Treuenbrietzen:
     template: peers
     ip: 10.207.0.18
@@ -189,6 +189,10 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.7
     as: 65530
+  Wermelskirchen2:
+    template: peers
+    ip: 10.207.0.8
+    as: 65530
 
 
 peerings_v6:
@@ -246,6 +250,10 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:60
     as: 65529
+  Bremen1:
+    template: peers
+    ip: fec0::a:cf:0:c4
+    as: 65196
   diac24:
     template: peers
     ip: fec0::a:cf:ac:16
@@ -302,15 +310,19 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:83
     as: 65052
-  Schwarzach:
-    template: peers
-    ip: fec0::a:cf:0:56
-    as: 65527
   Weimar1:
     template: peers
     ip: fec0::a:cf:0:3
     as: 65042
+  Weimar2:
+    template: peers
+    ip: fec0::a:cf:0:4
+    as: 65042
   Wermelskirchen1:
     template: peers
     ip: fec0::a:cf:0:7
     as: 65530
+  Wermelskirchen2:
+    template: peers
+    ip: fec0::a:cf:0:8
+    as: 65530
diff --git a/templates/etc/bird/bird.conf.erb b/templates/etc/bird/bird.conf.erb
index 6f951f6..50e9ae5 100644
--- a/templates/etc/bird/bird.conf.erb
+++ b/templates/etc/bird/bird.conf.erb
@@ -70,7 +70,7 @@ function is_chaos() {
 # nothing in the other direction
 protocol kernel k_mast {
     scan time 10;
-    import where is_chaos();
+    import none;
     export filter {
         krt_prefsrc = <%= @own_ipv4 %>;
         accept;
@@ -163,8 +163,8 @@ template bgp peers {
   table ebgp;
   local as ownas;
   # ignore routes for our own network
-  import where ((is_freifunk() || is_dn42() || is_chaos()) && !is_self_net());
-  export where  (is_freifunk() || is_dn42() || is_chaos());
+  import where ((is_freifunk() || is_dn42()) && !is_chaos() && !is_self_net());
+  export where ((is_freifunk() || is_dn42()) && !is_chaos());
   route limit 10000;
 };
 

From 017ead9d9a93bc601a85c3c9a54ee3bb3eb2e413 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Sun, 1 Jun 2014 14:02:54 +0200
Subject: [PATCH 02/58] Ensure bc is installed for munin

as it is required for vnstat_ plugin
---
 manifests/sysadmin.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 5e203e4..96af1df 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -96,7 +96,7 @@ HostnameItem=${::hostname}
 
   # munin
   package {
-    [ 'munin-node', 'vnstat' ]:
+    [ 'munin-node', 'vnstat', 'bc' ]:
       ensure => installed,
   }
   ->

From 073cf1dc9e84a49982e0ad7269ae23ad940ab43d Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Sun, 1 Jun 2014 14:15:41 +0200
Subject: [PATCH 03/58] Monitor more interfaces with munin

---
 manifests/sysadmin.pp | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 96af1df..b0e0b55 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -144,6 +144,30 @@ host <%= @ipaddress_eth0 %>
     '/etc/munin/plugins/udp-statistics':
       ensure => link,
       target => '/usr/share/munin/plugins/udp-statistics';
+    '/etc/munin/plugins/if_mullvad':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_mullvad':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_bat0':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_bat0':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_br-ffhh':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_br-ffhh':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_ffhh-mesh-vpn':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_ffhh-mesh-vpn':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
     # TODO: delete not needed plugins
     '/etc/munin/plugin-conf.d/vnstat':
       ensure  => file,

From 13d37b6a5447e84e09fe0329a5fd5ab9cf50f73f Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 21:44:16 +0200
Subject: [PATCH 04/58] disable atop daemon

---
 manifests/sysadmin.pp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index b0e0b55..4d494b5 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -42,6 +42,12 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
     'screen', 'tcpdump', 'rsync', 'file', 'psmisc']:
       ensure => installed,
   }
+  # stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
+  service { 'atop':
+    ensure  => stopped,
+    enable  => false,
+    require => Package['atop']
+  }
 
   # user accounts
   create_resources('account', $accounts)

From a375035f2cd92f3ee3b90f922873b8404db2361b Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 21:47:08 +0200
Subject: [PATCH 05/58] puppet-lintify

---
 manifests/sysadmin.pp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 4d494b5..9b91411 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -192,19 +192,19 @@ class ff_gw::sysadmin::hostname($newname, $newip) {
   $alias = regsubst($newname, '^([^.]*).*$', '\1')
 
   # clean old names
-  if "$::hostname" != "$alias" {
-    host { "$hostname": ensure => absent }
+  if $::hostname != $alias {
+    host { $::hostname: ensure => absent }
   }
-  if "$::fqdn" != "$newname" {
-    host { "$fqdn":     ensure => absent }
+  if $::fqdn != $newname {
+    host { $::fqdn:     ensure => absent }
   }
 
   # rewrite config files:
-  host { "$newname":
+  host { $newname:
     ensure => present,
     ip     => $newip,
     alias  => $alias ? {
-      "$hostname" => undef,
+      $::hostname => undef,
       default     => $alias
     },
     before => Exec['hostname.sh'],
@@ -214,7 +214,7 @@ class ff_gw::sysadmin::hostname($newname, $newip) {
     ensure  => present,
     owner   => 'root',
     group   => 'root',
-    mode    => 644,
+    mode    => '0644',
     content => "${newname}\n",
   }
 
@@ -222,7 +222,7 @@ class ff_gw::sysadmin::hostname($newname, $newip) {
     ensure  => present,
     owner   => 'root',
     group   => 'root',
-    mode    => 644,
+    mode    => '0644',
     content => "${newname}\n",
     notify  => Exec['hostname.sh'],
   }

From 125baa50e4469479d81b2d249633c852e86d7d77 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 21:49:32 +0200
Subject: [PATCH 06/58] provide defaults for ff_gw::tinc params (and remove
 tabs)

---
 manifests/init.pp | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 355ecef..42b9efd 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,4 +1,4 @@
-class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key, $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key, $dhcprange_start, $dhcprange_end, $gw_do_ic_peering = false, $tinc_name, $tinc_keyfile, $ic_vpn_ip4, $ic_vpn_ip6) {
+class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key, $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key, $dhcprange_start, $dhcprange_end, $gw_do_ic_peering = false, $tinc_name = false, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4 = false, $ic_vpn_ip6 = false) {
   class { 'ff_gw::software': }
   ->
   class { 'ff_gw::fastd':
@@ -446,8 +446,8 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
       ensure  => file,
       content => template('ff_gw/etc/bird/bird6.conf.erb');
     '/etc/bird6.conf':
-	  ensure => link,
-	  target => '/etc/bird/bird6.conf';
+      ensure => link,
+      target => '/etc/bird/bird6.conf';
   }
   ~>
   service {
@@ -468,8 +468,8 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
       ensure  => file,
       content => template('ff_gw/etc/bird/bird.conf.erb');
     '/etc/bird.conf':
-	  ensure => link,
-	  target => '/etc/bird/bird.conf';
+      ensure => link,
+      target => '/etc/bird/bird.conf';
   }
   ~>
   service {
@@ -480,7 +480,15 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
   }
 }
 
-class ff_gw::tinc($tinc_name, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4, $ic_vpn_ip6, $version = 'present') {
+class ff_gw::tinc($tinc_name, $tinc_keyfile, $ic_vpn_ip4, $ic_vpn_ip6, $version = 'present') {
+  # note: class ff_gw needs default values and sets these to false.
+  # in case the tinc class is applied then these are the real checks,
+  # making sure the user set usable parameters:
+  validate_string($tinc_name)
+  validate_string($tinc_keyfile)
+  validate_string($ic_vpn_ip4)
+  validate_string($ic_vpn_ip6)
+
   package {
     'tinc':
       ensure => $version,
@@ -495,7 +503,7 @@ class ff_gw::tinc($tinc_name, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_
   file {
     '/etc/tinc/nets.boot':
       ensure  => file,
-	  content => '# all tinc networks -- managed by puppet
+      content => '# all tinc networks -- managed by puppet
 icvpn
 ';
     '/etc/tinc/icvpn/tinc.conf':

From abc3df60e4f3e22185fd5ee8722276ec2ad22163 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 21:52:25 +0200
Subject: [PATCH 07/58] ensure old & new bird version compatibility

---
 manifests/init.pp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 42b9efd..f137c46 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -436,6 +436,11 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
   $ic_peerings_v4 = $peeringdata[ic_peerings_v4]
   $ic_peerings_v6 = $peeringdata[ic_peerings_v6]
 
+  # for compatibility with old & new bird versions
+  file { '/etc/bird':
+    ensure => directory;
+  }
+
   package {
     'bird6':
       ensure => $version,
@@ -444,10 +449,11 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
   file {
     '/etc/bird/bird6.conf':
       ensure  => file,
+      require => File['/etc/bird'],
       content => template('ff_gw/etc/bird/bird6.conf.erb');
     '/etc/bird6.conf':
-      ensure => link,
-      target => '/etc/bird/bird6.conf';
+      ensure  => link,
+      target  => '/etc/bird/bird6.conf';
   }
   ~>
   service {
@@ -466,6 +472,7 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
   file {
     '/etc/bird/bird.conf':
       ensure  => file,
+      require => File['/etc/bird'],
       content => template('ff_gw/etc/bird/bird.conf.erb');
     '/etc/bird.conf':
       ensure => link,

From 19529f1659f236a223671e2e771e501d14778010 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 21:58:33 +0200
Subject: [PATCH 08/58] rsyslog: add stop action after dhcp log

---
 manifests/init.pp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index f137c46..4924448 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -222,7 +222,8 @@ class ff_gw::dhcpd($gw_ipv4, $dhcprange_start, $dhcprange_end) {
     '/etc/rsyslog.d/dhcpd.conf':
       ensure  => file,
       notify  => Service['rsyslog'],
-      content => 'local7.warn /var/log/dhcpd.log';
+      content => 'local7.warn /var/log/dhcpd.log
+& ~';
     '/etc/default/isc-dhcpd':
       ensure  => file,
       content => '# managed by puppet

From 5f98dd4613acac096b6db3c568ed34f5796973e3 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 22:01:25 +0200
Subject: [PATCH 09/58] rsyslog: fix dhcp log levels

---
 manifests/init.pp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 4924448..645767d 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -222,8 +222,11 @@ class ff_gw::dhcpd($gw_ipv4, $dhcprange_start, $dhcprange_end) {
     '/etc/rsyslog.d/dhcpd.conf':
       ensure  => file,
       notify  => Service['rsyslog'],
-      content => 'local7.warn /var/log/dhcpd.log
-& ~';
+      content => '# managed by puppet
+# log DHCP warnings
+local7.warn /var/log/dhcpd.log
+# but do not log DHCP leases etc.
+local7.* ~';
     '/etc/default/isc-dhcpd':
       ensure  => file,
       content => '# managed by puppet

From 13ba5abc7af8d899f298e68c5a43960bf18d8646 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 22:11:49 +0200
Subject: [PATCH 10/58] ensure bird version 1.4.3-2~bpo70+1 by default

---
 manifests/init.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 645767d..ea2b5ff 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -431,7 +431,7 @@ exit 0';
   }
 }
 
-class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic_peering, $ic_vpn_ip6, $version = 'present') {
+class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic_peering, $ic_vpn_ip6, $version = '1.4.3-2~bpo70+1') {
   # read peering data from data file
   $module_path = get_module_path($module_name)
   $peeringdata = loadyaml("${module_path}/data/peering.yaml")

From a734032c5dfe6df46e5e096b4ae2393939356c6a Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 22:19:28 +0200
Subject: [PATCH 11/58] bird6 depends on bird

---
 manifests/init.pp | 47 ++++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index ea2b5ff..b16627f 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -445,29 +445,6 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
     ensure => directory;
   }
 
-  package {
-    'bird6':
-      ensure => $version,
-  }
-  ->
-  file {
-    '/etc/bird/bird6.conf':
-      ensure  => file,
-      require => File['/etc/bird'],
-      content => template('ff_gw/etc/bird/bird6.conf.erb');
-    '/etc/bird6.conf':
-      ensure  => link,
-      target  => '/etc/bird/bird6.conf';
-  }
-  ~>
-  service {
-    'bird6':
-      ensure  => running,
-      enable  => true,
-      require => Service['openvpn'],
-  }
-
-
   package {
     'bird':
       ensure => $version,
@@ -489,6 +466,30 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
       enable  => true,
       require => Service['openvpn'],
   }
+
+  package {
+    'bird6':
+      ensure  => $version,
+      require => Package['bird'],
+  }
+  ->
+  file {
+    '/etc/bird/bird6.conf':
+      ensure  => file,
+      require => File['/etc/bird'],
+      content => template('ff_gw/etc/bird/bird6.conf.erb');
+    '/etc/bird6.conf':
+      ensure  => link,
+      target  => '/etc/bird/bird6.conf';
+  }
+  ~>
+  service {
+    'bird6':
+      ensure  => running,
+      enable  => true,
+      require => Service['openvpn'],
+  }
+
 }
 
 class ff_gw::tinc($tinc_name, $tinc_keyfile, $ic_vpn_ip4, $ic_vpn_ip6, $version = 'present') {

From 669c7036a5fd0a03595d51cd1d6581e3ae0bb95a Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 22:30:32 +0200
Subject: [PATCH 12/58] add gw13 v6 peering

---
 data/peering.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/data/peering.yaml b/data/peering.yaml
index 79e4df1..87293b4 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -228,6 +228,10 @@ peerings_v6:
     template: locals
     ip: fd51:2bb2:fd0d::501
     as: 65112
+  hamburg13:
+    template: locals
+    ip: fd51:2bb2:fd0d::401
+    as: 65112
 
 ic_peerings_v6:
   Augsburg1:

From e5890bf06ea326a6cb47736ce60267334b5d3045 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 1 Jun 2014 23:11:16 +0200
Subject: [PATCH 13/58] add own IP to resolv.conf

---
 manifests/init.pp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/manifests/init.pp b/manifests/init.pp
index b16627f..30cdf6e 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -28,6 +28,10 @@ class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secre
   ->
   class { 'ff_gw::dnsmasq': }
   ->
+  class { 'ff_gw::dns_resolvconf':
+    gw_ipv4    => $gw_ipv4,
+  }
+  ->
   class { 'ff_gw::bird':
     ff_net           => $ff_net,
     ff_mesh_net      => $ff_mesh_net,
@@ -311,6 +315,19 @@ class ff_gw::dnsmasq() {
   }
 }
 
+class ff_gw::dns_resolvconf($gw_ipv4) {
+  # add our own IP as first entry to /etc/resolv.conf
+  # try to preserve everything else as the default nameserver should be the fastest
+  augeas { 'edit_resolv_conf':
+      context => '/files/etc/resolv.conf',
+      changes => [
+          'ins nameserver before nameserver[1]',
+          "set nameserver[1] \"${gw_ipv4}\"",
+      ],
+      onlyif  => "get nameserver[1] != \"${gw_ipv4}\"",
+  }
+}
+
 class ff_gw::radvd($own_ipv6) {
   package {
     'radvd':

From e582db0a8b7ff060831aacc8eb7e07e2609b5f3b Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Mon, 2 Jun 2014 09:38:18 +0200
Subject: [PATCH 14/58] DHCP: Announce this gateway and srv01 as DNS servers

---
 templates/etc/dhcp/dhcpd.conf.erb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/etc/dhcp/dhcpd.conf.erb b/templates/etc/dhcp/dhcpd.conf.erb
index 733d413..dc50cc0 100644
--- a/templates/etc/dhcp/dhcpd.conf.erb
+++ b/templates/etc/dhcp/dhcpd.conf.erb
@@ -16,8 +16,8 @@ subnet 10.112.0.0 netmask 255.255.192.0 {
     authoritative;
     range <%= @dhcprange_start %> <%= @dhcprange_end %>;
 
-    # DNS: srv01 (10.112.1.1) & gw01 (10.112.14.1)
-    option domain-name-servers 10.112.1.1, 10.112.14.1;
+    # DNS: this gateway (<%= @gw_ipv4 %>) & srv01 (10.112.1.1)
+    option domain-name-servers <%= @gw_ipv4 %>, 10.112.1.1;
     option routers <%= @gw_ipv4 %>;
 }
 

From 3b7ff697fa635a4b5fc488735e3534e8d042cb22 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Mon, 2 Jun 2014 12:59:12 +0200
Subject: [PATCH 15/58] remove atop cronjob

---
 manifests/sysadmin.pp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 9b91411..55f7302 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -42,11 +42,16 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
     'screen', 'tcpdump', 'rsync', 'file', 'psmisc']:
       ensure => installed,
   }
+  ->
+  # remove atop cronjob
+  file { '/etc/cron.d/atop':
+    ensure => absent,
+  }
+  ->
   # stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
   service { 'atop':
     ensure  => stopped,
     enable  => false,
-    require => Package['atop']
   }
 
   # user accounts

From d751c18dfe86a5205b31546183dc2b79fa7651a5 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Thu, 5 Jun 2014 21:37:09 +0200
Subject: [PATCH 16/58] Bird: Add peering with RheinNeckar1

---
 data/peering.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/data/peering.yaml b/data/peering.yaml
index 87293b4..b17ef7c 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -173,6 +173,10 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.27
     as: 65513
+  RheinNeckar1:
+    template: peers
+    ip: 10.207.0.142
+    as: 76118
   Treuenbrietzen:
     template: peers
     ip: 10.207.0.18

From ba62e670c60bd47b1b134c933b046b93e46db570 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Thu, 5 Jun 2014 21:37:50 +0200
Subject: [PATCH 17/58] Add cronjob for ntpdate

---
 manifests/sysadmin.pp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 55f7302..4dab594 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -39,7 +39,7 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
   # then install some basic packages
   package {
     ['vim-nox', 'git', 'etckeeper', 'pv', 'curl', 'atop',
-    'screen', 'tcpdump', 'rsync', 'file', 'psmisc']:
+    'screen', 'tcpdump', 'rsync', 'file', 'psmisc', 'ntpdate']:
       ensure => installed,
   }
   ->
@@ -54,6 +54,13 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
     enable  => false,
   }
 
+  cron {
+    'ntpdate-debian':
+      command => '/usr/sbin/ntpdate-debian',
+      user    => root,
+      minute  => '0';
+  }
+
   # user accounts
   create_resources('account', $accounts)
   # Sudo

From e6f165ad29218aeb47b7fbb70bfe16c1e58755cd Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Fri, 6 Jun 2014 00:59:54 +0200
Subject: [PATCH 18/58] Bird/Bird6: Add Ostholstein1 peering

---
 data/peering.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/data/peering.yaml b/data/peering.yaml
index b17ef7c..9ccf58d 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -173,6 +173,10 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.27
     as: 65513
+  Ostholstein1:
+    template: peers
+    ip: 10.207.0.135
+    as: 65152
   RheinNeckar1:
     template: peers
     ip: 10.207.0.142
@@ -318,6 +322,10 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:83
     as: 65052
+  Ostholstein1:
+    template: peers
+    ip: fec0::a:cf:0:87
+    as: 65152
   Weimar1:
     template: peers
     ip: fec0::a:cf:0:3

From f4150d7ec31d74fce12803f92be85f82390fba2d Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 18 Jun 2014 15:06:54 +0200
Subject: [PATCH 19/58] Use DNS Server pushed by VPN provider

---
 files/etc/openvpn/mullvad.conf           |  1 +
 files/etc/openvpn/update-dnsmasq-forward | 56 ++++++++++++++++++++++++
 manifests/init.pp                        |  2 +-
 3 files changed, 58 insertions(+), 1 deletion(-)
 create mode 100755 files/etc/openvpn/update-dnsmasq-forward

diff --git a/files/etc/openvpn/mullvad.conf b/files/etc/openvpn/mullvad.conf
index a438799..a7b0003 100644
--- a/files/etc/openvpn/mullvad.conf
+++ b/files/etc/openvpn/mullvad.conf
@@ -37,6 +37,7 @@ script-security 2
 # Parses DHCP options from openvpn to update resolv.conf
 route-noexec
 up    /etc/openvpn/mullvad/mullvad-up
+down  /etc/openvpn/update-dnsmasq-forward
 
 ping 10
 
diff --git a/files/etc/openvpn/update-dnsmasq-forward b/files/etc/openvpn/update-dnsmasq-forward
new file mode 100755
index 0000000..eb57a81
--- /dev/null
+++ b/files/etc/openvpn/update-dnsmasq-forward
@@ -0,0 +1,56 @@
+#!/bin/bash
+# 
+# Parses DHCP options from openvpn to update resolv.conf
+# To use set as 'up' and 'down' script in your openvpn *.conf:
+# up /etc/openvpn/update-resolv-conf
+# down /etc/openvpn/update-resolv-conf
+#
+# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
+# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL. 
+# 
+# Example envs set from openvpn:
+#
+#     foreign_option_1='dhcp-option DNS 193.43.27.132'
+#     foreign_option_2='dhcp-option DNS 193.43.27.133'
+#     foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
+#
+
+[ "$script_type" ] || exit 0
+[ "$dev" ] || exit 0
+
+split_into_parts()
+{
+	part1="$1"
+	part2="$2"
+	part3="$3"
+}
+
+case "$script_type" in
+  up)
+	NMSRVRS=""
+	SRCHS=""
+	for optionvarname in ${!foreign_option_*} ; do
+		option="${!optionvarname}"
+		echo "$option"
+		split_into_parts $option
+		if [ "$part1" = "dhcp-option" ] ; then
+			if [ "$part2" = "DNS" ] ; then
+				NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
+			elif [ "$part2" = "DOMAIN" ] ; then
+				SRCHS="${SRCHS:+$SRCHS }$part3"
+			fi
+		fi
+	done
+	R=""
+	for NS in $NMSRVRS ; do
+        	R="${R}server=$NS@$dev\n"
+	done
+	echo -en "$R" > /etc/dnsmasq.d/forward
+	/usr/sbin/service dnsmasq restart
+	;;
+  down)
+	echo -n "" > /etc/dnsmasq.d/forward
+	/usr/sbin/service dnsmasq restart
+	;;
+esac
+
diff --git a/manifests/init.pp b/manifests/init.pp
index 30cdf6e..b69bbf5 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -391,7 +391,7 @@ class ff_gw::vpn($ca_crt, $usr_crt, $usr_key, $openvpn_version = '2.3.2-7~bpo70+
       content => '#!/bin/sh
 ip route replace 0.0.0.0/1 via $5 table 42
 ip route replace 128.0.0.0/1 via $5 table 42
-/usr/sbin/service dnsmasq restart
+/etc/openvpn/update-dnsmasq-forward
 exit 0';
     "/etc/openvpn/${vpnname}.conf":
       ensure => file,

From 2073295b3c69120593eb509a29aafa56f2abafe7 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 18 Jun 2014 15:34:04 +0200
Subject: [PATCH 20/58] Fix using DNS server of VPN provider

---
 manifests/init.pp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/manifests/init.pp b/manifests/init.pp
index b69bbf5..bdf286a 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -396,6 +396,10 @@ exit 0';
     "/etc/openvpn/${vpnname}.conf":
       ensure => file,
       source => "puppet:///modules/ff_gw/etc/openvpn/${vpnname}.conf";
+    "/etc/openvpn/update-dnsmasq-forward":
+      ensure => file,
+      mode    => '0755',
+      source => "puppet:///modules/ff_gw/etc/openvpn/update-dnsmasq-forward";
   }
   ~>
   service { 'openvpn':

From 30e37c0f37fc4f0b89f6b8b861b52580a6c17392 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 18:28:43 +0200
Subject: [PATCH 21/58] use augeas for /etc/network/interfaces, leave lo and
 eth0 as they were

---
 manifests/init.pp | 88 +++++++++++++++++++++++++++++------------------
 1 file changed, 55 insertions(+), 33 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index bdf286a..3953456 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -73,6 +73,10 @@ class ff_gw::software {
 
 class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key) {
   validate_re($mesh_mac, '^de:ad:be:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}$')
+  # TODO: parameterize interface names
+  $br_if='br-ffhh'
+  $bat_if='bat0'
+  $mesh_if='ffhh-mesh-vpn'
 
   file {
     '/etc/fastd/ffhh-mesh-vpn':
@@ -95,39 +99,57 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key) {
       ensure => file,
       mode   => '0755',
       source => 'puppet:///modules/ff_gw/usr/local/bin/check_gateway';
-    '/etc/network/interfaces':
-      ensure  => file,
-      #
-      content => inline_template('# managed by puppet
-
-# The loopback network interface
-auto lo
-iface lo inet loopback
-
-# The primary network interface
-allow-hotplug eth0
-iface eth0 inet dhcp
-
-auto br-ffhh
-iface br-ffhh inet6 static
-  bridge-ports none
-  address <%= @gw_ipv6 %>
-  netmask 64
-iface br-ffhh inet static
-  address <%= @gw_ipv4 %>
-  netmask 255.255.192.0
-
-allow-hotplug bat0
-iface bat0 inet6 manual
-  pre-up modprobe batman-adv
-  pre-up batctl if add ffhh-mesh-vpn
-  up ip link set $IFACE up
-  post-up brctl addif br-ffhh $IFACE
-  post-up batctl it 10000
-  post-up /sbin/ip rule add from all fwmark 0x1 table 42
-  pre-down brctl delif br-ffhh $IFACE || true
-  down ip link set $IFACE down
-');
+  }
+  ->
+  # should use an abstraction layer like https://forge.puppetlabs.com/ajjahn/network,
+  # but I found none that is flexible enough to handle all our config lines
+  augeas {
+    "${br_if}-inet6":
+      context   => '/files/etc/network/interfaces',
+      show_diff => true,
+      changes   => [
+        "set auto[child::1 = '${br_if}']/1 ${br_if}",
+        "set iface[. = '${br_if}'][1] ${br_if}",
+        "set iface[. = '${br_if}'][1]/family inet6",
+        "set iface[. = '${br_if}'][1]/method static",
+        "set iface[. = '${br_if}'][1]/bridge-ports none",
+        "set iface[. = '${br_if}'][1]/address $gw_ipv6",
+        "set iface[. = '${br_if}'][1]/netmask 64",
+      ],
+  }
+  ->
+  augeas {
+    "${br_if}-inet":
+      context   => '/files/etc/network/interfaces',
+      show_diff => true,
+      changes   => [
+        "set iface[. = '${br_if}'][2] ${br_if}",
+        "set iface[. = '${br_if}'][2]/family inet",
+        "set iface[. = '${br_if}'][2]/method static",
+        "set iface[. = '${br_if}'][2]/address $gw_ipv4",
+        "set iface[. = '${br_if}'][2]/netmask 255.255.192.0",
+      ],
+  }
+  ->
+  # TODO: parameterize ffhh-mesh-vpn
+  augeas {
+    "${bat_if}":
+      context   => '/files/etc/network/interfaces',
+      show_diff => true,
+      changes   => [
+        "set allow-hotplug[child::1 = '${bat_if}']/1 ${bat_if}",
+        "set iface[. = '${bat_if}'] ${bat_if}",
+        "set iface[. = '${bat_if}']/family inet6",
+        "set iface[. = '${bat_if}']/method manual",
+        "set iface[. = '${bat_if}']/pre-up[1] 'modprobe batman-adv'",
+        "set iface[. = '${bat_if}']/pre-up[2] 'batctl if add ${mesh_if}'",
+        "set iface[. = '${bat_if}']/up 'ip link set \$IFACE up'",
+        "set iface[. = '${bat_if}']/post-up[1] 'brctl addif ${br_if} \$IFACE'",
+        "set iface[. = '${bat_if}']/post-up[2] 'batctl it 10000'",
+        "set iface[. = '${bat_if}']/post-up[3] '/sbin/ip rule add from all fwmark 0x1 table 42'",
+        "set iface[. = '${bat_if}']/pre-down 'brctl delif ${br_if} \$IFACE || true'",
+        "set iface[. = '${bat_if}']/down 'ip link set \$IFACE down'",
+      ];
   }
   ->
   vcsrepo { '/etc/fastd/ffhh-mesh-vpn/peers':

From 5b8b7454e3dbe1252973d70dd80c97b91beb77eb Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 18:29:59 +0200
Subject: [PATCH 22/58] small cleanup

---
 README.md         |  2 --
 manifests/init.pp | 30 ++++++++++++++++--------------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index 30ff514..17aebe6 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,6 @@ design pattern.
 
 ## Open Problems
 
-* The current code overwrites `/etc/network/interfaces` -- this needs to be
-  improved.
 * The apt repository at http://bird.network.cz/debian/ does not use PGP
   signatures, so `bird` and `bird6` will not be installed automatically.
 * Setting the hostname should occur before everything else. So either
diff --git a/manifests/init.pp b/manifests/init.pp
index 3953456..e5e96ab 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,11 +1,13 @@
-class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key, $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key, $dhcprange_start, $dhcprange_end, $gw_do_ic_peering = false, $tinc_name = false, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4 = false, $ic_vpn_ip6 = false) {
+class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv4_netmask = '255.255.192.0', $gw_ipv6, $gw_ipv6_prefixlen = '64', $secret_key, $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key, $dhcprange_start, $dhcprange_end, $gw_do_ic_peering = false, $tinc_name = false, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4 = false, $ic_vpn_ip6 = false) {
   class { 'ff_gw::software': }
   ->
   class { 'ff_gw::fastd':
-    mesh_mac   => $mesh_mac,
-    gw_ipv4    => $gw_ipv4,
-    gw_ipv6    => $gw_ipv6,
-    secret_key => $secret_key,
+    mesh_mac          => $mesh_mac,
+    gw_ipv4           => $gw_ipv4,
+    gw_ipv4_netmask   => $gw_ipv4_netmask,
+    gw_ipv6           => $gw_ipv6,
+    gw_ipv6_prefixlen => $gw_ipv6_prefixlen,
+    secret_key        => $secret_key,
   }
   ->
   class { 'ff_gw::dhcpd':
@@ -29,7 +31,7 @@ class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secre
   class { 'ff_gw::dnsmasq': }
   ->
   class { 'ff_gw::dns_resolvconf':
-    gw_ipv4    => $gw_ipv4,
+    gw_ipv4 => $gw_ipv4,
   }
   ->
   class { 'ff_gw::bird':
@@ -71,12 +73,12 @@ class ff_gw::software {
   }
 }
 
-class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key) {
+class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_prefixlen, $secret_key) {
   validate_re($mesh_mac, '^de:ad:be:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}$')
   # TODO: parameterize interface names
-  $br_if='br-ffhh'
-  $bat_if='bat0'
-  $mesh_if='ffhh-mesh-vpn'
+  $br_if   = 'br-ffhh'
+  $bat_if  = 'bat0'
+  $mesh_if = 'ffhh-mesh-vpn'
 
   file {
     '/etc/fastd/ffhh-mesh-vpn':
@@ -113,8 +115,8 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key) {
         "set iface[. = '${br_if}'][1]/family inet6",
         "set iface[. = '${br_if}'][1]/method static",
         "set iface[. = '${br_if}'][1]/bridge-ports none",
-        "set iface[. = '${br_if}'][1]/address $gw_ipv6",
-        "set iface[. = '${br_if}'][1]/netmask 64",
+        "set iface[. = '${br_if}'][1]/address ${gw_ipv6}",
+        "set iface[. = '${br_if}'][1]/netmask ${gw_ipv6_prefixlen}",
       ],
   }
   ->
@@ -126,8 +128,8 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv6, $secret_key) {
         "set iface[. = '${br_if}'][2] ${br_if}",
         "set iface[. = '${br_if}'][2]/family inet",
         "set iface[. = '${br_if}'][2]/method static",
-        "set iface[. = '${br_if}'][2]/address $gw_ipv4",
-        "set iface[. = '${br_if}'][2]/netmask 255.255.192.0",
+        "set iface[. = '${br_if}'][2]/address ${gw_ipv4}",
+        "set iface[. = '${br_if}'][2]/netmask ${gw_ipv4_netmask}",
       ],
   }
   ->

From daf7f768f06e10f010845a0328d16932cce4e635 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 22:03:10 +0200
Subject: [PATCH 23/58] extend ff_gw::vpn for hideme support

---
 README.md                     | 15 +++++++
 files/etc/openvpn/hideme.conf | 42 +++++++++++++++++++
 manifests/init.pp             | 76 ++++++++++++++++++++++++++---------
 3 files changed, 113 insertions(+), 20 deletions(-)
 create mode 100644 files/etc/openvpn/hideme.conf

diff --git a/README.md b/README.md
index 17aebe6..d1ea1f7 100644
--- a/README.md
+++ b/README.md
@@ -128,3 +128,18 @@ The verbose flag is optional and shows all changes.
 To be even more catious you can also add the `--noop` flag to only show changes
 but not apply them.
 
+## VPN providers
+
+The example above is written for a mullvad VPN using X.509 authentication.
+
+For hide.me with username/password auth use:
+```
+class { 'ff_gw':
+    # ...
+	vpn_provider => 'hideme',
+	vpn_usr_name => 'username',
+	vpn_usr_pass => 'vpn_password',
+    vpn_ca_crt   => '-----BEGIN CERTIFICATE-----
+MIIE ...
+-----END CERTIFICATE-----',
+```
diff --git a/files/etc/openvpn/hideme.conf b/files/etc/openvpn/hideme.conf
new file mode 100644
index 0000000..0a4c320
--- /dev/null
+++ b/files/etc/openvpn/hideme.conf
@@ -0,0 +1,42 @@
+client
+
+dev mullvad   # this is important because other scripts rely on this device name
+dev-type tun
+
+proto udp
+
+remote nl.hide.me 3478
+
+# Keep trying indefinitely to resolve the
+# host name of the OpenVPN server.  Very useful
+# on machines which are not permanently connected
+# to the internet such as laptops.
+resolv-retry infinite
+
+# Most clients don't need to bind to
+# a specific local port number.
+nobind
+
+# Try to preserve some state across restarts.
+persist-key
+persist-tun
+
+# Set log file verbosity.
+verb 3
+
+# ping 5          # this is pushed by hideme
+# ping-restart 15 # this is pushed by hideme
+
+# Allow calling of built-in executables and user-defined scripts.
+script-security 3 system
+
+# Parses DHCP options from openvpn to update resolv.conf
+route-noexec
+up    /etc/openvpn/mullvad/mullvad-up
+down  /etc/openvpn/update-dnsmasq-forward
+
+# hideme specifics
+ca /etc/openvpn/hideme/ca.crt
+auth-user-pass /etc/openvpn/hideme/auth.txt
+cipher AES-128-CBC
+reneg-sec 0
diff --git a/manifests/init.pp b/manifests/init.pp
index e5e96ab..382b50a 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,4 +1,22 @@
-class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv4_netmask = '255.255.192.0', $gw_ipv6, $gw_ipv6_prefixlen = '64', $secret_key, $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key, $dhcprange_start, $dhcprange_end, $gw_do_ic_peering = false, $tinc_name = false, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4 = false, $ic_vpn_ip6 = false) {
+class ff_gw(
+	$ff_net,
+	$ff_mesh_net,
+	$ff_as,
+	$mesh_mac,
+	$gw_ipv4, $gw_ipv4_netmask = '255.255.192.0',
+	$gw_ipv6, $gw_ipv6_prefixlen = '64',
+	$secret_key,                                      # for fastd
+	$vpn_provider = 'mullvad',                        # supported: mullvad or hideme
+	$vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key,          # openvpn x.509 credentials
+	$vpn_usr_name = false,                            # openvpn user for auth-user-pass
+	$vpn_usr_pass = false,                            # openvpn password for auth-user-pass
+	$dhcprange_start, $dhcprange_end,
+	$gw_do_ic_peering = false,                        # configure inter city VPN
+	$tinc_name = false,
+	$tinc_keyfile = '/etc/tinc/rsa_key.priv',
+	$ic_vpn_ip4 = false,
+	$ic_vpn_ip6 = false
+) {
   class { 'ff_gw::software': }
   ->
   class { 'ff_gw::fastd':
@@ -21,9 +39,12 @@ class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv4_netmask
   }
   ->
   class { 'ff_gw::vpn':
-    usr_crt => $vpn_usr_crt,
-    usr_key => $vpn_usr_key,
-    ca_crt  => $vpn_ca_crt,
+    provider => $vpn_provider,
+    usr_crt  => $vpn_usr_crt,
+    usr_key  => $vpn_usr_key,
+    ca_crt   => $vpn_ca_crt,
+    usr_name => $vpn_usr_name,
+    usr_pass => $vpn_usr_pass,
   }
   ->
   class { 'ff_gw::iptables': }
@@ -386,10 +407,32 @@ class ff_gw::radvd($own_ipv6) {
   }
 }
 
-class ff_gw::vpn($ca_crt, $usr_crt, $usr_key, $openvpn_version = '2.3.2-7~bpo70+1', $ensure = 'running') {
-  # TODO: this name is used in several places including dnsmasq
-  # and is even used for other providers, thus hard to change
-  $vpnname = 'mullvad'
+class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $openvpn_version = '2.3.2-7~bpo70+1', $ensure = 'running') {
+  # TODO: note that even the hideme.conf uses the interface name 'mullvad',
+  #       because that interface is referenced elsewhere
+
+  # TODO: maybe we should check that provider and auth methods match
+  #       atm we trust the caller to give the right combination
+  if str2bool("$usr_name") {
+    # hideme config with user/pass file
+    file {
+      "/etc/openvpn/${provider}/auth.txt":
+        ensure  => file,
+        mode    => '0600',
+        content => "$usr_name\n$usr_pass\n";
+    }
+  } else {
+    # mullvad config with x.509
+    file {
+      "/etc/openvpn/${provider}/client.crt":
+        ensure  => file,
+        content => $usr_crt;
+      "/etc/openvpn/${provider}/client.key":
+        ensure  => file,
+        mode    => '0600',
+        content => $usr_key;
+    }
+  }
 
   package {
     'openvpn':
@@ -397,19 +440,12 @@ class ff_gw::vpn($ca_crt, $usr_crt, $usr_key, $openvpn_version = '2.3.2-7~bpo70+
   }
   ->
   file {
-    "/etc/openvpn/${vpnname}":
+    "/etc/openvpn/${provider}":
       ensure => directory;
-    "/etc/openvpn/${vpnname}/ca.crt":
+    "/etc/openvpn/${provider}/ca.crt":
       ensure  => file,
       content => $ca_crt;
-    "/etc/openvpn/${vpnname}/client.crt":
-      ensure  => file,
-      content => $usr_crt;
-    "/etc/openvpn/${vpnname}/client.key":
-      ensure  => file,
-      mode    => '0600',
-      content => $usr_key;
-    "/etc/openvpn/${vpnname}/mullvad-up":
+    "/etc/openvpn/${provider}/${provider}-up":
       ensure  => file,
       mode    => '0755',
       content => '#!/bin/sh
@@ -417,9 +453,9 @@ ip route replace 0.0.0.0/1 via $5 table 42
 ip route replace 128.0.0.0/1 via $5 table 42
 /etc/openvpn/update-dnsmasq-forward
 exit 0';
-    "/etc/openvpn/${vpnname}.conf":
+    "/etc/openvpn/${provider}.conf":
       ensure => file,
-      source => "puppet:///modules/ff_gw/etc/openvpn/${vpnname}.conf";
+      source => "puppet:///modules/ff_gw/etc/openvpn/${provider}.conf";
     "/etc/openvpn/update-dnsmasq-forward":
       ensure => file,
       mode    => '0755',

From 9e93f9a9e592303edde900b68414403a98ff8976 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 22:34:56 +0200
Subject: [PATCH 24/58] fix whitespace

---
 manifests/init.pp | 59 ++++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 31 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 382b50a..02c3350 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,21 +1,21 @@
 class ff_gw(
-	$ff_net,
-	$ff_mesh_net,
-	$ff_as,
-	$mesh_mac,
-	$gw_ipv4, $gw_ipv4_netmask = '255.255.192.0',
-	$gw_ipv6, $gw_ipv6_prefixlen = '64',
-	$secret_key,                                      # for fastd
-	$vpn_provider = 'mullvad',                        # supported: mullvad or hideme
-	$vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key,          # openvpn x.509 credentials
-	$vpn_usr_name = false,                            # openvpn user for auth-user-pass
-	$vpn_usr_pass = false,                            # openvpn password for auth-user-pass
-	$dhcprange_start, $dhcprange_end,
-	$gw_do_ic_peering = false,                        # configure inter city VPN
-	$tinc_name = false,
-	$tinc_keyfile = '/etc/tinc/rsa_key.priv',
-	$ic_vpn_ip4 = false,
-	$ic_vpn_ip6 = false
+  $ff_net,
+  $ff_mesh_net,
+  $ff_as,
+  $mesh_mac,
+  $gw_ipv4, $gw_ipv4_netmask = '255.255.192.0',
+  $gw_ipv6, $gw_ipv6_prefixlen = '64',
+  $secret_key,                                      # for fastd
+  $vpn_provider = 'mullvad',                        # supported: mullvad or hideme
+  $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key,          # openvpn x.509 credentials
+  $vpn_usr_name = false,                            # openvpn user for auth-user-pass
+  $vpn_usr_pass = false,                            # openvpn password for auth-user-pass
+  $dhcprange_start, $dhcprange_end,
+  $gw_do_ic_peering = false,                        # configure inter city VPN
+  $tinc_name = false,
+  $tinc_keyfile = '/etc/tinc/rsa_key.priv',
+  $ic_vpn_ip4 = false,
+  $ic_vpn_ip6 = false
 ) {
   class { 'ff_gw::software': }
   ->
@@ -128,9 +128,8 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
   # but I found none that is flexible enough to handle all our config lines
   augeas {
     "${br_if}-inet6":
-      context   => '/files/etc/network/interfaces',
-      show_diff => true,
-      changes   => [
+      context => '/files/etc/network/interfaces',
+      changes => [
         "set auto[child::1 = '${br_if}']/1 ${br_if}",
         "set iface[. = '${br_if}'][1] ${br_if}",
         "set iface[. = '${br_if}'][1]/family inet6",
@@ -143,9 +142,8 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
   ->
   augeas {
     "${br_if}-inet":
-      context   => '/files/etc/network/interfaces',
-      show_diff => true,
-      changes   => [
+      context => '/files/etc/network/interfaces',
+      changes => [
         "set iface[. = '${br_if}'][2] ${br_if}",
         "set iface[. = '${br_if}'][2]/family inet",
         "set iface[. = '${br_if}'][2]/method static",
@@ -156,10 +154,9 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
   ->
   # TODO: parameterize ffhh-mesh-vpn
   augeas {
-    "${bat_if}":
-      context   => '/files/etc/network/interfaces',
-      show_diff => true,
-      changes   => [
+    $bat_if:
+      context => '/files/etc/network/interfaces',
+      changes => [
         "set allow-hotplug[child::1 = '${bat_if}']/1 ${bat_if}",
         "set iface[. = '${bat_if}'] ${bat_if}",
         "set iface[. = '${bat_if}']/family inet6",
@@ -413,7 +410,7 @@ class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $
 
   # TODO: maybe we should check that provider and auth methods match
   #       atm we trust the caller to give the right combination
-  if str2bool("$usr_name") {
+  if str2bool($usr_name) {
     # hideme config with user/pass file
     file {
       "/etc/openvpn/${provider}/auth.txt":
@@ -456,10 +453,10 @@ exit 0';
     "/etc/openvpn/${provider}.conf":
       ensure => file,
       source => "puppet:///modules/ff_gw/etc/openvpn/${provider}.conf";
-    "/etc/openvpn/update-dnsmasq-forward":
+    '/etc/openvpn/update-dnsmasq-forward':
       ensure => file,
-      mode    => '0755',
-      source => "puppet:///modules/ff_gw/etc/openvpn/update-dnsmasq-forward";
+      mode   => '0755',
+      source => 'puppet:///modules/ff_gw/etc/openvpn/update-dnsmasq-forward';
   }
   ~>
   service { 'openvpn':

From 207c82e834d1cfd33a6a3c80dea0f7f684d800e0 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 22:41:53 +0200
Subject: [PATCH 25/58] vpn: fix cert/username params and conditions

---
 manifests/init.pp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 02c3350..3105fa9 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -3,11 +3,12 @@ class ff_gw(
   $ff_mesh_net,
   $ff_as,
   $mesh_mac,
-  $gw_ipv4, $gw_ipv4_netmask = '255.255.192.0',
+  $gw_ipv4, $gw_ipv4_netmask   = '255.255.192.0',
   $gw_ipv6, $gw_ipv6_prefixlen = '64',
   $secret_key,                                      # for fastd
   $vpn_provider = 'mullvad',                        # supported: mullvad or hideme
-  $vpn_ca_crt, $vpn_usr_crt, $vpn_usr_key,          # openvpn x.509 credentials
+  $vpn_ca_crt   = false,                            # openvpn CA cert to verify server
+  $vpn_usr_crt  = false, $vpn_usr_key = false,      # openvpn x.509 credentials
   $vpn_usr_name = false,                            # openvpn user for auth-user-pass
   $vpn_usr_pass = false,                            # openvpn password for auth-user-pass
   $dhcprange_start, $dhcprange_end,
@@ -410,7 +411,7 @@ class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $
 
   # TODO: maybe we should check that provider and auth methods match
   #       atm we trust the caller to give the right combination
-  if str2bool($usr_name) {
+  if $usr_name {
     # hideme config with user/pass file
     file {
       "/etc/openvpn/${provider}/auth.txt":
@@ -418,7 +419,7 @@ class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $
         mode    => '0600',
         content => "$usr_name\n$usr_pass\n";
     }
-  } else {
+  } elsif $usr_crt {
     # mullvad config with x.509
     file {
       "/etc/openvpn/${provider}/client.crt":

From cd374601f1bd7e1ade9c373fa6655a6db0740ba5 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 22:48:02 +0200
Subject: [PATCH 26/58] bugfix wrong path

---
 files/etc/openvpn/hideme.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/files/etc/openvpn/hideme.conf b/files/etc/openvpn/hideme.conf
index 0a4c320..79c0455 100644
--- a/files/etc/openvpn/hideme.conf
+++ b/files/etc/openvpn/hideme.conf
@@ -32,7 +32,7 @@ script-security 3 system
 
 # Parses DHCP options from openvpn to update resolv.conf
 route-noexec
-up    /etc/openvpn/mullvad/mullvad-up
+up    /etc/openvpn/hideme/hideme-up
 down  /etc/openvpn/update-dnsmasq-forward
 
 # hideme specifics

From c03c8822cd33cbd7ae6529f20e7dbc44778fda2e Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Sun, 22 Jun 2014 22:51:14 +0200
Subject: [PATCH 27/58] bump version

---
 Modulefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Modulefile b/Modulefile
index 438ba60..ebe7f37 100644
--- a/Modulefile
+++ b/Modulefile
@@ -1,5 +1,5 @@
 name    'puppet-ff_gw'
-version '0.3.0'
+version '0.4.0'
 license 'BSD 2-clause license'
 author 'Martin Schuette <info@mschuette.name>'
 dependency 'puppetlabs/apt', '>= 1.4.0'

From b5b7814581334de983bcab31fb309607d4af8742 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Sch=C3=BCtte?= <martin.schuette@deck36.de>
Date: Tue, 24 Jun 2014 11:59:39 +0200
Subject: [PATCH 28/58] openvpn: different up scripts

---
 files/etc/openvpn/hideme/hideme-up   |  5 +++++
 files/etc/openvpn/mullvad/mullvad-up |  5 +++++
 manifests/init.pp                    | 10 +++-------
 3 files changed, 13 insertions(+), 7 deletions(-)
 create mode 100644 files/etc/openvpn/hideme/hideme-up
 create mode 100644 files/etc/openvpn/mullvad/mullvad-up

diff --git a/files/etc/openvpn/hideme/hideme-up b/files/etc/openvpn/hideme/hideme-up
new file mode 100644
index 0000000..311aaca
--- /dev/null
+++ b/files/etc/openvpn/hideme/hideme-up
@@ -0,0 +1,5 @@
+#!/bin/sh
+ip route replace 0.0.0.0/1 via $4 table 42
+ip route replace 128.0.0.0/1 via $4 table 42
+/etc/openvpn/update-dnsmasq-forward
+exit 0
diff --git a/files/etc/openvpn/mullvad/mullvad-up b/files/etc/openvpn/mullvad/mullvad-up
new file mode 100644
index 0000000..f59a2bd
--- /dev/null
+++ b/files/etc/openvpn/mullvad/mullvad-up
@@ -0,0 +1,5 @@
+#!/bin/sh
+ip route replace 0.0.0.0/1 via $5 table 42
+ip route replace 128.0.0.0/1 via $5 table 42
+/etc/openvpn/update-dnsmasq-forward
+exit 0
diff --git a/manifests/init.pp b/manifests/init.pp
index 3105fa9..fe9b724 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -444,13 +444,9 @@ class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $
       ensure  => file,
       content => $ca_crt;
     "/etc/openvpn/${provider}/${provider}-up":
-      ensure  => file,
-      mode    => '0755',
-      content => '#!/bin/sh
-ip route replace 0.0.0.0/1 via $5 table 42
-ip route replace 128.0.0.0/1 via $5 table 42
-/etc/openvpn/update-dnsmasq-forward
-exit 0';
+      ensure => file,
+      mode   => '0755',
+      source => "puppet:///modules/ff_gw/etc/openvpn/${provider}/${provider}-up";
     "/etc/openvpn/${provider}.conf":
       ensure => file,
       source => "puppet:///modules/ff_gw/etc/openvpn/${provider}.conf";

From 4664e1bd1bf604e9b3643a5d99e2c2e4323c70a1 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 1 Jul 2014 01:09:35 +0200
Subject: [PATCH 29/58] Prepare for fastd v14

---
 templates/etc/fastd/ffhh-mesh-vpn/fastd.conf.erb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/templates/etc/fastd/ffhh-mesh-vpn/fastd.conf.erb b/templates/etc/fastd/ffhh-mesh-vpn/fastd.conf.erb
index 0ea508d..b4962e9 100644
--- a/templates/etc/fastd/ffhh-mesh-vpn/fastd.conf.erb
+++ b/templates/etc/fastd/ffhh-mesh-vpn/fastd.conf.erb
@@ -4,6 +4,7 @@ log to syslog level info;
 interface "ffhh-mesh-vpn";
 method "salsa2012+gmac"; # new method, between gateways for the moment (faster)
 method "xsalsa20-poly1305"; # old method
+secure handshakes no; # be compatible to old peers
 bind 0.0.0.0:10000;
 hide ip addresses yes;
 hide mac addresses yes;

From ba5030ffce428d16b2004893555a18c1176221a7 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 1 Jul 2014 17:49:35 +0200
Subject: [PATCH 30/58] Add munin plugin to monitor dhcp leases

---
 files/usr/share/munin/plugins/dhcp-pool | 192 ++++++++++++++++++++++++
 manifests/sysadmin.pp                   |  12 ++
 2 files changed, 204 insertions(+)
 create mode 100644 files/usr/share/munin/plugins/dhcp-pool

diff --git a/files/usr/share/munin/plugins/dhcp-pool b/files/usr/share/munin/plugins/dhcp-pool
new file mode 100644
index 0000000..2cb715d
--- /dev/null
+++ b/files/usr/share/munin/plugins/dhcp-pool
@@ -0,0 +1,192 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2008 Rien Broekstra <rien@rename-it.nl>
+#
+# 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; version 2 dated June,
+# 1991.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+#
+# Munin plugin to measure saturation of DHCP pools.
+#
+# Configuration variables:
+#
+#       conffile     - path to dhcpd's configuration file (default "/etc/dhcpd.conf")
+#       leasefile    - path to dhcpd's leases file (default "/var/lib/dhcp/dhcpd.leases")
+#
+# Parameters:
+#
+#       config    (required)
+#
+# Version 1.0, 2-12-2008
+
+use POSIX;
+use Time::Local;
+use strict;
+
+my $CONFFILE = exists $ENV{'conffile'} ? $ENV{'conffile'} : "/etc/dhcpd.conf";
+my $LEASEFILE = exists $ENV{'leasefile'} ? $ENV{'leasefile'} : "/var/lib/dhcp/dhcpd.leases";
+
+if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
+
+}
+elsif ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
+    my (%pools, $start, $label);
+
+    # Print general information
+    print "graph_title DHCP pool usage (in %)\n";
+    print "graph_args --upper-limit 100 -l 0\n";
+    print "graph_vlabel %\n";
+    print "graph_category network\n";
+
+    # Determine the available IP pools
+    %pools = determine_pools();
+    
+    # Print a label for each pool
+    foreach $start (keys %pools) {
+	$label = ip2string($start);
+	$label =~ s/\./\_/g;
+	print "$label.label Pool ".ip2string($start)."\n";
+	print "$label.warning 75\n";
+	print "$label.critical 100\n";
+    }
+}
+else {
+    my (@activeleases, %pools, $start, $end, $size, $free, $label, $lease);
+    
+    # Determine all leased IP addresses 
+    @activeleases = determine_active_leases();
+    
+    # Determine the available IP pools
+    %pools = determine_pools();
+
+    # For each pool, count how many leases from that pool are currently active
+    foreach $start (keys %pools) {
+	$size = $pools{$start};
+	$end = $start+$size;
+	$free = $size;
+
+	foreach $lease (@activeleases) {
+	    if ($lease >= $start && $lease <= $end) {
+		$free--;
+	    }
+	}
+	$label = ip2string($start);
+	$label =~ s/\./\_/g;
+	print "$label.value ".sprintf("%.1f", 100*($size-$free)/$size)."\n";
+    }
+}
+
+# Parse dhcpd.conf for range statements.
+#
+# Returns a hash with start IP -> size
+sub determine_pools {
+    my (%pools, @conffile, $line, $start, $end, $size);
+
+    open(CONFFILE, "<${CONFFILE}") || exit -1;
+    @conffile = <CONFFILE>;
+    close (CONFFILE);
+
+    foreach $line (@conffile) {
+	if ($line =~ /range[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)/) {
+	    $start = string2ip($1);
+	    $end = string2ip($2);
+	    $size = $end - $start;
+	    defined($start) || next;
+	    defined($end) || next;
+	    
+	    $pools{$start} = $size;
+	}
+    }
+    return %pools;
+}
+
+# Very simple parser for dhcpd.leases. This will break very easily if dhcpd decides to 
+# format the file differently. Ideally a simple recursive-descent parser should be used.
+#
+# Returns an array with currently leased IP's
+sub determine_active_leases {
+    my (@leasefile, $startdate, $enddate, $lease, @activeleases, $mytz, $line, %saw);
+
+    open(LEASEFILE, "<${LEASEFILE}") || exit -1;
+    @leasefile = <LEASEFILE>;
+    close (LEASEFILE);
+
+    @activeleases = ();
+
+    # Portable way of converting a GMT date/time string to timestamp is setting TZ to UTC, and then calling mktime()
+    $mytz = $ENV{'TZ'};
+    $ENV{'TZ'} = 'UTC 0';
+    tzset();
+
+    foreach $line (@leasefile) {
+	if ($line =~ /lease ([\d]+\.[\d]+\.[\d]+\.[\d]+)/) {
+	    $lease = string2ip($1);
+	    defined($lease) || next;
+
+	    undef $startdate;
+	    undef $enddate;
+	}
+	elsif ($line =~ /starts \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) {
+	    $startdate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0);
+	}
+	elsif ($line =~ /ends \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) {
+	    $enddate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0);
+	    if (defined($enddate) && defined($startdate) && defined($lease)) {
+		if ($startdate < time() && $enddate > time()) {
+		    push (@activeleases, $lease);
+		}
+	    }
+	}
+
+    }
+    
+    # Set TZ back to its original setting
+    if (defined($mytz)) {
+	$ENV{'TZ'} = $mytz;
+    }
+    else {
+	delete $ENV{'TZ'};
+    }
+    tzset();
+
+    # Sort the array, strip doubles, and return
+    return grep(!$saw{$_}++, @activeleases);
+}
+
+#
+# Helper routine to convert an IP address a.b.c.d into an integer
+#
+# Returns an integer representation of an IP address
+sub string2ip {
+    my $string = shift;
+    defined($string) || return undef;
+    if ($string =~ /([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)/) {
+	if ($1 < 0 || $1 > 255 || $2 < 0 || $2 > 255 || $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255) {
+	    return undef;
+	}
+	else {
+	    return $1 << 24 | $2 << 16 | $3 << 8 | $4;
+	}
+    }
+    return undef;
+}
+	    
+#
+# Returns a dotted quad notation of an 
+#
+sub ip2string {
+    my $ip = shift;
+    defined ($ip) || return undef;
+    return sprintf ("%d.%d.%d.%d", ($ip >> 24) & 0xff, ($ip >> 16) & 0xff, ($ip >> 8) & 0xff, $ip & 0xff);
+}
diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 4dab594..a6586b9 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -162,6 +162,18 @@ host <%= @ipaddress_eth0 %>
     '/etc/munin/plugins/udp-statistics':
       ensure => link,
       target => '/usr/share/munin/plugins/udp-statistics';
+    '/usr/share/munin/plugins/dhcp-pool':
+      ensure => file,
+      mode   => '0755',
+      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/dhcp-pool';
+    '/etc/munin/plugins/dhcp-pool':
+      ensure => link,
+      target => '/usr/share/munin/plugins/dhcp-pool';
+    '/etc/munin/plugin-conf.d/dhcp-pool':
+      ensure  => file,
+      content => '[dhcp-pool]
+env.leasefile /var/lib/dhcp/dhcpd.leases
+env.conffile /etc/dhcp/dhcpd.conf';
     '/etc/munin/plugins/if_mullvad':
       ensure => link,
       target => '/usr/share/munin/plugins/if_';

From b412e55cfa854f3c838813b57edb80d98c25fa19 Mon Sep 17 00:00:00 2001
From: Martin Schuette <info@mschuette.name>
Date: Tue, 1 Jul 2014 18:33:46 +0200
Subject: [PATCH 31/58] split ff_gw::sysadmin class

---
 manifests/sysadmin.pp        | 215 ++++++++---------------------------
 manifests/sysadmin/munin.pp  |  99 ++++++++++++++++
 manifests/sysadmin/zabbix.pp |  28 +++++
 3 files changed, 177 insertions(+), 165 deletions(-)
 create mode 100644 manifests/sysadmin/munin.pp
 create mode 100644 manifests/sysadmin/zabbix.pp

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index a6586b9..5ac7be0 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -1,6 +1,5 @@
 # kitchen sink class for various small settings
 class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $sethostname = false, $setip = false, $accounts = {}) {
-
   # first of all: fix my hostname
   if $sethostname and $setip {
     # set system hostname
@@ -11,48 +10,7 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
   }
 
   # next important thing: set up apt repositories
-  #
-  class { '::apt':
-    always_apt_update => true
-  }
-  # use backports repo
-  apt::source { 'wheezy-backports':
-    location => 'http://ftp.de.debian.org/debian/',
-    release  => 'wheezy-backports',
-    repos    => 'main',
-  }
-  # batman repo
-  apt::source { 'universe-factory':
-    location   => 'http://repo.universe-factory.net/debian/',
-    release    => 'sid',
-    repos      => 'main',
-    key        => '16EF3F64CB201D9C',
-    key_server => 'pool.sks-keyservers.net',
-  }
-  # bird repo // TODO: no PGP key
-  apt::source { 'bird-network':
-    location   => 'http://bird.network.cz/debian/',
-    release    => 'wheezy',
-    repos      => 'main',
-  }
-
-  # then install some basic packages
-  package {
-    ['vim-nox', 'git', 'etckeeper', 'pv', 'curl', 'atop',
-    'screen', 'tcpdump', 'rsync', 'file', 'psmisc', 'ntpdate']:
-      ensure => installed,
-  }
-  ->
-  # remove atop cronjob
-  file { '/etc/cron.d/atop':
-    ensure => absent,
-  }
-  ->
-  # stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
-  service { 'atop':
-    ensure  => stopped,
-    enable  => false,
-  }
+  class { 'ff_gw::sysadmin::software': }
 
   cron {
     'ntpdate-debian':
@@ -85,129 +43,11 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
     enable => true,
   }
 
-  # zabbix
-  apt::source { 'zabbix':
-    location   => 'http://repo.zabbix.com/zabbix/2.2/debian',
-    release    => 'wheezy',
-    repos      => 'main',
-    key        => '79EA5ED4',
-    key_server => 'pgpkeys.mit.edu',
+  class { 'ff_gw::sysadmin::zabbix':
+    zabbixserver => $zabbixserver,
   }
-  ->
-  package { 'zabbix-agent':
-    ensure => latest;
-  }
-  ->
-  file { '/etc/zabbix/zabbix_agentd.d/argos_monitoring.conf':
-    ensure  => file,
-    content => "# managed by puppet
-Server=${zabbixserver}
-ServerActive=${zabbixserver}
-HostnameItem=${::hostname}
-";
-  }
-  ~>
-  service { 'zabbix-agent':
-    ensure => running,
-    enable => true,
-  }
-
-  # munin
-  package {
-    [ 'munin-node', 'vnstat', 'bc' ]:
-      ensure => installed,
-  }
-  ->
-  file {
-    '/etc/munin/munin-node.conf':
-      ensure  => file,
-      # mostly Debin pkg default
-      content => inline_template('# managed by puppet
-log_level 4
-log_file /var/log/munin/munin-node.log
-pid_file /var/run/munin/munin-node.pid
-
-background 1
-setsid 1
-
-user root
-group root
-
-# Regexps for files to ignore
-ignore_file [\#~]$
-ignore_file DEADJOE$
-ignore_file \.bak$
-ignore_file %$
-ignore_file \.dpkg-(tmp|new|old|dist)$
-ignore_file \.rpm(save|new)$
-ignore_file \.pod$
-
-port 4949
-
-host_name <%= @fqdn %>
-cidr_allow <%= @muninserver %>/32
-host <%= @ipaddress_eth0 %>
-');
-    '/usr/share/munin/plugins/vnstat_':
-      ensure => file,
-      mode   => '0755',
-      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/vnstat_';
-    '/etc/munin/plugins/vnstat_eth0_monthly_rxtx':
-      ensure => link,
-      target => '/usr/share/munin/plugins/vnstat_';
-    '/usr/share/munin/plugins/udp-statistics':
-      ensure => file,
-      mode   => '0755',
-      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/udp-statistics';
-    '/etc/munin/plugins/udp-statistics':
-      ensure => link,
-      target => '/usr/share/munin/plugins/udp-statistics';
-    '/usr/share/munin/plugins/dhcp-pool':
-      ensure => file,
-      mode   => '0755',
-      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/dhcp-pool';
-    '/etc/munin/plugins/dhcp-pool':
-      ensure => link,
-      target => '/usr/share/munin/plugins/dhcp-pool';
-    '/etc/munin/plugin-conf.d/dhcp-pool':
-      ensure  => file,
-      content => '[dhcp-pool]
-env.leasefile /var/lib/dhcp/dhcpd.leases
-env.conffile /etc/dhcp/dhcpd.conf';
-    '/etc/munin/plugins/if_mullvad':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_';
-    '/etc/munin/plugins/if_err_mullvad':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_err_';
-    '/etc/munin/plugins/if_bat0':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_';
-    '/etc/munin/plugins/if_err_bat0':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_err_';
-    '/etc/munin/plugins/if_br-ffhh':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_';
-    '/etc/munin/plugins/if_err_br-ffhh':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_err_';
-    '/etc/munin/plugins/if_ffhh-mesh-vpn':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_';
-    '/etc/munin/plugins/if_err_ffhh-mesh-vpn':
-      ensure => link,
-      target => '/usr/share/munin/plugins/if_err_';
-    # TODO: delete not needed plugins
-    '/etc/munin/plugin-conf.d/vnstat':
-      ensure  => file,
-      content => '[vnstat_eth0_monthly_rxtx]
-env.estimate 1';
-  }
-  ~>
-  service { 'munin-node':
-    ensure => running,
-    enable => true;
+  class { 'ff_gw::sysadmin::munin':
+    muninserver => $muninserver,
   }
 }
 
@@ -256,3 +96,48 @@ class ff_gw::sysadmin::hostname($newname, $newip) {
     refreshonly => true,
   }
 }
+
+# everything related to apt-repos and default tools
+class ff_gw::sysadmin::software() {
+  class { '::apt':
+    always_apt_update => true
+  }
+  # use backports repo
+  apt::source { 'wheezy-backports':
+    location => 'http://ftp.de.debian.org/debian/',
+    release  => 'wheezy-backports',
+    repos    => 'main',
+  }
+  # batman repo
+  apt::source { 'universe-factory':
+    location   => 'http://repo.universe-factory.net/debian/',
+    release    => 'sid',
+    repos      => 'main',
+    key        => '16EF3F64CB201D9C',
+    key_server => 'pool.sks-keyservers.net',
+  }
+  # bird repo // TODO: no PGP key
+  apt::source { 'bird-network':
+    location   => 'http://bird.network.cz/debian/',
+    release    => 'wheezy',
+    repos      => 'main',
+  }
+
+  # then install some basic packages
+  package {
+    ['vim-nox', 'git', 'etckeeper', 'pv', 'curl', 'atop',
+    'screen', 'tcpdump', 'rsync', 'file', 'psmisc', 'ntpdate']:
+      ensure => installed,
+  }
+  ->
+  # remove atop cronjob
+  file { '/etc/cron.d/atop':
+    ensure => absent,
+  }
+  ->
+  # stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
+  service { 'atop':
+    ensure  => stopped,
+    enable  => false,
+  }
+}
diff --git a/manifests/sysadmin/munin.pp b/manifests/sysadmin/munin.pp
new file mode 100644
index 0000000..2a4acd8
--- /dev/null
+++ b/manifests/sysadmin/munin.pp
@@ -0,0 +1,99 @@
+# munin config
+class ff_gw::sysadmin::munin($muninserver) {
+  package {
+    [ 'munin-node', 'vnstat', 'bc' ]:
+      ensure => installed,
+  }
+  ->
+  file {
+    '/etc/munin/munin-node.conf':
+      ensure  => file,
+      # mostly Debin pkg default
+      content => inline_template('# managed by puppet
+log_level 4
+log_file /var/log/munin/munin-node.log
+pid_file /var/run/munin/munin-node.pid
+
+background 1
+setsid 1
+
+user root
+group root
+
+# Regexps for files to ignore
+ignore_file [\#~]$
+ignore_file DEADJOE$
+ignore_file \.bak$
+ignore_file %$
+ignore_file \.dpkg-(tmp|new|old|dist)$
+ignore_file \.rpm(save|new)$
+ignore_file \.pod$
+
+port 4949
+
+host_name <%= @fqdn %>
+cidr_allow <%= @muninserver %>/32
+host <%= @ipaddress_eth0 %>
+');
+    '/usr/share/munin/plugins/vnstat_':
+      ensure => file,
+      mode   => '0755',
+      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/vnstat_';
+    '/etc/munin/plugins/vnstat_eth0_monthly_rxtx':
+      ensure => link,
+      target => '/usr/share/munin/plugins/vnstat_';
+    '/usr/share/munin/plugins/udp-statistics':
+      ensure => file,
+      mode   => '0755',
+      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/udp-statistics';
+    '/etc/munin/plugins/udp-statistics':
+      ensure => link,
+      target => '/usr/share/munin/plugins/udp-statistics';
+    '/usr/share/munin/plugins/dhcp-pool':
+      ensure => file,
+      mode   => '0755',
+      source => 'puppet:///modules/ff_gw/usr/share/munin/plugins/dhcp-pool';
+    '/etc/munin/plugins/dhcp-pool':
+      ensure => link,
+      target => '/usr/share/munin/plugins/dhcp-pool';
+    '/etc/munin/plugin-conf.d/dhcp-pool':
+      ensure  => file,
+      content => '[dhcp-pool]
+env.leasefile /var/lib/dhcp/dhcpd.leases
+env.conffile /etc/dhcp/dhcpd.conf';
+    '/etc/munin/plugins/if_mullvad':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_mullvad':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_bat0':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_bat0':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_br-ffhh':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_br-ffhh':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    '/etc/munin/plugins/if_ffhh-mesh-vpn':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_';
+    '/etc/munin/plugins/if_err_ffhh-mesh-vpn':
+      ensure => link,
+      target => '/usr/share/munin/plugins/if_err_';
+    # TODO: delete not needed plugins
+    '/etc/munin/plugin-conf.d/vnstat':
+      ensure  => file,
+      content => '[vnstat_eth0_monthly_rxtx]
+env.estimate 1';
+  }
+  ~>
+  service { 'munin-node':
+    ensure => running,
+    enable => true;
+  }
+}
diff --git a/manifests/sysadmin/zabbix.pp b/manifests/sysadmin/zabbix.pp
new file mode 100644
index 0000000..d3db871
--- /dev/null
+++ b/manifests/sysadmin/zabbix.pp
@@ -0,0 +1,28 @@
+# zabbix agent config
+class ff_gw::sysadmin::zabbix($zabbixserver) {
+  apt::source { 'zabbix':
+    location   => 'http://repo.zabbix.com/zabbix/2.2/debian',
+    release    => 'wheezy',
+    repos      => 'main',
+    key        => '79EA5ED4',
+    key_server => 'pgpkeys.mit.edu',
+  }
+  ->
+  package { 'zabbix-agent':
+    ensure => latest;
+  }
+  ->
+  file { '/etc/zabbix/zabbix_agentd.d/argos_monitoring.conf':
+    ensure  => file,
+    content => "# managed by puppet
+Server=${zabbixserver}
+ServerActive=${zabbixserver}
+HostnameItem=${::hostname}
+";
+  }
+  ~>
+  service { 'zabbix-agent':
+    ensure => running,
+    enable => true,
+  }
+}

From 4291261c6b65773ca0661a345da5ae423e836789 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:14:54 +0200
Subject: [PATCH 32/58] refactor bird6.conf for policy routing

Berlin1 is allowed to send us default routes now
---
 data/peering.yaml                 |   2 +-
 templates/etc/bird/bird6.conf.erb | 157 +++++++++++++++++++++---------
 2 files changed, 112 insertions(+), 47 deletions(-)

diff --git a/data/peering.yaml b/data/peering.yaml
index 9ccf58d..4837a49 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -251,7 +251,7 @@ ic_peerings_v6:
     ip: fec0::a:cf:0:19
     as: 65025
   Berlin1:
-    template: peers
+    template: upstream
     ip: fec0::a:cf:0:5
     as: 44194
   Bielefeld1:
diff --git a/templates/etc/bird/bird6.conf.erb b/templates/etc/bird/bird6.conf.erb
index dca6927..de3a28b 100644
--- a/templates/etc/bird/bird6.conf.erb
+++ b/templates/etc/bird/bird6.conf.erb
@@ -1,63 +1,119 @@
-# managed by puppet
-#
-# the ff ip of the gateway
+table ibgp; # internal BGP peerings
+table ebgp; # external (icvpn) BGP peerings
+table freifunk; # kernel table 42 for routing from ff network
+
+define ownas = <%= @ff_as %>;
+
 router id <%= @own_ipv4 %>;
 
-# routing tables
-table ffhh;
+### functions ###
 
-# filter to check ulas
-function is_ula() {
-  return (net ~ [ fc00::/7{48,64} ]);
+# own networks
+function is_self_net() {
+  return net ~ [ fd51:2bb2:fd0d::/48+,
+    2001:bf7:180::/44+,
+    2001:bf7:190::/44+,
+    2001:bf7:200::/44+,
+    2001:bf7:210::/44+,
+    2001:bf7:220::/44+,
+    2001:bf7:230::/44+];
 }
 
-function is_self() {
-  return (proto = "static_ffhh");
+# freifunk ip ranges in general
+function is_freifunk() {
+  return net ~ [ fc00::/7{48,64},
+    2001:bf7::/32+];
 }
 
-filter ffhh_internal_export {
-  if (proto = "local_ffhh") then accept;
-  if (source != RTS_BGP) then reject;
-  if (is_ula() && proto != "static_ffhh") then accept;
-  else reject;
+function is_default() {
+  return net ~ [ ::0/0 ];
 }
 
-# don't use kernel's routes for bird, but export bird's routes to kernel
-protocol kernel {
-  scan time 20;  # Scan kernel routing table every 20 seconds
-  import none;  # Default is import all
+### kernel ###
+
+# synchronize from bird to main kernel routing table
+# nothing in the other direction
+# (do not sync a default route we received to the main routing table
+# as this might collide with the normal default route of the host)
+protocol kernel k_mast {
+  scan time 10;
+  import none;
+  export where !is_default();
+};
+
+# synchronize from birds freifunk table to kernel routing table 42
+# nothing in the other direction
+protocol kernel k_frei {
+  scan time 10;
+  table freifunk;
+  kernel table 42;
+  import none;
   export all;
-}
+};
 
-# This pseudo-protocol watches all interface up/down events.
+# this pseudo-protocol watches all interface up/down events
 protocol device {
-  scan time 10;  # Scan interfaces every 10 seconds
-}
-
-# define our routes
-protocol static static_ffhh {
-  table ffhh;
-  # reject route if announced from external
-  route fd51:2bb2:fd0d::/48 reject;
+    scan time 10;
 };
 
-protocol static local_ffhh {
-  table ffhh;
-  route fd51:2bb2:fd0d::/64 via "br-ffhh";
-};
+### pipes ###
 
-protocol pipe pipe_ffhh {
-  peer table ffhh;
-  import all;
+# sync nothing from main routing table to ebgp
+# sync routes (not own network) from ebgp to main routing table
+protocol pipe p_maintbl {
+  peer table ebgp;
+  import where !is_self_net();
   export none;
 };
 
-# template for internal routing
-template bgp locals {
-  table ffhh;
-  local as 65112;
-  source address <%= @own_ipv6 %>;
+# sync routes (not own network) from ebgp to ibgp
+# sync routes (all) from ibgp to ebgp
+protocol pipe p_ibgptbl {
+  table ebgp;
+  peer table ibgp;
   import all;
+  export where !is_self_net();
+};
+
+# sync routes (freifunk and default routes we got) from ibgp to freifunk
+# sync nothing from freifunk to ibgp
+protocol pipe p_freitbl {
+  table ibgp;
+  peer table freifunk;
+  import none;
+  export where is_freifunk() || is_default();
+};
+
+### static routes ###
+
+protocol static static_ffhh {  
+  route fd51:2bb2:fd0d::/48 reject;
+  route 2001:bf7:180::/44 reject;
+  route 2001:bf7:190::/44 reject;
+  route 2001:bf7:200::/44 reject;
+  route 2001:bf7:210::/44 reject;
+  route 2001:bf7:220::/44 reject;
+  route 2001:bf7:230::/44 reject;
+  table ebgp;
+};
+
+protocol static local_ffhh {
+  route fd51:2bb2:fd0d::/64 via "br-ffhh";
+  route 2001:bf7:180::/64 via "br-ffhh";
+  table freifunk;
+};
+
+### templates ###
+
+# template for same city freifunk gateways
+template bgp locals {
+  table ibgp;
+  local as ownas;
+  source address <%= @own_ipv6 %>;
+  import filter {
+    preference = 99;
+    accept;
+  };
   export where source = RTS_BGP;
   direct;
   next hop self;
@@ -70,13 +126,21 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
 <% end -%><% end -%>
 
 <% if @gw_do_ic_peering -%>
-# icvpn template for hamburg03
+# template for icvpn gateways of other cities
 template bgp peers {
-  local as 65112;
+  table ebgp;
+  local as ownas;
   source address <%= @ic_vpn_ip6 %>;
-  table ffhh;
-  import where is_ula();
-  export where is_self() || (source = RTS_BGP);
+  # ignore routes for our own network
+  import where is_freifunk() && !is_self_net();
+  export where is_freifunk() || (source = RTS_BGP);
+  route limit 10000;
+};
+
+# template for upstream gateways
+template bgp upstream from peers {
+  # accept freifunk networks and default route
+  import where (is_freifunk() || is_default()) && !is_self_net();
 };
 
 <% @ic_peerings_v6.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv6 -%>
@@ -85,3 +149,4 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
 };
 <% end -%><% end -%>
 <% end -%>
+

From a9bb0605cf059ab3cf01c0e47189576ab31028ec Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:15:58 +0200
Subject: [PATCH 33/58] Update list of tincd peers

---
 templates/etc/tinc/icvpn/tinc.conf.erb | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/templates/etc/tinc/icvpn/tinc.conf.erb b/templates/etc/tinc/icvpn/tinc.conf.erb
index 6bc8c52..838139d 100644
--- a/templates/etc/tinc/icvpn/tinc.conf.erb
+++ b/templates/etc/tinc/icvpn/tinc.conf.erb
@@ -15,22 +15,20 @@ ConnectTo = bremen2
 ConnectTo = chemnitz1
 ConnectTo = diac24_sbc
 ConnectTo = diac24_sbz
+ConnectTo = dreilaendereck1
 ConnectTo = dresden1
 ConnectTo = ffhallevpn1
 ConnectTo = franken1
 ConnectTo = franken2
 ConnectTo = franken3
 ConnectTo = franken_ro1
-ConnectTo = Frankfurt1
 ConnectTo = freiburg1
 ConnectTo = gronau1
 ConnectTo = gronau2
 ConnectTo = halle1
-ConnectTo = halle2
-ConnectTo = jena1
-ConnectTo = jena2
+ConnectTo = kiel0
 ConnectTo = kiel1
-ConnectTo = kiel13
+ConnectTo = kiel2
 ConnectTo = kiel3
 ConnectTo = kiel4
 ConnectTo = koeln1
@@ -39,10 +37,13 @@ ConnectTo = leipzig2
 ConnectTo = ljubljana1
 ConnectTo = luebeck1
 ConnectTo = luebeck2
+ConnectTo = magdeburg1
+ConnectTo = magdeburg2
 ConnectTo = mainz1
+ConnectTo = mainz2
 ConnectTo = nrw2
 ConnectTo = oldenburg1
+ConnectTo = ostholstein1
+ConnectTo = rheinneckar1
 ConnectTo = weimar1
 ConnectTo = weimar2
-ConnectTo = wermelskirchen1
-

From 4b891bdd23a3cb07d44d2fe09309967b4cadd2c8 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:17:34 +0200
Subject: [PATCH 34/58] Implement policy routing for IPv6

---
 files/etc/iptables/rules.v6 | 17 +++++++++++++++++
 manifests/init.pp           |  7 +++++--
 2 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 files/etc/iptables/rules.v6

diff --git a/files/etc/iptables/rules.v6 b/files/etc/iptables/rules.v6
new file mode 100644
index 0000000..4ee0a77
--- /dev/null
+++ b/files/etc/iptables/rules.v6
@@ -0,0 +1,17 @@
+# Generated by ip6tables-save v1.4.14 on Mon Aug 18 22:31:43 2014
+*mangle
+:PREROUTING ACCEPT [347182:29416089]
+:INPUT ACCEPT [95377:10719074]
+:FORWARD ACCEPT [50710:3964545]
+:OUTPUT ACCEPT [108706:9522484]
+:POSTROUTING ACCEPT [161591:13748029]
+-A PREROUTING -i br-ffhh -j MARK --set-xmark 0x1/0xffffffff
+COMMIT
+# Completed on Mon Aug 18 22:31:43 2014
+# Generated by ip6tables-save v1.4.14 on Mon Aug 18 22:31:43 2014
+*filter
+:INPUT ACCEPT [1244932:115240832]
+:FORWARD ACCEPT [51046:3997994]
+:OUTPUT ACCEPT [1330577:118074893]
+COMMIT
+# Completed on Mon Aug 18 22:31:43 2014
diff --git a/manifests/init.pp b/manifests/init.pp
index fe9b724..ba69839 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -167,7 +167,6 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
         "set iface[. = '${bat_if}']/up 'ip link set \$IFACE up'",
         "set iface[. = '${bat_if}']/post-up[1] 'brctl addif ${br_if} \$IFACE'",
         "set iface[. = '${bat_if}']/post-up[2] 'batctl it 10000'",
-        "set iface[. = '${bat_if}']/post-up[3] '/sbin/ip rule add from all fwmark 0x1 table 42'",
         "set iface[. = '${bat_if}']/pre-down 'brctl delif ${br_if} \$IFACE || true'",
         "set iface[. = '${bat_if}']/down 'ip link set \$IFACE down'",
       ];
@@ -478,9 +477,12 @@ class ff_gw::iptables {
     '/etc/iptables/rules.v4':
       ensure => file,
       source => 'puppet:///modules/ff_gw/etc/iptables/rules.v4';
+    '/etc/iptables/rules.v6':
+      ensure => file,
+      source => 'puppet:///modules/ff_gw/etc/iptables/rules.v6';
     '/etc/rc.local':
       ensure  => file,
-      content => '#!/bin/sh -e
+      content => '#!/bin/sh
 # managed by puppet
 #
 # rc.local
@@ -496,6 +498,7 @@ class ff_gw::iptables {
 
 /sbin/ip route add unreachable default table 42
 /sbin/ip rule add from all fwmark 0x1 table 42
+/sbin/ip -6 rule add from all fwmark 0x1 table 42
 exit 0';
   }
   ~>

From f555ac22766f54bbba0cd42221fdeda37464b3b2 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:18:38 +0200
Subject: [PATCH 35/58] Fix some problems with routing

before it happened regulary that locally generated ICMP messages
left eth0 with wrong source address instead of going out via the vpn interface
---
 files/etc/iptables/rules.v4        | 51 ++++++++++++++++--------------
 files/etc/openvpn/hideme/hideme-up |  6 ++++
 manifests/init.pp                  |  3 +-
 3 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/files/etc/iptables/rules.v4 b/files/etc/iptables/rules.v4
index 14e4a4c..38537b3 100644
--- a/files/etc/iptables/rules.v4
+++ b/files/etc/iptables/rules.v4
@@ -1,26 +1,31 @@
-# Generated by iptables-save v1.4.14 on Sun Mar 24 14:14:50 2013
-*filter
-:INPUT ACCEPT [273:40363]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [194:28568]
-COMMIT
-# Completed on Mon Mar 25 19:41:40 2013
-# Generated by iptables-save v1.4.14 on Mon Mar 25 19:41:40 2013
-*mangle
-:PREROUTING ACCEPT [286:41734]
-:INPUT ACCEPT [273:40363]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [194:28568]
-:POSTROUTING ACCEPT [194:28568]
--A PREROUTING -i br-ffhh -j MARK --set-xmark 0x1/0xffffffff
-COMMIT
-# Completed on Mon Mar 25 19:41:40 2013
-# Generated by iptables-save v1.4.14 on Mon Mar 25 19:41:40 2013
+# Generated by iptables-save v1.4.14 on Mon Aug 18 22:31:43 2014
 *nat
-:PREROUTING ACCEPT [15:1459]
-:INPUT ACCEPT [2:88]
-:OUTPUT ACCEPT [1:74]
-:POSTROUTING ACCEPT [1:74]
+:PREROUTING ACCEPT [1508898:60980199]
+:INPUT ACCEPT [85622:9125051]
+:OUTPUT ACCEPT [195829:12103496]
+:POSTROUTING ACCEPT [194526:11989631]
 -A POSTROUTING -o mullvad -j MASQUERADE
 COMMIT
-# Completed on Mon Mar 25 19:41:40 2013
+# Completed on Mon Aug 18 22:31:43 2014
+# Generated by iptables-save v1.4.14 on Mon Aug 18 22:31:43 2014
+*mangle
+:PREROUTING ACCEPT [100732184:31760093690]
+:INPUT ACCEPT [88878861:23870786312]
+:FORWARD ACCEPT [10499612:7842070628]
+:OUTPUT ACCEPT [158193447:33293545226]
+:POSTROUTING ACCEPT [168692266:41135440990]
+-A PREROUTING -i br-ffhh -j MARK --set-xmark 0x1/0xffffffff
+-A PREROUTING -i mullvad -j MARK --set-xmark 0x1/0xffffffff
+COMMIT
+# Completed on Mon Aug 18 22:31:43 2014
+# Generated by iptables-save v1.4.14 on Mon Aug 18 22:31:43 2014
+*filter
+:INPUT ACCEPT [88878720:23870769673]
+:FORWARD ACCEPT [10499612:7842070628]
+:OUTPUT ACCEPT [158192660:33293370754]
+-A INPUT -i mullvad -m state --state INVALID,NEW,UNTRACKED -j DROP
+-A FORWARD -i mullvad -m state --state INVALID,NEW,UNTRACKED -j DROP
+-A FORWARD -o eth0 -j DROP
+-A FORWARD -i eth0 -j DROP
+COMMIT
+# Completed on Mon Aug 18 22:31:43 2014
diff --git a/files/etc/openvpn/hideme/hideme-up b/files/etc/openvpn/hideme/hideme-up
index 311aaca..7574b1c 100644
--- a/files/etc/openvpn/hideme/hideme-up
+++ b/files/etc/openvpn/hideme/hideme-up
@@ -1,5 +1,11 @@
 #!/bin/sh
 ip route replace 0.0.0.0/1 via $4 table 42
 ip route replace 128.0.0.0/1 via $4 table 42
+
+ip rule del priority 30000
+ip rule add priority 30000 from $4 table 42
+
+ip route flush cache
+
 /etc/openvpn/update-dnsmasq-forward
 exit 0
diff --git a/manifests/init.pp b/manifests/init.pp
index ba69839..87c05b3 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -392,7 +392,8 @@ class ff_gw::radvd($own_ipv6) {
     context => '/files/etc/sysctl.conf',
     changes => [
       'set net.ipv4.ip_forward 1',
-      'set net.ipv6.conf.all.forwarding 1'
+      'set net.ipv6.conf.all.forwarding 1',
+      'set net.ipv4.icmp_errors_use_inbound_ifaddr 1'
     ],
   }
   ~>

From a9c15dd2ffddc3a85985e6c1010892b1f69b9e7c Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:19:59 +0200
Subject: [PATCH 36/58] Improved version of the check_gateway script

in case the vpn is offline, also shutdown radvd and dhcpd so that
clients get a new default gateway when their lease time expires
---
 files/usr/local/bin/check_gateway | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/files/usr/local/bin/check_gateway b/files/usr/local/bin/check_gateway
index 91059e0..589814b 100644
--- a/files/usr/local/bin/check_gateway
+++ b/files/usr/local/bin/check_gateway
@@ -1,7 +1,8 @@
 #!/bin/bash
-INTERFACE=mullvad
+INTERFACE=mullvad        # 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
@@ -10,13 +11,27 @@ 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 54MBit/54MBit > $MESH/gw_bandwidth
-         logger "batman gateway mode changed to $NEW_STATE"
+    echo $NEW_STATE > $MESH/gw_mode
+    echo 54MBit/54MBit > $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
+        service isc-dhcp-server stop
+        # Shutdown radvd daemon to prevent advertisment of server as gateway
+        service radvd stop
+    fi
+
+    # Check whether gateway modus has been activated
+    if [ "$NEW_STATE" == "server" ]; then
+        # Restart DHCP server and radvd daemon
+        service isc-dhcp-server start
+        service radvd start
+    fi
 done
-
-# vim: noai:ts=4:sw=4:ff=unix:ft=text:fdm=marker
-

From 74eec29e0b77de9ccbab2c5a76bd6a58e03a2400 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:21:02 +0200
Subject: [PATCH 37/58] Let dhcpd also announce NTP servers

---
 templates/etc/dhcp/dhcpd.conf.erb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/templates/etc/dhcp/dhcpd.conf.erb b/templates/etc/dhcp/dhcpd.conf.erb
index dc50cc0..56a2ca4 100644
--- a/templates/etc/dhcp/dhcpd.conf.erb
+++ b/templates/etc/dhcp/dhcpd.conf.erb
@@ -19,6 +19,7 @@ subnet 10.112.0.0 netmask 255.255.192.0 {
     # DNS: this gateway (<%= @gw_ipv4 %>) & srv01 (10.112.1.1)
     option domain-name-servers <%= @gw_ipv4 %>, 10.112.1.1;
     option routers <%= @gw_ipv4 %>;
+    option ntp-servers 10.112.16.1, 10.112.22.1;
 }
 
 include "/etc/dhcp/static.conf";

From 1b2299a2cc78ad5680c2e63d7b7f3668e3b278ed Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:21:39 +0200
Subject: [PATCH 38/58] Allow to set public IPv6 of the gateway
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

in addition to the ULA as before. we now have multiple /44 IPv6
networks from the Förderverein
---
 manifests/init.pp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/manifests/init.pp b/manifests/init.pp
index 87c05b3..714ee64 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -5,6 +5,7 @@ class ff_gw(
   $mesh_mac,
   $gw_ipv4, $gw_ipv4_netmask   = '255.255.192.0',
   $gw_ipv6, $gw_ipv6_prefixlen = '64',
+  $gw_pup_ipv6, $gw_pub_ipv6_prefixlen = '64',
   $secret_key,                                      # for fastd
   $vpn_provider = 'mullvad',                        # supported: mullvad or hideme
   $vpn_ca_crt   = false,                            # openvpn CA cert to verify server
@@ -26,6 +27,8 @@ class ff_gw(
     gw_ipv4_netmask   => $gw_ipv4_netmask,
     gw_ipv6           => $gw_ipv6,
     gw_ipv6_prefixlen => $gw_ipv6_prefixlen,
+    gw_pub_ipv6           => $gw_pub_ipv6,
+    gw_pub_ipv6_prefixlen => $gw_pub_ipv6_prefixlen,
     secret_key        => $secret_key,
   }
   ->
@@ -138,6 +141,7 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
         "set iface[. = '${br_if}'][1]/bridge-ports none",
         "set iface[. = '${br_if}'][1]/address ${gw_ipv6}",
         "set iface[. = '${br_if}'][1]/netmask ${gw_ipv6_prefixlen}",
+        "set iface[. = '${br_if}'][1]/post-up /sbin/ip -6 addr add ${gw_pub_ipv6}/${gw_pub_ipv6_prefixlen} dev $IFACE",
       ],
   }
   ->

From e0750129f3a56d31f9598b59ce2d502e4f7d302b Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:50:43 +0200
Subject: [PATCH 39/58] Small fixes (typos)

---
 manifests/init.pp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 714ee64..acc58f2 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -5,7 +5,7 @@ class ff_gw(
   $mesh_mac,
   $gw_ipv4, $gw_ipv4_netmask   = '255.255.192.0',
   $gw_ipv6, $gw_ipv6_prefixlen = '64',
-  $gw_pup_ipv6, $gw_pub_ipv6_prefixlen = '64',
+  $gw_pub_ipv6, $gw_pub_ipv6_prefixlen = '64',
   $secret_key,                                      # for fastd
   $vpn_provider = 'mullvad',                        # supported: mullvad or hideme
   $vpn_ca_crt   = false,                            # openvpn CA cert to verify server
@@ -98,7 +98,7 @@ class ff_gw::software {
   }
 }
 
-class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_prefixlen, $secret_key) {
+class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_prefixlen, $gw_pub_ipv6, $gw_pub_ipv6_prefixlen, $secret_key) {
   validate_re($mesh_mac, '^de:ad:be:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}$')
   # TODO: parameterize interface names
   $br_if   = 'br-ffhh'

From 8211257f0089ba88e34d229f698ac4850dd7f10d Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:51:10 +0200
Subject: [PATCH 40/58] Increase conntrack size

---
 manifests/init.pp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index acc58f2..73915b0 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -397,7 +397,8 @@ class ff_gw::radvd($own_ipv6) {
     changes => [
       'set net.ipv4.ip_forward 1',
       'set net.ipv6.conf.all.forwarding 1',
-      'set net.ipv4.icmp_errors_use_inbound_ifaddr 1'
+      'set net.ipv4.icmp_errors_use_inbound_ifaddr 1',
+      'set net.ipv4.netfilter.ip_conntrack_max 65536'
     ],
   }
   ~>
@@ -504,6 +505,7 @@ class ff_gw::iptables {
 /sbin/ip route add unreachable default table 42
 /sbin/ip rule add from all fwmark 0x1 table 42
 /sbin/ip -6 rule add from all fwmark 0x1 table 42
+/bin/echo 8192 > /sys/module/nf_conntrack/parameters/hashsize
 exit 0';
   }
   ~>

From 25a761343d8e57ed6cd21f33b6303c8744d63582 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 11:51:29 +0200
Subject: [PATCH 41/58] Ensure new bird version is installed

---
 manifests/init.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index 73915b0..c8e5088 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -516,7 +516,7 @@ exit 0';
   }
 }
 
-class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic_peering, $ic_vpn_ip6, $version = '1.4.3-2~bpo70+1') {
+class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic_peering, $ic_vpn_ip6, $version = '1.4.4-1~bpo70+1') {
   # read peering data from data file
   $module_path = get_module_path($module_name)
   $peeringdata = loadyaml("${module_path}/data/peering.yaml")

From fe986dd7940a316ba2e80e0c730d7ca0f434a7d1 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 12:08:53 +0200
Subject: [PATCH 42/58] Some fixes

---
 manifests/init.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index c8e5088..84b96c2 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -141,7 +141,7 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
         "set iface[. = '${br_if}'][1]/bridge-ports none",
         "set iface[. = '${br_if}'][1]/address ${gw_ipv6}",
         "set iface[. = '${br_if}'][1]/netmask ${gw_ipv6_prefixlen}",
-        "set iface[. = '${br_if}'][1]/post-up /sbin/ip -6 addr add ${gw_pub_ipv6}/${gw_pub_ipv6_prefixlen} dev $IFACE",
+        "set iface[. = '${br_if}'][1]/post-up '/sbin/ip -6 addr add ${gw_pub_ipv6}/${gw_pub_ipv6_prefixlen} dev \$IFACE'",
       ],
   }
   ->

From 768334815e4217d5ca90278fca3db45a62377aaf Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 18:36:04 +0200
Subject: [PATCH 43/58] Announce new network

---
 templates/etc/radvd.conf.erb | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/templates/etc/radvd.conf.erb b/templates/etc/radvd.conf.erb
index 50cffde..0932dac 100644
--- a/templates/etc/radvd.conf.erb
+++ b/templates/etc/radvd.conf.erb
@@ -7,6 +7,9 @@ interface br-ffhh
 
  prefix fd51:2bb2:fd0d::/64 {
  };
+ prefix 2001:bf7:180::/64 {
+ };
+
 
  RDNSS <%= @own_ipv6 %> {
  };

From 3253943fd1c099825f9dc4a0e001bf674dce9126 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Tue, 19 Aug 2014 18:54:26 +0200
Subject: [PATCH 44/58] State of VPN does not give a hint about IPv6 uplink
 state

---
 files/usr/local/bin/check_gateway | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/files/usr/local/bin/check_gateway b/files/usr/local/bin/check_gateway
index 589814b..b4b7e72 100644
--- a/files/usr/local/bin/check_gateway
+++ b/files/usr/local/bin/check_gateway
@@ -24,14 +24,11 @@ OLD_STATE="$(cat $MESH/gw_mode)"
     if [ "$NEW_STATE" == "off" ]; then
         # Shutdown DHCP server to prevent renewal of leases
         service isc-dhcp-server stop
-        # Shutdown radvd daemon to prevent advertisment of server as gateway
-        service radvd stop
     fi
 
     # Check whether gateway modus has been activated
     if [ "$NEW_STATE" == "server" ]; then
         # Restart DHCP server and radvd daemon
         service isc-dhcp-server start
-        service radvd start
     fi
 done

From c1f82290231fbb6a2e5985faa89e8fe46b4201d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Sch=C3=BCtte?= <martin.schuette@deck36.de>
Date: Wed, 20 Aug 2014 18:18:56 +0200
Subject: [PATCH 45/58] install ntpd

---
 manifests/sysadmin.pp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/manifests/sysadmin.pp b/manifests/sysadmin.pp
index 5ac7be0..b5f3d9f 100644
--- a/manifests/sysadmin.pp
+++ b/manifests/sysadmin.pp
@@ -12,12 +12,22 @@ class ff_gw::sysadmin($zabbixserver = '127.0.0.1', $muninserver = '127.0.0.1', $
   # next important thing: set up apt repositories
   class { 'ff_gw::sysadmin::software': }
 
+  # remove cronjob
   cron {
     'ntpdate-debian':
+      ensure  => absent,
       command => '/usr/sbin/ntpdate-debian',
       user    => root,
       minute  => '0';
   }
+  # replace with a real NTP daemon
+  package { 'ntp':
+    ensure => present,
+  }
+  ~>
+  service { 'ntp':
+    ensure => true,
+  }
 
   # user accounts
   create_resources('account', $accounts)

From fd9498ab107a1aa9cd79509c702457f834e3b7a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Sch=C3=BCtte?= <martin.schuette@deck36.de>
Date: Wed, 20 Aug 2014 18:24:26 +0200
Subject: [PATCH 46/58] silence cronjob

---
 files/root/bin/autoupdate_fastd_keys.sh | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/files/root/bin/autoupdate_fastd_keys.sh b/files/root/bin/autoupdate_fastd_keys.sh
index ae797d5..15ad96f 100644
--- a/files/root/bin/autoupdate_fastd_keys.sh
+++ b/files/root/bin/autoupdate_fastd_keys.sh
@@ -2,6 +2,10 @@
 # Simple script to update fastd peers from git upstream
 # and only send HUP to fastd when changes happend.
 
+if [[ "$1" == "-v" ]]; then
+  VERBOSE=1
+fi
+
 # CONFIGURE THIS TO YOUR PEER DIRECTORY
 FASTD_PEERS=/etc/fastd/ffhh-mesh-vpn/peers
 
@@ -17,11 +21,11 @@ GIT_REVISION=$(getCurrentVersion)
 
 # Automagically commit local changes
 # This preserves local changes
-git commit -m "CRON: auto commit"
+git commit --quiet -m "CRON: auto commit"
 
 # Pull latest changes from upstream
-git fetch
-git merge origin/master -m "Auto Merge"
+git fetch --quiet
+git merge origin/master --quiet -m "Auto Merge"
 
 # Get new version hash
 GIT_NEW_REVISION=$(getCurrentVersion)
@@ -29,7 +33,7 @@ GIT_NEW_REVISION=$(getCurrentVersion)
 if [ $GIT_REVISION != $GIT_NEW_REVISION ]
 then
   # Version has changed we need to update
-  echo "Reload fastd peers"
+  test -n "$VERBOSE" && echo "Reload fastd peers"
   kill -HUP $(pidof fastd)
 fi
 

From 1d222434e850c4e46a846a7466bd0fe81034e83c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Sch=C3=BCtte?= <martin.schuette@deck36.de>
Date: Wed, 20 Aug 2014 19:06:19 +0200
Subject: [PATCH 47/58] silence cronjob, -q is not enough

---
 files/root/bin/autoupdate_fastd_keys.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/files/root/bin/autoupdate_fastd_keys.sh b/files/root/bin/autoupdate_fastd_keys.sh
index 15ad96f..9be4f8f 100644
--- a/files/root/bin/autoupdate_fastd_keys.sh
+++ b/files/root/bin/autoupdate_fastd_keys.sh
@@ -21,7 +21,7 @@ GIT_REVISION=$(getCurrentVersion)
 
 # Automagically commit local changes
 # This preserves local changes
-git commit --quiet -m "CRON: auto commit"
+git commit --quiet -m "CRON: auto commit" > /dev/null
 
 # Pull latest changes from upstream
 git fetch --quiet

From 710921dc661fe4f420f945aff02e3a34ae3e5c02 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:10:16 +0200
Subject: [PATCH 48/58] update list of peers

---
 data/peering.yaml | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/data/peering.yaml b/data/peering.yaml
index 4837a49..42b14f3 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -201,6 +201,22 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.8
     as: 65530
+  Dreilaendereck1:
+    template: peers
+    ip: 10.207.0.75
+    as: 65043
+  Flensburg1:
+    template: peers
+    ip: 10.207.0.129
+    as: 65056
+  Guetersloh1:
+    template: peers
+    ip: 10.207.0.132
+    as: 65533
+  Guetersloh4:
+    template: peers
+    ip: 10.207.0.134
+    as: 65533
 
 
 peerings_v6:
@@ -342,3 +358,19 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:8
     as: 65530
+  Dreilaendereck1:
+    template: peers
+    ip: fec0::a:cf:0:be
+    as: 65043
+  Flensburg1:
+    template: peers
+    ip: fec0::a:cf:0:10
+    as: 65056
+  Guetersloh1:
+    template: peers
+    ip: fec0::a:cf:0:84
+    as: 65533
+  Guetersloh4:
+    template: peers
+    ip: fec0::a:cf:0:86
+    as: 65533

From 65d52150937df0613d340675201c696e22241627 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:30:07 +0200
Subject: [PATCH 49/58] update bird and bird6 config

---
 templates/etc/bird/bird.conf.erb  | 25 ++++++----
 templates/etc/bird/bird6.conf.erb | 83 ++++++++++++++++++++++++-------
 2 files changed, 79 insertions(+), 29 deletions(-)

diff --git a/templates/etc/bird/bird.conf.erb b/templates/etc/bird/bird.conf.erb
index 50e9ae5..3f2b2ae 100644
--- a/templates/etc/bird/bird.conf.erb
+++ b/templates/etc/bird/bird.conf.erb
@@ -158,6 +158,17 @@ template bgp locals {
   next hop self;
 };
 
+### local gateways ###
+
+<% @peerings_v4.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv4 -%>
+protocol bgp <%= key %> from <%= hash["template"] %> {
+  neighbor <%= hash["ip"] %> as ownas;
+};
+<% end -%><% end -%>
+
+<% if @gw_do_ic_peering -%>
+### icvpn peerings ###
+
 # template for icvpn gateways of other cities
 template bgp peers {
   table ebgp;
@@ -168,20 +179,12 @@ template bgp peers {
   route limit 10000;
 };
 
-### local gateways ###
-
-<% @peerings_v4.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv4 -%>
-protocol bgp <%= key %> from <%= hash["template"] %> {
-  neighbor <%= hash["ip"] %> as ownas;
-};
-<% end -%><% end -%>
-
-### icvpn peerings ###
-
-<% if @gw_do_ic_peering -%>
 <% @ic_peerings_v4.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv4 -%>
 protocol bgp <%= key %> from <%= hash["template"] %> {
   neighbor <%= hash["ip"] %> as <%= hash["as"] %>;
 };
 <% end -%><% end -%>
 <% end -%>
+
+# this is for local peerings not managed by puppet
+include "*.peering"
diff --git a/templates/etc/bird/bird6.conf.erb b/templates/etc/bird/bird6.conf.erb
index de3a28b..8bd036e 100644
--- a/templates/etc/bird/bird6.conf.erb
+++ b/templates/etc/bird/bird6.conf.erb
@@ -1,14 +1,23 @@
-table ibgp; # internal BGP peerings
-table ebgp; # external (icvpn) BGP peerings
-table freifunk; # kernel table 42 for routing from ff network
+table ibgp;	# internal BGP peerings
+table ebgp;	# external (icvpn) BGP peerings
+table freifunk; # synced to kernel table 42 for routing from ff network
+table unreach;	# synced to kernel table 43 to intercept in cases there 
+		# is no default route via icvpn
 
+# quite self explanatory :)
 define ownas = <%= @ff_as %>;
 
+# the router id in bird is 32 bit wide and bird allows the IPv4 notation
+# to set it. quite confusing, but setting it to the gateway's IPv4 address
+# is a good approach here.
 router id <%= @own_ipv4 %>;
 
 ### functions ###
 
-# own networks
+# own networks as of http://wiki.freifunk.net/IPv6:Prefixe and
+# http://wiki.freifunk.net/IC-VPN
+# the '+' defines to not only match the prefix length given but
+# also any smaller prefixes (like 48 and 64)
 function is_self_net() {
   return net ~ [ fd51:2bb2:fd0d::/48+,
     2001:bf7:180::/44+,
@@ -20,11 +29,21 @@ function is_self_net() {
 }
 
 # freifunk ip ranges in general
+# this is the public address space assigned to the
+# Foerderverein freie Netzwerke e.V.
 function is_freifunk() {
-  return net ~ [ fc00::/7{48,64},
-    2001:bf7::/32+];
+  return net ~ [ 2001:bf7::/32+ ];
 }
 
+# unique local addresses
+# this is the non-public address range used within freifunk
+# communities and the IC-VPN
+function is_ula() {
+  return net ~ [ fc00::/7{48,64} ];
+}
+
+# default route
+# be careful with importing default routes from arbitrary peers
 function is_default() {
   return net ~ [ ::0/0 ];
 }
@@ -33,10 +52,10 @@ function is_default() {
 
 # synchronize from bird to main kernel routing table
 # nothing in the other direction
-# (do not sync a default route we received to the main routing table
-# as this might collide with the normal default route of the host)
+# do not sync a default route we received to the main routing table
+# as this might collide with the normal default route of the host
 protocol kernel k_mast {
-  scan time 10;
+  scan time 20;
   import none;
   export where !is_default();
 };
@@ -44,16 +63,26 @@ protocol kernel k_mast {
 # synchronize from birds freifunk table to kernel routing table 42
 # nothing in the other direction
 protocol kernel k_frei {
-  scan time 10;
+  scan time 20;
   table freifunk;
   kernel table 42;
   import none;
   export all;
 };
 
+# syncronize from birds unreach table to kernel routing table 43
+# nothing in the other direction
+protocol kernel k_unreach {
+  scan time 20;
+  table unreach;
+  kernel table 43;
+  import none;
+  export all;
+};
+
 # this pseudo-protocol watches all interface up/down events
 protocol device {
-    scan time 10;
+    scan time 20;
 };
 
 ### pipes ###
@@ -75,17 +104,20 @@ protocol pipe p_ibgptbl {
   export where !is_self_net();
 };
 
-# sync routes (freifunk and default routes we got) from ibgp to freifunk
+# sync routes (freifunk, ula and default routes we got) from ibgp to freifunk
 # sync nothing from freifunk to ibgp
 protocol pipe p_freitbl {
   table ibgp;
   peer table freifunk;
   import none;
-  export where is_freifunk() || is_default();
+  export where is_freifunk() || is_default() || is_ula();
 };
 
 ### static routes ###
 
+# here you should define unreachable (=reject) routes for your own
+# prefixes from http://wiki.freifunk.net/IC-VPN and
+# http://wiki.freifunk.net/IPv6:Prefixe
 protocol static static_ffhh {  
   route fd51:2bb2:fd0d::/48 reject;
   route 2001:bf7:180::/44 reject;
@@ -97,15 +129,27 @@ protocol static static_ffhh {
   table ebgp;
 };
 
+# these are the address ranges used in your network
+# note that these should be /64 networks in most cases from within
+# the above bigger ranges
 protocol static local_ffhh {
-  route fd51:2bb2:fd0d::/64 via "br-ffhh";
-  route 2001:bf7:180::/64 via "br-ffhh";
+  route fd51:2bb2:fd0d::/64 via "br-ffhh"; # replace br-ffhh with the name
+  route 2001:bf7:180::/64 via "br-ffhh";   # of your freifunk interface
   table freifunk;
 };
 
+# this defines an unreachable default route so that pakets are not forwarded
+# via the main routing table if no default route exists within table 42
+# note that this requires an additional rule within your policy routing
+protocol static unreachable_default {
+  route ::/0 reject;
+  table unreach;
+};
+
 ### templates ###
 
 # template for same city freifunk gateways
+# even the ones which do not have a direct IC-VPN connection
 template bgp locals {
   table ibgp;
   local as ownas;
@@ -132,15 +176,16 @@ template bgp peers {
   local as ownas;
   source address <%= @ic_vpn_ip6 %>;
   # ignore routes for our own network
-  import where is_freifunk() && !is_self_net();
-  export where is_freifunk() || (source = RTS_BGP);
+  import where (is_freifunk() || is_ula()) && !is_self_net();
+  export where (is_ula() || is_freifunk() || (source = RTS_BGP)) && !is_default();
   route limit 10000;
 };
 
 # template for upstream gateways
+# that are allowed to announce a default route to us
 template bgp upstream from peers {
   # accept freifunk networks and default route
-  import where (is_freifunk() || is_default()) && !is_self_net();
+  import where (is_freifunk() || is_ula() || is_default()) && !is_self_net();
 };
 
 <% @ic_peerings_v6.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv6 -%>
@@ -150,3 +195,5 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
 <% end -%><% end -%>
 <% end -%>
 
+# this is for local peerings not managed by puppet
+include "*.peering6";

From 68ce6b91d7625c808291dd48d20322547f7a6e76 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:36:10 +0200
Subject: [PATCH 50/58] always filter ipv6 RH0 pakets

---
 files/etc/iptables/rules.v6 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/files/etc/iptables/rules.v6 b/files/etc/iptables/rules.v6
index 4ee0a77..a00c3d0 100644
--- a/files/etc/iptables/rules.v6
+++ b/files/etc/iptables/rules.v6
@@ -13,5 +13,8 @@ COMMIT
 :INPUT ACCEPT [1244932:115240832]
 :FORWARD ACCEPT [51046:3997994]
 :OUTPUT ACCEPT [1330577:118074893]
+-A INPUT -m rt --rt-type 0 -j DROP
+-A FORWARD -m rt --rt-type 0 -j DROP
+-A OUTPUT -m rt --rt-type 0 -j DROP
 COMMIT
 # Completed on Mon Aug 18 22:31:43 2014

From 32a3802cba465bef6c840c02a6a67c23600fb61c Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:39:09 +0200
Subject: [PATCH 51/58] use full path within check_gateway script

---
 files/usr/local/bin/check_gateway | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/files/usr/local/bin/check_gateway b/files/usr/local/bin/check_gateway
index b4b7e72..43e4683 100644
--- a/files/usr/local/bin/check_gateway
+++ b/files/usr/local/bin/check_gateway
@@ -23,12 +23,12 @@ OLD_STATE="$(cat $MESH/gw_mode)"
     # Check whether gateway modus has been deactivated
     if [ "$NEW_STATE" == "off" ]; then
         # Shutdown DHCP server to prevent renewal of leases
-        service isc-dhcp-server stop
+        /usr/sbin/service isc-dhcp-server stop
     fi
 
     # Check whether gateway modus has been activated
     if [ "$NEW_STATE" == "server" ]; then
-        # Restart DHCP server and radvd daemon
-        service isc-dhcp-server start
+        # Restart DHCP server
+        /usr/sbin/service isc-dhcp-server start
     fi
 done

From 21603848083c7bf79fe6d4f3ec3c2b4b18091db3 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:43:30 +0200
Subject: [PATCH 52/58] add second rule for ipv6 policy routing

---
 manifests/init.pp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/manifests/init.pp b/manifests/init.pp
index 84b96c2..da3c5cb 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -506,6 +506,7 @@ class ff_gw::iptables {
 /sbin/ip rule add from all fwmark 0x1 table 42
 /sbin/ip -6 rule add from all fwmark 0x1 table 42
 /bin/echo 8192 > /sys/module/nf_conntrack/parameters/hashsize
+/sbin/ip -6 rule add priority 30000 from all fwmark 0x1 table 43
 exit 0';
   }
   ~>

From e43d58fbef8d9ba09520de35e9bcfead874c43f7 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:48:17 +0200
Subject: [PATCH 53/58] correct typo

---
 templates/etc/bird/bird.conf.erb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/etc/bird/bird.conf.erb b/templates/etc/bird/bird.conf.erb
index 3f2b2ae..2697190 100644
--- a/templates/etc/bird/bird.conf.erb
+++ b/templates/etc/bird/bird.conf.erb
@@ -187,4 +187,4 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
 <% end -%>
 
 # this is for local peerings not managed by puppet
-include "*.peering"
+include "*.peering";

From 755fe47d3c893bec800e9d8b89789c0a17bbdea3 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 27 Aug 2014 15:48:47 +0200
Subject: [PATCH 54/58] update list of tinc peers

---
 templates/etc/tinc/icvpn/tinc.conf.erb | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/templates/etc/tinc/icvpn/tinc.conf.erb b/templates/etc/tinc/icvpn/tinc.conf.erb
index 838139d..5ea534b 100644
--- a/templates/etc/tinc/icvpn/tinc.conf.erb
+++ b/templates/etc/tinc/icvpn/tinc.conf.erb
@@ -18,6 +18,7 @@ ConnectTo = diac24_sbz
 ConnectTo = dreilaendereck1
 ConnectTo = dresden1
 ConnectTo = ffhallevpn1
+ConnectTo = flensburg1
 ConnectTo = franken1
 ConnectTo = franken2
 ConnectTo = franken3
@@ -25,7 +26,11 @@ ConnectTo = franken_ro1
 ConnectTo = freiburg1
 ConnectTo = gronau1
 ConnectTo = gronau2
+ConnectTo = guetersloh1
+ConnectTo = guetersloh4
 ConnectTo = halle1
+ConnectTo = jena1
+ConnectTo = jena2
 ConnectTo = kiel0
 ConnectTo = kiel1
 ConnectTo = kiel2
@@ -40,10 +45,12 @@ ConnectTo = luebeck2
 ConnectTo = magdeburg1
 ConnectTo = magdeburg2
 ConnectTo = mainz1
-ConnectTo = mainz2
 ConnectTo = nrw2
 ConnectTo = oldenburg1
 ConnectTo = ostholstein1
 ConnectTo = rheinneckar1
+ConnectTo = ruhrgebiet1
 ConnectTo = weimar1
 ConnectTo = weimar2
+ConnectTo = wiesbaden1
+

From 30e221a63f151e5584f51f4e9f222adf1d8d7b63 Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 1 Oct 2014 23:50:49 +0200
Subject: [PATCH 55/58] Remove hamburg11

---
 data/peering.yaml | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/data/peering.yaml b/data/peering.yaml
index 42b14f3..7ba51e2 100644
--- a/data/peering.yaml
+++ b/data/peering.yaml
@@ -17,9 +17,6 @@ peerings_v4:
   hamburg09:
     template: locals
     ip: 10.112.24.1
-  hamburg11:
-    template: locals
-    ip: 10.112.28.1
   hamburg12:
     template: locals
     ip: 10.112.30.1
@@ -217,7 +214,14 @@ ic_peerings_v4:
     template: peers
     ip: 10.207.0.134
     as: 65533
-
+  Magdeburg1:
+    template: peers
+    ip: 10.207.39.1
+    as: 65039
+  Magdeburg2:
+    template: peers
+    ip: 10.207.39.2
+    as: 65039
 
 peerings_v6:
   srv01:
@@ -306,6 +310,10 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:51
     as: 65526
+  Kiel0:
+    template: peers
+    ip: fec0::a:cf:0:34
+    as: 65525
   Kiel1:
     template: peers
     ip: fec0::a:cf:0:35
@@ -374,3 +382,11 @@ ic_peerings_v6:
     template: peers
     ip: fec0::a:cf:0:86
     as: 65533
+  Magdeburg1:
+    template: peers
+    ip: fec0::a:cf:39:1
+    as: 65039
+  Magdeburg1:
+    template: peers
+    ip: fec0::a:cf:39:2
+    as: 65039

From 6ec13b343f04dc9b1c30695fdf1db581c2c0088a Mon Sep 17 00:00:00 2001
From: ohrensessel <git@leokrueger.de>
Date: Wed, 1 Oct 2014 23:52:02 +0200
Subject: [PATCH 56/58] Extend check_gateway script

ensure that dhcp server is stopped or started depending on gw mode
---
 files/usr/local/bin/check_gateway | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/files/usr/local/bin/check_gateway b/files/usr/local/bin/check_gateway
index 43e4683..1e65f07 100644
--- a/files/usr/local/bin/check_gateway
+++ b/files/usr/local/bin/check_gateway
@@ -31,4 +31,21 @@ OLD_STATE="$(cat $MESH/gw_mode)"
         # 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
+

From 69ef80b070fe4bb957d76e9140b995a983537c3b Mon Sep 17 00:00:00 2001
From: Andreas Baldeau <andreas@baldeau.net>
Date: Mon, 3 Nov 2014 22:33:28 +0100
Subject: [PATCH 57/58] Git URL in README aktualisiert

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d1ea1f7..cb87142 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ design pattern.
   do that manually or run a small `ff_gw::sysadmin`-only manifest before the
   main `ff_gw` manifest.
 * User root requires ssh access to the git repository
-  `git@freifunk-gw01.hamburg.ccc.de:fastdkeys` --
+  `git@git.hamburg.freifunk.net:fastdkeys` --
   so create a key and have it authorized beforehand.
 
 ## Usage

From a9466f95493cfdc1ed9833668caba392b649cd1d Mon Sep 17 00:00:00 2001
From: Andreas Baldeau <andreas@baldeau.net>
Date: Mon, 3 Nov 2014 22:35:02 +0100
Subject: [PATCH 58/58] Git URL angepasst

---
 manifests/init.pp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manifests/init.pp b/manifests/init.pp
index da3c5cb..cc5f9f1 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -179,7 +179,7 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
   vcsrepo { '/etc/fastd/ffhh-mesh-vpn/peers':
     ensure   => present,
     provider => git,
-    source   => 'git@freifunk-gw01.hamburg.ccc.de:fastdkeys',
+    source   => 'git@git.hamburg.freifunk.net:fastdkeys',
   }
 
   cron {