Compare commits

...

60 commits

Author SHA1 Message Date
Andreas Baldeau
a9466f9549 Git URL angepasst 2014-11-03 22:35:02 +01:00
Andreas Baldeau
69ef80b070 Git URL in README aktualisiert 2014-11-03 22:33:28 +01:00
ohrensessel
6ec13b343f Extend check_gateway script
ensure that dhcp server is stopped or started depending on gw mode
2014-10-01 23:52:02 +02:00
ohrensessel
30e221a63f Remove hamburg11 2014-10-01 23:50:49 +02:00
ohrensessel
e8740e0b18 Merge branch 'master' of github.com:freifunkhamburg/puppet-ff_gw 2014-08-27 15:49:18 +02:00
ohrensessel
755fe47d3c update list of tinc peers 2014-08-27 15:48:47 +02:00
ohrensessel
e43d58fbef correct typo 2014-08-27 15:48:17 +02:00
ohrensessel
2160384808 add second rule for ipv6 policy routing 2014-08-27 15:43:30 +02:00
ohrensessel
32a3802cba use full path within check_gateway script 2014-08-27 15:39:09 +02:00
ohrensessel
68ce6b91d7 always filter ipv6 RH0 pakets 2014-08-27 15:36:10 +02:00
ohrensessel
65d5215093 update bird and bird6 config 2014-08-27 15:30:07 +02:00
ohrensessel
710921dc66 update list of peers 2014-08-27 15:10:16 +02:00
Martin Schütte
1d222434e8 silence cronjob, -q is not enough 2014-08-20 19:06:19 +02:00
Martin Schütte
fd9498ab10 silence cronjob 2014-08-20 18:24:45 +02:00
Martin Schütte
c1f8229023 install ntpd 2014-08-20 18:18:56 +02:00
ohrensessel
3253943fd1 State of VPN does not give a hint about IPv6 uplink state 2014-08-19 18:54:26 +02:00
ohrensessel
768334815e Announce new network 2014-08-19 18:36:04 +02:00
ohrensessel
fe986dd794 Some fixes 2014-08-19 12:08:53 +02:00
ohrensessel
2ed563f3e6 Merge branch 'master' of github.com:freifunkhamburg/puppet-ff_gw 2014-08-19 11:52:00 +02:00
ohrensessel
25a761343d Ensure new bird version is installed 2014-08-19 11:51:29 +02:00
ohrensessel
8211257f00 Increase conntrack size 2014-08-19 11:51:10 +02:00
ohrensessel
e0750129f3 Small fixes (typos) 2014-08-19 11:50:43 +02:00
ohrensessel
1b2299a2cc Allow to set public IPv6 of the gateway
in addition to the ULA as before. we now have multiple /44 IPv6
networks from the Förderverein
2014-08-19 11:21:39 +02:00
ohrensessel
74eec29e0b Let dhcpd also announce NTP servers 2014-08-19 11:21:02 +02:00
ohrensessel
a9c15dd2ff 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
2014-08-19 11:19:59 +02:00
ohrensessel
f555ac2276 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
2014-08-19 11:18:38 +02:00
ohrensessel
4b891bdd23 Implement policy routing for IPv6 2014-08-19 11:17:34 +02:00
ohrensessel
a9bb0605cf Update list of tincd peers 2014-08-19 11:15:58 +02:00
ohrensessel
4291261c6b refactor bird6.conf for policy routing
Berlin1 is allowed to send us default routes now
2014-08-19 11:14:54 +02:00
Martin Schuette
b412e55cfa split ff_gw::sysadmin class 2014-07-01 18:33:46 +02:00
ohrensessel
ba5030ffce Add munin plugin to monitor dhcp leases 2014-07-01 17:49:35 +02:00
ohrensessel
4664e1bd1b Prepare for fastd v14 2014-07-01 01:09:35 +02:00
Martin Schütte
b5b7814581 openvpn: different up scripts 2014-06-24 11:59:39 +02:00
Martin Schuette
c03c8822cd bump version 2014-06-22 22:51:14 +02:00
Martin Schuette
cd374601f1 bugfix wrong path 2014-06-22 22:48:02 +02:00
Martin Schuette
207c82e834 vpn: fix cert/username params and conditions 2014-06-22 22:41:53 +02:00
Martin Schuette
9e93f9a9e5 fix whitespace 2014-06-22 22:34:56 +02:00
Martin Schuette
daf7f768f0 extend ff_gw::vpn for hideme support 2014-06-22 22:03:10 +02:00
Martin Schuette
5b8b7454e3 small cleanup 2014-06-22 18:47:04 +02:00
Martin Schuette
30e37c0f37 use augeas for /etc/network/interfaces, leave lo and eth0 as they were 2014-06-22 18:28:43 +02:00
ohrensessel
2073295b3c Fix using DNS server of VPN provider 2014-06-18 15:34:04 +02:00
ohrensessel
f4150d7ec3 Use DNS Server pushed by VPN provider 2014-06-18 15:06:54 +02:00
ohrensessel
e6f165ad29 Bird/Bird6: Add Ostholstein1 peering 2014-06-06 00:59:54 +02:00
ohrensessel
ba62e670c6 Add cronjob for ntpdate 2014-06-05 21:37:50 +02:00
ohrensessel
d751c18dfe Bird: Add peering with RheinNeckar1 2014-06-05 21:37:09 +02:00
Martin Schuette
3b7ff697fa remove atop cronjob 2014-06-02 12:59:25 +02:00
ohrensessel
e582db0a8b DHCP: Announce this gateway and srv01 as DNS servers 2014-06-02 09:38:18 +02:00
Martin Schuette
e5890bf06e add own IP to resolv.conf 2014-06-01 23:11:16 +02:00
Martin Schuette
669c7036a5 add gw13 v6 peering 2014-06-01 22:30:32 +02:00
Martin Schuette
a734032c5d bird6 depends on bird 2014-06-01 22:20:14 +02:00
Martin Schuette
13ba5abc7a ensure bird version 1.4.3-2~bpo70+1 by default 2014-06-01 22:11:49 +02:00
Martin Schuette
5f98dd4613 rsyslog: fix dhcp log levels 2014-06-01 22:01:25 +02:00
Martin Schuette
19529f1659 rsyslog: add stop action after dhcp log 2014-06-01 21:58:33 +02:00
Martin Schuette
abc3df60e4 ensure old & new bird version compatibility 2014-06-01 21:54:02 +02:00
Martin Schuette
125baa50e4 provide defaults for ff_gw::tinc params (and remove tabs) 2014-06-01 21:49:32 +02:00
Martin Schuette
a375035f2c puppet-lintify 2014-06-01 21:47:08 +02:00
Martin Schuette
13d37b6a54 disable atop daemon 2014-06-01 21:44:16 +02:00
ohrensessel
073cf1dc9e Monitor more interfaces with munin 2014-06-01 14:15:41 +02:00
ohrensessel
017ead9d9a Ensure bc is installed for munin
as it is required for vnstat_ plugin
2014-06-01 14:02:54 +02:00
ohrensessel
37728ec27d Update bird.conf and peering data 2014-05-20 15:54:52 +02:00
23 changed files with 1130 additions and 366 deletions

