Compare commits

..

No commits in common. "master" and "0.3.0" have entirely different histories.

23 changed files with 365 additions and 1129 deletions

View file

@ -1,5 +1,5 @@
name 'puppet-ff_gw'
version '0.4.0'
version '0.3.0'
license 'BSD 2-clause license'
author 'Martin Schuette <info@mschuette.name>'
dependency 'puppetlabs/apt', '>= 1.4.0'

View file

@ -14,13 +14,15 @@ 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@git.hamburg.freifunk.net:fastdkeys` --
`git@freifunk-gw01.hamburg.ccc.de:fastdkeys` --
so create a key and have it authorized beforehand.
## Usage
@ -128,18 +130,3 @@ 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,6 +17,9 @@ 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
@ -58,10 +61,6 @@ 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
@ -126,9 +125,9 @@ ic_peerings_v4:
template: peers
ip: 10.207.0.66
as: 65055
Kiel2:
Kiel4:
template: peers
ip: 10.207.0.52
ip: 10.207.0.58
as: 65525
Koblenz:
template: peers
@ -170,14 +169,10 @@ ic_peerings_v4:
template: peers
ip: 10.207.0.27
as: 65513
Ostholstein1:
Schwarzach1:
template: peers
ip: 10.207.0.135
as: 65152
RheinNeckar1:
template: peers
ip: 10.207.0.142
as: 76118
ip: 10.207.0.56
as: 65527
Treuenbrietzen:
template: peers
ip: 10.207.0.18
@ -194,34 +189,7 @@ 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:
@ -256,10 +224,6 @@ 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:
@ -271,7 +235,7 @@ ic_peerings_v6:
ip: fec0::a:cf:0:19
as: 65025
Berlin1:
template: upstream
template: peers
ip: fec0::a:cf:0:5
as: 44194
Bielefeld1:
@ -282,10 +246,6 @@ 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
@ -310,10 +270,6 @@ 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
@ -346,47 +302,15 @@ ic_peerings_v6:
template: peers
ip: fec0::a:cf:0:83
as: 65052
Ostholstein1:
Schwarzach:
template: peers
ip: fec0::a:cf:0:87
as: 65152
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
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,31 +1,26 @@
# Generated by iptables-save v1.4.14 on Mon Aug 18 22:31:43 2014
# 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
*nat
:PREROUTING ACCEPT [1508898:60980199]
:INPUT ACCEPT [85622:9125051]
:OUTPUT ACCEPT [195829:12103496]
:POSTROUTING ACCEPT [194526:11989631]
:PREROUTING ACCEPT [15:1459]
:INPUT ACCEPT [2:88]
:OUTPUT ACCEPT [1:74]
:POSTROUTING ACCEPT [1:74]
-A POSTROUTING -o mullvad -j MASQUERADE
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
*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
# Completed on Mon Mar 25 19:41:40 2013

View file

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

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

@ -1,11 +0,0 @@
#!/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,7 +37,6 @@ 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

@ -1,5 +0,0 @@
#!/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

@ -1,56 +0,0 @@
#!/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,10 +2,6 @@
# 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
@ -21,11 +17,11 @@ GIT_REVISION=$(getCurrentVersion)
# Automagically commit local changes
# This preserves local changes
git commit --quiet -m "CRON: auto commit" > /dev/null
git commit -m "CRON: auto commit"
# Pull latest changes from upstream
git fetch --quiet
git merge origin/master --quiet -m "Auto Merge"
git fetch
git merge origin/master -m "Auto Merge"
# Get new version hash
GIT_NEW_REVISION=$(getCurrentVersion)
@ -33,7 +29,7 @@ GIT_NEW_REVISION=$(getCurrentVersion)
if [ $GIT_REVISION != $GIT_NEW_REVISION ]
then
# Version has changed we need to update
test -n "$VERBOSE" && echo "Reload fastd peers"
echo "Reload fastd peers"
kill -HUP $(pidof fastd)
fi

View file

@ -1,8 +1,7 @@
#!/bin/bash
INTERFACE=mullvad # Set to name of VPN interface
INTERFACE=mullvad
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
@ -11,41 +10,13 @@ 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"
# Check whether gateway modus has been deactivated
if [ "$NEW_STATE" == "off" ]; then
# Shutdown DHCP server to prevent renewal of leases
/usr/sbin/service isc-dhcp-server stop
fi
# Check whether gateway modus has been activated
if [ "$NEW_STATE" == "server" ]; then
# Restart DHCP server
/usr/sbin/service isc-dhcp-server start
fi
exit 0
done
if [ "$NEW_STATE" == "server" ]; then
/usr/sbin/service isc-dhcp-server status 2>&1> /dev/null
if [[ $? -ne 0 ]]
then
/usr/sbin/service isc-dhcp-server restart
fi
fi
if [ "$NEW_STATE" == "off" ]; then
/usr/sbin/service isc-dhcp-server status 2>&1> /dev/null
if [[ $? -eq 0 ]]
then
/usr/sbin/service isc-dhcp-server stop
fi
fi
# vim: noai:ts=4:sw=4:ff=unix:ft=text:fdm=marker

View file

@ -1,192 +0,0 @@
#!/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,34 +1,10 @@
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($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::software': }
->
class { 'ff_gw::fastd':
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,
}
->
@ -43,22 +19,15 @@ class ff_gw(
}
->
class { 'ff_gw::vpn':
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,
@ -98,12 +67,8 @@ class ff_gw::software {
}
}
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) {
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':
@ -126,60 +91,45 @@ class ff_gw::fastd($mesh_mac, $gw_ipv4, $gw_ipv4_netmask, $gw_ipv6, $gw_ipv6_pre
ensure => file,
mode => '0755',
source => 'puppet:///modules/ff_gw/usr/local/bin/check_gateway';
}
->
# 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'",
];
'/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
');
}
->
vcsrepo { '/etc/fastd/ffhh-mesh-vpn/peers':
ensure => present,
provider => git,
source => 'git@git.hamburg.freifunk.net:fastdkeys',
source => 'git@freifunk-gw01.hamburg.ccc.de:fastdkeys',
}
cron {
@ -272,11 +222,7 @@ class ff_gw::dhcpd($gw_ipv4, $dhcprange_start, $dhcprange_end) {
'/etc/rsyslog.d/dhcpd.conf':
ensure => file,
notify => Service['rsyslog'],
content => '# managed by puppet
# log DHCP warnings
local7.warn /var/log/dhcpd.log
# but do not log DHCP leases etc.
local7.* ~';
content => 'local7.warn /var/log/dhcpd.log';
'/etc/default/isc-dhcpd':
ensure => file,
content => '# managed by puppet
@ -361,19 +307,6 @@ 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':
@ -396,9 +329,7 @@ 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.ipv4.icmp_errors_use_inbound_ifaddr 1',
'set net.ipv4.netfilter.ip_conntrack_max 65536'
'set net.ipv6.conf.all.forwarding 1'
],
}
~>
@ -410,32 +341,10 @@ class ff_gw::radvd($own_ipv6) {
}
}
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;
}
}
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'
package {
'openvpn':
@ -443,22 +352,29 @@ class ff_gw::vpn($provider, $ca_crt, $usr_crt, $usr_key, $usr_name, $usr_pass, $
}
->
file {
"/etc/openvpn/${provider}":
"/etc/openvpn/${vpnname}":
ensure => directory;
"/etc/openvpn/${provider}/ca.crt":
"/etc/openvpn/${vpnname}/ca.crt":
ensure => file,
content => $ca_crt;
"/etc/openvpn/${provider}/${provider}-up":
"/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',
source => "puppet:///modules/ff_gw/etc/openvpn/${provider}/${provider}-up";
"/etc/openvpn/${provider}.conf":
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":
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';
source => "puppet:///modules/ff_gw/etc/openvpn/${vpnname}.conf";
}
~>
service { 'openvpn':
@ -483,12 +399,9 @@ 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
content => '#!/bin/sh -e
# managed by puppet
#
# rc.local
@ -504,9 +417,6 @@ 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';
}
~>
@ -517,7 +427,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.4-1~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 = 'present') {
# read peering data from data file
$module_path = get_module_path($module_name)
$peeringdata = loadyaml("${module_path}/data/peering.yaml")
@ -526,43 +436,14 @@ 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 {
'bird':
ensure => $version,
}
->
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';
}
~>
service {
'bird':
ensure => running,
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,
@ -576,17 +457,30 @@ class ff_gw::bird($ff_net, $ff_mesh_net, $ff_as, $own_ipv4, $own_ipv6, $gw_do_ic
require => Service['openvpn'],
}
package {
'bird':
ensure => $version,
}
->
file {
'/etc/bird/bird.conf':
ensure => file,
content => template('ff_gw/etc/bird/bird.conf.erb');
'/etc/bird.conf':
ensure => link,
target => '/etc/bird/bird.conf';
}
~>
service {
'bird':
ensure => running,
enable => true,
require => Service['openvpn'],
}
}
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)
class ff_gw::tinc($tinc_name, $tinc_keyfile = '/etc/tinc/rsa_key.priv', $ic_vpn_ip4, $ic_vpn_ip6, $version = 'present') {
package {
'tinc':
ensure => $version,

View file

@ -1,5 +1,6 @@
# 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
@ -10,105 +11,7 @@ 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
}
@ -136,18 +39,166 @@ class ff_gw::sysadmin::software() {
# then install some basic packages
package {
['vim-nox', 'git', 'etckeeper', 'pv', 'curl', 'atop',
'screen', 'tcpdump', 'rsync', 'file', 'psmisc', 'ntpdate']:
'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' ]:
ensure => installed,
}
->
# remove atop cronjob
file { '/etc/cron.d/atop':
ensure => absent,
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';
}
->
# stop atop daemon (cf. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506191)
service { 'atop':
ensure => stopped,
enable => false,
~>
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,
}
}

View file

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

@ -1,28 +0,0 @@
# 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 none;
import where is_chaos();
export filter {
krt_prefsrc = <%= @own_ipv4 %>;
accept;
@ -158,6 +158,16 @@ 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 -%>
@ -166,25 +176,12 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
};
<% end -%><% end -%>
<% if @gw_do_ic_peering -%>
### icvpn peerings ###
# 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;
};
<% 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";

View file

@ -1,163 +1,63 @@
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.
# managed by puppet
#
# the ff ip of the gateway
router id <%= @own_ipv4 %>;
### functions ###
# routing tables
table ffhh;
# 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
# filter to check ulas
function is_ula() {
return net ~ [ fc00::/7{48,64} ];
return (net ~ [ fc00::/7{48,64} ]);
}
# default route
# be careful with importing default routes from arbitrary peers
function is_default() {
return net ~ [ ::0/0 ];
function is_self() {
return (proto = "static_ffhh");
}
### kernel ###
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;
}
# 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;
# 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
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
# This pseudo-protocol watches all interface up/down events.
protocol device {
scan time 20;
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;
};
### pipes ###
protocol static local_ffhh {
table ffhh;
route fd51:2bb2:fd0d::/64 via "br-ffhh";
};
# 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();
protocol pipe pipe_ffhh {
peer table ffhh;
import all;
export none;
};
# 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 for internal routing
template bgp locals {
table ibgp;
local as ownas;
table ffhh;
local as 65112;
source address <%= @own_ipv6 %>;
import filter {
preference = 99;
accept;
};
import all;
export where source = RTS_BGP;
direct;
next hop self;
@ -170,22 +70,13 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
<% end -%><% end -%>
<% if @gw_do_ic_peering -%>
# template for icvpn gateways of other cities
# icvpn template for hamburg03
template bgp peers {
table ebgp;
local as ownas;
local as 65112;
source address <%= @ic_vpn_ip6 %>;
# 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();
table ffhh;
import where is_ula();
export where is_self() || (source = RTS_BGP);
};
<% @ic_peerings_v6.each_pair do |key, hash| -%><% if hash["ip"] != @own_ipv6 -%>
@ -194,6 +85,3 @@ protocol bgp <%= key %> from <%= hash["template"] %> {
};
<% end -%><% end -%>
<% end -%>
# this is for local peerings not managed by puppet
include "*.peering6";

View file

@ -16,10 +16,9 @@ subnet 10.112.0.0 netmask 255.255.192.0 {
authoritative;
range <%= @dhcprange_start %> <%= @dhcprange_end %>;
# DNS: this gateway (<%= @gw_ipv4 %>) & srv01 (10.112.1.1)
option domain-name-servers <%= @gw_ipv4 %>, 10.112.1.1;
# DNS: srv01 (10.112.1.1) & gw01 (10.112.14.1)
option domain-name-servers 10.112.1.1, 10.112.14.1;
option routers <%= @gw_ipv4 %>;
option ntp-servers 10.112.16.1, 10.112.22.1;
}
include "/etc/dhcp/static.conf";

View file

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

View file

@ -15,25 +15,22 @@ 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 = kiel2
ConnectTo = kiel13
ConnectTo = kiel3
ConnectTo = kiel4
ConnectTo = koeln1
@ -42,15 +39,10 @@ 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 = wiesbaden1
ConnectTo = wermelskirchen1