View file

@ -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'

View file

@ -14,15 +14,13 @@ 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
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
@ -130,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-----',
```

View file

@ -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
@ -61,6 +58,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 +126,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 +170,14 @@ ic_peerings_v4:
template: peers
ip: 10.207.0.27
as: 65513
Schwarzach1:
Ostholstein1:
template: peers
ip: 10.207.0.56
as: 65527
ip: 10.207.0.135
as: 65152
RheinNeckar1:
template: peers
ip: 10.207.0.142
as: 76118
Treuenbrietzen:
template: peers
ip: 10.207.0.18
@ -189,7 +194,34 @@ ic_peerings_v4:
template: peers
ip: 10.207.0.7
as: 65530
Wermelskirchen2:
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
Magdeburg1:
template: peers
ip: 10.207.39.1
as: 65039
Magdeburg2:
template: peers
ip: 10.207.39.2
as: 65039
peerings_v6:
srv01:
@ -224,6 +256,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:
@ -235,7 +271,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:
@ -246,6 +282,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
@ -270,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
@ -302,15 +346,47 @@ ic_peerings_v6:
template: peers
ip: fec0::a:cf:0:83
as: 65052
Schwarzach:
Ostholstein1:
template: peers
ip: fec0::a:cf:0:56
as: 65527
ip: fec0::a:cf:0:87
as: 65152
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
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
Magdeburg1:
template: peers
ip: fec0::a:cf:39:1
as: 65039
Magdeburg1:
template: peers
ip: fec0::a:cf:39:2
as: 65039

View file

@ -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

View file

@ -0,0 +1,20 @@
# 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]
-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

View file

@ -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/hideme/hideme-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

View file

@ -0,0 +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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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" > /dev/null
# 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

View file

@ -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,41 @@ 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
/usr/sbin/service isc-dhcp-server stop
fi
# Check whether gateway modus has been activated
if [ "$NEW_STATE" == "server" ]; then
# Restart DHCP server
/usr/sbin/service isc-dhcp-server start
fi
exit 0
done
# vim: noai:ts=4:sw=4:ff=unix:ft=text:fdm=marker
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

View file

@ -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);
}

View file

@ -1,11 +1,35 @@
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_ipv4_netmask = '255.255.192.0',
$gw_ipv6, $gw_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
$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,
$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':
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,
gw_pub_ipv6 => $gw_pub_ipv6,
gw_pub_ipv6_prefixlen => $gw_pub_ipv6_prefixlen,
secret_key => $secret_key,
}
->
class { 'ff_gw::dhcpd':
@ -19,15 +43,22 @@ class ff_gw($ff_net, $ff_mesh_net, $ff_as, $mesh_mac, $gw_ipv4, $gw_ipv6, $secre
}
->
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': }
->
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,
@ -67,8 +98,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, $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'
$bat_if = 'bat0'
$mesh_if = 'ffhh-mesh-vpn'
file {
'/etc/fastd/ffhh-mesh-vpn':
@ -91,45 +126,60 @@ 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',
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 ${gw_ipv6_prefixlen}",
"set iface[. = '${br_if}'][1]/post-up '/sbin/ip -6 addr add ${gw_pub_ipv6}/${gw_pub_ipv6_prefixlen} dev \$IFACE'",
],
}
->
augeas {
"${br_if}-inet":
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",
"set iface[. = '${br_if}'][2]/address ${gw_ipv4}",
"set iface[. = '${br_if}'][2]/netmask ${gw_ipv4_netmask}",
],
}
->
# TODO: parameterize ffhh-mesh-vpn
augeas {
$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",
"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}']/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':
ensure => present,
provider => git,
source => 'git@freifunk-gw01.hamburg.ccc.de:fastdkeys',
source => 'git@git.hamburg.freifunk.net:fastdkeys',
}
cron {
@ -222,7 +272,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
@ -307,6 +361,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':
@ -329,7 +396,9 @@ 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',
'set net.ipv4.netfilter.ip_conntrack_max 65536'
],
}
~>
@ -341,10 +410,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 $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";
}
} elsif $usr_crt {
# 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':
@ -352,29 +443,22 @@ 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":
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
/usr/sbin/service dnsmasq restart
exit 0';
"/etc/openvpn/${vpnname}.conf":
"/etc/openvpn/${provider}/${provider}-up":
ensure => file,
source => "puppet:///modules/ff_gw/etc/openvpn/${vpnname}.conf";
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";
'/etc/openvpn/update-dnsmasq-forward':
ensure => file,
mode => '0755',
source => 'puppet:///modules/ff_gw/etc/openvpn/update-dnsmasq-forward';
}
~>
service { 'openvpn':
@ -399,9 +483,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
@ -417,6 +504,9 @@ 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
/sbin/ip -6 rule add priority 30000 from all fwmark 0x1 table 43
exit 0';
}
~>
@ -427,7 +517,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.4-1~bpo70+1') {
# read peering data from data file
$module_path = get_module_path($module_name)
$peeringdata = loadyaml("${module_path}/data/peering.yaml")
@ -436,27 +526,10 @@ 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]
package {
'bird6':
ensure => $version,
# for compatibility with old & new bird versions
file { '/etc/bird':
ensure => directory;
}
->
file {
'/etc/bird/bird6.conf':
ensure => file,
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':
@ -466,10 +539,11 @@ 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,
target => '/etc/bird/bird.conf';
ensure => link,
target => '/etc/bird/bird.conf';
}
~>
service {
@ -478,9 +552,41 @@ 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 = '/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 +601,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':

View file

@ -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,7 +10,105 @@ 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)
# Sudo
include sudo
sudo::conf { 'admins':
priority => 10,
content => '%sudo ALL=(ALL) NOPASSWD: ALL',
}
# sshd
augeas { 'harden_sshd':
context => '/files/etc/ssh/sshd_config',
changes => [
'set PermitRootLogin no',
'set PasswordAuthentication no',
'set PubkeyAuthentication yes'
],
}
~>
service { 'ssh':
ensure => running,
enable => true,
}
class { 'ff_gw::sysadmin::zabbix':
zabbixserver => $zabbixserver,
}
class { 'ff_gw::sysadmin::munin':
muninserver => $muninserver,
}
}
class ff_gw::sysadmin::hostname($newname, $newip) {
# short name
$alias = regsubst($newname, '^([^.]*).*$', '\1')
# clean old names
if $::hostname != $alias {
host { $::hostname: ensure => absent }
}
if $::fqdn != $newname {
host { $::fqdn: ensure => absent }
}
# rewrite config files:
host { $newname:
ensure => present,
ip => $newip,
alias => $alias ? {
$::hostname => undef,
default => $alias
},
before => Exec['hostname.sh'],
}
file { '/etc/mailname':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => "${newname}\n",
}
file { '/etc/hostname':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => "${newname}\n",
notify => Exec['hostname.sh'],
}
exec { 'hostname.sh':
command => '/etc/init.d/hostname.sh start',
refreshonly => true,
}
}
# everything related to apt-repos and default tools
class ff_gw::sysadmin::software() {
class { '::apt':
always_apt_update => true
}
@ -39,166 +136,18 @@ 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']:
ensure => installed,
}
# user accounts
create_resources('account', $accounts)
# Sudo
include sudo
sudo::conf { 'admins':
priority => 10,
content => '%sudo ALL=(ALL) NOPASSWD: ALL',
}
# sshd
augeas { 'harden_sshd':
context => '/files/etc/ssh/sshd_config',
changes => [
'set PermitRootLogin no',
'set PasswordAuthentication no',
'set PubkeyAuthentication yes'
],
}
~>
service { 'ssh':
ensure => running,
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',
}
->
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' ]:
'screen', 'tcpdump', 'rsync', 'file', 'psmisc', 'ntpdate']:
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';
# TODO: delete not needed plugins
'/etc/munin/plugin-conf.d/vnstat':
ensure => file,
content => '[vnstat_eth0_monthly_rxtx]
env.estimate 1';
# remove atop cronjob
file { '/etc/cron.d/atop':
ensure => absent,
}
~>
service { 'munin-node':
ensure => running,
enable => true;
}
}
class ff_gw::sysadmin::hostname($newname, $newip) {
# short name
$alias = regsubst($newname, '^([^.]*).*$', '\1')
# clean old names
if "$::hostname" != "$alias" {
host { "$hostname": ensure => absent }
}
if "$::fqdn" != "$newname" {
host { "$fqdn": ensure => absent }
}
# rewrite config files:
host { "$newname":
ensure => present,
ip => $newip,
alias => $alias ? {
"$hostname" => undef,
default => $alias
},
before => Exec['hostname.sh'],
}
file { '/etc/mailname':
ensure => present,
owner => 'root',
group => 'root',
mode => 644,
content => "${newname}\n",
}
file { '/etc/hostname':
ensure => present,
owner => 'root',
group => 'root',
mode => 644,
content => "${newname}\n",
notify => Exec['hostname.sh'],
}
exec { 'hostname.sh':
command => '/etc/init.d/hostname.sh start',
refreshonly => true,
->
# stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
service { 'atop':
ensure => stopped,
enable => false,
}
}

View file

@ -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;
}
}

View file

@ -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,
}
}

View file

@ -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;
@ -158,16 +158,6 @@ template bgp locals {
next hop self;
};
# template for icvpn gateways of other cities
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());
route limit 10000;
};
### local gateways ###
<% @peerings_v4.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv4 -%>
@ -176,12 +166,25 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
};
<% end -%><% end -%>
<% if @gw_do_ic_peering -%>
### icvpn peerings ###
<% if @gw_do_ic_peering -%>
# template for icvpn gateways of other cities
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());
route limit 10000;
};
<% @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";

View file

@ -1,63 +1,163 @@
# managed by puppet
#
# the ff ip of the gateway
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 %>;
# routing tables
table ffhh;
### functions ###
# filter to check ulas
# 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+,
2001:bf7:190::/44+,
2001:bf7:200::/44+,
2001:bf7:210::/44+,
2001:bf7:220::/44+,
2001:bf7:230::/44+];
}
# freifunk ip ranges in general
# this is the public address space assigned to the
# Foerderverein freie Netzwerke e.V.
function is_freifunk() {
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} ]);
return net ~ [ fc00::/7{48,64} ];
}
function is_self() {
return (proto = "static_ffhh");
# default route
# be careful with importing default routes from arbitrary peers
function is_default() {
return net ~ [ ::0/0 ];
}
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;
}
### kernel ###
# 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
# 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 20;
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 20;
table freifunk;
kernel table 42;
import none;
export all;
}
};
# This pseudo-protocol watches all interface up/down events.
# 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 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 20;
};
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, 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() || 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;
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;
};
# 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"; # 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;
source address <%= @own_ipv6 %>;
import filter {
preference = 99;
accept;
};
export where source = RTS_BGP;
direct;
next hop self;
@ -70,13 +170,22 @@ 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_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_ula() || is_default()) && !is_self_net();
};
<% @ic_peerings_v6.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv6 -%>
@ -85,3 +194,6 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
};
<% end -%><% end -%>
<% end -%>
# this is for local peerings not managed by puppet
include "*.peering6";

View file

@ -16,9 +16,10 @@ 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 %>;
option ntp-servers 10.112.16.1, 10.112.22.1;
}
include "/etc/dhcp/static.conf";

View file

@ -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;

View file

@ -7,6 +7,9 @@ interface br-ffhh
prefix fd51:2bb2:fd0d::/64 {
};
prefix 2001:bf7:180::/64 {
};
RDNSS <%= @own_ipv6 %> {
};

View file

@ -15,22 +15,25 @@ ConnectTo = bremen2
ConnectTo = chemnitz1
ConnectTo = diac24_sbc
ConnectTo = diac24_sbz
ConnectTo = dreilaendereck1
ConnectTo = dresden1
ConnectTo = ffhallevpn1
ConnectTo = flensburg1
ConnectTo = franken1
ConnectTo = franken2
ConnectTo = franken3
ConnectTo = franken_ro1
ConnectTo = Frankfurt1
ConnectTo = freiburg1
ConnectTo = gronau1
ConnectTo = gronau2
ConnectTo = guetersloh1
ConnectTo = guetersloh4
ConnectTo = halle1
ConnectTo = halle2
ConnectTo = jena1
ConnectTo = jena2
ConnectTo = kiel0
ConnectTo = kiel1
ConnectTo = kiel13
ConnectTo = kiel2
ConnectTo = kiel3
ConnectTo = kiel4
ConnectTo = koeln1
@ -39,10 +42,15 @@ ConnectTo = leipzig2
ConnectTo = ljubljana1
ConnectTo = luebeck1
ConnectTo = luebeck2
ConnectTo = magdeburg1
ConnectTo = magdeburg2
ConnectTo = mainz1
ConnectTo = nrw2
ConnectTo = oldenburg1
ConnectTo = ostholstein1
ConnectTo = rheinneckar1
ConnectTo = ruhrgebiet1
ConnectTo = weimar1
ConnectTo = weimar2
ConnectTo = wermelskirchen1
ConnectTo = wiesbaden1