├── .ansible-lint
├── .gitignore
├── .gitmodules
├── README.md
├── ansible.cfg
├── behave
├── README.md
├── steps
│ └── steps_webserver.py
└── webserver.feature
├── filter_plugins
├── derive_mac_addr.py
├── remove_filter.py
└── resolve_filter.py
├── group_vars
├── all.yml
├── dnsserver.yml
├── eventsserver.yml
└── webserver.yml
├── hosts
├── lib
├── hosts.py
├── slpp.py
└── tests
│ ├── hosts.json
│ ├── site.conf
│ └── tests.py
├── library
└── fastd_key
├── playbooks
├── backbone.yml
├── dnsserver.yml
├── downlinks.yml
├── eventsserver.yml
├── ffmapserver.yml
├── standardserver.yml
├── vpnserver.yml
└── webserver.yml
├── requirements.txt
├── roles
├── apache
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── anon-logs.conf
│ │ ├── default-dir-options.conf
│ │ ├── deflate-more-types.conf
│ │ ├── logrotate-apache2-user
│ │ ├── ocsp-stapling.conf
│ │ ├── proxy.conf
│ │ └── user-php-exec.conf
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── 000-default.conf
├── apt
│ ├── README.md
│ ├── files
│ │ ├── apt-periodic.conf
│ │ ├── apt-recommends.conf
│ │ └── unattended-upgrades-dpkg.conf
│ └── tasks
│ │ └── main.yml
├── automysqlbackup
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── backbone-gre
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── firewall.sh
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ └── interfaces
│ └── vars
│ │ └── main.yml
├── batman-adv-14
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── dkms-batman-adv-downgrade
│ └── tasks
│ │ └── main.yml
├── batman-adv-interface
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── if-pre-up
│ │ └── if-pre-up-legacy
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── interfaces
├── batman-adv
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── caddy
│ ├── README.md
│ ├── files
│ │ └── caddy.service.patch
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── Caddyfile
│ │ └── hostname.caddy
├── chrony
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── chrony.conf
│ │ └── firewall.sh
├── dnsmasq
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── dnsmasq-hook.sh
│ │ ├── dnsmasq-tmpfs.service
│ │ └── dnsmasq-tmpfs.timer
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── dnsmasq.conf
│ │ └── firewall.sh
├── downlink-firewall
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── ipv6-neigh-cache-negative.service
│ │ └── ipv6-neigh-cache-negative.sh
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── downloadsite
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── htaccess
│ │ └── rsync.service
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ └── rsyncd.conf
├── etckeeper-post
│ └── tasks
│ │ └── main.yml
├── etckeeper-pre
│ └── tasks
│ │ └── main.yml
├── etckeeper
│ ├── README.md
│ ├── files
│ │ └── git-config
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── eventswebsite
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── index.html
├── exit-ipv4
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── 10-allow-gre
│ │ └── 10-allow-ipip
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ ├── default.yml
│ │ ├── generic.yml
│ │ └── main.yml
│ └── templates
│ │ ├── default
│ │ ├── 10-tcpmss-ipv4
│ │ ├── 20-exit-ipv4
│ │ └── up.sh
│ │ └── generic
│ │ └── interface
├── exit-ipv6
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── bird-radv.conf
│ │ └── firewall.sh
│ └── vars
│ │ └── main.yml
├── fail2ban
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── fastd
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ ├── blacklist.yml
│ │ ├── instance.yml
│ │ └── main.yml
│ └── templates
│ │ ├── fastd.conf
│ │ ├── firewall.sh
│ │ ├── interfaces
│ │ ├── peer.conf
│ │ ├── update-fastd-blacklist@.service
│ │ └── update-fastd-blacklist@.timer
├── firewall
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── 00-base
│ │ ├── 90-established
│ │ ├── 99-reject
│ │ ├── firewall.service
│ │ └── ipv4-netfilter-ip-conntrack-max.conf
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ ├── included.yml
│ │ └── main.yml
│ └── templates
│ │ └── init.sh
├── freifunkmanager
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── caddy
│ │ ├── config.toml
│ │ └── freifunkmanager.service
├── gatemon
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ └── php-fcgi-starter
├── git
│ └── tasks
│ │ └── main.yml
├── go
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── go.sh
├── grafana
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── Short.json
│ │ └── json
│ │ │ ├── global.json
│ │ │ └── node.json
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ ├── caddy
│ │ └── grafana.ini
├── group-webusers
│ └── tasks
│ │ └── main.yml
├── influxdb
│ ├── files
│ │ └── firewall.sh
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── influxdb.conf
├── letsencrypt
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── acme-challenge.conf
│ │ ├── config
│ │ ├── cronjob
│ │ └── hook.sh
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── main-bridge
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── bridge-filter.conf
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── interfaces
│ │ └── main-bridge-ip-neigh-tuning.conf
├── mesh-announce
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── cronjob
│ │ ├── firewall.sh
│ │ └── service
├── meshviewer
│ ├── defaults
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ ├── apache.yml
│ │ ├── geojson.yml
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ ├── geojson-update.sh
│ │ └── geojson.cronjob
├── monitoring-client
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── 98mk-apt
│ │ ├── authorized_keys
│ │ └── plugins
│ │ │ ├── check_conntrack.sh
│ │ │ ├── check_git_status
│ │ │ ├── check_release_eol
│ │ │ └── check_rkhunter
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── motd
│ ├── files
│ │ ├── add-motd-tail
│ │ ├── figlet
│ │ └── remove-motd-dynamic
│ └── tasks
│ │ └── main.yml
├── mysql-server
│ ├── README.md
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── nginx
│ ├── files
│ │ └── firewall.sh
│ └── tasks
│ │ └── main.yml
├── nodejs
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── nodemon
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ └── php-fcgi-starter
├── non_persistent_logging
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── nsd
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── cronjob
│ │ ├── firewall.sh
│ │ ├── update-dns-zones.sh
│ │ └── zonegen.py
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── nsd.conf
├── nullmailer
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ └── remotes
├── openssh
│ ├── README.md
│ ├── files
│ │ └── firewall.sh
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── php
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── restic
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── backup-restic
│ │ └── backup-restic.default
│ └── tasks
│ │ └── main.yml
├── rkhunter
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── router-bird
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ │ ├── bird.conf
│ │ ├── bird6.conf
│ │ ├── firewall.sh
│ │ ├── internal_ipv4.conf
│ │ └── internal_ipv6.conf
│ └── vars
│ │ └── main.yml
├── ruby
│ └── tasks
│ │ └── main.yml
├── speedtest
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── nginx.conf
│ └── tasks
│ │ └── main.yml
├── sudo
│ ├── README.md
│ ├── meta
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── system
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── autologin.conf
│ │ └── sysctl.d
│ │ │ ├── dmesg-restrict.conf
│ │ │ ├── fs-file-max.conf
│ │ │ ├── ipv4-arp-ignore.conf
│ │ │ ├── ipv4-forwarding.conf
│ │ │ ├── ipv4-icmp-errors-use-inbound-ifaddr.conf
│ │ │ ├── ipv4-ignore-icmp-bogus-error-responses.conf
│ │ │ ├── ipv4-ignore-icmp-broadcast.conf
│ │ │ ├── ipv4-tcp-abort-on-overflow.conf
│ │ │ ├── ipv4-tcp-fin-timeout.conf
│ │ │ ├── ipv4-tcp-syn-retries.conf
│ │ │ ├── ipv4-tcp-synack-retries.conf
│ │ │ ├── ipv4-tcp-syncookies.conf
│ │ │ ├── ipv6-forwarding.conf
│ │ │ ├── kernel-core-uses-pid.conf
│ │ │ ├── kernel-panic.conf
│ │ │ ├── kernel-pid-max.conf
│ │ │ ├── kernel-shm.conf
│ │ │ ├── kernel-sysrq.conf
│ │ │ ├── no-ipv4-redirects.conf
│ │ │ ├── no-ipv4-rp-filter.conf
│ │ │ ├── no-ipv6.conf
│ │ │ ├── vm-min-free-kbytes.conf
│ │ │ ├── vm-overcommit.conf
│ │ │ └── vm-swappiness.conf
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ ├── main.yml
│ │ └── vm.yml
│ └── templates
│ │ └── grub-serial.cfg
├── tasksite
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── htaccess
│ │ └── run-log
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache-tasks.conf
│ │ ├── ffhb.conf.php
│ │ ├── phabricator-daemon-file
│ │ ├── phabricator.service
│ │ ├── php-extopts.ini
│ │ └── php-fcgi-starter
├── tiles
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ └── OpenSans
│ │ │ ├── Apache License.txt
│ │ │ ├── OpenSans-Bold.ttf
│ │ │ ├── OpenSans-Italic.ttf
│ │ │ ├── OpenSans-Light.ttf
│ │ │ ├── OpenSans-LightItalic.ttf
│ │ │ ├── OpenSans-Regular.ttf
│ │ │ └── OpenSans-Semibold.ttf
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ └── tessera.service
├── tmpfs
│ ├── README.md
│ └── tasks
│ │ └── main.yml
├── tools
│ ├── README.md
│ └── tasks
│ │ └── main.yml
├── unbound
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── firewall.sh
│ │ ├── unbound-ip-up.d
│ │ └── unbound.conf.d
│ │ │ ├── caching-timeouts.conf
│ │ │ ├── caching-tweaking.conf
│ │ │ ├── disable-dnssec.conf
│ │ │ ├── edns-buffer-size.conf
│ │ │ ├── harden-glue.conf
│ │ │ ├── hide-version.conf
│ │ │ ├── jostle-timeout.conf
│ │ │ ├── minimal-responses.conf
│ │ │ ├── no-logging.conf
│ │ │ ├── number-of-threads.conf
│ │ │ └── root-hints.conf
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── access-control.conf
│ │ ├── listen-on-all-interfaces.conf
│ │ └── remote-control.conf
├── website
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── config.json
│ │ └── htaccess
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ ├── php-fcgi-starter
│ │ ├── update-jekyll.sh
│ │ └── webhook.php
├── wiki
│ ├── README.md
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ │ ├── favicon.ico
│ │ ├── gitconfig
│ │ └── robots.txt
│ ├── meta
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ │ ├── apache2.conf
│ │ ├── gollum.service
│ │ └── htaccess
└── yanic
│ ├── defaults
│ └── main.yml
│ ├── handlers
│ └── main.yml
│ ├── meta
│ └── main.yml
│ ├── tasks
│ └── main.yml
│ └── templates
│ ├── config.toml
│ ├── yanic-publish-ssh-master.service
│ ├── yanic-publish.service
│ ├── yanic-publish.timer
│ └── yanic.service
├── scripts
├── open.sh
└── resign.sh
├── vagrant
├── .gitignore
└── Vagrantfile
└── vault_passphrase.gpg
/.ansible-lint:
--------------------------------------------------------------------------------
1 | skip_list:
2 | - metadata
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.orig
3 | *.retry
4 | playbooks/credentials/
5 | host_vars/*
6 | !host_vars/*.gpg
7 | # build products...
8 | *.py[co]
9 | .vault_password
10 | /pythonenv/
11 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "site"]
2 | path = site
3 | url = https://github.com/FreifunkBremen/gluon-site-ffhb.git
4 |
--------------------------------------------------------------------------------
/ansible.cfg:
--------------------------------------------------------------------------------
1 | [defaults]
2 |
3 | inventory = ./hosts
4 | roles_path = ./roles
5 | filter_plugins = ./filter_plugins
6 | library = ./library
7 | remote_user = root
8 | nocows = 1
9 | gathering = smart
10 | ansible_managed = Ansible managed
11 | vault_password_file = ./scripts/open.sh
12 |
13 | [ssh_connection]
14 | pipelining = true
15 |
--------------------------------------------------------------------------------
/behave/README.md:
--------------------------------------------------------------------------------
1 | Webserver Tests With Python Behave
2 | ==================================
3 |
4 | Installation
5 | ------------
6 | * virtualenv env
7 | * source env/bin/activate
8 | * pip install behave mechanize
9 |
10 |
11 | Running
12 | -------
13 | * source env/bin/activate
14 | * behave
15 |
--------------------------------------------------------------------------------
/behave/steps/steps_webserver.py:
--------------------------------------------------------------------------------
1 |
2 | from behave import *
3 | import mechanize
4 | import re
5 |
6 | def escape_special_chars(s):
7 | return re.sub(r"([^a-zA-Z0-9_-])", lambda m: "\\%02X" % ord(m.group(1)), s)
8 |
9 | @when(u"I access {url} as {user}/{password}")
10 | def step_impl(context, url, user, password):
11 | br = mechanize.Browser()
12 | br.add_password(url, user, password)
13 | step_impl_download(context, url, br)
14 |
15 | @when(u"I access {url}")
16 | def step_impl_download(context, url, br=None):
17 | if br is None:
18 | br = mechanize.Browser()
19 | br.set_handle_robots(False)
20 | try:
21 | fp = br.open(url)
22 | except Exception, e:
23 | fp = e
24 |
25 | context.http_status_code = fp.code
26 | context.current_url = br.geturl()
27 | context.page_source = fp.read().decode("utf-8")
28 |
29 | @then(u'the page will contain "{text}"')
30 | @then(u"the page will contain '{text}'")
31 | def step_impl(context, text):
32 | print(context.page_source)
33 | assert context.page_source.find(text) >= 0, "page source (%d bytes) didn't contain text '%s'" % (len(context.page_source), text)
34 |
35 | @then(u'the page content will be "{text}"')
36 | @then(u'the page content will be \'{text}\'')
37 | def step_impl(context, text):
38 | text = text.replace("\\n", "\n")
39 | print("expected: " + escape_special_chars(text))
40 | print("received: " + escape_special_chars(context.page_source))
41 | assert context.page_source == text, "page source (%d bytes) was not '%s'" % (len(context.page_source), text)
42 |
43 | @then(u'the status code will be {http_status_code}')
44 | def step_impl(context, http_status_code):
45 | assert context.http_status_code == int(http_status_code), "HTTP code is '%d' but should be '%s'" % (context.http_status_code, http_status_code)
46 |
47 | @then(u'the page URL will be "{url}"')
48 | def step_impl(context, url):
49 | assert context.current_url == url, "current URL is '%s' but should be '%s'" % (context.current_url, url)
50 |
--------------------------------------------------------------------------------
/filter_plugins/derive_mac_addr.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | def ntuples(lst, n):
4 | return zip(*[lst[i::n] for i in range(n)])
5 |
6 | class FilterModule(object):
7 | def filters(self):
8 | return {
9 | "derive_mac_addr": self.derive_mac_addr
10 | }
11 |
12 | def derive_mac_addr(self, original, offset):
13 | if not re.match('^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}|([0-9a-fA-F]{4}\.){2}[0-9a-fA-F]{4})$', original):
14 | raise Exception("Not a MAC address: %s" % original)
15 |
16 | splitbytes = [int("".join(x), 16) for x in ntuples(re.sub('[^0-9a-fA-F]', '', original), 2)]
17 | splitbytes[0] |= 2
18 | splitbytes[-1] += offset
19 | return ':'.join('%02x' % x for x in splitbytes)
20 |
21 | if __name__ == '__main__':
22 | instance = FilterModule()
23 | for orig in ('00:00:00:00:00:00', '02:00:00:00:00:00', '0000.0000.0000'):
24 | derived = instance.derive_mac_addr(orig, 2)
25 | assert derived == '02:00:00:00:00:02', derived
26 |
--------------------------------------------------------------------------------
/filter_plugins/remove_filter.py:
--------------------------------------------------------------------------------
1 | # removes an element from a list
2 | class FilterModule (object):
3 | def filters(self):
4 | return {
5 | "remove": self.remove,
6 | }
7 |
8 | def remove(self, l, e):
9 | if e in l:
10 | l.remove(e)
11 | return l
12 |
--------------------------------------------------------------------------------
/filter_plugins/resolve_filter.py:
--------------------------------------------------------------------------------
1 | # Install dependencies:
2 | # apt-get install python-dnspython
3 | import dns.resolver
4 |
5 | class FilterModule (object):
6 | def filters(self):
7 | return {
8 | "resolve": self.resolve,
9 | }
10 |
11 | def resolve(self, hostname, rrtype):
12 | answers = dns.resolver.query(hostname, rrtype)
13 | for data in answers:
14 | return data.address
15 |
16 | raise errors.AnsibleFilterError('unable to get %s record for: %s' % (rrtype, hostname))
17 |
--------------------------------------------------------------------------------
/group_vars/all.yml:
--------------------------------------------------------------------------------
1 | ---
2 | pgp_keyserver: 'pool.sks-keyservers.net'
3 | site_git_root: 'https://github.com/FreifunkBremen'
4 | site_city: 'bremen'
5 | site_domain: 'bremen.freifunk.net'
6 | site_vpn_prefix: 'vpn'
7 | icvpn_as: 65196
8 | fastd_peers_limit: 200
9 |
--------------------------------------------------------------------------------
/group_vars/dnsserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dns_domain_freifunk_net: bremen.freifunk.net
3 |
--------------------------------------------------------------------------------
/group_vars/eventsserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | main_domain: events.bremen.freifunk.net
3 | alt_domain: events.ffhb.de
4 |
5 | respondd_vpn: false
6 | caddy_email: "geno+ffhb@fireorbit.de"
7 |
8 | meshviewer_domain: '{{ main_domain }}'
9 | meshviewer_git_root: https://github.com/FreifunkBremen/meshviewer-ffrgb.git
10 | meshviewer_git_version: ffhb-events-config
11 | meshviewer_email: info@bremen.freifunk.net
12 | meshviewer_apache: false
13 | meshviewer_geojson: true
14 |
15 | yanic_nodes_state_path: /var/www/html/data/nodes.json
16 | yanic_meshviewer_path: /var/www/html/data
17 | yanic_meshviewer_nodes: /var/www/html/data/nodes_v2.json
18 | yanic_socket:
19 | - enable: true
20 | type: unix
21 | address: "/tmp/yanic-database.socket"
22 |
23 | influxdb_username: yanic
24 | influxdb_database: yanic
25 | influxdb_password: "{{ lookup('password', 'credentials/influx_yanic length=15') }}"
26 |
27 | yanic_influxdb:
28 | - enable: true
29 | host: http://localhost:8086
30 | database: "{{ influxdb_database }}"
31 | username: "{{ influxdb_username }}"
32 | password: "{{ influxdb_password }}"
33 |
34 | influxdb_admin_user: admin
35 | influxdb_admin_password: "{{ lookup('password', 'credentials/influx_admin length=15') }}"
36 | influxdb_users:
37 | - user: "{{ influxdb_username }}"
38 | pass: "{{ influxdb_password }}"
39 | - user: public
40 | pass: public
41 | influxdb_databases:
42 | - "{{ influxdb_database }}"
43 | influxdb_access:
44 | - user: "{{ influxdb_username }}"
45 | database: "{{ influxdb_database }}"
46 | access: ALL
47 | - user: public
48 | database: "{{ influxdb_database }}"
49 | access: READ
50 |
51 | grafana_caddy: true
52 | grafana_location: /grafana
53 | grafana_domain: "{{ main_domain }}"
54 | grafana_port: 8081
55 |
56 | freifunkmanager_domain: mgmt.ffhb.de
57 | freifunkmanager_email: "{{caddy_email}}"
58 | freifunkmanager_yanic_address: "/tmp/yanic-database.socket"
59 |
--------------------------------------------------------------------------------
/lib/tests/site.conf:
--------------------------------------------------------------------------------
1 | {
2 | site_name = 'Freifunk Bremen',
3 | site_code = 'ffhb',
4 |
5 | prefix4 = '10.196.0.0/16',
6 | prefix6 = 'fd2f:5119:f2c::/64'
7 | }
8 |
--------------------------------------------------------------------------------
/lib/tests/tests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python2
2 | #
3 | # Requirements:
4 | # apt-get install python-unittest2
5 | #
6 | # Run with:
7 | # unit2 discover
8 | #
9 |
10 | from sys import path
11 | path.append("..")
12 |
13 | import unittest2
14 | import json
15 | import hosts
16 |
17 | class TestHosts(unittest2.TestCase):
18 |
19 | def test_starttls_true(self):
20 |
21 | inv = hosts.Inventory('site.conf',
22 | ipv6_global_network = "2a06:8782:ffbb:1337::/64",
23 | ipv6_uplink_network = "2a06:8782:ffbb::/64",
24 | )
25 |
26 | grp = inv.group("vpnservers",
27 | dhcp=True,
28 | batman_gateway=True,
29 | )
30 | grp.host(1, "vpn01.bremen.freifunk.net", exit="gre", ansible_ssh_port=60023)
31 |
32 | grp = inv.group("services")
33 | grp.host(10, "service.example.com")
34 |
35 | with open('hosts.json') as data_file:
36 | data = json.load(data_file)
37 |
38 | # print inv.json_dump(indent=4)
39 |
40 | self.assertEqual(data, inv.data())
41 |
--------------------------------------------------------------------------------
/library/fastd_key:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | EXAMPLES = '''
4 | # Generates a fastd key
5 | - fastd_key: path=/etc/fastd/site/secret.conf
6 | '''
7 |
8 | from ansible.module_utils.basic import *
9 | import os
10 |
11 | if __name__ == '__main__':
12 | module = AnsibleModule(
13 | argument_spec={
14 | 'path': {'required': True, 'type': 'str'},
15 | }
16 | )
17 |
18 | path = module.params['path']
19 | changed = False
20 |
21 | # file does not exist or is empty?
22 | if not os.path.isfile(path) or os.stat(path).st_size == 0:
23 | # create file with restrictive permissions
24 | with os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, 0o600), 'w') as handle:
25 | # generate fastd secret
26 | secret = subprocess.check_output(["fastd", "--machine-readable", "--generate-key"]).strip()
27 | handle.write('secret "{}";\n'.format(secret.decode()))
28 |
29 | changed = True
30 |
31 | module.exit_json(changed=changed)
32 |
--------------------------------------------------------------------------------
/playbooks/backbone.yml:
--------------------------------------------------------------------------------
1 | # Konfiguriert Batman und GRE-Tunnel für das Backbone
2 | ---
3 | - hosts: backbone:backbone_legacy
4 | roles:
5 | - backbone-gre
6 |
--------------------------------------------------------------------------------
/playbooks/dnsserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: dnsserver
3 | roles:
4 | - { role: etckeeper-pre, tags: [etckeeper-pre] }
5 | - { role: nsd, tags: [nsd] }
6 | - { role: etckeeper-post, tags: [etckeeper-post] }
7 |
--------------------------------------------------------------------------------
/playbooks/downlinks.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: downlinks
3 | vars:
4 | batman_gateway: true
5 | roles:
6 | - { role: etckeeper-pre, tags: [etckeeper-pre, always] }
7 | - { role: openssh, tags: [openssh] }
8 | - { role: non_persistent_logging, tags: [non_persistent_logging] }
9 | - { role: downlink-firewall, tags: [downlink-firewall] }
10 | - { role: batman-adv-14, tags: [batman-adv-14], when: ('backbone_legacy' in group_names) or ('downlinks_legacy' in group_names) or ('vpnservers_legacy' in group_names) }
11 | - { role: batman-adv, tags: [batman-adv], when: ('backbone_legacy' not in group_names) and ('downlinks_legacy' not in group_names) and ('vpnservers_legacy' not in group_names) }
12 | - { role: batman-adv-interface, tags: [batman-adv-interface] }
13 | - { role: main-bridge, tags: [main-bridge] }
14 | - { role: chrony, tags: [chrony] }
15 | - { role: etckeeper-post, tags: [etckeeper-post, always] }
16 |
--------------------------------------------------------------------------------
/playbooks/eventsserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: eventsserver
3 | roles:
4 | - { role: etckeeper-pre, tags: [etckeeper-pre] }
5 | - { role: apt, tags: [apt] }
6 | - { role: openssh, tags: [openssh] }
7 | - { role: system, tags: [system] }
8 | - { role: tmpfs, tags: [tmpfs] }
9 | - { role: tools, tags: [tools] }
10 | - { role: motd, tags: [motd] }
11 | - { role: mesh-announce, tags: [mesh-announce] }
12 | - { role: caddy, tags: [caddy] }
13 | - { role: eventswebsite, tags: [eventswebsite] }
14 | - { role: meshviewer, tags: [meshviewer] }
15 | - { role: influxdb, tags: [influxdb] }
16 | - { role: yanic, tags: [yanic] }
17 | - { role: grafana, tags: [grafana] }
18 | - { role: freifunkmanager, tags: [freifunkmanager] }
19 | - { role: etckeeper-post, tags: [etckeeper-post] }
20 |
--------------------------------------------------------------------------------
/playbooks/ffmapserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: ffmapserver
3 | vars:
4 | yanic_publisher: true
5 | yanic_respondd_interface: "bat0"
6 | yanic_webserver: false
7 | yanic_nodes_save_interval: "15s"
8 | yanic_nodes_state_path: /opt/yanic/nodes_state.json
9 | yanic_meshviewer_path: /opt/yanic
10 | yanic_meshviewer_nodes: /opt/yanic/nodes_v2.json
11 | yanic_influxdb:
12 | - enable: "true"
13 | host: http://webserver.bremen.freifunk.net:8086
14 | database: "ffhb-nodes"
15 | username: "ffhb-respondd-collector"
16 | password: ""
17 | roles:
18 | - { role: etckeeper-pre, tags: [etckeeper-pre] }
19 | - { role: yanic, tags: [yanic] }
20 | - { role: etckeeper-post, tags: [etckeeper-post] }
21 |
--------------------------------------------------------------------------------
/playbooks/standardserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: standardserver
3 | roles:
4 | - { role: etckeeper-pre, tags: [etckeeper-pre, always] }
5 | - { role: apt, tags: [apt] }
6 | - { role: nullmailer, tags: [nullmailer] }
7 | - { role: openssh, tags: [openssh] }
8 | - { role: fail2ban, tags: [fail2ban] }
9 | - { role: system, tags: [system] }
10 | - { role: tmpfs, tags: [tmpfs] }
11 | - { role: tools, tags: [tools] }
12 | - { role: motd, tags: [motd] }
13 | - { role: rkhunter, tags: [rkhunter] }
14 | - { role: etckeeper, tags: [etckeeper] }
15 | - { role: monitoring-client, tags: [monitoring-client] }
16 | - { role: etckeeper-post, tags: [etckeeper-post, always] }
17 |
--------------------------------------------------------------------------------
/playbooks/vpnserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: vpnservers:vpnservers_legacy
3 | vars:
4 | batman_gateway: true
5 | roles:
6 | - { role: etckeeper-pre, tags: [etckeeper-pre, always] }
7 | - { role: tmpfs, tags: [tmpfs] }
8 | - { role: openssh, tags: [openssh] }
9 | - { role: non_persistent_logging, tags: [non_persistent_logging] }
10 | - { role: batman-adv-14, tags: [batman-adv-14], when: ('backbone_legacy' in group_names) or ('downlinks_legacy' in group_names) or ('vpnservers_legacy' in group_names) }
11 | - { role: batman-adv, tags: [batman-adv], when: ('backbone_legacy' not in group_names) and ('downlinks_legacy' not in group_names) and ('vpnservers_legacy' not in group_names) }
12 | - { role: batman-adv-interface, tags: [batman-adv-interface] }
13 | - { role: main-bridge, tags: [main-bridge] }
14 | - { role: fastd, tags: [fastd] }
15 | - { role: mesh-announce, tags: [mesh-announce] }
16 | - { role: exit-ipv4, tags: [exit-ipv4] }
17 | - { role: exit-ipv6, tags: [exit-ipv6] }
18 | - { role: chrony, tags: [chrony] }
19 | - { role: unbound, tags: [unbound] }
20 | - { role: dnsmasq, tags: [dnsmasq] }
21 | - { role: nginx, tags: [nginx] }
22 | - { role: speedtest, tags: [speedtest] }
23 | - { role: etckeeper-post, tags: [etckeeper-post, always] }
24 |
--------------------------------------------------------------------------------
/playbooks/webserver.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: webserver
3 | vars:
4 | main_domain: bremen.freifunk.net
5 | alt_domain: ffhb.de
6 | roles:
7 | - { role: etckeeper-pre, tags: [etckeeper-pre] }
8 | - { role: chrony, tags: [chrony] }
9 | - { role: letsencrypt, tags: [letsencrypt] }
10 | - { role: apache, tags: [apache] }
11 | - { role: gatemon, tags: [gatemon] }
12 | - { role: nodemon, tags: [nodemon] }
13 | - { role: website, tags: [website] }
14 | - { role: downloadsite, tags: [downloadsite] }
15 | - { role: wiki, tags: [wiki] }
16 | - { role: tiles, tags: [tiles] }
17 | - { role: influxdb, tags: [influxdb] }
18 | - { role: grafana, tags: [grafana] }
19 | - { role: meshviewer, tags: [meshviewer] }
20 | - { role: restic, tags: [restic] }
21 | - { role: tasksite, tags: [tasksite] }
22 | - { role: etckeeper-post, tags: [etckeeper-post] }
23 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | ansible==4.7.0
2 | ansible-core==2.11.6
3 | cffi==1.15.0
4 | cryptography==35.0.0
5 | dnspython==2.1.0
6 | Jinja2==3.0.2
7 | MarkupSafe==2.0.1
8 | netaddr==0.8.0
9 | packaging==21.0
10 | pycparser==2.20
11 | pyparsing==2.4.7
12 | PyYAML==6.0
13 | resolvelib==0.5.4
14 | six==1.16.0
15 |
--------------------------------------------------------------------------------
/roles/apache/README.md:
--------------------------------------------------------------------------------
1 | apache
2 | =========================
3 |
4 | Installs Apache webserver
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - apache
13 |
14 | License
15 | -------------------------
16 |
17 | GPLv3
18 |
--------------------------------------------------------------------------------
/roles/apache/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apache_redirect_target: 'bremen.freifunk.net'
3 | apache_ssl_host: 'bremen.freifunk.net'
4 |
--------------------------------------------------------------------------------
/roles/apache/files/anon-logs.conf:
--------------------------------------------------------------------------------
1 | LogFormat "%v:%p 127.0.0.1 - - %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
2 | LogFormat "127.0.0.1 - - %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
3 | LogFormat "127.0.0.1 - - %t \"%r\" %>s %O" common
4 |
--------------------------------------------------------------------------------
/roles/apache/files/default-dir-options.conf:
--------------------------------------------------------------------------------
1 |
2 | Options -Indexes +FollowSymLinks -ExecCGI
3 | AllowOverride None
4 | Require all granted
5 |
6 |
7 | # disallow access to all directories and files starting with a dot:
8 |
9 | Require all denied
10 |
11 |
12 | Require all denied
13 |
14 |
--------------------------------------------------------------------------------
/roles/apache/files/deflate-more-types.conf:
--------------------------------------------------------------------------------
1 | # apply GZip compression to some more file types:
2 | AddOutputFilterByType DEFLATE image/svg+xml
3 |
--------------------------------------------------------------------------------
/roles/apache/files/logrotate-apache2-user:
--------------------------------------------------------------------------------
1 | /var/log/apache2/*/*.log {
2 | daily
3 | missingok
4 | rotate 14
5 | compress
6 | delaycompress
7 | notifempty
8 | create 644 root adm
9 | sharedscripts
10 | postrotate
11 | if /etc/init.d/apache2 status > /dev/null ; then \
12 | /etc/init.d/apache2 reload > /dev/null; \
13 | fi;
14 | endscript
15 | prerotate
16 | if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
17 | run-parts /etc/logrotate.d/httpd-prerotate; \
18 | fi;
19 | endscript
20 | }
21 |
--------------------------------------------------------------------------------
/roles/apache/files/ocsp-stapling.conf:
--------------------------------------------------------------------------------
1 |
2 | SSLUseStapling on
3 | SSLStaplingCache shmcb:${APACHE_RUN_DIR}/stapling-cache(150000)
4 | SSLStaplingReturnResponderErrors off
5 |
6 |
--------------------------------------------------------------------------------
/roles/apache/files/proxy.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 | # If you want to use apache2 as a forward proxy, uncomment the
4 | # 'ProxyRequests On' line and the block below.
5 | # WARNING: Be careful to restrict access inside the block.
6 | # Open proxy servers are dangerous both to your network and to the
7 | # Internet at large.
8 | #
9 | # If you only want to use apache2 as a reverse proxy/gateway in
10 | # front of some web application server, you DON'T need
11 | # 'ProxyRequests On'.
12 |
13 | #ProxyRequests On
14 | #
15 | # AddDefaultCharset off
16 | # Require all denied
17 | # #Require local
18 | #
19 |
20 | # Enable/disable the handling of HTTP/1.1 "Via:" headers.
21 | # ("Full" adds the server version; "Block" removes all outgoing Via: headers)
22 | # Set to one of: Off | On | Full | Block
23 | #ProxyVia Off
24 |
25 | ProxyPreserveHost On
26 |
27 |
28 |
29 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
30 |
--------------------------------------------------------------------------------
/roles/apache/files/user-php-exec.conf:
--------------------------------------------------------------------------------
1 | # 1) enable FastCGI scripts (with mod_fcgid)
2 |
3 | SetHandler fcgid-script
4 |
5 |
6 | Action application/x-httpd-php /fcgi-bin/php-fcgi-starter
7 | AddHandler application/x-httpd-php .php
8 |
9 | # Direkten Zugriff auf /fcgi-bin/php-fcgi-starter verbieten;
10 | # es duerfen nur Zugriffe ueber einen Action Handler laufen,
11 | # der dann REDIRECT_HANDLER setzt.
12 | RewriteCond %{ENV:REDIRECT_HANDLER} =""
13 | RewriteRule ^/fcgi-bin/php-fcgi-starter - [F,L]
14 |
15 | # PHP-Scripts
16 | RewriteCond %{ENV:REDIRECT_HTTPS} =on
17 | RewriteRule .* - [E=HTTPS:on]
18 |
--------------------------------------------------------------------------------
/roles/apache/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart apache
3 | service:
4 | name: apache2
5 | state: restarted
6 | enabled: yes
7 | - name: reload apache
8 | service:
9 | name: apache2
10 | state: reloaded
11 | enabled: yes
12 |
--------------------------------------------------------------------------------
/roles/apache/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - jessie
7 |
--------------------------------------------------------------------------------
/roles/apache/templates/000-default.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | RewriteEngine on
5 | RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R,L,NE]
6 |
7 |
8 |
9 | DocumentRoot /var/www/html
10 | Redirect 307 "/" "https://{{apache_redirect_target}}/"
11 |
12 | SSLEngine on
13 | SSLCertificateFile /etc/ssl/certs/{{apache_ssl_host}}.pem
14 | SSLCertificateKeyFile /etc/ssl/private/{{apache_ssl_host}}.key
15 |
16 |
--------------------------------------------------------------------------------
/roles/apt/README.md:
--------------------------------------------------------------------------------
1 | apt
2 | =========================
3 |
4 | Configures APT
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - apt
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/apt/files/apt-periodic.conf:
--------------------------------------------------------------------------------
1 | APT::Periodic {
2 | Enable "1";
3 | Update-Package-Lists "1";
4 | Download-Upgradeable-Packages "1";
5 | Unattended-Upgrade "1";
6 | AutocleanInterval "7";
7 | }
8 |
--------------------------------------------------------------------------------
/roles/apt/files/apt-recommends.conf:
--------------------------------------------------------------------------------
1 | APT::Install-Recommends "false";
2 |
--------------------------------------------------------------------------------
/roles/apt/files/unattended-upgrades-dpkg.conf:
--------------------------------------------------------------------------------
1 | Dpkg::Options {
2 | "--force-confdef";
3 | "--force-confold";
4 | }
5 |
--------------------------------------------------------------------------------
/roles/automysqlbackup/README.md:
--------------------------------------------------------------------------------
1 | automysqlbackup
2 | =========================
3 |
4 | Installs backup toolsuite for MySQL
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - automysqlbackup
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/automysqlbackup/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - mysql-server
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - wheezy
9 | - jessie
10 |
--------------------------------------------------------------------------------
/roles/automysqlbackup/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install Backup for MySQL
3 | apt:
4 | name: automysqlbackup
5 | state: present
6 |
--------------------------------------------------------------------------------
/roles/backbone-gre/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | batman_interface: "bat-{{ site_code }}"
3 |
--------------------------------------------------------------------------------
/roles/backbone-gre/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p gre -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/backbone-gre/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: ifup backbone-gre
3 | # ifup && ifdown führt verlässlich zum Absturz des Systems
4 | command: ifup backbone-vpn{{ hostvars[item].vpn_id }}
5 | with_items: '{{ backbone_peers }}'
6 |
--------------------------------------------------------------------------------
/roles/backbone-gre/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/backbone-gre/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Setup GRE interfaces
3 | template:
4 | src: interfaces
5 | dest: /etc/network/interfaces.d/backbone
6 | mode: 0644
7 | owner: root
8 | group: root
9 | notify:
10 | - ifup backbone-gre
11 |
12 | - name: Open firewall
13 | copy:
14 | src: firewall.sh
15 | dest: "{{ firewall_path }}/10-allow-gre"
16 | mode: 0644
17 | owner: root
18 | group: root
19 | when: firewall_enabled
20 | notify: reload firewall
21 |
--------------------------------------------------------------------------------
/roles/backbone-gre/templates/interfaces:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | {% for host in backbone_peers %}
4 | {% set ifname = "backbone-vpn%d" % hostvars[host].vpn_id %}
5 | # {{ host }}
6 | auto {{ ifname }}
7 | iface {{ ifname }} inet manual
8 | pre-up ip link add $IFACE type gretap local {{ ansible_default_ipv4.address }} remote {{ host | resolve('a') }} ttl 64
9 | post-down ip link del $IFACE
10 | up ip link set up $IFACE
11 | down ip link set down $IFACE
12 | up ip link set $IFACE mtu {{ [ hostvars[host].max_mtu, max_mtu ] | min }}
13 | up batctl meshif {{ batman_interface }} interface add $IFACE
14 | down batctl meshif {{ batman_interface }} interface del $IFACE
15 |
16 | {% endfor %}
17 |
--------------------------------------------------------------------------------
/roles/backbone-gre/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Other backbone hosts (not myself)
3 | backbone_peers: "{{ (('backbone' in group_names) or ('vpnservers' in group_names)) | ternary(groups['backbone'], groups['backbone_legacy']) | remove(inventory_hostname) }}"
4 |
--------------------------------------------------------------------------------
/roles/batman-adv-14/README.md:
--------------------------------------------------------------------------------
1 | batman-adv-14
2 | =========================
3 |
4 | Install batman-adv compat 14 from universe-factory repo
5 |
6 |
7 | Role Variables
8 | -------------------------
9 |
10 | pgp_keyserver: keyserver for retreiving the repository key (default: 'pgp.surfnet.nl')
11 | batman-adv-14_repository: (default: 'https://repo.universe-factory.net/debian sid main')
12 | batman-adv-14_repository_key: (default: '6664E7BDA6B669881EC52E7516EF3F64CB201D9C')
13 | batman-adv-14_pkg_name: (default: 'batman-adv-dkms')
14 |
15 |
16 | Usage
17 | -------------------------
18 |
19 | - hosts: servers
20 | roles:
21 | - batman-adv-14
22 |
23 |
24 | License
25 | -------------------------
26 |
27 | GPLv3
28 |
--------------------------------------------------------------------------------
/roles/batman-adv-14/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | batman_adv_14_apt_repository: 'https://repo.universe-factory.net/debian/ sid main'
3 | batman_adv_14_repository: 'https://github.com/freifunk-gluon/batman-adv-legacy'
4 | batman_adv_14_git_commit: '90b4d1511cd7bd3e0802412ca6d1b90e964d8691'
5 |
--------------------------------------------------------------------------------
/roles/batman-adv-14/files/dkms-batman-adv-downgrade:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # We're passed the version of the kernel being installed
4 | inst_kern=$1
5 | pkg_name=batman-adv-legacy
6 | pkg_ver=2013.4.0
7 | module_name=$pkg_name
8 |
9 | uname_s=$(uname -s)
10 |
11 | _get_kernel_dir() {
12 | KVER=$1
13 | case ${uname_s} in
14 | Linux) DIR="/lib/modules/$KVER/build" ;;
15 | GNU/kFreeBSD) DIR="/usr/src/kfreebsd-headers-$KVER/sys" ;;
16 | esac
17 | echo $DIR
18 | }
19 |
20 | _check_kernel_dir() {
21 | DIR=$(_get_kernel_dir $1)
22 | case ${uname_s} in
23 | Linux) test -e $DIR/include ;;
24 | GNU/kFreeBSD) test -e $DIR/kern && test -e $DIR/conf/kmod.mk ;;
25 | *) return 1 ;;
26 | esac
27 | return $?
28 | }
29 |
30 | case "${uname_s}" in
31 | Linux)
32 | header_pkg="linux-headers-$inst_kern"
33 | kernel="Linux"
34 | ;;
35 | GNU/kFreeBSD)
36 | header_pkg="kfreebsd-headers-$inst_kern"
37 | kernel="kFreeBSD"
38 | ;;
39 | esac
40 |
41 | if dkms status -m $pkg_name -v $pkg_ver -k $inst_kern | grep -q ' installed$'; then
42 | echo "$pkg_name in version $pkg_ver already installed." >&2
43 | else
44 | dkms remove -m $pkg_name -v $pkg_ver -k $inst_kern || true
45 | dkms build -m $pkg_name -v $pkg_ver -k $inst_kern
46 | dkms install -m $pkg_name -v $pkg_ver --force -k $inst_kern
47 | fi
48 |
49 | if ! _check_kernel_dir $inst_kern ; then
50 | echo "dkms: WARNING: $kernel headers are missing, which may explain the above failures." >&2
51 | echo " please install the $header_pkg package to fix this." >&2
52 | fi
53 |
--------------------------------------------------------------------------------
/roles/batman-adv-14/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # tasks file for batman-adv-14
3 | - name: Remove old repository
4 | apt_repository:
5 | repo: "deb {{ batman_adv_14_apt_repository }}"
6 | state: absent
7 |
8 | - name: Remove old dkms package
9 | apt:
10 | name: batman-adv-dkms
11 | state: absent
12 | purge: yes
13 |
14 | - name: Install batman-adv dependencies
15 | apt:
16 | name:
17 | - dkms
18 | - lsof
19 | - linux-headers-amd64
20 |
21 | - name: Clone batman-adv repo
22 | git:
23 | repo: "{{ batman_adv_14_repository }}"
24 | dest: "/usr/src/batman-adv-legacy-2013.4.0"
25 | version: "{{ batman_adv_14_git_commit }}"
26 |
27 | - name: Add repo to dkms
28 | command: dkms add -m batman-adv-legacy -v 2013.4.0
29 | args:
30 | creates: /var/lib/dkms/batman-adv-legacy/2013.4.0/source/Makefile
31 |
32 | - name: Copy kernel postinst downgrade hook
33 | copy:
34 | src: dkms-batman-adv-downgrade
35 | dest: /etc/kernel/postinst.d/00dkms-batman-adv-downgrade
36 | mode: 0755
37 |
38 | - name: Ensure correct version was installed
39 | shell: /etc/kernel/postinst.d/00dkms-batman-adv-downgrade $(uname -r)
40 | register: batman_adv_version_result
41 | changed_when: '"already installed" not in batman_adv_version_result.stderr'
42 |
43 | - name: Enable batman during boot
44 | lineinfile:
45 | path: /etc/modules
46 | line: batman-adv
47 |
48 | - name: Load batman-adv module
49 | modprobe:
50 | name: batman-adv
51 |
--------------------------------------------------------------------------------
/roles/batman-adv-interface/README.md:
--------------------------------------------------------------------------------
1 | batman-adv-interface
2 | =========================
3 |
4 | Install the batman interface
5 |
6 |
7 | Role Variables
8 | -------------------------
9 |
10 | batman_interface: Interface on which works Batman (default: 'bat-{{ site_code }}' )
11 |
12 |
13 | Usage
14 | -------------------------
15 |
16 | - hosts: servers
17 | vars:
18 | site_code: ffhb
19 | roles:
20 | - batman-adv-interface
21 |
22 |
23 | License
24 | -------------------------
25 |
26 | GPLv3
27 |
--------------------------------------------------------------------------------
/roles/batman-adv-interface/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | batman_interface: bat-{{ site_code }}
3 | batman_dummy_interface: 'bat-{{ site_code }}-dummy'
4 | batman_hop_penalty: 96
5 | batman_gateway: false
6 |
--------------------------------------------------------------------------------
/roles/batman-adv-interface/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install bridge-utils
3 | apt:
4 | name: bridge-utils
5 |
6 | - name: Install old networking tools
7 | apt:
8 | name: net-tools
9 |
10 | - name: Install batctl
11 | apt:
12 | name: batctl
13 |
14 | - name: Install batman pre-up script
15 | copy:
16 | src: if-pre-up
17 | dest: /etc/network/if-pre-up.d/batadv
18 | mode: 0755
19 | when: (ansible_distribution == "Debian" and (ansible_distribution_version is version_compare("11", ">=")))
20 |
21 | - name: Install batman pre-up script
22 | copy:
23 | src: if-pre-up-legacy
24 | dest: /etc/network/if-pre-up.d/batadv
25 | mode: 0755
26 | when: (ansible_distribution == "Debian" and (ansible_distribution_version is version_compare("11", "<")))
27 |
28 | - name: Install interfaces file
29 | template:
30 | src: interfaces
31 | dest: /etc/network/interfaces.d/{{ batman_interface }}
32 | mode: 0644
33 | owner: root
34 | group: root
35 |
36 | - name: Set interfaces up
37 | command: ifup {{ item }}
38 | register: ifup_result
39 | changed_when: '"already configured" not in ifup_result.stderr'
40 | with_items:
41 | - "{{ batman_dummy_interface }}"
42 | - "{{ batman_interface }}"
43 |
--------------------------------------------------------------------------------
/roles/batman-adv-interface/templates/interfaces:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | auto {{ batman_dummy_interface }}
4 | iface {{ batman_dummy_interface }} inet manual
5 | pre-up ip link add name $IFACE type dummy
6 | up ip link set $IFACE up
7 | down ip link set $IFACE down
8 | post-down ip link del $IFACE
9 |
10 | auto {{ batman_interface }}
11 | iface {{ batman_interface }} inet manual
12 | batadv-ports {{ batman_dummy_interface }}
13 | {% if ansible_default_ipv6.macaddress is defined %}
14 | batadv-hw {{ ansible_default_ipv6.macaddress | derive_mac_addr(2) }}
15 | {% else %}
16 | batadv-hw {{ ansible_default_ipv4.macaddress | derive_mac_addr(2) }}
17 | {% endif %}
18 | batadv-hop-penalty {{ batman_hop_penalty }}
19 | {% if batman_gateway %}
20 | batadv-gw-mode server
21 | batadv-gw-bandwidth 100Mbit/100Mbit
22 | {% endif %}
23 | batadv-orig-interval 5000
24 | # set interface up
25 | up ip link set $IFACE up
26 | down ip link set $IFACE down
27 |
--------------------------------------------------------------------------------
/roles/batman-adv/README.md:
--------------------------------------------------------------------------------
1 | batman-adv
2 | =========================
3 |
4 | Install batman-adv
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - batman-adv
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/batman-adv/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | author: kaleng
4 | categories:
5 | - networking
6 | description: "install batman-adv"
7 | license: GPLv3
8 | min_ansible_version: 1.6
9 | platforms:
10 | - name: Debian
11 | versions:
12 | - wheezy
13 | - jessie
14 |
--------------------------------------------------------------------------------
/roles/batman-adv/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # tasks file for batman-adv
3 | - name: Enable batman during boot
4 | lineinfile:
5 | path: /etc/modules
6 | line: batman-adv
7 |
8 | - name: Load batman-adv module
9 | modprobe:
10 | name: batman-adv
11 |
--------------------------------------------------------------------------------
/roles/caddy/README.md:
--------------------------------------------------------------------------------
1 | # caddy
2 |
3 | ## Bugfix
4 | Caddy need the current version of systemd (or without user change)
5 |
6 | ```
7 | deb http://httpredir.debian.org/debian jessie-backports main contrib non-free
8 | ```
9 |
10 | ```
11 | apt update
12 | apt install systemd -t jessie-backports
13 | apt upgrade -t jessie-backports
14 | ```
15 |
--------------------------------------------------------------------------------
/roles/caddy/files/caddy.service.patch:
--------------------------------------------------------------------------------
1 | --- caddy.service 2016-09-28 21:07:57.000000000 +0200
2 | +++ caddy 2016-12-07 12:42:54.304716833 +0100
3 | @@ -17,7 +17,7 @@ Group=www-data
4 | Environment=CADDYPATH=/etc/ssl/caddy
5 |
6 | ; Always set "-root" to something safe in case it gets forgotten in the Caddyfile.
7 | -ExecStart=/usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
8 | +ExecStart=/opt/go/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
9 | ExecReload=/bin/kill -USR1 $MAINPID
10 |
11 | ; Limit the number of file descriptors; see `man systemd.exec` for more limit settings.
12 | @@ -38,9 +38,9 @@ ReadWriteDirectories=/etc/ssl/caddy
13 | ; The following additional security directives only work with systemd v229 or later.
14 | ; They further retrict privileges that can be gained by caddy. Uncomment if you like.
15 | ; Note that you may have to add capabilities required by any plugins in use.
16 | -;CapabilityBoundingSet=CAP_NET_BIND_SERVICE
17 | -;AmbientCapabilities=CAP_NET_BIND_SERVICE
18 | +CapabilityBoundingSet=CAP_NET_BIND_SERVICE
19 | +AmbientCapabilities=CAP_NET_BIND_SERVICE
20 | ;NoNewPrivileges=true
21 |
22 | [Install]
23 | WantedBy=multi-user.target
24 |
--------------------------------------------------------------------------------
/roles/caddy/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart caddy
3 | service:
4 | name: caddy
5 | state: restarted
6 |
7 | - name: reload systemd
8 | systemd:
9 | daemon_reload: yes
10 |
--------------------------------------------------------------------------------
/roles/caddy/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - go
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - jessie
9 |
--------------------------------------------------------------------------------
/roles/caddy/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install tools
3 | apt:
4 | name:
5 | - patch
6 | - debian-keyring
7 | - debian-archive-keyring
8 |
9 | - name: Install caddy repo keyring
10 | apt_key:
11 | url: https://dl.cloudsmith.io/public/caddy/stable/gpg.key
12 | state: present
13 |
14 | - name: Install caddy repo
15 | apt_repository:
16 | repo: deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main
17 | state: present
18 |
19 | - name: Install caddy
20 | apt:
21 | name: caddy
22 | notify:
23 | - restart caddy
24 |
25 | - name: Create ssl folder
26 | file:
27 | path: /etc/ssl/caddy
28 | state: directory
29 | mode: 0750
30 | owner: www-data
31 | group: www-data
32 |
33 | - name: Create configuration folder
34 | file:
35 | path: /etc/caddy/hosts
36 | state: directory
37 | mode: 0755
38 | owner: www-data
39 | group: www-data
40 |
41 | - name: Configurate caddy
42 | template:
43 | src: Caddyfile
44 | dest: /etc/caddy/Caddyfile
45 | mode: 0644
46 | owner: www-data
47 | group: www-data
48 | notify: restart caddy
49 |
50 | - name: Create web folders
51 | file:
52 | path: /var/www/html
53 | state: directory
54 | mode: 0755
55 | owner: www-data
56 | group: www-data
57 |
58 | - name: Configurate caddy for hostname
59 | template:
60 | src: hostname.caddy
61 | dest: /etc/caddy/hosts/00-default.act
62 | mode: 0644
63 | owner: www-data
64 | group: www-data
65 | notify: restart caddy
66 |
67 | - name: Enable caddy
68 | service:
69 | name: caddy
70 | enabled: yes
71 |
--------------------------------------------------------------------------------
/roles/caddy/templates/Caddyfile:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | import ./hosts/*.act
4 |
--------------------------------------------------------------------------------
/roles/caddy/templates/hostname.caddy:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | http://{{main_domain}}, http://{{alt_domain}} {
3 | redir https://{{main_domain}}{uri}
4 | }
5 |
6 | https://{{main_domain}}, https://{{alt_domain}} {
7 | tls {{caddy_email}}
8 | gzip
9 | index index.html
10 | root /var/www/html
11 | header / {
12 | Access-Control-Allow-Origin *
13 | Access-Control-Allow-Methods "GET, POST, OPTIONS"
14 | -Server
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/roles/chrony/README.md:
--------------------------------------------------------------------------------
1 | chrony
2 | =========================
3 |
4 | Install NTP server
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - chrony
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/chrony/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart chrony
3 | service:
4 | name: chrony
5 | state: restarted
6 |
--------------------------------------------------------------------------------
/roles/chrony/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/chrony/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install chrony
3 | apt:
4 | name: chrony
5 |
6 | - name: Install configuration
7 | template:
8 | src: chrony.conf
9 | dest: /etc/chrony/chrony.conf
10 | mode: 0644
11 | owner: root
12 | group: root
13 | notify: restart chrony
14 | when: "'vpnservers' in group_names"
15 |
16 | - name: Open firewall for NTP
17 | template:
18 | src: firewall.sh
19 | dest: "{{ firewall_path }}/30-chrony"
20 | mode: 0644
21 | owner: root
22 | group: root
23 | notify: reload firewall
24 | when: "firewall_enabled and 'vpnservers' in group_names"
25 |
26 | - name: Autostart chrony
27 | service:
28 | name: chrony
29 | enabled: yes
30 |
--------------------------------------------------------------------------------
/roles/chrony/templates/chrony.conf:
--------------------------------------------------------------------------------
1 | # Welcome to the chrony configuration file. See chrony.conf(5) for more
2 | # information about usuable directives.
3 | server 0.debian.pool.ntp.org minpoll 8
4 | server 1.debian.pool.ntp.org minpoll 8
5 | server 2.debian.pool.ntp.org minpoll 8
6 | server 3.debian.pool.ntp.org minpoll 8
7 |
8 |
9 | # This directive specify the location of the file containing ID/key pairs for
10 | # NTP authentication.
11 | keyfile /etc/chrony/chrony.keys
12 |
13 | # This directive specify the file into which chronyd will store the rate
14 | # information.
15 | driftfile /var/lib/chrony/chrony.drift
16 |
17 | # Uncomment the following line to turn logging on.
18 | #log tracking measurements statistics
19 |
20 | # Log files location.
21 | logdir /var/log/chrony
22 |
23 | # Stop bad estimates upsetting machine clock.
24 | maxupdateskew 100.0
25 |
26 | # Allow computers on the unrouted nets to use the server.
27 |
28 | allow {{ ipv4_network }}
29 | allow {{ ipv6_local_network }}
30 | {% if ipv6_global_network %}
31 | allow {{ ipv6_global_network }}
32 | {% endif %}
33 |
34 | # This directive tells 'chronyd' to parse the 'adjtime' file to find out if the
35 | # real-time clock keeps local time or UTC. It overrides the 'rtconutc' directive.
36 | hwclockfile /etc/adjtime
37 |
38 | # This directive enables kernel synchronisation (every 11 minutes) of the
39 | # real-time clock. Note that it can’t be used along with the 'rtcfile' directive.
40 | rtcsync
41 |
42 | # Step the system clock instead of slewing it if the adjustment is larger than
43 | # one second, but only in the first three clock updates.
44 | makestep 1 3
45 |
--------------------------------------------------------------------------------
/roles/chrony/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -i '{{ main_bridge }}' -p udp --dport 123 -j ACCEPT
2 | ipt6 -A INPUT -i '{{ main_bridge }}' -p udp --dport 123 -j ACCEPT
3 |
--------------------------------------------------------------------------------
/roles/dnsmasq/README.md:
--------------------------------------------------------------------------------
1 | dnsmasq
2 | =========================
3 |
4 | Install and configure dnsmasq for DHCP
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - dnsmasq
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/dnsmasq/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dhcp_dns: '{{ batman_ipv4.address }}'
3 | main_bridge: 'br-{{ site_code }}'
4 |
--------------------------------------------------------------------------------
/roles/dnsmasq/files/dnsmasq-hook.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | set -eu
4 |
5 | MODE="$1"
6 | MAC="$2"
7 | IP="$3"
8 |
9 | if [ -z "${DNSMASQ_INTERFACE:-}" ]; then
10 | exit 0
11 | fi
12 |
13 | case "$MODE" in
14 | add|old)
15 | ip neigh replace "$IP" dev "$DNSMASQ_INTERFACE" lladdr "$MAC" nud reachable
16 | ;;
17 | del)
18 | ip neigh delete "$IP" dev "$DNSMASQ_INTERFACE"
19 | conntrack -D -s "$IP" > /dev/null
20 | ;;
21 | esac
22 |
--------------------------------------------------------------------------------
/roles/dnsmasq/files/dnsmasq-tmpfs.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Persist DHCP leases file to disk
3 | ConditionFileNotEmpty=/tmp/dnsmasq.leases
4 |
5 | [Service]
6 | ExecStart=/bin/cp /tmp/dnsmasq.leases /var/lib/misc/dnsmasq.leases
7 |
--------------------------------------------------------------------------------
/roles/dnsmasq/files/dnsmasq-tmpfs.timer:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Regularly persist DHCP leases file to disk
3 |
4 | [Timer]
5 | OnCalendar=hourly
6 | RandomizedDelaySec=1h
7 | FixedRandomDelay=yes
8 |
9 | [Install]
10 | WantedBy=timers.target
11 |
--------------------------------------------------------------------------------
/roles/dnsmasq/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload systemd
3 | systemd:
4 | daemon_reload: yes
5 |
6 | - name: restart dnsmasq
7 | service:
8 | name: dnsmasq
9 | state: restarted
10 |
--------------------------------------------------------------------------------
/roles/dnsmasq/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/dnsmasq/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install dnsmasq
3 | apt:
4 | name:
5 | - dnsmasq
6 | - conntrack # for clearing connections on lease expiration
7 |
8 | - name: Create dropin folder for systemd
9 | file:
10 | path: /etc/systemd/system/dnsmasq.service.d
11 | state: directory
12 | mode: '0755'
13 | owner: root
14 | group: root
15 |
16 | - name: Create dropin file
17 | copy:
18 | dest: /etc/systemd/system/dnsmasq.service.d/local.conf
19 | mode: '0644'
20 | owner: root
21 | group: root
22 | content: |
23 | [Service]
24 | ExecStartPre=-/bin/cp /var/lib/misc/dnsmasq.leases /tmp/dnsmasq.leases
25 | ExecStopPost=/bin/cp /tmp/dnsmasq.leases /var/lib/misc/dnsmasq.leases
26 | notify: reload systemd
27 |
28 | - name: Install timer unit to persist leases file
29 | copy:
30 | src: '{{ item }}'
31 | dest: /etc/systemd/system/
32 | mode: 0644
33 | loop:
34 | - dnsmasq-tmpfs.service
35 | - dnsmasq-tmpfs.timer
36 |
37 |
38 | - name: Enable timer unit to persist leases file
39 | systemd:
40 | name: dnsmasq-tmpfs.timer
41 | state: started
42 | enabled: yes
43 | daemon_reload: yes
44 |
45 | - name: Remove obsolete cronjob
46 | file:
47 | path: /etc/cron.hourly/dnsmasq-tmpfs
48 | state: absent
49 |
50 | - name: Copy dnsmasq lease script
51 | copy:
52 | dest: /usr/local/sbin/dnsmasq-hook.sh
53 | src: dnsmasq-hook.sh
54 | owner: root
55 | group: root
56 | mode: '0755'
57 |
58 | - name: Configure dnsmasq
59 | template:
60 | src: dnsmasq.conf
61 | dest: /etc/dnsmasq.conf
62 | mode: 0644
63 | owner: root
64 | group: root
65 | notify: restart dnsmasq
66 |
67 | - name: Open firewall for DHCP
68 | template:
69 | src: firewall.sh
70 | dest: "{{ firewall_path }}/30-dnsmasq"
71 | mode: 0644
72 | owner: root
73 | group: root
74 | when: firewall_enabled
75 | notify: reload firewall
76 |
77 | - name: Enable dnsmasq
78 | service:
79 | name: dnsmasq
80 | enabled: yes
81 |
--------------------------------------------------------------------------------
/roles/dnsmasq/templates/dnsmasq.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | log-facility=local7
4 |
5 | interface={{ main_bridge }}
6 | bind-interfaces
7 |
8 | port=0
9 |
10 | quiet-dhcp
11 |
12 | dhcp-authoritative
13 | dhcp-leasefile=/tmp/dnsmasq.leases
14 | dhcp-lease-max=2550
15 |
16 | dhcp-range=set:main,{{ dhcp.range_begin }},{{ dhcp.range_end }},{{ dhcp.netmask }},30m
17 | dhcp-option=main,option:router,{{ batman_ipv4.address }}
18 | dhcp-option=option:dns-server,{{ batman_ipv4.address }}
19 | dhcp-option=option:domain-search,{{site_domain}}
20 |
21 | no-ping
22 | dhcp-script=/usr/local/sbin/dnsmasq-hook.sh
23 | {% if 'vpnservers_legacy' not in group_names %}
24 | script-on-renewal
25 | {% endif %}
26 |
--------------------------------------------------------------------------------
/roles/dnsmasq/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt4 -A INPUT -i '{{ main_bridge }}' -p udp --dport 67:68 -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/downlink-firewall/defaults/main.yml:
--------------------------------------------------------------------------------
1 | main_bridge: 'br-{{ site_code }}'
2 |
--------------------------------------------------------------------------------
/roles/downlink-firewall/files/ipv6-neigh-cache-negative.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Cache negative IPv6 ND results
3 | Before=firewall.service
4 |
5 | [Service]
6 | ExecStart=/usr/local/sbin/ipv6-neigh-cache-negative.sh
7 | Restart=always
8 | RestartSec=10
9 |
10 | [Install]
11 | WantedBy=network.target
--------------------------------------------------------------------------------
/roles/downlink-firewall/files/ipv6-neigh-cache-negative.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | set -eu
4 |
5 | # This little script listens to `ip -6 monitor neigh` and adds addresses for
6 | # which IPv6 ND lookups failed to an ipset, which in turn can be used by the
7 | # firewall to drop packets to these addresses.
8 |
9 | IPSET_NAME="ND_FAILED"
10 | IPSET_TIMEOUT=60
11 | IPSET_HASHSIZE=4096
12 |
13 |
14 | ipset -exist create "$IPSET_NAME" hash:net family inet6 hashsize "$IPSET_HASHSIZE" timeout "$IPSET_TIMEOUT"
15 |
16 | ip -6 monitor neigh | while read -r LINE; do
17 | case "$LINE" in
18 | fe80::*|"Deleted "*)
19 | continue
20 | ;;
21 | *" FAILED")
22 | printf "add -exist %s %s\nCOMMIT\n" "$IPSET_NAME" "${LINE%% *}"
23 | ;;
24 | esac
25 | done | ipset restore
26 |
--------------------------------------------------------------------------------
/roles/downlink-firewall/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Reload systemd
3 | systemd:
4 | daemon_reload: yes
5 |
6 | - name: Restart ipv6-neigh-cache-negative
7 | systemd:
8 | name: ipv6-neigh-cache-negative.service
9 | state: restarted
10 |
--------------------------------------------------------------------------------
/roles/downlink-firewall/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install ipv6-neigh-cache-negative.sh
3 | copy:
4 | src: ipv6-neigh-cache-negative.sh
5 | dest: /usr/local/sbin/ipv6-neigh-cache-negative.sh
6 | mode: '0755'
7 | notify: Restart ipv6-neigh-cache-negative
8 | when: firewall_enabled
9 |
10 | - name: Install ipv6-neigh-cache-negative.service
11 | copy:
12 | src: ipv6-neigh-cache-negative.service
13 | dest: /etc/systemd/system/ipv6-neigh-cache-negative.service
14 | mode: '0644'
15 | notify:
16 | - Reload systemd
17 | - Restart ipv6-neigh-cache-negative
18 | when: firewall_enabled
19 |
20 | - name: Enable ipv6-neigh-cache-negative.service
21 | systemd:
22 | daemon_reload: yes
23 | name: ipv6-neigh-cache-negative.service
24 | enabled: yes
25 | state: started
26 | when: firewall_enabled
27 |
28 | - name: Install firewall for dowlink
29 | copy:
30 | dest: /etc/firewall.d/20-downlink-forwarding
31 | content: |
32 | ipt6 -A FORWARD -m set --match-set ND_FAILED dst -j REJECT --reject-with addr-unreach
33 | ipt6 -A FORWARD -i '{{ exit_ipv6_interface }}' -o '{{ main_bridge }}' -j ACCEPT
34 | mode: 0644
35 | owner: root
36 | group: root
37 | when: firewall_enabled
38 | notify: reload firewall
39 |
--------------------------------------------------------------------------------
/roles/downloadsite/README.md:
--------------------------------------------------------------------------------
1 | downloadsite
2 | =========================
3 |
4 | Set up webserver for download site of Freifunk Bremen
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - downloadsite
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/downloadsite/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | downloads_email: 'info@bremen.freifunk.net'
3 | downloads_user: 'downloads'
4 | downloads_group: 'downloads'
5 | downloads_subdomain: 'downloads'
6 | downloads_domain: '{{ downloads_subdomain }}.{{ main_domain }}'
7 | downloads_rsync_port: 63113
8 |
--------------------------------------------------------------------------------
/roles/downloadsite/files/htaccess:
--------------------------------------------------------------------------------
1 | Options +Indexes
2 | IndexOptions FancyIndexing FoldersFirst HTMLTable IconsAreLinks SuppressRules SuppressDescription XHTML
3 | HeaderName /header.html
4 | IndexStyleSheet /style.css
5 | ReadmeName footer.html
6 | IndexIgnore header.html style.css footer.html robots.txt favicon.ico
7 | AddDescription "Knotendaten für die Liste" data
8 | AddDescription "Aktuelle Firmware, s.a. Anleitung zum Flashen" firmware
9 | AddDescription "\"Freifunk verbindet!\"-Video" video
10 | AddOutputFilter DEFLATE json
11 | AddType text/plain manifest
12 | Header set Access-Control-Allow-Origin "*"
13 |
--------------------------------------------------------------------------------
/roles/downloadsite/files/rsync.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=fast remote file copy program daemon
3 |
4 | [Service]
5 | ExecStart=/usr/bin/rsync --no-detach --daemon --config .config/rsyncd.conf
6 |
7 | [Install]
8 | WantedBy=default.target
9 |
--------------------------------------------------------------------------------
/roles/downloadsite/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - tools
4 | - apache
5 | - letsencrypt
6 | galaxy_info:
7 | platforms:
8 | - name: Debian
9 | versions:
10 | - jessie
11 |
--------------------------------------------------------------------------------
/roles/downloadsite/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ downloads_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ downloads_subdomain }}.{{ alt_domain }}
6 |
7 | ServerAdmin {{ downloads_email }}
8 |
9 | DocumentRoot /var/www/{{ downloads_user }}/domains/{{ downloads_domain }}
10 |
11 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
12 | Options +SymLinksIfOwnerMatch -Includes
13 |
14 |
15 | SSLProxyEngine on
16 | ProxyPass /opkg/openwrt/ https://downloads.openwrt.org/
17 | ProxyPreserveHost Off
18 |
19 | ErrorLog /var/log/apache2/{{ downloads_user }}/default-error.log
20 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
21 |
22 | SSLEngine on
23 | SSLCertificateFile /etc/letsencrypt/certs/{{ downloads_domain }}/fullchain.pem
24 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ downloads_domain }}/privkey.pem
25 |
26 |
27 | ServerName {{ downloads_subdomain }}.{{ main_domain }}
28 | ServerAlias {{ downloads_subdomain }}.{{ alt_domain }}
29 |
30 | ServerAdmin {{ downloads_email }}
31 |
32 | DocumentRoot /var/www/{{ downloads_user }}/domains/{{ downloads_domain }}
33 |
34 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
35 | Options +SymLinksIfOwnerMatch -Includes
36 |
37 |
38 | ProxyPass /opkg/openwrt/ http://downloads.openwrt.org/
39 | ProxyPreserveHost Off
40 |
41 | ErrorLog /var/log/apache2/{{ downloads_user }}/default-error.log
42 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
43 |
44 |
--------------------------------------------------------------------------------
/roles/downloadsite/templates/rsyncd.conf:
--------------------------------------------------------------------------------
1 | use chroot = false
2 | port = {{ downloads_rsync_port }}
3 | pid file = /home/{{ downloads_user }}/.var/run/rsyncd.pid
4 | lock file = /home/{{ downloads_user }}/.var/run/rsyncd.lock
5 | max connections = 5
6 |
7 | [firmware]
8 | path=/var/www/{{ downloads_user }}/domains/{{ downloads_domain }}/firmware
9 | comment=Freifunk Bremen Firmware
10 |
11 | [opkg]
12 | path=/var/www/{{ downloads_user }}/domains/{{ downloads_domain }}/opkg
13 | comment=Freifunk Bremen Package Repository
14 |
--------------------------------------------------------------------------------
/roles/etckeeper-post/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check if etckeeper is installed
3 | stat:
4 | path: /usr/bin/etckeeper
5 | register: etckeeper_binary
6 |
7 | - block:
8 | - name: Run handlers
9 | meta: flush_handlers
10 |
11 | - name: Reenable autocommit before APT run
12 | replace:
13 | dest: /etc/etckeeper/etckeeper.conf
14 | regexp: '^([\#\s]*)?AVOID_COMMIT_BEFORE_INSTALL=[01]'
15 | replace: 'AVOID_COMMIT_BEFORE_INSTALL=1'
16 | changed_when: false
17 |
18 | - name: Get Git commit id
19 | command: git rev-parse HEAD # noqa 303
20 | register: ansible_git_commit_id
21 | delegate_to: localhost
22 | changed_when: false
23 | check_mode: false
24 |
25 | - name: Commit etckeeper
26 | command: etckeeper commit "ansible run with commit {{ ansible_git_commit_id.stdout }}"
27 | register: etckeeper_commit
28 | changed_when: "etckeeper_commit.rc == 0"
29 | failed_when: "etckeeper_commit.rc > 1"
30 | when: not ansible_git_commit_id.skipped is defined
31 | when: etckeeper_binary.stat.executable is defined and etckeeper_binary.stat.executable
32 |
--------------------------------------------------------------------------------
/roles/etckeeper-pre/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check if etckeeper is installed
3 | stat:
4 | path: /usr/bin/etckeeper
5 | register: etckeeper_binary
6 |
7 | - block:
8 | - name: Check if etc is committed
9 | command: git -C /etc ls-files --modified --deleted --others --exclude-standard # noqa command-instead-of-module
10 | register: ansible_etckeeper_committed
11 | changed_when: false
12 | failed_when: ansible_etckeeper_committed.stdout != ""
13 |
14 | - name: Disable autocommit before APT run
15 | replace:
16 | dest: /etc/etckeeper/etckeeper.conf
17 | regexp: '^([\#\s]*)?AVOID_COMMIT_BEFORE_INSTALL=[01]'
18 | replace: 'AVOID_COMMIT_BEFORE_INSTALL=0'
19 | changed_when: false
20 | when: etckeeper_binary.stat.executable is defined and etckeeper_binary.stat.executable
21 |
--------------------------------------------------------------------------------
/roles/etckeeper/README.md:
--------------------------------------------------------------------------------
1 | etckeeper
2 | =========================
3 |
4 | Installs etckeeper
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - etckeeper
13 |
14 | License
15 | -------------------------
16 |
17 | GPLv3
18 |
--------------------------------------------------------------------------------
/roles/etckeeper/files/git-config:
--------------------------------------------------------------------------------
1 | [user]
2 | name = ffhb root-user
3 | email = server@bremen.freifunk.net
4 | [pull]
5 | rebase = true
6 | [push]
7 | default = simple
8 |
--------------------------------------------------------------------------------
/roles/etckeeper/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/etckeeper/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install etckeeper
3 | apt:
4 | name:
5 | - git
6 | - etckeeper
7 |
8 | - name: Comment all VCSs
9 | replace:
10 | dest: /etc/etckeeper/etckeeper.conf
11 | regexp: '^VCS="(?!git)'
12 | replace: '#VCS="'
13 |
14 | - name: Activate git as only VCS
15 | replace:
16 | dest: /etc/etckeeper/etckeeper.conf
17 | regexp: '^#VCS="git"'
18 | replace: 'VCS="git"'
19 |
20 | - name: Disable daily autocommit
21 | replace:
22 | dest: /etc/etckeeper/etckeeper.conf
23 | regexp: '^#AVOID_DAILY_AUTOCOMMITS=1'
24 | replace: 'AVOID_DAILY_AUTOCOMMITS=1'
25 |
26 | - name: Create git configuration directory
27 | file:
28 | path: /root/.config/git
29 | recurse: yes
30 | state: directory
31 | owner: root
32 | group: root
33 | mode: 0700
34 |
35 | - name: Copy Git configuration
36 | copy:
37 | src: git-config
38 | dest: /root/.config/git/config
39 | owner: root
40 | group: root
41 | mode: 0600
42 | force: no
43 |
44 | - name: Uninitialize repository in /etc
45 | command: /usr/bin/etckeeper uninit -f
46 | args:
47 | creates: /etc/.git
48 |
49 | - name: Initialize repository in /etc with git
50 | command: /usr/bin/etckeeper init
51 | args:
52 | creates: /etc/.git
53 |
--------------------------------------------------------------------------------
/roles/eventswebsite/README.md:
--------------------------------------------------------------------------------
1 | # Eventswebsite
2 | Install a little website on a server.
3 | This website would be a index to get access to public services on a event.
4 | (Examples for such services are grafana and a meshviewer).
5 |
6 |
7 | Maybe later, replace it with a git clone of a website!
8 |
--------------------------------------------------------------------------------
/roles/eventswebsite/tasks/main.yml:
--------------------------------------------------------------------------------
1 | - name: Install index
2 | template:
3 | src: index.html
4 | dest: /var/www/html/
5 | owner: www-data
6 | mode: 0644
7 |
--------------------------------------------------------------------------------
/roles/eventswebsite/templates/index.html:
--------------------------------------------------------------------------------
1 |
Freifunk Bremen Events
2 | This is a public accessable server for services during a events managed by Freifunk Bremen.
3 | The list of public services:
4 |
5 | {% if grafana_caddy is defined %}- Grafana
{% endif %}
6 | {% if meshviewer_apache is defined %}- Meshviewer
{% endif %}
7 |
8 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/README.md:
--------------------------------------------------------------------------------
1 | exit-ipv4
2 | =========================
3 |
4 | A role to setup up a OpenVPN, GRE or IPIP connection as exit.
5 |
6 |
7 | Role Variables
8 | ------------------------
9 |
10 | ### GRE or IPIP Exit
11 |
12 | exit_ipv4: Tunnel mode (GRE or IPIP)
13 | exit_ipv4_address
14 | exit_ipv4_address_global
15 | exit_ipv4_address_peer
16 | exit_ipv4_local
17 | exit_ipv4_remote
18 |
19 | ### default (dangerous)
20 |
21 | Be aware of the german "Störerhaftung"!
22 |
23 | exit_ipv4: default
24 |
25 |
26 | Usage
27 | ------------------------
28 |
29 | - hosts: servers
30 | roles:
31 | - { role: exit-ipv4, exit_ipv4: "gre" }
32 |
33 |
34 | License
35 | ------------------------
36 |
37 | GPLv3
38 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | exit_ipv4: ""
3 | exit_ipv4_mtu: 1400
4 | exit_ipv4_interface: vpn-uplink
5 | exit_ipv4_address_global: False
6 | ffhb_routing_table: default-freifunk
7 | main_bridge: 'br-{{ site_code }}'
8 | exit_masquerade: true
9 | ipp2p_drop: false
10 | ipp2p_protocols:
11 | - apple
12 | - ares
13 | - bit
14 | - dc
15 | - edk
16 | - gnu
17 | - kazaa
18 | - mute
19 | - soul
20 | - waste
21 | - winmx
22 | - xdcc
23 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/files/10-allow-gre:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p gre -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/files/10-allow-ipip:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p ipip -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - wheezy
9 | - jessie
10 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/tasks/default.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Configure firewall for IPv4 exit
3 | template:
4 | src: "default/{{ item }}"
5 | dest: "{{ firewall_path }}/"
6 | mode: 0644
7 | owner: root
8 | group: root
9 | with_items:
10 | - 10-tcpmss-ipv4
11 | - 20-exit-ipv4
12 | when: firewall_enabled
13 | notify: reload firewall
14 |
15 | - name: Install hook
16 | template:
17 | src: default/up.sh
18 | dest: "/etc/network/if-up.d/{{ ffhb_routing_table }}"
19 | mode: 0755
20 | owner: root
21 | group: root
22 | when: exit_ipv4 == "default"
23 |
24 | - name: Remove hook
25 | file:
26 | path: "/etc/network/if-up.d/{{ ffhb_routing_table }}"
27 | state: absent
28 | when: exit_ipv4 != "default"
29 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/tasks/generic.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Open firewall for GRE
3 | copy:
4 | src: "10-allow-{{ exit_ipv4.lower() }}"
5 | dest: "{{ firewall_path }}/"
6 | mode: 0644
7 | owner: root
8 | group: root
9 | when: firewall_enabled
10 | notify: reload firewall
11 |
12 | - name: Install interfaces file
13 | template:
14 | src: generic/interface
15 | dest: "/etc/network/interfaces.d/{{ exit_ipv4_interface }}"
16 | mode: 0644
17 | owner: root
18 | group: root
19 |
20 | - name: Set interfaces up
21 | command: ifup {{ exit_ipv4_interface }}
22 | register: ifup_result
23 | changed_when: '"already configured" not in ifup_result.stderr'
24 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Include generic
3 | import_tasks: generic.yml
4 | when: exit_ipv4.lower() in ["gre", "ipip"]
5 |
6 | - name: Include default
7 | import_tasks: default.yml
8 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/templates/default/10-tcpmss-ipv4:
--------------------------------------------------------------------------------
1 | ipt4 -A FORWARD -i {{ main_bridge }} -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1354
2 | ipt4 -A FORWARD -o {{ main_bridge }} -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1354
3 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/templates/default/20-exit-ipv4:
--------------------------------------------------------------------------------
1 | {% if ipp2p_drop is defined and ipp2p_drop %}
2 | {% for protocol in ipp2p_protocols %}
3 | ipt4 -A FORWARD -i {{ main_bridge }} -o {{ exit_ipv4_interface }} -m ipp2p --{{protocol}} -j DROP
4 | ipt4 -A FORWARD -i {{ exit_ipv4_interface }} -o {{ main_bridge }} -m ipp2p --{{protocol}} -j DROP
5 | {% endfor %}
6 | {% endif %}
7 |
8 | # Traffic from our network to the Internet
9 | ipt4 -A FORWARD -i {{ main_bridge }} -o {{ exit_ipv4_interface }} -j ACCEPT
10 | ipt4 -A FORWARD -o {{ main_bridge }} -i {{ exit_ipv4_interface }} -j ACCEPT
11 |
12 | {% if exit_masquerade %}
13 | ipt4 -t nat -A POSTROUTING -s {{ ipv4_network }} -o {{ exit_ipv4_interface }} -j MASQUERADE
14 | {% endif %}
15 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/templates/default/up.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # Copy default route
4 | if [ "$IFACE" = "{{ ansible_default_ipv4.interface }}" ]; then
5 | if ! ip -4 route list 0/0 table '{{ ffhb_routing_table }}' | grep -q '^default'; then
6 | ip -4 route list 0/0 | xargs ip route add table '{{ ffhb_routing_table }}'
7 | fi
8 | fi
9 |
--------------------------------------------------------------------------------
/roles/exit-ipv4/templates/generic/interface:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | auto {{ exit_ipv4_interface }}
4 | iface {{ exit_ipv4_interface }} inet manual
5 | mode {{ exit_ipv4 }}
6 |
7 | pre-up ip tunnel add $IFACE mode {{ exit_ipv4 }} remote {{ exit_ipv4_remote }} local {{ exit_ipv4_local }} ttl 255
8 | post-down ip tunnel del $IFACE
9 |
10 | up ip link set up dev $IFACE
11 | down ip link set down dev $IFACE
12 |
13 | up ip link set mtu {{ exit_ipv4_mtu }} dev $IFACE
14 | down ip link set mtu {{ exit_ipv4_mtu }} dev $IFACE
15 |
16 | # Set address to interface with scope link
17 | {% set exit_ipv4_prefix = exit_ipv4_address | ipaddr('host/prefix') | ipaddr('prefix') %}
18 | {% set exit_ipv4_address_plain = exit_ipv4_address | ipaddr('host/prefix') | ipaddr('address') %}
19 | {% if exit_ipv4_prefix == 32 %}
20 | up ip address add {{ exit_ipv4_address }} peer {{ exit_ipv4_address_peer }} scope link dev $IFACE
21 | down ip address del {{ exit_ipv4_address }} peer {{ exit_ipv4_address_peer }} scope link dev $IFACE
22 | {% else %}
23 | up ip address add {{ exit_ipv4_address }} dev $IFACE
24 | down ip address del {{ exit_ipv4_address }} dev $IFACE
25 | {% endif %}
26 | post-up ip rule add from {{ exit_ipv4_address_plain }} lookup default-freifunk priority 16385
27 | pre-down ip rule del from {{ exit_ipv4_address_plain }} lookup default-freifunk priority 16385
28 |
29 | {% if exit_ipv4_address_global %}
30 | # Set address for NAT
31 | post-up ip address add {{ exit_ipv4_address_global }}/32 dev $IFACE
32 | pre-down ip address del {{ exit_ipv4_address_global }}/32 dev $IFACE
33 | post-up ip rule add from {{ exit_ipv4_address_global }} lookup default-freifunk priority 16384
34 | pre-down ip rule del from {{ exit_ipv4_address_global }} lookup default-freifunk priority 16384
35 | {% endif %}
36 |
37 | # Default route
38 | post-up ip route add default via {{ exit_ipv4_address_peer }} dev $IFACE table {{ ffhb_routing_table }}
39 | pre-down ip route del default via {{ exit_ipv4_address_peer }} dev $IFACE table {{ ffhb_routing_table }}
40 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/README.md:
--------------------------------------------------------------------------------
1 | exit-ipv6
2 | =========================
3 |
4 | Configure IPv6 exit
5 |
6 |
7 | Role Variables
8 | ------------------------
9 |
10 |
11 | Usage
12 | ------------------------
13 |
14 | - hosts: servers
15 | roles:
16 | - exit-ipv6
17 |
18 |
19 | License
20 | ------------------------
21 |
22 | GPLv3
23 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | main_bridge: 'br-{{ site_code }}'
3 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install radv protocol for bird
3 | template:
4 | src: bird-radv.conf
5 | dest: /etc/bird/bird6.conf.d/radv.conf
6 | mode: 0644
7 | owner: root
8 | group: root
9 | notify: reload bird6
10 |
11 | - name: Configure firewall for IPv6 exit
12 | template:
13 | src: firewall.sh
14 | dest: "{{ firewall_path }}/20-exit-ipv6"
15 | mode: 0644
16 | owner: root
17 | group: root
18 | when: firewall_enabled
19 | notify: reload firewall
20 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/templates/bird-radv.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | protocol radv {
4 | interface "{{ main_bridge }}" {
5 | prefix {{ ipv6_local_address | ipaddr('network/prefix') }} {};
6 | prefix {{ ipv6_global_address | ipaddr('network/prefix') }} {};
7 | rdnss {
8 | ns {{ batman_ipv6_local.address }};
9 | };
10 | dnssl {
11 | domain "{{ site_domain }}";
12 | lifetime mult 10;
13 | };
14 | };
15 | export where net = ::/0;
16 | };
17 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt6 -A FORWARD -i '{{ main_bridge }}' -o '{{ exit_ipv6_interface }}' -j ACCEPT
2 | ipt6 -A FORWARD -o '{{ main_bridge }}' -i '{{ exit_ipv6_interface }}' -j ACCEPT
3 | ipt6 -A FORWARD -i '{{ main_bridge }}' -o '{{ main_bridge }}' -j ACCEPT
4 | ipt -A INPUT -p ipv6 -j ACCEPT
5 |
--------------------------------------------------------------------------------
/roles/exit-ipv6/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ipv6_global_address: "{{ batman_ipv6_global.address }}/{{ batman_ipv6_global.size }}"
3 | ipv6_local_address: "{{ batman_ipv6_local.address }}/{{ batman_ipv6_local.size }}"
4 |
--------------------------------------------------------------------------------
/roles/fail2ban/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Reload fail2ban
3 | ansible.builtin.systemd:
4 | name: fail2ban
5 | state: reloaded
6 |
--------------------------------------------------------------------------------
/roles/fail2ban/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install fail2ban and dependencies
3 | ansible.builtin.apt:
4 | name:
5 | - fail2ban
6 | - python3-systemd
7 | - iptables
8 | - ipset
9 |
10 | - name: Configure fail2ban to use systemd-journald for its own logging
11 | community.general.ini_file:
12 | path: /etc/fail2ban/fail2ban.local
13 | section: Definition
14 | option: logtarget
15 | value: SYSLOG
16 | notify: Reload fail2ban
17 |
18 | - name: Configure fail2ban to parse systemd-journald for login failures
19 | community.general.ini_file:
20 | path: /etc/fail2ban/jail.local
21 | section: DEFAULT
22 | option: backend
23 | value: systemd
24 | notify: Reload fail2ban
25 |
26 | - name: Configure fail2ban to use ipsets
27 | community.general.ini_file:
28 | path: /etc/fail2ban/jail.local
29 | section: DEFAULT
30 | option: banaction
31 | value: iptables-ipset-proto6
32 | notify: Reload fail2ban
33 |
34 | - name: Configure fail2ban to be more strict
35 | community.general.ini_file:
36 | path: /etc/fail2ban/jail.local
37 | section: DEFAULT
38 | option: "{{ item.option }}"
39 | value: "{{ item.value }}"
40 | loop:
41 | - option: maxretry
42 | value: 3
43 | - option: bantime
44 | value: 30m
45 | notify: Reload fail2ban
46 |
--------------------------------------------------------------------------------
/roles/fastd/README.md:
--------------------------------------------------------------------------------
1 | fastd
2 | =========================
3 |
4 | Install fastd
5 |
6 |
7 | Configuration
8 | -------------------------
9 |
10 | This role creates three instances of fastd:
11 |
12 | * `/etc/fastd/{{ site_code }}` listening on port 50000 (IPv4 and IPv6)
13 | * `/etc/fastd/{{ site_code }}-legacy` listening on port 10000 (IPv4 only)
14 |
15 |
16 | Usage
17 | -------------------------
18 |
19 | - hosts: servers
20 | roles:
21 | - fastd
22 |
23 |
24 | License
25 | -------------------------
26 |
27 | GPLv3
28 |
--------------------------------------------------------------------------------
/roles/fastd/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Interface-Namen dürfen maximal 15 Zeichen lang sein
3 | # http://lxr.free-electrons.com/source/include/uapi/linux/if.h?v=3.19#L26
4 |
5 | batman_interface: bat-{{ site_code }}
6 |
7 | fastd_peers_limit: -1
8 | fastd_anonymous: true
9 |
10 | fastd_interface: vpn-{{ site_code }}
11 | fastd_port: 50000
12 | fastd_mtu: 1280
13 |
14 | fastd_legacy_interface: vpn-{{ site_code }}-legacy
15 | fastd_legacy_port: 10000
16 | fastd_legacy_mtu: 1426
17 |
18 | fastd_blacklist_git_commit: '2b920b5e3009e075baffdfec8c27670388b43c96'
19 |
--------------------------------------------------------------------------------
/roles/fastd/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart fastd
3 | service:
4 | name: "fastd@{{ item }}"
5 | state: restarted
6 | with_items:
7 | - "{{ site_code }}"
8 | - "{{ site_code }}_legacy"
9 |
10 | - name: reload systemd
11 | systemd:
12 | daemon_reload: yes
13 |
--------------------------------------------------------------------------------
/roles/fastd/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - batman-adv-interface
4 | - firewall
5 | - git
6 | galaxy_info:
7 | platforms:
8 | - name: Debian
9 | versions:
10 | - wheezy
11 | - jessie
12 |
--------------------------------------------------------------------------------
/roles/fastd/tasks/blacklist.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install JSON processor and dnsutils
3 | apt:
4 | name:
5 | - jq
6 | - dnsutils
7 |
8 | - name: Clone blacklist repository
9 | git:
10 | repo: "{{ site_git_root }}/vpn-blacklist/"
11 | dest: "/opt/{{ site_code }}/vpn-blacklist/"
12 | version: "{{ fastd_blacklist_git_commit }}"
13 |
14 | - name: Copy blacklist script
15 | command: cp /opt/{{ site_code }}/vpn-blacklist/blacklist.sh /etc/fastd/{{ site_code }}/blacklist.sh
16 | args:
17 | creates: /etc/fastd/{{ site_code }}/blacklist.sh
18 |
19 | - name: Install timer unit to automatically update blacklist repository
20 | template:
21 | src: '{{ item }}'
22 | dest: "/etc/systemd/system/"
23 | mode: 0644
24 | loop:
25 | - update-fastd-blacklist@.service
26 | - update-fastd-blacklist@.timer
27 |
28 | - name: Enable timer unit to automatically update blacklist repository
29 | systemd:
30 | name: "update-fastd-blacklist@{{ site_code }}.timer"
31 | enabled: yes
32 | state: started
33 | daemon_reload: yes
34 |
35 | - name: Remove obsolete cronjob
36 | file:
37 | path: "/etc/cron.hourly/update-fastd-blacklist-{{ site_code }}"
38 | state: absent
39 |
--------------------------------------------------------------------------------
/roles/fastd/tasks/instance.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Check interface length
3 | fail:
4 | msg: "{{ fastd_interface }} has more than 15 characters!"
5 | when: fastd_interface|length > 15
6 |
7 | - name: Create directories
8 | file:
9 | path: "/etc/fastd/{{ fastd_instance }}/peers"
10 | state: directory
11 | mode: 0755
12 | owner: root
13 | group: root
14 |
15 | - name: Upload fastd.conf
16 | template:
17 | src: fastd.conf
18 | dest: "/etc/fastd/{{ fastd_instance }}/"
19 | mode: 0644
20 | owner: root
21 | group: root
22 | notify:
23 | - restart fastd
24 |
25 | - name: Add network configuration
26 | template:
27 | src: interfaces
28 | dest: "/etc/network/interfaces.d/{{ fastd_interface }}"
29 | mode: 0644
30 | owner: root
31 | group: root
32 |
33 | - name: Open firewall for fastd
34 | template:
35 | src: firewall.sh
36 | dest: "{{ firewall_path }}/30-fastd-{{ fastd_instance }}"
37 | mode: 0644
38 | owner: root
39 | group: root
40 | when: firewall_enabled
41 | notify: reload firewall
42 |
43 | - name: Enable fastd instance
44 | service:
45 | name: "fastd@{{ fastd_instance }}"
46 | enabled: yes
47 |
--------------------------------------------------------------------------------
/roles/fastd/templates/fastd.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | log to syslog level warn;
4 | hide ip addresses yes;
5 | status socket "/run/fastd-{{ fastd_instance }}.sock";
6 |
7 | interface "{{ fastd_interface }}";
8 |
9 | method "null";
10 | method "salsa2012+umac";
11 | method "salsa2012+gmac";
12 | {% if ('backbone_legacy' in group_names) or ('downlinks_legacy' in group_names) or ('vpnservers_legacy' in group_names) %}
13 | method "xsalsa20-poly1305";
14 |
15 | secure handshakes yes;
16 | {% endif %}
17 |
18 | bind {{ fastd_bind }}:{{ fastd_port }};
19 |
20 | include "secret.conf";
21 |
22 | mtu {{ fastd_mtu }};
23 |
24 | {% if fastd_peers_limit > -1 %}
25 | peer limit {{ fastd_peers_limit }};
26 | {% endif %}
27 |
28 | on up "ifup --allow hotplug {{ fastd_interface }}";
29 | on down "ifdown --allow hotplug {{ fastd_interface }}";
30 |
31 | {% if fastd_anonymous %}
32 | on verify "/etc/fastd/{{ site_code }}/blacklist.sh /opt/{{ site_code }}/vpn-blacklist/blacklist.json";
33 | {% endif %}
34 |
35 | include peers from "peers";
36 |
--------------------------------------------------------------------------------
/roles/fastd/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt6 -A INPUT -p udp --dport '{{ fastd_port }}' -s 2002::/16 -j REJECT --reject-with icmp6-adm-prohibited
2 | ipt -A INPUT -p udp --dport '{{ fastd_port }}' -j ACCEPT
3 |
--------------------------------------------------------------------------------
/roles/fastd/templates/interfaces:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | allow-hotplug {{ fastd_interface }}
4 | iface {{ fastd_interface }} inet manual
5 | up ip link set up $IFACE
6 | up batctl meshif {{ batman_interface }} if add $IFACE
7 | down batctl meshif {{ batman_interface }} if del $IFACE
8 | down ip link set down $IFACE
9 |
--------------------------------------------------------------------------------
/roles/fastd/templates/peer.conf:
--------------------------------------------------------------------------------
1 | key "{{ item.value.key }}";
2 | {% for remote in item.value.remotes %}
3 | remote {{ remote | regex_replace('(\d+)$', '') }} {{ fastd_port }};
4 | {% endfor %}
5 | float yes;
6 |
--------------------------------------------------------------------------------
/roles/fastd/templates/update-fastd-blacklist@.service:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | [Unit]
4 | Description=Update fastd blacklist for site %i
5 |
6 | [Service]
7 | ExecStart=/usr/bin/git -C /opt/%I/vpn-blacklist/ pull --rebase --quiet origin master
8 | Type=exec
9 |
--------------------------------------------------------------------------------
/roles/fastd/templates/update-fastd-blacklist@.timer:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | [Unit]
4 | Description=Regularly update fastd blacklist for site %i
5 |
6 | [Timer]
7 | OnCalendar=hourly
8 | RandomizedDelaySec=1h
9 | FixedRandomDelay=yes
10 |
11 | [Install]
12 | WantedBy=timers.target
13 |
--------------------------------------------------------------------------------
/roles/firewall/README.md:
--------------------------------------------------------------------------------
1 | firewall
2 | =========================
3 |
4 | Configure firewall
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | vars:
12 | firewall_enabled: true
13 | roles:
14 | - firewall
15 |
16 |
17 | License
18 | -------------------------
19 |
20 | GPLv3
21 |
--------------------------------------------------------------------------------
/roles/firewall/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | firewall_enabled: false
3 | firewall_path: /etc/firewall.d
4 |
--------------------------------------------------------------------------------
/roles/firewall/files/00-base:
--------------------------------------------------------------------------------
1 | # clear all tables, not only filter
2 | for table in $(iptables-save | grep '^*' | cut -d'*' -f2); do
3 | ipt -t $table -F
4 | ipt -t $table -X
5 | done
6 |
7 | ipt -P INPUT ACCEPT
8 | ipt -P OUTPUT ACCEPT
9 | ipt -P FORWARD ACCEPT
10 |
11 | ipt -A INPUT -i lo -j ACCEPT
12 | ipt4 -A INPUT -p icmp -j ACCEPT
13 | ipt6 -A INPUT -p ipv6-icmp -j ACCEPT
14 |
--------------------------------------------------------------------------------
/roles/firewall/files/90-established:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/firewall/files/99-reject:
--------------------------------------------------------------------------------
1 | ipt4 -A INPUT -j REJECT --reject-with icmp-admin-prohibited
2 | ipt6 -A INPUT -j REJECT --reject-with icmp6-adm-prohibited
3 | ipt4 -A FORWARD -j REJECT --reject-with icmp-admin-prohibited
4 | ipt6 -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
5 |
--------------------------------------------------------------------------------
/roles/firewall/files/firewall.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Firewall
3 | DefaultDependencies=no
4 | Before=network.target
5 | Requires=systemd-modules-load.service local-fs.target
6 | After=systemd-modules-load.service local-fs.target
7 |
8 | [Service]
9 | Type=oneshot
10 | RemainAfterExit=yes
11 | ExecStart=/etc/init.d/firewall.sh start
12 |
13 | [Install]
14 | WantedBy=multi-user.target
15 |
--------------------------------------------------------------------------------
/roles/firewall/files/ipv4-netfilter-ip-conntrack-max.conf:
--------------------------------------------------------------------------------
1 | net.netfilter.nf_conntrack_max = 131072
2 |
--------------------------------------------------------------------------------
/roles/firewall/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload firewall
3 | service:
4 | name: firewall
5 | state: restarted
6 |
7 | - name: reload sysctl
8 | command: /sbin/sysctl --system
9 |
--------------------------------------------------------------------------------
/roles/firewall/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/firewall/tasks/included.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install packages
3 | apt:
4 | name: iptables
5 |
6 | - name: Install xtables-addons-dkms
7 | apt:
8 | name: xtables-addons-dkms
9 | when: ipp2p_drop is defined and ipp2p_drop
10 |
11 | - name: Install firewall script
12 | template:
13 | src: init.sh
14 | dest: /etc/init.d/firewall.sh
15 | mode: 0755
16 | owner: root
17 | group: root
18 |
19 | - name: Install systemd unit
20 | copy:
21 | src: firewall.service
22 | dest: /etc/systemd/system/firewall.service
23 | mode: 0644
24 | owner: root
25 | group: root
26 |
27 | - name: Install basic firewall rules
28 | copy:
29 | src: "{{ item }}"
30 | dest: "{{ firewall_path }}/"
31 | mode: 0644
32 | owner: root
33 | group: root
34 | with_items:
35 | - 00-base
36 | - 90-established
37 | - 99-reject
38 | notify: reload firewall
39 |
40 | - name: Enable firewall service
41 | service:
42 | name: firewall
43 | enabled: yes
44 |
45 | - name: Add nf_conntrack to /etc/modules
46 | lineinfile:
47 | dest: /etc/modules
48 | line: nf_conntrack
49 | regexp: '^nf_conntrack'
50 |
51 | - name: Copy sysctl file for conntrack
52 | copy:
53 | src: ipv4-netfilter-ip-conntrack-max.conf
54 | dest: /etc/sysctl.d/
55 | mode: 0644
56 | owner: root
57 | group: root
58 | notify: reload sysctl
59 |
60 | - name: Create rc.local
61 | copy:
62 | content: "#!/bin/sh -e\nexit 0\n"
63 | dest: /etc/rc.local
64 | mode: 0755
65 | owner: root
66 | group: root
67 | force: no
68 |
69 | - name: Add sysctl call to /etc/rc.local
70 | lineinfile:
71 | name: /etc/rc.local
72 | insertbefore: "^exit"
73 | line: "sysctl --quiet --load=/etc/sysctl.d/ipv4-netfilter-ip-conntrack-max.conf"
74 | regexp: '^sysctl --quiet --load=/etc/sysctl.d/ipv4-netfilter-ip-conntrack-max\.conf$'
75 | create: yes
76 | mode: 0755
77 |
78 | - name: Uninstall iptables-persistent
79 | apt:
80 | name: netfilter-persistent
81 | state: absent
82 |
--------------------------------------------------------------------------------
/roles/firewall/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - import_tasks: included.yml
3 | when: firewall_enabled
4 |
--------------------------------------------------------------------------------
/roles/firewall/templates/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ### BEGIN INIT INFO
4 | # Provides: firewall.sh
5 | # Required-Start: mountkernfs $remote_fs
6 | # Required-Stop: $remote_fs
7 | # Default-Start: S
8 | # Default-Stop: 0 1 6
9 | # Short-Description: Load boot-time netfilter configuration
10 | # Description: Loads boot-time netfilter configuration
11 | ### END INIT INFO
12 |
13 | set -eu
14 |
15 | RULEPATH="${RULEPATH:-"{{ firewall_path }}"}"
16 |
17 | new_rule() {
18 | for arg in "$@"; do
19 | case "$arg" in
20 | -I|-A)
21 | comment="Set by file $rule"
22 | ;;
23 | --comment)
24 | comment=""
25 | break
26 | ;;
27 | esac
28 | done
29 |
30 | "$@" ${comment:+-m comment --comment "${comment}"} \
31 | || echo "$@" ${comment:+-m comment --comment "${comment}"}
32 | }
33 |
34 | ipt() {
35 | ipt4 "$@"
36 | ipt6 "$@"
37 | }
38 |
39 | ipt4() {
40 | new_rule iptables "$@"
41 | }
42 |
43 | ipt6() {
44 | new_rule ip6tables "$@"
45 | }
46 |
47 | case "$1" in
48 | start|restart)
49 | for rule in "$RULEPATH"/*; do
50 | # shellcheck disable=SC1090
51 | . "$rule"
52 | done
53 | ;;
54 | *)
55 | echo "Action $1 unsupported"
56 | esac
57 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | freifunkmanager_caddy: true
3 | freifunkmanager_webserver_bind: "127.0.0.1:8080"
4 | freifunkmanager_webroot: "/opt/go/src/github.com/FreifunkBremen/freifunkmanager/webroot"
5 |
6 | freifunkmanager_state_path: "freifunkmanager.json"
7 | freifunkmanager_ssh_interface: "eth0"
8 | freifunkmanager_ssh_key: .ssh/id_rsa
9 |
10 | freifunkmanager_yanic: true
11 | freifunkmanager_yanic_type: unix
12 | freifunkmanager_yanic_address: "/var/lib/yanic-database.socket"
13 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart freifunkmanager
3 | service:
4 | name: freifunkmanager
5 | state: restarted
6 |
7 | - name: reload caddy
8 | service:
9 | name: caddy
10 | state: reloaded
11 |
12 | - name: reload systemd
13 | systemd:
14 | daemon_reload: yes
15 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - go
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - jessie
9 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Create users
3 | user:
4 | name: freifunkmanager
5 | generate_ssh_key: yes
6 | ssh_key_type: rsa
7 | ssh_key_file: .ssh/id_rsa
8 | ssh_key_comment: "yanic@{{ inventory_hostname }}"
9 |
10 | - name: Install yanic
11 | command:
12 | cmd: /usr/local/go/bin/go get -u github.com/FreifunkBremen/freifunkmanager/cmd/freifunkmanager
13 | creates: /opt/go/bin/freifunkmanager
14 | environment:
15 | GOPATH: /opt/go
16 | notify:
17 | - restart freifunkmanager
18 |
19 | - name: Configure freifunkmanager
20 | template:
21 | src: config.toml
22 | dest: /etc/freifunkmanager.conf
23 | mode: 0644
24 | owner: root
25 | group: root
26 | notify:
27 | - restart freifunkmanager
28 |
29 | - name: Configure caddy
30 | template:
31 | src: caddy
32 | dest: /etc/caddy/hosts/10-freifunkmanager.act
33 | mode: 0644
34 | owner: root
35 | group: root
36 | when: freifunkmanager_caddy
37 | notify:
38 | - reload caddy
39 |
40 | - name: Create directory
41 | file:
42 | path: "{{ yanic_meshviewer_path }}/"
43 | state: directory
44 | mode: 0755
45 | owner: yanic
46 | group: yanic
47 |
48 | - name: Install system unit
49 | template:
50 | src: freifunkmanager.service
51 | dest: /lib/systemd/system/freifunkmanager.service
52 | mode: 0644
53 | owner: root
54 | group: root
55 | notify:
56 | - reload systemd
57 | - restart yanic
58 |
59 | - name: Enable freifunkmanager
60 | service:
61 | name: freifunkmanager
62 | enabled: yes
63 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/templates/caddy:
--------------------------------------------------------------------------------
1 | http://{{freifunkmanager_domain}} {
2 | redir https://{{freifunkmanager_domain}}{uri}
3 | }
4 | https://{{freifunkmanager_domain}} {
5 | tls {{freifunkmanager_email}}
6 | gzip
7 | basicauth / ffhb {{freifunkmanager_password}}
8 | index index.html
9 |
10 | push / /img/logo.png
11 | push / /css/images/layers.png
12 | push / /css/leaflet.css
13 | push / /css/main.css
14 | push / /css/map.css
15 | push / /js/moment.js
16 | push / /js/navigo.js
17 | push / /js/leaflet.js
18 | push / /js/leaflet.ajax.min.js
19 | push / /js/webgl-heatmap.js
20 | push / /js/leaflet-webgl-heatmap.min.js
21 | push / /js/config.js
22 | push / /js/domlib.js
23 | push / /js/store.js
24 | push / /js/notify.js
25 | push / /js/gui_list.js
26 | push / /js/gui_map.js
27 | push / /js/gui_node.js
28 | push / /js/gui_stats.js
29 | push / /js/gui.js
30 | push / /js/socket.js
31 | push / /js/app.js
32 |
33 |
34 | root /opt/go/src/github.com/FreifunkBremen/freifunkmanager/webroot
35 | proxy /websocket {{freifunkmanager_webserver_bind}} {
36 | header_upstream Host {host}
37 | header_upstream X-Real-IP {remote}
38 | header_upstream X-Forwarded-For {remote}
39 | header_upstream X-Forwarded-Proto {scheme}
40 | websocket
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/templates/config.toml:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | webserver_bind = "{{freifunkmanager_webserver_bind}}"
3 | webroot = "{{freifunkmanager_webroot}}"
4 |
5 | state_path = "{{freifunkmanager_state_path}}"
6 |
7 | ssh_key = "{{freifunkmanager_ssh_key}}"
8 | ssh_interface = "{{freifunkmanager_ssh_interface}}"
9 |
10 | [yanic]
11 | enable = {{freifunkmanager_yanic | ternary('true','false') }}
12 | type = "{{freifunkmanager_yanic_type}}"
13 | address = "{{freifunkmanager_yanic_address}}"
14 |
--------------------------------------------------------------------------------
/roles/freifunkmanager/templates/freifunkmanager.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=freifunkmanager
3 |
4 | [Service]
5 | Type=simple
6 | ExecStart=/opt/go/bin/freifunkmanager -config /etc/freifunkmanager.conf
7 | Restart=always
8 | RestartSec=5s
9 | Environment=PATH=/usr/bin:/usr/local/bin
10 |
11 | [Install]
12 | WantedBy=multi-user.target
13 |
--------------------------------------------------------------------------------
/roles/gatemon/README.md:
--------------------------------------------------------------------------------
1 | gatemon
2 | =========================
3 |
4 | Installing gatemon
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - gatemon
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/gatemon/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | gatemon_email: 'gatemon@bremen.freifunk.net'
3 | gatemon_user: 'gatemon'
4 | gatemon_group: 'gatemon'
5 | gatemon_subdomain: 'status'
6 | gatemon_domain: '{{ gatemon_subdomain }}.{{ main_domain }}'
7 | gatemon_git_root: 'https://github.com/FreifunkBremen/gatemon-html.git'
8 | gatemon_git_version: 'v0.8'
9 |
--------------------------------------------------------------------------------
/roles/gatemon/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install dependencies
3 | command:
4 | cmd: /usr/bin/composer install
5 | chdir: /var/www/{{ gatemon_user }}/domains/{{ gatemon_domain }}
6 | become: yes
7 | become_user: "{{ gatemon_user }}"
8 |
--------------------------------------------------------------------------------
/roles/gatemon/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - sudo
4 | - apache
5 | - letsencrypt
6 | - php
7 | - git
8 | galaxy_info:
9 | platforms:
10 | - name: Debian
11 | versions:
12 | - jessie
13 |
--------------------------------------------------------------------------------
/roles/gatemon/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ gatemon_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ gatemon_subdomain }}.{{ alt_domain }}
6 |
7 | # Enable HTTPS proxying
8 | SSLProxyEngine On
9 |
10 | # Don't add header to proxy
11 | ProxyAddHeaders Off
12 |
13 | # set this to customers mail address
14 | ServerAdmin {{ gatemon_email }}
15 |
16 | SuexecUserGroup {{ gatemon_user }} {{ gatemon_group }}
17 |
18 | DocumentRoot /var/www/{{ gatemon_user }}/domains/{{ gatemon_domain }}
19 |
20 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
21 | Options +SymLinksIfOwnerMatch -Includes
22 |
23 |
24 | Alias /icons /usr/share/apache2/icons
25 | ScriptAlias /cgi-bin /var/www/{{ gatemon_user }}/cgi-bin
26 | ScriptAlias /fcgi-bin /var/www/{{ gatemon_user }}/fcgi-bin
27 | Include /etc/apache2/user-php-exec.conf
28 |
29 | ErrorLog /var/log/apache2/{{ gatemon_user }}/{{ gatemon_domain }}-error.log
30 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
31 |
32 | SSLEngine on
33 | SSLCertificateFile /etc/letsencrypt/certs/{{ gatemon_domain }}/fullchain.pem
34 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ gatemon_domain }}/privkey.pem
35 |
36 |
--------------------------------------------------------------------------------
/roles/gatemon/templates/php-fcgi-starter:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # Set safe path
4 | export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
5 |
6 | # Set user environment
7 | export USER={{ gatemon_user }}
8 | export HOME=/home/{{ gatemon_user }}
9 |
10 | PHP_FCGI_CHILDREN=0
11 | export PHP_FCGI_CHILDREN
12 | PHP_FCGI_MAX_REQUESTS=250
13 | export PHP_FCGI_MAX_REQUESTS
14 | exec php-cgi
15 |
--------------------------------------------------------------------------------
/roles/git/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install git
3 | apt:
4 | name: git
5 |
6 | - name: Install ca-certificates
7 | apt:
8 | name: ca-certificates
9 |
--------------------------------------------------------------------------------
/roles/go/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Download and install go
3 | unarchive:
4 | src: https://golang.org/dl/go1.17.1.linux-amd64.tar.gz
5 | dest: /usr/local
6 | copy: no
7 |
8 | - name: Configure go
9 | template:
10 | src: go.sh
11 | dest: /etc/profile.d/go.sh
12 | mode: 0644
13 | owner: root
14 | group: root
15 |
--------------------------------------------------------------------------------
/roles/go/templates/go.sh:
--------------------------------------------------------------------------------
1 | export GOPATH=/opt/go
2 | export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
3 |
--------------------------------------------------------------------------------
/roles/grafana/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | In influxdb:
5 |
6 | CREATE USER "grafana" WITH PASSWORD 'grafana'
7 |
--------------------------------------------------------------------------------
/roles/grafana/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | grafana_email: 'info@bremen.freifunk.net'
3 | grafana_subdomain: grafana
4 | grafana_domain: '{{ grafana_subdomain }}.{{ main_domain }}'
5 | grafana_addr: 127.0.0.1
6 | grafana_port: 8080
7 | grafana_caddy: false
8 |
9 | # caddy support only
10 | grafana_location: ""
11 |
--------------------------------------------------------------------------------
/roles/grafana/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart grafana
3 | service:
4 | name: grafana-server
5 | state: restarted
6 |
7 | - name: regenerate certificates
8 | command: /opt/dehydrated/dehydrated -f /etc/letsencrypt/config -c
9 |
10 | - name: reload apache
11 | service:
12 | name: apache2
13 | state: reloaded
14 |
15 | - name: reload caddy
16 | service:
17 | name: caddy
18 | state: reloaded
19 |
--------------------------------------------------------------------------------
/roles/grafana/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ grafana_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ grafana_subdomain }}.{{ alt_domain }}
6 |
7 | # set this to customers mail address
8 | ServerAdmin {{ grafana_email }}
9 |
10 | ProxyPass / http://{{ grafana_addr }}:{{ grafana_port }}/
11 |
12 | # Sets CORS headers for request from example1.com and example2.com pages
13 | # for both SSL and non-SSL
14 | SetEnvIf Origin "^https?://[^/]*(ffhb\.de|bremen\.freifunk\.net)$" ORIGIN=$0
15 | Header set Access-Control-Allow-Origin %{ORIGIN}e env=ORIGIN
16 | Header set Access-Control-Allow-Credentials "true" env=ORIGIN
17 | # Always set Vary: Origin when it's possible you may send CORS headers
18 | Header merge Vary Origin
19 |
20 | # Don't add header to proxy
21 | ProxyAddHeaders Off
22 |
23 | # cache tiles for 7 days on disk, ignoring client refreshes
24 | CacheEnable disk /
25 | CacheDisable /.well-known/acme-challenge
26 | CacheDisable /api
27 | CacheDisable /render
28 | CacheDefaultExpire 604800
29 | CacheIgnoreCacheControl on
30 | CacheIgnoreQueryString on
31 | # this unifies the cache for HTTP and HTTPS
32 | CacheKeyBaseURL "http://{{ grafana_domain }}/"
33 |
34 | SSLEngine on
35 | SSLCertificateFile /etc/letsencrypt/certs/{{ grafana_domain }}/fullchain.pem
36 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ grafana_domain }}/privkey.pem
37 |
38 |
--------------------------------------------------------------------------------
/roles/grafana/templates/caddy:
--------------------------------------------------------------------------------
1 | https://{{grafana_domain}}{{grafana_location}} {
2 | tls {{grafana_email}}
3 | gzip
4 | proxy / {{ grafana_addr }}:{{ grafana_port }}
5 | }
6 |
--------------------------------------------------------------------------------
/roles/grafana/templates/grafana.ini:
--------------------------------------------------------------------------------
1 | [server]
2 | http_addr = {{ grafana_addr }}
3 | http_port = {{ grafana_port }}
4 | root_url = https://{{grafana_domain}}{{grafana_location}}
5 |
6 | [analytics]
7 | check_for_updates = true
8 |
9 | [auth.anonymous]
10 | enabled = true
11 |
12 | [log]
13 | # Either "console", "file", "syslog". Default is console and file
14 | # Use comma to separate multiple modes, e.g. "console, file"
15 | mode = console
16 | level = Warn
17 |
18 | [dashboards.json]
19 | enabled = true
20 | path = /var/lib/grafana/dashboards
21 |
--------------------------------------------------------------------------------
/roles/group-webusers/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Added webusers group
3 | group:
4 | name: webusers
5 | state: present
6 |
--------------------------------------------------------------------------------
/roles/influxdb/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p tcp --dport 8083 -j ACCEPT
2 | ipt -A INPUT -p tcp --dport 8086 -j ACCEPT
3 |
--------------------------------------------------------------------------------
/roles/influxdb/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/letsencrypt/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | letsencrypt_git_root: 'https://github.com/lukas2511/dehydrated.git'
3 | letsencrypt_git_commit: '05eda91a2fbaed1e13c733230238fc68475c535e'
4 |
--------------------------------------------------------------------------------
/roles/letsencrypt/files/acme-challenge.conf:
--------------------------------------------------------------------------------
1 | Alias /.well-known/acme-challenge /var/www/acme-challenge
2 |
3 | Require all granted
4 |
5 |
6 | ProxyPass /.well-known/acme-challenge !
7 |
8 |
9 | CacheDisable /.well-known/acme-challenge
10 |
11 |
12 | RewriteOptions InheritDownBefore
13 | RewriteRule ^/.well-known/acme-challenge - [L]
14 |
15 |
--------------------------------------------------------------------------------
/roles/letsencrypt/files/cronjob:
--------------------------------------------------------------------------------
1 | 0 */12 * * * root test -x /opt/dehydrated/dehydrated && perl -e 'sleep int(rand(3600))' && chronic /opt/dehydrated/dehydrated -f /etc/letsencrypt/config -c -g
2 |
--------------------------------------------------------------------------------
/roles/letsencrypt/files/hook.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | case "$1" in
4 | deploy_cert)
5 | systemctl reload apache2
6 | esac
7 |
8 | exit 0
9 |
--------------------------------------------------------------------------------
/roles/letsencrypt/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: regenerate certificates
3 | command: /opt/dehydrated/dehydrated -f /etc/letsencrypt/config -c
4 |
--------------------------------------------------------------------------------
/roles/letsencrypt/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Create directory for letsencrypt challenges
3 | file:
4 | path: /var/www/acme-challenge
5 | state: directory
6 | mode: 0750
7 | owner: root
8 | group: www-data
9 |
10 | - name: Install Apache config for letsencrypt challenges
11 | copy:
12 | src: acme-challenge.conf
13 | dest: /etc/apache2/conf-available/acme-challenge.conf
14 | mode: 0644
15 | owner: root
16 | group: root
17 |
18 | - name: Enable Apache config for letsencrypt challenges
19 | command: a2enconf acme-challenge.conf
20 | args:
21 | creates: /etc/apache2/conf-enabled/acme-challenge.conf
22 |
23 | - name: Install letsencrypt client
24 | git:
25 | repo: "{{ letsencrypt_git_root }}"
26 | version: "{{ letsencrypt_git_commit }}"
27 | dest: '/opt/dehydrated/'
28 |
29 | - name: Create config directory for letsencrypt client
30 | file:
31 | path: /etc/letsencrypt
32 | state: directory
33 | mode: 0755
34 | owner: root
35 | group: root
36 |
37 | - name: Copy letsencrypt client config
38 | copy:
39 | src: config
40 | dest: /etc/letsencrypt/config
41 | mode: 0644
42 | owner: root
43 | group: root
44 | notify: regenerate certificates
45 |
46 | - name: Copy letsencrypt client hook script
47 | copy:
48 | src: hook.sh
49 | dest: /etc/letsencrypt/hook.sh
50 | mode: 0755
51 | owner: root
52 | group: root
53 | notify: regenerate certificates
54 |
55 | - name: Copy letsencrypt cronjob
56 | copy:
57 | src: cronjob
58 | dest: /etc/cron.d/letsencrypt
59 | mode: 0644
60 | owner: root
61 | group: root
62 |
--------------------------------------------------------------------------------
/roles/main-bridge/README.md:
--------------------------------------------------------------------------------
1 | main-bridge
2 | =========================
3 |
4 | Install the bridge for Freifunk Bremen VPN gateways
5 |
6 |
7 | Role Variables
8 | -------------------------
9 |
10 | ffhb_routing_table: Routing table for default gateway via VPN and ICVPN (default: default-freifunk)
11 | batman_interface: Interface on which works Batman (default: 'bat-{{ site_code }}' )
12 |
13 |
14 | Usage
15 | -------------------------
16 |
17 | - hosts: servers
18 | vars:
19 | site_code: ffhb
20 | roles:
21 | - main-bridge
22 |
23 |
24 | License
25 | -------------------------
26 |
27 | GPLv3
28 |
--------------------------------------------------------------------------------
/roles/main-bridge/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | batman_interface: bat-{{ site_code }}
3 | ffhb_routing_table: default-freifunk
4 |
--------------------------------------------------------------------------------
/roles/main-bridge/files/bridge-filter.conf:
--------------------------------------------------------------------------------
1 | net.bridge.bridge-nf-call-ip6tables = 0
2 | net.bridge.bridge-nf-call-iptables = 0
3 | net.bridge.bridge-nf-call-arptables = 0
4 |
--------------------------------------------------------------------------------
/roles/main-bridge/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload sysctl
3 | command: /sbin/sysctl --system
4 |
--------------------------------------------------------------------------------
/roles/main-bridge/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install bridge-utils
3 | apt:
4 | name: bridge-utils
5 |
6 | - name: Create batman routing table
7 | lineinfile:
8 | dest: /etc/iproute2/rt_tables
9 | line: "252 {{ ffhb_routing_table }}"
10 | regexp: "^252 "
11 |
12 | - name: Install interfaces file
13 | template:
14 | src: interfaces
15 | dest: "/etc/network/interfaces.d/br-{{ site_code }}"
16 | mode: 0644
17 | owner: root
18 | group: root
19 |
20 | - name: Copy sysctl file to disable bridge firewall filtering
21 | copy:
22 | src: bridge-filter.conf
23 | dest: /etc/sysctl.d/bridge-filter.conf
24 | mode: 0644
25 | owner: root
26 | group: root
27 | notify: reload sysctl
28 |
29 | - name: Copy sysctl file tuning neighbor discovery
30 | template:
31 | src: main-bridge-ip-neigh-tuning.conf
32 | dest: /etc/sysctl.d/main-bridge-ip-neigh-tuning.conf
33 | mode: 0644
34 | owner: root
35 | group: root
36 | notify: reload sysctl
37 |
38 | - name: Set interfaces up
39 | command: ifup br-{{ site_code }}
40 | register: ifup_result
41 | changed_when: '"already configured" not in ifup_result.stderr'
42 |
--------------------------------------------------------------------------------
/roles/main-bridge/templates/main-bridge-ip-neigh-tuning.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.neigh.br-{{ site_code }}.gc_stale_time = 120
2 | net.ipv4.neigh.br-{{ site_code }}.base_reachable_time_ms = 1800000
3 | net.ipv4.neigh.br-{{ site_code }}.mcast_solicit = 1
4 | net.ipv6.neigh.br-{{ site_code }}.gc_stale_time = 120
5 | net.ipv6.neigh.br-{{ site_code }}.base_reachable_time_ms = 120000
6 | net.ipv6.neigh.br-{{ site_code }}.mcast_solicit = 1
7 |
8 | {% if 'downlinks' in group_names or 'downlinks_legacy' in group_names %}
9 | net.ipv6.neigh.default.gc_thresh1 = 4096
10 | net.ipv6.neigh.default.gc_thresh2 = 8192
11 | net.ipv6.neigh.default.gc_thresh3 = 16384
12 | {% else %}
13 | # gc_thresh1 = size of DHCP pool (minimum number of cached neighbor entries)
14 | net.ipv4.neigh.default.gc_thresh1 = 2560
15 | net.ipv4.neigh.default.gc_thresh2 = 3072
16 | net.ipv4.neigh.default.gc_thresh3 = 4096
17 |
18 | net.ipv6.neigh.default.gc_thresh1 = 1024
19 | net.ipv6.neigh.default.gc_thresh2 = 2048
20 | net.ipv6.neigh.default.gc_thresh3 = 3072
21 | {% endif %}
22 |
--------------------------------------------------------------------------------
/roles/mesh-announce/README.md:
--------------------------------------------------------------------------------
1 | respondd
2 | =========================
3 |
4 | Install respondd from git repo with systemd unit and alfred to announce informations
5 |
6 |
7 | Role Variables
8 | -------------------------
9 |
10 | mesh_announce_git_root: (default: 'https://github.com/ffnord/mesh-announce/')
11 |
12 |
13 | Usage
14 | -------------------------
15 |
16 | - hosts: servers
17 | vars:
18 | site_code: ffhb
19 | roles:
20 | - mesh-announce
21 |
22 | License
23 | -------------------------
24 |
25 | GPLv3
26 |
--------------------------------------------------------------------------------
/roles/mesh-announce/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | mesh_announce_git_root: 'https://github.com/ffnord/mesh-announce/'
3 | mesh_announce_git_commit: 'c34d9f203aba41d1b68967a69e517eb4c0962851'
4 | batman_interface: 'bat-{{ site_code }}'
5 | main_bridge: 'br-{{ site_code }}'
6 |
7 | # alfred
8 | mesh_announce_alfred: false
9 | alfred_master: False
10 | alfred_mtu_interface: 'br-{{ site_code }}-mtu'
11 |
12 | # respondds
13 | respondd_vpn: true
14 |
--------------------------------------------------------------------------------
/roles/mesh-announce/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart respondd
3 | service:
4 | name: respondd
5 | state: restarted
6 |
7 | - name: reload systemd
8 | systemd:
9 | daemon_reload: yes
10 |
--------------------------------------------------------------------------------
/roles/mesh-announce/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - git
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - wheezy
9 | - jessie
10 |
--------------------------------------------------------------------------------
/roles/mesh-announce/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install needed tools
3 | apt:
4 | name: ethtool
5 |
6 | - name: Clone respondd announce repository
7 | git:
8 | repo: "{{ mesh_announce_git_root }}"
9 | dest: "/opt/{{ site_code }}/mesh-announce/"
10 | version: "{{ mesh_announce_git_commit }}"
11 | notify:
12 | - restart respondd
13 |
14 | - name: Install system unit
15 | template:
16 | src: service
17 | dest: /etc/systemd/system/respondd.service
18 | mode: 0644
19 | owner: root
20 | group: root
21 | notify:
22 | - reload systemd
23 | - restart respondd
24 |
25 | - name: Enable respondd
26 | service:
27 | name: respondd
28 | enabled: yes
29 |
30 | - name: Install cronjob to automatically update alfred announce
31 | template:
32 | src: cronjob
33 | dest: /etc/cron.d/mesh-announce-alfred
34 | mode: 0644
35 | owner: root
36 | group: root
37 | when: mesh_announce_alfred
38 |
39 | - name: Open firewall for respondd
40 | template:
41 | src: firewall.sh
42 | dest: "{{ firewall_path }}/30-respondd"
43 | mode: 0644
44 | owner: root
45 | group: root
46 | when: firewall_enabled
47 | notify: reload firewall
48 |
--------------------------------------------------------------------------------
/roles/mesh-announce/templates/cronjob:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
3 | {% if alfred_master %}
4 | * * * * * root sh /opt/{{ site_code }}/mesh-announce/announce.sh -i {{ alfred_mtu_interface }} -b {{ batman_interface }}
5 | {% else %}
6 | * * * * * root sh /opt/{{ site_code }}/mesh-announce/announce.sh -i {{ main_bridge }} -b {{ batman_interface }}
7 | {% endif %}
8 |
--------------------------------------------------------------------------------
/roles/mesh-announce/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt6 -A INPUT -i '{{ main_bridge }}' -p udp --dport 1001 -j ACCEPT
2 | ipt6 -A INPUT -i 'vpn-{{ site_code }}-legacy' -p udp --dport 1001 -j ACCEPT
3 | ipt6 -A INPUT -i 'vpn-{{ site_code }}' -p udp --dport 1001 -j ACCEPT
4 |
--------------------------------------------------------------------------------
/roles/mesh-announce/templates/service:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | [Unit]
3 | Description=Respondd
4 | After=network.target
5 |
6 | [Service]
7 | {% if respondd_vpn %}
8 | ExecStart=/opt/{{ site_code }}/mesh-announce/respondd.py -d /opt/{{ site_code }}/mesh-announce/providers -b {{ batman_interface }} -i {{ main_bridge }} -i vpn-{{ site_code }}-legacy -i vpn-{{ site_code }}
9 | {% else %}
10 | ExecStart=/opt/{{ site_code }}/mesh-announce/respondd.py -d /opt/{{ site_code }}/mesh-announce/providers -b {{ ansible_default_ipv4.interface }} -i {{ ansible_default_ipv4.interface }}
11 | {% endif %}
12 |
13 | [Install]
14 | WantedBy=multi-user.target
15 |
--------------------------------------------------------------------------------
/roles/meshviewer/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | meshviewer_git_root: "{{ site_git_root }}/meshviewer.git"
3 | meshviewer_git_version: '19bc3e505e6ac265210f20741b1e372ef598ce1e'
4 | meshviewer_path_bin: '/var/www/html/meshviewer'
5 | meshviewer_path_src: '/usr/src/meshviewer'
6 |
7 | meshviewer_apache: true
8 |
9 | meshviewer_geojson: false
10 | meshviewer_geojson_git_root: 'https://github.com/FreifunkBremen/internal-maps.git'
11 | meshviewer_geojson_git_commit: '69dcaa8a22885549b89038c51d49d2470eec56bf'
12 | meshviewer_geojson_file: 'meshviewer.geojson'
13 | meshviewer_geojson_file_path: '/var/www/html/data'
14 |
--------------------------------------------------------------------------------
/roles/meshviewer/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - apt
4 | - git
5 | - nodejs
6 | galaxy_info:
7 | platforms:
8 | - name: Debian
9 | versions:
10 | - jessie
11 |
--------------------------------------------------------------------------------
/roles/meshviewer/tasks/apache.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Get letsencrypt certificates
3 | lineinfile:
4 | dest: /etc/letsencrypt/domains.txt
5 | line: "{{ meshviewer_subdomain }}.{{ main_domain }} {{ meshviewer_subdomain }}.{{ alt_domain }}"
6 | create: yes
7 | mode: 0644
8 | owner: root
9 | group: root
10 | when: meshviewer_subdomain is defined
11 | notify: regenerate certificates
12 |
13 | - name: Install Apache vHost config
14 | template:
15 | src: apache2.conf
16 | dest: "/etc/apache2/sites-available/{{ filename }}.conf"
17 | mode: 0644
18 | owner: root
19 | group: root
20 | notify: reload apache
21 | vars:
22 | filename: "{{ meshviewer_subdomain is defined | ternary(meshviewer_subdomain + '.' + main_domain, meshviewer_domain) }}"
23 |
24 | - name: Enable Apache vHost config
25 | command: a2ensite {{ filename }}
26 | args:
27 | creates: /etc/apache2/sites-enabled/{{ filename }}.conf
28 | notify: reload apache
29 | vars:
30 | filename: "{{ meshviewer_subdomain is defined | ternary(meshviewer_subdomain + '.' + main_domain, meshviewer_domain) }}"
31 |
--------------------------------------------------------------------------------
/roles/meshviewer/tasks/geojson.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Clone repository
3 | git:
4 | repo: "{{ meshviewer_geojson_git_root }}"
5 | dest: "/opt/meshviewer_geojson_git"
6 | force: yes
7 | version: "{{ meshviewer_geojson_git_commit }}"
8 |
9 | - name: Install script to copy valide geojson
10 | template:
11 | src: geojson-update.sh
12 | dest: /usr/local/bin/geojson-update
13 | owner: root
14 | group: root
15 | mode: 0755
16 |
17 | - name: Install cronjob to copy valide geojson
18 | template:
19 | src: geojson.cronjob
20 | dest: /etc/cron.d/geojson-update
21 | owner: root
22 | group: root
23 | mode: 0644
24 |
--------------------------------------------------------------------------------
/roles/meshviewer/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install yarn
3 | npm:
4 | name: yarn
5 | global: yes
6 |
7 | - name: Clone repository
8 | git:
9 | repo: "{{ meshviewer_git_root }}"
10 | dest: "{{ meshviewer_path_src }}/"
11 | version: "{{ meshviewer_git_version }}"
12 | force: yes
13 |
14 | - name: Install node dependencies
15 | command: node /usr/bin/yarn install
16 | args:
17 | chdir: "{{ meshviewer_path_src }}"
18 | creates: node_modules
19 |
20 | - name: Build meshviewer
21 | command: node_modules/.bin/gulp
22 | args:
23 | chdir: "{{ meshviewer_path_src }}"
24 | creates: build
25 |
26 | - name: Create destination directory
27 | file:
28 | path: "{{ meshviewer_path_bin }}"
29 | state: directory
30 | mode: 0755
31 | owner: root
32 | group: root
33 |
34 | - name: Install rsync
35 | apt:
36 | name: rsync
37 |
38 | # does not work (https://github.com/ansible/ansible/issues/11873)
39 | #- name: Copy generated files
40 | # delegate_to: "{{ inventory_hostname }}"
41 | # synchronize:
42 | # src: {{ meshviewer_path_src }}/build/
43 | # dest: {{ meshviewer_path_bin }}/
44 | # delete: True
45 | # rsync_opts:
46 | # - "--exclude=config.json"
47 |
48 | - name: Copy files
49 | command: >
50 | rsync -a --delete
51 | {{ meshviewer_path_src }}/build/
52 | {{ meshviewer_path_bin }}/
53 |
54 | - name: Enable Apache
55 | include: apache.yml
56 | when: meshviewer_apache
57 |
58 | - name: Enable Geojson
59 | import_tasks: geojson.yml
60 | when: meshviewer_geojson
61 |
--------------------------------------------------------------------------------
/roles/meshviewer/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | {% if meshviewer_subdomain is defined %}
5 | ServerName {{ meshviewer_subdomain }}.{{ main_domain }}
6 | ServerAlias {{ meshviewer_subdomain }}.{{ alt_domain }}
7 | {% else %}
8 | ServerName {{ meshviewer_domain }}
9 | {% endif %}
10 |
11 | ServerAdmin {{ meshviewer_email }}
12 |
13 | DocumentRoot {{ meshviewer_path_bin }}
14 | Alias /icons /usr/share/apache2/icons
15 |
16 | SSLEngine on
17 | SSLCertificateFile /etc/letsencrypt/certs/{{ meshviewer_domain }}/fullchain.pem
18 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ meshviewer_domain }}/privkey.pem
19 |
20 |
--------------------------------------------------------------------------------
/roles/meshviewer/templates/geojson-update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | MAP_GIT='/opt/meshviewer_geojson_git'
4 |
5 | if [ ! -d "$MAP_GIT" ]; then
6 | echo "${MAP_GIT} does not exists!" >&2
7 | exit 1
8 | fi
9 |
10 | git -C "$MAP_GIT" pull
11 | if jq . "$MAP_GIT/{{meshviewer_geojson_file}}"; then
12 | cp "$MAP_GIT/{{meshviewer_geojson_file}}" "{{meshviewer_geojson_file_path}}/meshviewer.geojson"
13 | fi
14 |
--------------------------------------------------------------------------------
/roles/meshviewer/templates/geojson.cronjob:
--------------------------------------------------------------------------------
1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
2 | */5 * * * * root /usr/local/bin/geojson-update
3 |
--------------------------------------------------------------------------------
/roles/monitoring-client/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | main_bridge: "br-{{ site_code }}"
3 | cmk_version: 2.2.0p30
4 | cmk_url: 'https://monitoring.bremen.freifunk.net/ffhb'
5 | cmk_plugins:
6 | - name: mk_filehandler
7 | - name: mk_sshd_config
8 | - name: mk_apt
9 | interval: 3600
10 | - name: mk_inventory.linux
11 | interval: 3600
12 | - name: admins
13 | local: true
14 | - name: systemtime
15 | local: true
16 | - name: lsbrelease
17 | local: true
18 | - name: fail2ban
19 | local: true
20 | - name: smart
21 | include: '{{ ansible_virtualization_role != "guest" }}'
22 | - name: unbound
23 | local: true
24 | include: "{{ (('vpnservers' in group_names) or ('vpnservers_legacy' in group_names)) }}"
25 | cmk_mrpe_checks:
26 | - name: conntrack
27 | command: /usr/local/lib/nagios/plugins/check_conntrack.sh 80 90
28 | include: "{{ (('vpnservers' in group_names) or ('vpnservers_legacy' in group_names)) }}"
29 | - name: dhcp
30 | command: /usr/lib/nagios/plugins/check_dhcp -i {{ main_bridge }} -u -s {{ batman_ipv4.address }} -t 5
31 | include: "{{ (('vpnservers' in group_names) or ('vpnservers_legacy' in group_names)) }}"
32 | - name: needrestart
33 | command: /usr/sbin/needrestart -p
34 | interval: 3600
35 | - name: etckeeper
36 | command: /usr/local/lib/nagios/plugins/check_git_status /etc
37 |
--------------------------------------------------------------------------------
/roles/monitoring-client/files/98mk-apt:
--------------------------------------------------------------------------------
1 | #
2 | # retrigger mk-apt
3 | #
4 | # If you want use this hook, copy this file to:
5 | # /etc/apt/apt.conf.d/98mk-apt.
6 | #
7 | # For further details please consult the check manual page of apt.
8 |
9 | DPkg::Post-Invoke {"touch -t 197012181200 /var/lib/check_mk_agent/cache/*mk_apt.cache"; };
10 |
--------------------------------------------------------------------------------
/roles/monitoring-client/files/authorized_keys:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJt2JopyozJi6md8wKlK5DNwmMVy7q+Si9x9I7xBWzhYEZjhlIRR13pWzDgxsE/ETEgRld5j1Tv20Tqfx4vGCRLKTqvYWXLczC5f59RnFCDcSnGTWh/lJKRRY0spEqAhn+jEp3U4wGE+bXw+oPt127E6HcItqz0zhd5RdiA3auC5UkG1xKnza1Eh/+E+obdkswSQoe3A2tOO5rF3m4/K4O/CzHL0iJytmduwy8sNL1RO5adEu72HSrCn/xKTRtvfHS5CXxpPk4qBtCc/N7TrGX734bGiljgPlIBmGbfFzpDAARaC87YWKMmwCoOG4PN8ZY169gzrsnIMZvQUWQ5ao2eZ7XFpn+7MwgXKG+5Bf21dm1iYygHJqRwwhsf50d+p3e0lzPSLCybiE88DBG0SlJ8iWuBbWFmPCaigUHj2AlMopjsSspIoTUHHNByH3gCP4WU0ZjGMtjlhm31vakAjVMvb/ZmmNhoZHGlEB0FwNdoImM+3TSwE0IKMF7khEK3/dpmOJ1kF7Q7Rce9002jEd1UB/rGYI/+d7ChJLyEiCS9dZqkJOADoY9dK3pOovUPQALj7+8QRqLGb0STE+Di+xP486vGDmG5a6WDQS9oBOxv8wuYlToocjvfxZb9hqLhssDmNHMUhdHi63XmLfR1cvWBSQmiYnNuEZ/R4q6ZBHy7w== Monitoring key of ffhb-monitoring
2 |
--------------------------------------------------------------------------------
/roles/monitoring-client/files/plugins/check_git_status:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # Copyright © 2010 by Daniel Friesel
4 | # License: WTFPL:
5 | # 0. You just DO WHAT THE FUCK YOU WANT TO.
6 | #
7 | # You probably need to run this check via sudo. For /etc,
8 | # > nagios ALL=(root) NOPASSWD: /usr/local/lib/nagios/plugins/check_git_status /etc
9 | # should do the job.
10 |
11 | declare -i STATE_OK=0
12 | declare -i STATE_WARNING=1
13 | declare -i STATE_CRITICAL=2
14 | declare -i STATE_UNKNOWN=3
15 |
16 | GIT="/usr/bin/git"
17 |
18 | REPO="${1}"
19 |
20 | if [ ! -x ${GIT} ]; then
21 | echo "Can't execute ${GIT}"
22 | exit $STATE_UNKNOWN
23 | fi
24 |
25 | if [ $# -lt 1 ]; then
26 | echo "Usage: $0 "
27 | exit $STATE_UNKNOWN
28 | fi
29 |
30 | if [ -z "${REPO}/.git" -o ! -d "${REPO}/.git" ]; then
31 | echo "No repo specified or ${REPO} is not a git repo"
32 | exit $STATE_UNKNOWN
33 | fi
34 |
35 | cd "${REPO}" || exit $STATE_UNKNOWN
36 |
37 | if [ -z "$(${GIT} ls-files --modified --deleted --others --exclude-standard)" ]; then
38 | echo "No uncommited changes in ${REPO}"
39 | exit $STATE_OK
40 | else
41 | echo "Uncommited changes in ${REPO}"
42 | exit $STATE_WARNING
43 | fi
44 |
45 | echo "Someting went wrong"
46 | exit $STATE_UNKNOWN
47 |
--------------------------------------------------------------------------------
/roles/monitoring-client/files/plugins/check_rkhunter:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | declare -i STATE_OK=0
4 | declare -i STATE_WARNING=1
5 | declare -i STATE_CRITICAL=2
6 | declare -i STATE_UNKNOWN=3
7 |
8 | if [ ! -f /etc/rkhunter.conf ]; then
9 | ERR_MSG="rkhunter.conf not found. So probably rkhunter is not installed!"
10 | ERR_CODE=$STATE_CRITICAL
11 | else
12 | ERR_MSG="rkhunter.conf found. So rkhunter is installed."
13 | ERR_CODE=$STATE_OK
14 | fi
15 |
16 | if [ $ERR_CODE -eq $STATE_OK ]; then
17 | echo "OK: $ERR_MSG"
18 | else
19 | echo "ERROR: $ERR_MSG"
20 | fi
21 |
22 | exit $ERR_CODE
23 |
--------------------------------------------------------------------------------
/roles/monitoring-client/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
--------------------------------------------------------------------------------
/roles/motd/files/add-motd-tail:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | if [ -e /etc/motd.tail ]; then
4 | cat /etc/motd.tail
5 | fi
6 |
--------------------------------------------------------------------------------
/roles/motd/files/figlet:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | /usr/bin/figlet $(hostname)
4 |
--------------------------------------------------------------------------------
/roles/motd/files/remove-motd-dynamic:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | if [ -e /var/run/motd.dynamic ]; then
4 | rm /var/run/motd.dynamic
5 | fi
6 |
--------------------------------------------------------------------------------
/roles/motd/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install figlet
3 | apt:
4 | name: figlet
5 |
6 | - name: Create /etc/update-motd.d
7 | file:
8 | path: /etc/update-motd.d
9 | state: directory
10 | mode: 0755
11 | owner: root
12 | group: root
13 |
14 | - name: Copy script to create hostname banner
15 | copy:
16 | src: figlet
17 | dest: /etc/update-motd.d/10figlet
18 | owner: root
19 | group: root
20 | mode: 0755
21 |
22 | - name: Copy script to remove /var/run/motd.dynamic
23 | copy:
24 | src: remove-motd-dynamic
25 | dest: /etc/update-motd.d/20remove-motd-dynamic
26 | owner: root
27 | group: root
28 | mode: 0755
29 |
30 | - name: Copy script to add motd.tail to motd
31 | copy:
32 | src: add-motd-tail
33 | dest: /etc/update-motd.d/30add-motd-tail
34 | owner: root
35 | group: root
36 | mode: 0755
37 |
38 | - name: Create symlink
39 | file:
40 | src: /run/motd
41 | dest: /etc/motd
42 | state: link
43 | force: yes
44 |
--------------------------------------------------------------------------------
/roles/mysql-server/README.md:
--------------------------------------------------------------------------------
1 | mysql-server
2 | =========================
3 |
4 | Installs MySQL server
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - mysql-server
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/mysql-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart mysql
3 | service:
4 | name: mysql
5 | state: restarted
6 |
--------------------------------------------------------------------------------
/roles/mysql-server/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/mysql-server/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install MySQL server
3 | apt:
4 | name: mariadb-server
5 |
6 | - name: Increase max_allowed_packet setting
7 | lineinfile:
8 | dest: /etc/mysql/mariadb.conf.d/50-server.cnf
9 | regexp: '^\s*max_allowed_packet\s*='
10 | line: 'max_allowed_packet = 32M'
11 | notify: restart mysql
12 |
--------------------------------------------------------------------------------
/roles/nginx/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p tcp --dport 80 -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/nginx/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install nginx with Lua
3 | apt:
4 | name:
5 | - nginx-light
6 | - libnginx-mod-http-lua
7 |
8 | - name: Open firewall for nginx
9 | copy:
10 | src: firewall.sh
11 | dest: "{{ firewall_path }}/30-nginx"
12 | mode: 0644
13 | owner: root
14 | group: root
15 | when: firewall_enabled
16 | notify: reload firewall
17 |
--------------------------------------------------------------------------------
/roles/nodejs/README.md:
--------------------------------------------------------------------------------
1 | nodejs
2 | =========================
3 |
4 | Install nodejs from
5 | Repository
6 |
7 |
8 | Usage
9 | -------------------------
10 |
11 | - hosts: servers
12 | roles:
13 | - nodejs
14 |
15 |
16 | License
17 | -------------------------
18 |
19 | GPLv3
20 |
--------------------------------------------------------------------------------
/roles/nodejs/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/nodejs/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Fetch APT repository key
3 | apt_key:
4 | url: 'https://deb.nodesource.com/gpgkey/nodesource.gpg.key'
5 | state: present
6 |
7 | - name: Install the Node.js APT repository
8 | apt_repository:
9 | repo: "deb https://deb.nodesource.com/node_14.x {{ ansible_distribution_release }} main"
10 |
11 | - name: Install Node.js
12 | apt:
13 | name: nodejs
14 |
--------------------------------------------------------------------------------
/roles/nodemon/README.md:
--------------------------------------------------------------------------------
1 | nodemon
2 | =========================
3 |
4 | Installing nodemon
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - nodemon
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/nodemon/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | nodemon_email: 'nodemon@bremen.freifunk.net'
3 | nodemon_user: 'nodemon'
4 | nodemon_group: 'nodemon'
5 | nodemon_subdomain: 'nodemon'
6 | nodemon_domain: '{{ nodemon_subdomain }}.{{ main_domain }}'
7 | nodemon_git_root: 'https://github.com/FreifunkBremen/nodemon.git'
8 | nodemon_git_version: 'v0.2'
9 |
--------------------------------------------------------------------------------
/roles/nodemon/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install dependencies
3 | command:
4 | cmd: /usr/bin/composer install
5 | chdir: /var/www/{{ nodemon_user }}/domains/{{ nodemon_domain }}
6 | become: yes
7 | become_user: "{{ nodemon_user }}"
8 |
--------------------------------------------------------------------------------
/roles/nodemon/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - sudo
4 | - apache
5 | - letsencrypt
6 | - php
7 | - git
8 | galaxy_info:
9 | platforms:
10 | - name: Debian
11 | versions:
12 | - jessie
13 |
--------------------------------------------------------------------------------
/roles/nodemon/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ nodemon_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ nodemon_subdomain }}.{{ alt_domain }}
6 |
7 | # Enable HTTPS proxying
8 | SSLProxyEngine On
9 |
10 | # Don't add header to proxy
11 | ProxyAddHeaders Off
12 |
13 | # set this to customers mail address
14 | ServerAdmin {{ nodemon_email }}
15 |
16 | SuexecUserGroup {{ nodemon_user }} {{ nodemon_group }}
17 |
18 | DocumentRoot /var/www/{{ nodemon_user }}/domains/{{ nodemon_domain }}
19 |
20 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
21 | Options +SymLinksIfOwnerMatch -Includes
22 |
23 |
24 | Alias /icons /usr/share/apache2/icons
25 | ScriptAlias /cgi-bin /var/www/{{ nodemon_user }}/cgi-bin
26 | ScriptAlias /fcgi-bin /var/www/{{ nodemon_user }}/fcgi-bin
27 | Include /etc/apache2/user-php-exec.conf
28 |
29 | ErrorLog /var/log/apache2/{{ nodemon_user }}/{{ nodemon_domain }}-error.log
30 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
31 |
32 | SSLEngine on
33 | SSLCertificateFile /etc/letsencrypt/certs/{{ nodemon_domain }}/fullchain.pem
34 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ nodemon_domain }}/privkey.pem
35 |
36 |
--------------------------------------------------------------------------------
/roles/nodemon/templates/php-fcgi-starter:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # Set safe path
4 | export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
5 |
6 | # Set user environment
7 | export USER={{ nodemon_user }}
8 | export HOME=/home/{{ nodemon_user }}
9 |
10 | PHP_FCGI_CHILDREN=0
11 | export PHP_FCGI_CHILDREN
12 | PHP_FCGI_MAX_REQUESTS=250
13 | export PHP_FCGI_MAX_REQUESTS
14 | exec php-cgi
15 |
--------------------------------------------------------------------------------
/roles/non_persistent_logging/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart journald
3 | systemd:
4 | name: systemd-journald
5 | state: restarted
6 |
--------------------------------------------------------------------------------
/roles/non_persistent_logging/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Remove syslog daemons
3 | apt:
4 | name:
5 | - busybox-syslogd
6 | - dsyslog
7 | - inetutils-syslogd
8 | - rsyslog
9 | - syslog-ng
10 | state: absent
11 | purge: yes
12 |
13 | - name: Disable persistent storage
14 | replace:
15 | dest: /etc/systemd/journald.conf
16 | regexp: '^\#?Storage=.*$'
17 | replace: 'Storage=volatile'
18 | mode: '0644'
19 | notify:
20 | - restart journald
21 |
--------------------------------------------------------------------------------
/roles/nsd/README.md:
--------------------------------------------------------------------------------
1 | nsd
2 | =========================
3 |
4 | Install and configure NSD
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - nsd
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/nsd/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | nsd_update_nodes: false
3 | dns_nsd_git_repo: 'https://github.com/FreifunkBremen/ffhb-dns/'
4 | dns_nsd_git_commit: '01b065797e13f77fcc02b1c80c11a7a541229f9b'
5 |
--------------------------------------------------------------------------------
/roles/nsd/files/cronjob:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | /usr/local/bin/zonegen.py \
4 | http://downloads.bremen.freifunk.net/data/v1/nodes.json \
5 | --contact=noc.bremen.freifunk.net \
6 | --prefix=2a06:8782:ffbb::/48 \
7 | --nserver dns.bremen.freifunk.net ns2.afraid.org ns2.he.net \
8 | --file=/var/lib/nsd/nodes.bremen.freifunk.net.zone || exit
9 |
10 | # TODO: fix me! we could auto generate this based on ipv6_global_network
11 | /usr/local/bin/zonegen.py \
12 | http://downloads.bremen.freifunk.net/data/v1/nodes.json \
13 | --contact=noc.bremen.freifunk.net \
14 | --prefix=2a06:8782:ffbb:42::/64 \
15 | --nserver dns.bremen.freifunk.net ns2.afraid.org ns2.he.net \
16 | --file=/var/lib/nsd/2.4.0.0.b.b.f.f.2.8.7.8.6.0.a.2.ip6.arpa.zone --reverse nodes.ffhb.de. || exit
17 |
18 | /usr/local/bin/zonegen.py \
19 | http://downloads.bremen.freifunk.net/data/v1/nodes.json \
20 | --contact=noc.bremen.freifunk.net \
21 | --prefix=2a06:8782:ffbb:1337::/64 \
22 | --nserver dns.bremen.freifunk.net ns2.afraid.org ns2.he.net \
23 | --file=/var/lib/nsd/7.3.3.1.b.b.f.f.2.8.7.8.6.0.a.2.ip6.arpa.zone --reverse nodes.ffhb.de. || exit
24 |
25 | /usr/local/bin/zonegen.py \
26 | http://downloads.bremen.freifunk.net/data/v1/nodes.json \
27 | --contact=noc.bremen.freifunk.net \
28 | --prefix=2a06:8782:ffbb:bab0::/64 \
29 | --nserver dns.bremen.freifunk.net ns2.afraid.org ns2.he.net \
30 | --file=/var/lib/nsd/0.b.a.b.b.b.f.f.2.8.7.8.6.0.a.2.ip6.arpa.zone --reverse nodes.ffhb.de. || exit
31 |
32 | nsd-control reload > /dev/null
33 |
--------------------------------------------------------------------------------
/roles/nsd/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p udp --dport 53 -j ACCEPT
2 | ipt -A INPUT -p tcp --dport 53 -j ACCEPT
3 |
--------------------------------------------------------------------------------
/roles/nsd/files/update-dns-zones.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
4 |
5 | DNS_ZONES_FOLDER='/opt/ffhb/dns'
6 |
7 | # Check if DNS zones folder exists
8 | if [ ! -d "$DNS_ZONES_FOLDER" ]; then
9 | echo "${DNS_ZONES_FOLDER} does not exists!" >&2
10 | exit 1
11 | fi
12 |
13 | git -C "$DNS_ZONES_FOLDER" pull
14 |
15 | for DNS_ZONE in "${DNS_ZONES_FOLDER}/"*.zone; do
16 | if ! nsd-checkzone "$(basename "$DNS_ZONE" '.zone')" "$DNS_ZONE"; then
17 | continue
18 | fi
19 |
20 | cp "$DNS_ZONE" "/var/lib/nsd/"
21 |
22 | # Reload DNS server configuration
23 | nsd-control reconfig >/dev/null
24 |
25 | # Reload zone
26 | nsd-control reload "$(basename "$DNS_ZONE" '.zone')"
27 |
28 | # Notify slaves about changed zones
29 | nsd-control notify "$(basename "$DNS_ZONE" '.zone')"
30 | done
31 |
--------------------------------------------------------------------------------
/roles/nsd/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart nsd
3 | service:
4 | name: nsd
5 | state: restarted
6 |
7 | - name: copy zone files
8 | command: /usr/local/sbin/update-dns-zones.sh
9 |
--------------------------------------------------------------------------------
/roles/nsd/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 | - git
5 | galaxy_info:
6 | platforms:
7 | - name: Debian
8 | versions:
9 | - wheezy
10 | - jessie
11 |
--------------------------------------------------------------------------------
/roles/nsd/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install packages
3 | apt:
4 | name:
5 | - nsd
6 | - python3
7 |
8 | - name: Configure NSD
9 | template:
10 | src: nsd.conf
11 | dest: /etc/nsd/nsd.conf
12 | mode: 0644
13 | owner: root
14 | group: root
15 | notify: restart nsd
16 |
17 | - name: Clone internal dns repo
18 | git:
19 | repo: "{{ dns_nsd_git_repo }}"
20 | dest: "/opt/{{ site_code }}/dns/"
21 | version: "{{ dns_nsd_git_commit }}"
22 | notify: copy zone files
23 |
24 | - name: Install script to copy zone files
25 | copy:
26 | src: update-dns-zones.sh
27 | dest: /usr/local/sbin/update-dns-zones.sh
28 | mode: 0755
29 | owner: root
30 | group: root
31 |
32 | - name: Install script to generate nodes zone
33 | copy:
34 | src: zonegen.py
35 | dest: /usr/local/bin/zonegen.py
36 | mode: 0755
37 | owner: root
38 | group: root
39 |
40 | - name: Install cronjob to generate nodes zone
41 | copy:
42 | src: cronjob
43 | dest: /etc/cron.hourly/zonegen
44 | mode: 0755
45 | owner: root
46 | group: root
47 |
48 | - name: Initially generate nodes zone
49 | command:
50 | cmd: /etc/cron.hourly/zonegen
51 | creates: /var/lib/nsd/nodes.bremen.freifunk.net.zone
52 |
53 | - name: Open firewall for DNS
54 | copy:
55 | src: firewall.sh
56 | dest: "{{ firewall_path }}/30-nsd"
57 | mode: 0644
58 | owner: root
59 | group: root
60 | when: firewall_enabled
61 | notify: reload firewall
62 |
63 | - name: Autostart NSD
64 | service:
65 | name: nsd
66 | enabled: yes
67 |
--------------------------------------------------------------------------------
/roles/nsd/templates/nsd.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | server:
3 | hide-version: yes
4 | identity: "unidentified server"
5 | ip4-only: no
6 | ip6-only: no
7 | debug-mode: no
8 | pidfile: "/run/nsd.pid"
9 | zonesdir: "/var/lib/nsd"
10 | verbosity: 0
11 |
12 | pattern:
13 | name: default
14 | zonefile: "%s.zone"
15 | # dns.he.net
16 | notify: 216.218.130.2 NOKEY
17 | provide-xfr: 216.218.133.2 NOKEY
18 | provide-xfr: 2001:470:600::2 NOKEY
19 | # afraid.org
20 | notify: 69.65.50.192 NOKEY
21 | notify: 2001:1850:1:5:800::6b NOKEY
22 | notify: 69.65.50.223 NOKEY
23 | provide-xfr: 69.65.50.192 NOKEY
24 | provide-xfr: 2001:1850:1:5:800::6b NOKEY
25 | provide-xfr: 69.65.50.223 NOKEY
26 |
27 | zone:
28 | name: {{ dns_domain_freifunk_net }}
29 | include-pattern: default
30 |
31 | zone:
32 | name: nodes.{{ dns_domain_freifunk_net }}
33 | include-pattern: default
34 |
35 | zone:
36 | name: {{ site_code }}.de
37 | include-pattern: default
38 | zonefile: {{ dns_domain_freifunk_net }}.zone
39 |
40 | zone:
41 | name: nodes.{{ site_code }}.de
42 | include-pattern: default
43 | zonefile: nodes.{{ dns_domain_freifunk_net }}.zone
44 |
45 | zone:
46 | name: on{{ site_code }}.de
47 | include-pattern: default
48 |
49 | zone:
50 | name: 2.8.7.8.6.0.a.2.ip6.arpa
51 | include-pattern: default
52 |
53 | zone:
54 | name: 7.3.3.1.b.b.f.f.2.8.7.8.6.0.a.2.ip6.arpa
55 | include-pattern: default
56 |
57 | zone:
58 | name: 0.b.a.b.b.b.f.f.2.8.7.8.6.0.a.2.ip6.arpa
59 | include-pattern: default
60 |
61 | zone:
62 | name: 213.117.185.in-addr.arpa
63 | include-pattern: default
64 |
--------------------------------------------------------------------------------
/roles/nullmailer/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | nullmailer_remote_server: 'mail.bremen.freifunk.net'
3 | mail_root_target: 'server@bremen.freifunk.net'
4 |
--------------------------------------------------------------------------------
/roles/nullmailer/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart nullmailer
3 | service:
4 | name: nullmailer
5 | state: restarted
6 |
--------------------------------------------------------------------------------
/roles/nullmailer/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install local mailserver
3 | apt:
4 | name: nullmailer
5 |
6 | - name: Copy nullmailer remote
7 | template:
8 | src: remotes
9 | dest: /etc/nullmailer/remotes
10 | mode: '0640'
11 | owner: root
12 | group: "{{ group }}"
13 | notify: restart nullmailer
14 | vars:
15 | group: "{{ (ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu') | ternary('mail', 'nullmail') }}"
16 |
17 | - name: Copy nullmailer adminaddr
18 | copy:
19 | dest: /etc/nullmailer/adminaddr
20 | content: "{{ mail_root_target }}\n"
21 | mode: 0644
22 | owner: root
23 | group: root
24 | notify: restart nullmailer
25 |
--------------------------------------------------------------------------------
/roles/nullmailer/templates/remotes:
--------------------------------------------------------------------------------
1 | {{ nullmailer_remote_server }} smtp{% if nullmailer_remote_user is defined %} --user={{ nullmailer_remote_user }} --pass={{ nullmailer_remote_password }}{% endif %}
2 |
--------------------------------------------------------------------------------
/roles/openssh/README.md:
--------------------------------------------------------------------------------
1 | openssh
2 | =========================
3 |
4 | Some hardening for your OpenSSH daemon
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - openssh
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/openssh/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p tcp --dport 22 -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/openssh/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload ssh
3 | service:
4 | name: ssh
5 | state: reloaded
6 |
--------------------------------------------------------------------------------
/roles/openssh/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/openssh/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Update SSH configuration
3 | replace:
4 | path: /etc/ssh/sshd_config
5 | regexp: '^([\#\s]*)?{{ item.key }}\s+([\w_-]+)'
6 | replace: "{{ item.key }} {{ item.value }}"
7 | backup: yes
8 | with_items:
9 | - key: PermitRootLogin
10 | value: without-password
11 | - key: PasswordAuthentication
12 | value: 'no'
13 | - key: ChallengeResponseAuthentication
14 | value: 'no'
15 | - key: PrintLastLog
16 | value: 'no'
17 | notify:
18 | - reload ssh
19 |
20 | - name: Open firewall for SSH
21 | copy:
22 | src: firewall.sh
23 | dest: "{{ firewall_path }}/10-ssh"
24 | mode: 0644
25 | owner: root
26 | group: root
27 | when: firewall_enabled
28 | notify: reload firewall
29 |
--------------------------------------------------------------------------------
/roles/php/README.md:
--------------------------------------------------------------------------------
1 | PHP
2 | =========================
3 |
4 | Installing PHP
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - php
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/php/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/php/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install PHP and needed modules
3 | apt:
4 | name:
5 | - composer
6 | - php7.4-cgi
7 | - php7.4-cli
8 | - php7.4-curl
9 | - php7.4-dev
10 | - php7.4-gd
11 | - php7.4-mysql
12 | - php7.4-sqlite3
13 | - php7.4-apcu
14 |
--------------------------------------------------------------------------------
/roles/restic/README.md:
--------------------------------------------------------------------------------
1 | restic
2 | =========================
3 |
4 | Install Restic backup tool
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - restic
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/restic/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | restic_version: 0.9.1
3 | restic_release_checksum: sha1:e65f3025db0ade9b7515da067a949b3d8b230a8a
4 |
--------------------------------------------------------------------------------
/roles/restic/files/backup-restic.default:
--------------------------------------------------------------------------------
1 | EXCLUDES=('/dev' '/proc' '/sys' '/var/run' '/var/tmp' '/run' '/lost+found' '/mnt' '/tmp')
2 | TARGETS=()
3 | BACKUP_NICE=0
4 | BACKUP_PASSWORDS=()
5 |
6 | backup_prepare() {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/roles/restic/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install restic
3 | apt:
4 | name: restic
5 |
6 | - name: Copy cronjob
7 | copy:
8 | src: backup-restic
9 | dest: /etc/cron.daily/backup-restic
10 | mode: 0755
11 | owner: root
12 | group: root
13 |
14 | - name: Copy configuration file
15 | copy:
16 | src: backup-restic.default
17 | dest: /etc/default/backup-restic
18 | mode: 0600
19 | owner: root
20 | group: root
21 | force: no
22 |
--------------------------------------------------------------------------------
/roles/rkhunter/README.md:
--------------------------------------------------------------------------------
1 | rkhunter
2 | =========================
3 |
4 | Installs rkhunter
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - rkhunter
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/rkhunter/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/router-bird/README.md:
--------------------------------------------------------------------------------
1 | router-bird
2 | =========================
3 |
4 | Install bird
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - router-bird
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/router-bird/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ffhb_routing_table: default-freifunk
3 |
--------------------------------------------------------------------------------
/roles/router-bird/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload bird
3 | service:
4 | name: bird
5 | state: reloaded
6 |
7 | - name: reload bird6
8 | service:
9 | name: bird6
10 | state: reloaded
11 |
--------------------------------------------------------------------------------
/roles/router-bird/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 |
--------------------------------------------------------------------------------
/roles/router-bird/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install bird
3 | apt:
4 | name: bird
5 |
6 | - name: Create directories for extra config snippets
7 | file:
8 | dest: "/etc/bird/{{ item }}"
9 | state: directory
10 | mode: 0755
11 | owner: root
12 | group: root
13 | with_items:
14 | - bird.conf.d
15 | - bird6.conf.d
16 |
17 | - name: Install config templates
18 | template:
19 | src: "{{ item }}"
20 | dest: "/etc/bird/{{ item }}"
21 | mode: 0644
22 | owner: root
23 | group: root
24 | with_items:
25 | - bird.conf
26 | - bird6.conf
27 | notify:
28 | - reload bird
29 | - reload bird6
30 |
31 | - name: Install internal ipv4 config templates
32 | template:
33 | src: internal_ipv4.conf
34 | dest: /etc/bird/bird.conf.d/internal.conf
35 | mode: 0644
36 | owner: root
37 | group: root
38 | notify:
39 | - reload bird
40 |
41 | - name: Install internal ipv6 config templates
42 | template:
43 | src: internal_ipv6.conf
44 | dest: /etc/bird/bird6.conf.d/internal.conf
45 | mode: 0644
46 | owner: root
47 | group: root
48 | notify:
49 | - reload bird6
50 |
51 | - name: Open firewall for BGP
52 | template:
53 | src: firewall.sh
54 | dest: "{{ firewall_path }}/30-bird"
55 | mode: 0644
56 | owner: root
57 | group: root
58 | when: firewall_enabled
59 | notify: reload firewall
60 |
61 | - name: Start bird
62 | service:
63 | name: "{{ item }}"
64 | state: started
65 | enabled: yes
66 | with_items:
67 | - bird
68 | - bird6
69 |
--------------------------------------------------------------------------------
/roles/router-bird/templates/bird.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | table ebgp;
3 |
4 | define ownas = {{ icvpn_as }};
5 |
6 | router id {{ batman_ipv4.address }};
7 |
8 | ### functions ###
9 |
10 | # own network
11 | function is_self_net() {
12 | return net ~ [
13 | 10.196.0.0/16+
14 | ];
15 | };
16 |
17 | # freifunk ip ranges in general
18 | function is_freifunk() {
19 | return net ~ [
20 | 10.0.0.0/8+,
21 | 104.0.0.0/8+
22 | ];
23 | };
24 |
25 | # dn42 ip ranges
26 | function is_dn42() {
27 | return net ~ [
28 | 172.22.0.0/15{16,32}
29 | ];
30 | };
31 |
32 | ### kernel ###
33 |
34 | protocol kernel k_frei {
35 | scan time 10;
36 | kernel table 252;
37 | import none;
38 | export filter {
39 | krt_prefsrc = {{ batman_ipv4.address }};
40 | accept;
41 | };
42 | };
43 |
44 | # this pseudo-protocol watches all interface up/down events
45 | protocol device {
46 | scan time 10;
47 | };
48 |
49 | ### pipes ###
50 |
51 | protocol pipe p_maintbl {
52 | peer table ebgp;
53 | import all;
54 | export none;
55 | };
56 |
57 | ### static routes ###
58 |
59 | # create a super route for own freifunk net in ebgp table
60 | protocol static static_{{ site_code }} {
61 | table ebgp;
62 | route 10.196.0.0/16 reject;
63 | };
64 |
65 | ### templates ###
66 |
67 | template bgp icvpn {
68 | local as ownas;
69 | table ebgp;
70 | import where ((is_freifunk() || is_dn42()) && !is_self_net());
71 | export where is_freifunk() || is_dn42() || is_self_net();
72 | };
73 |
74 | template bgp dn42 from icvpn {
75 | import where is_dn42() && !is_self_net();
76 | export where is_freifunk() || is_dn42() || is_self_net();
77 | };
78 |
79 | template bgp internal from icvpn {
80 | import filter {
81 | bgp_path.prepend(ownas);
82 | if ((is_freifunk() || is_dn42()) && !is_self_net()) then accept;
83 | else reject;
84 | };
85 | direct;
86 | };
87 |
88 | ### include extra config files ###
89 | include "/etc/bird/bird.conf.d/*.conf";
90 |
--------------------------------------------------------------------------------
/roles/router-bird/templates/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -i '{{ main_bridge }}' -p tcp --dport 179 -j ACCEPT
2 |
--------------------------------------------------------------------------------
/roles/router-bird/templates/internal_ipv4.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | {% for host in group %}
3 | {% if hostvars[host]['vpn_id'] != vpn_id %}
4 | protocol bgp {{ site_vpn_prefix }}{{ "%02d" % hostvars[host]['vpn_id'] }} from internal {
5 | neighbor {{ hostvars[host]['batman_ipv4']['address'] }} as ownas;
6 | };
7 | {% endif %}
8 | {% endfor %}
9 |
--------------------------------------------------------------------------------
/roles/router-bird/templates/internal_ipv6.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | {% for host in group %}
3 | {% if hostvars[host]['vpn_id'] != vpn_id %}
4 | protocol bgp {{ site_vpn_prefix }}{{ "%02d" % hostvars[host]['vpn_id'] }} from internal {
5 | neighbor {{ hostvars[host]['batman_ipv6_local']['address'] }} as ownas;
6 | };
7 | {% endif %}
8 | {% endfor %}
9 |
--------------------------------------------------------------------------------
/roles/router-bird/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | group: "{{ ('vpnservers' in group_names) | ternary(groups['vpnservers'], groups['vpnservers_legacy']) }}"
3 | ipv6_global_address: "{{ batman_ipv6_global.address }}/{{ batman_ipv6_global.size }}"
4 | ipv6_local_address: "{{ batman_ipv6_local.address }}/{{ batman_ipv6_local.size }}"
5 |
--------------------------------------------------------------------------------
/roles/ruby/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install Ruby
3 | apt:
4 | name:
5 | - build-essential
6 | - bundler
7 | - libsqlite3-dev
8 | - ruby
9 | - ruby-dev
10 | - ruby-i18n
11 |
--------------------------------------------------------------------------------
/roles/speedtest/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | speedtest_git_root: 'https://github.com/adolfintel/speedtest.git'
3 | speedtest_git_commit: 'bf696d8da26a1c5f9d8dec925ad1ed01d7a1bb35'
4 |
--------------------------------------------------------------------------------
/roles/speedtest/files/nginx.conf:
--------------------------------------------------------------------------------
1 | location /speedtest/ {
2 | add_header Access-Control-Allow-Origin "*";
3 | add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
4 | add_header Cache-Control "post-check=0, pre-check=0";
5 | add_header Pragma no-cache;
6 |
7 | location /speedtest/empty {
8 | return 200;
9 | }
10 |
11 | location /speedtest/getIP {
12 | default_type 'text/plain';
13 | content_by_lua_block {
14 | ngx.print(ngx.var.remote_addr);
15 | }
16 | }
17 |
18 | location /speedtest/garbage {
19 | default_type 'application/octet-stream';
20 | add_header Access-Control-Allow-Origin "*";
21 | add_header Content-Disposition "attachment; filename=random.dat";
22 | add_header Content-Transer-Encoding binary;
23 | add_header Content-Description "File Transfer";
24 | add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
25 | add_header Cache-Control "post-check=0, pre-check=0";
26 | add_header Pragma no-cache;
27 | content_by_lua_block {
28 | local urandom = io.open('/dev/urandom', 'r')
29 | local rand = urandom:read(1048576)
30 | local chunks = (ngx.var.arg_ckSize or 4) * 1
31 |
32 | while chunks > 0 do
33 | ngx.print(rand)
34 | ngx.flush()
35 | chunks = chunks - 1
36 | end
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/roles/speedtest/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Copy nginx config
3 | copy:
4 | src: nginx.conf
5 | dest: /etc/nginx/snippets/speedtest.conf
6 | mode: 0644
7 | owner: root
8 | group: root
9 |
10 | - name: Configure nginx default vHost
11 | lineinfile: # noqa no-tabs
12 | path: /etc/nginx/sites-available/default
13 | line: " include snippets/speedtest.conf;"
14 | insertafter: "server_name _;"
15 |
16 | - name: Clone HTML5 speedtest repo
17 | git:
18 | repo: "{{ speedtest_git_root }}"
19 | dest: '/var/www/html/speedtest'
20 | version: "{{ speedtest_git_commit }}"
21 |
22 | - name: Create symlink for index.html
23 | file:
24 | path: /var/www/html/speedtest/index.html
25 | state: link
26 | src: example-gauges.html
27 |
--------------------------------------------------------------------------------
/roles/sudo/README.md:
--------------------------------------------------------------------------------
1 | sudo
2 | =========================
3 |
4 | Install sudo
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - sudo
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/sudo/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | platforms:
4 | - name: Debian
5 | versions:
6 | - wheezy
7 | - jessie
8 |
--------------------------------------------------------------------------------
/roles/sudo/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install sudo
3 | apt:
4 | name: sudo
5 |
--------------------------------------------------------------------------------
/roles/system/README.md:
--------------------------------------------------------------------------------
1 | system
2 | =========================
3 |
4 | Install sysctl files
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - system
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/system/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | hostname: defaulthost
3 | reboot_flag: false
4 |
--------------------------------------------------------------------------------
/roles/system/files/autologin.conf:
--------------------------------------------------------------------------------
1 | [Service]
2 | ExecStart=
3 | ExecStart=-/sbin/agetty -p -a root --keep-baud 115200,57600,38400,9600 %I $TERM
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/dmesg-restrict.conf:
--------------------------------------------------------------------------------
1 | kernel.dmesg_restrict = 1
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/fs-file-max.conf:
--------------------------------------------------------------------------------
1 | # increase system file descriptor limit
2 | fs.file-max = 65535
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-arp-ignore.conf:
--------------------------------------------------------------------------------
1 | # only announce corresponding IP addresses on other interfaces
2 | net.ipv4.conf.default.arp_ignore=1
3 | net.ipv4.conf.all.arp_ignore=1
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-forwarding.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.conf.all.forwarding=1
2 | net.ipv4.conf.default.forwarding=1
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-icmp-errors-use-inbound-ifaddr.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.icmp_errors_use_inbound_ifaddr = 1
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-ignore-icmp-bogus-error-responses.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.icmp_ignore_bogus_error_responses=0
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-ignore-icmp-broadcast.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.icmp_echo_ignore_broadcasts=1
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-tcp-abort-on-overflow.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.tcp_abort_on_overflow=1
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-tcp-fin-timeout.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.tcp_fin_timeout=30
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-tcp-syn-retries.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.tcp_syn_retries=3
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-tcp-synack-retries.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.tcp_synack_retries=3
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv4-tcp-syncookies.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.tcp_syncookies=1
2 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/ipv6-forwarding.conf:
--------------------------------------------------------------------------------
1 | net.ipv6.conf.all.forwarding=1
2 | net.ipv6.conf.default.forwarding=1
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/kernel-core-uses-pid.conf:
--------------------------------------------------------------------------------
1 | # Controls whether core dumps will append the PID to the core filename
2 | # Useful for debugging multi-threaded applications
3 | kernel.core_uses_pid = 1
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/kernel-panic.conf:
--------------------------------------------------------------------------------
1 | # Auto-reboot linux 30 seconds after a kernel panic
2 | kernel.panic = 30
3 | kernel.panic_on_oops = 30
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/kernel-pid-max.conf:
--------------------------------------------------------------------------------
1 | # Allow for more PIDs
2 | kernel.pid_max = 65536
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/kernel-shm.conf:
--------------------------------------------------------------------------------
1 | # Set maximum amount of memory allocated to shm to 256MB
2 | kernel.shmmax = 67108864
3 | kernel.shmall = 67108864
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/kernel-sysrq.conf:
--------------------------------------------------------------------------------
1 | # Controls the System Request debugging functionality of the kernel
2 | kernel.sysrq = 0
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/no-ipv4-redirects.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.conf.all.send_redirects=0
2 | net.ipv4.conf.default.send_redirects=0
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/no-ipv4-rp-filter.conf:
--------------------------------------------------------------------------------
1 | net.ipv4.conf.all.rp_filter=0
2 | net.ipv4.conf.default.rp_filter=0
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/no-ipv6.conf:
--------------------------------------------------------------------------------
1 | net.ipv6.conf.all.autoconf=0
2 | net.ipv6.conf.all.accept_ra=0
3 | net.ipv6.conf.default.autoconf=0
4 | net.ipv6.conf.default.accept_ra=0
5 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/vm-min-free-kbytes.conf:
--------------------------------------------------------------------------------
1 | # Keep at least 64MB of free RAM space available
2 | vm.min_free_kbytes = 65536
3 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/vm-overcommit.conf:
--------------------------------------------------------------------------------
1 | # No overcommitment of available memory
2 | vm.overcommit_ratio = 0
3 | vm.overcommit_memory = 0
4 |
--------------------------------------------------------------------------------
/roles/system/files/sysctl.d/vm-swappiness.conf:
--------------------------------------------------------------------------------
1 | vm.swappiness = 0
2 |
--------------------------------------------------------------------------------
/roles/system/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: reload sysctl
3 | command: /sbin/sysctl --system
4 |
5 | - name: update grub
6 | command: update-grub
7 |
8 | - name: restart systemd-logind
9 | systemd:
10 | name: systemd-logind
11 | state: restarted
12 |
--------------------------------------------------------------------------------
/roles/system/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Installing sysctl.d configs
3 | copy:
4 | src: sysctl.d/
5 | dest: /etc/sysctl.d/
6 | mode: 0644
7 | owner: root
8 | group: root
9 | notify: reload sysctl
10 |
11 | - name: Load modules needed for sysctl configs early
12 | lineinfile:
13 | dest: /etc/modules
14 | line: nf_conntrack
15 | regexp: '^nf_conntrack'
16 |
17 | - name: Setting hostname
18 | hostname:
19 | name: "{{ hostname }}"
20 | when: hostname != 'defaulthost'
21 |
22 | - name: Make boot non-quiet
23 | lineinfile:
24 | path: /etc/default/grub
25 | regexp: '^#?GRUB_CMDLINE_LINUX_DEFAULT='
26 | line: 'GRUB_CMDLINE_LINUX_DEFAULT=""'
27 | notify: update grub
28 |
29 | - name: Detect serial devices
30 | slurp:
31 | src: /proc/tty/driver/serial
32 | register: system_serial_devices
33 |
34 | - name: Parse serial devices
35 | set_fact:
36 | serial_devices: "{{ system_serial_devices.content | b64decode | split('\n') | reject('search', 'serinfo:|uart:unknown|^$') | map('split', ': ') | map(attribute=0) | list }}"
37 |
38 | - name: Enable serial console in GRUB and Linux console
39 | template:
40 | src: grub-serial.cfg
41 | dest: /etc/default/grub.d/serial.cfg
42 | mode: '0644'
43 | notify: update grub
44 | when: 'serial_devices | length > 0'
45 |
46 | - name: Enable serial getty
47 | systemd:
48 | name: 'serial-getty@ttyS{{ item }}.service'
49 | state: started
50 | enabled: yes
51 | loop: "{{ serial_devices }}"
52 |
53 | - name: Configure VM
54 | include_tasks: vm.yml
55 | when: ansible_virtualization_role == "guest"
56 |
57 | - name: Reboot host
58 | command: reboot
59 | when: reboot_flag
60 |
--------------------------------------------------------------------------------
/roles/system/tasks/vm.yml:
--------------------------------------------------------------------------------
1 |
2 | - name: Optimize kernel parameters for VMs
3 | lineinfile:
4 | path: /etc/default/grub
5 | regexp: '^#?GRUB_CMDLINE_LINUX='
6 | line: 'GRUB_CMDLINE_LINUX="elevator=noop nohz=on consoleblank=0"'
7 | notify: update grub
8 | when: 'ansible_virtualization_role | default == "guest"'
9 |
10 | - name: Enable autologin on serial terminal
11 | copy:
12 | dest: /etc/systemd/system/serial-getty@.service.d/
13 | src: autologin.conf
14 |
15 | - name: Install packages
16 | apt:
17 | name:
18 | - dbus # for systemd-logind
19 | - qemu-guest-agent
20 | notify: restart systemd-logind
21 |
22 | - name: Let systemd-logind handle power button
23 | lineinfile:
24 | path: /etc/systemd/logind.conf
25 | regexp: '^#?HandlePowerKey='
26 | line: 'HandlePowerKey=poweroff'
27 | notify: restart systemd-logind
28 |
29 | - name: Install cloud kernel
30 | apt:
31 | name: linux-image-cloud-amd64
32 | when:
33 | - '"backbone" not in group_names'
34 | - '"ffmapserver" not in group_names'
35 | - '"bgp-" not in inventory_hostname'
36 |
37 | - name: Uninstall non-cloud kernel
38 | apt:
39 | name: linux-image-amd64
40 | state: absent
41 | purge: yes
42 | when:
43 | - '"backbone" not in group_names'
44 | - '"ffmapserver" not in group_names'
45 | - '"bgp-" not in inventory_hostname'
46 |
--------------------------------------------------------------------------------
/roles/system/templates/grub-serial.cfg:
--------------------------------------------------------------------------------
1 | GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} console=tty0 console=ttyS{{ serial_devices[-1] }},115200n8"
2 | GRUB_TERMINAL=serial
3 | GRUB_SERIAL_COMMAND="serial --unit={{ serial_devices[-1] }} --speed=115200 --word=8 --parity=no --stop=1"
4 |
--------------------------------------------------------------------------------
/roles/tasksite/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | tasks_email: 'info@bremen.freifunk.net'
3 | tasks_user: 'tasks'
4 | tasks_group: 'tasks'
5 | tasks_subdomain: 'tasks'
6 | tasks_domain: '{{ tasks_subdomain }}.{{ main_domain }}'
7 |
--------------------------------------------------------------------------------
/roles/tasksite/files/htaccess:
--------------------------------------------------------------------------------
1 | RewriteRule ^/rsrc/(.*) - [L,QSA]
2 | RewriteRule ^/favicon.ico - [L,QSA]
3 | RewriteRule ^(.*)$ index.php?__path__=/$1 [B,L,QSA]
4 |
--------------------------------------------------------------------------------
/roles/tasksite/files/run-log:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 | exec multilog t ./main
3 |
--------------------------------------------------------------------------------
/roles/tasksite/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - apt
4 | - sudo
5 | - tools
6 | - apache
7 | - letsencrypt
8 | - php
9 | - git
10 | - mysql-server
11 | galaxy_info:
12 | platforms:
13 | - name: Debian
14 | versions:
15 | - jessie
16 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/apache-tasks.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ tasks_subdomain }}.{{ alt_domain }}
5 |
6 | # Don't add header to proxy
7 | ProxyAddHeaders Off
8 |
9 | # set this to customers mail address
10 | ServerAdmin {{ tasks_email }}
11 |
12 | SuexecUserGroup {{ tasks_user }} {{ tasks_group }}
13 |
14 | DocumentRoot /var/www/{{ tasks_user }}/domains/{{ tasks_domain }}
15 |
16 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
17 | Options +SymLinksIfOwnerMatch -Includes
18 |
19 |
20 | ScriptAlias /cgi-bin /var/www/tasks/cgi-bin
21 | ScriptAlias /fcgi-bin /var/www/tasks/fcgi-bin
22 | Include /etc/apache2/user-php-exec.conf
23 |
24 | FcgidMaxRequestLen 16777216
25 | FcgidPassHeader Authorization
26 |
27 | RewriteEngine on
28 | RewriteOptions inherit
29 |
30 | ErrorLog /var/log/apache2/{{ tasks_user }}/default-error.log
31 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
32 |
33 | SSLEngine on
34 | SSLCertificateFile /etc/letsencrypt/certs/{{ tasks_domain }}/fullchain.pem
35 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ tasks_domain }}/privkey.pem
36 |
37 |
38 |
39 | ServerName {{ tasks_subdomain }}.{{ main_domain }}
40 |
41 | RewriteEngine on
42 | RewriteOptions inherit
43 |
44 | RedirectMatch 301 (.*) https://{{ tasks_subdomain }}.{{ alt_domain }}$1
45 |
46 | ErrorLog /var/log/apache2/{{ tasks_user }}/default-error.log
47 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
48 |
49 | SSLEngine on
50 | SSLCertificateFile /etc/letsencrypt/certs/{{ tasks_domain }}/fullchain.pem
51 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ tasks_domain }}/privkey.pem
52 |
53 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/ffhb.conf.php:
--------------------------------------------------------------------------------
1 | 'localhost',
7 | 'mysql.user' => 'phabric',
8 | 'mysql.pass' => '{{ mysql_password_base64["content"] | b64decode }}',
9 | 'phabricator.timezone' => 'Europe/Berlin',
10 | # Phabricator only supports one single base URI, and we have used the shorter one (tasks.ffhb.de) so far:
11 | 'phabricator.base-uri' => 'https://{{ tasks_subdomain }}.{{ alt_domain }}/',
12 | 'repository.default-local-path' => '/home/{{ tasks_user }}/.var/repo',
13 | 'storage.local-disk.path' => '/home/{{ tasks_user }}/.var/storage',
14 | );
15 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/phabricator-daemon-file:
--------------------------------------------------------------------------------
1 | {
2 | "daemonize": false,
3 | "daemons": [
4 | {
5 | "class": "PhabricatorRepositoryPullLocalDaemon",
6 | "label": "PhabricatorRepositoryPullLocalDaemon"
7 | },
8 | {
9 | "class": "PhabricatorTriggerDaemon",
10 | "label": "PhabricatorTriggerDaemon"
11 | },
12 | {
13 | "class": "PhabricatorTaskmasterDaemon",
14 | "label": "PhabricatorTaskmasterDaemon"
15 | }
16 | ],
17 | "log": "/home/{{ tasks_user }}/.var/tmp/log/daemons.log",
18 | "piddir": "/home/{{ tasks_user }}/.var/tmp/pid"
19 | }
20 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/phabricator.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Phabricator project management system
3 |
4 | [Service]
5 | Environment=PHP_INI_SCAN_DIR=:%h/.config/etc/php
6 | Environment=INSTALL_ROOT=/var/www/{{ tasks_user }}/opt/phabricator
7 | Environment=PHD_TMP_DIR=%h/.var/tmp/phabricator
8 | SyslogIdentifier=%p
9 | ExecStartPre=/bin/mkdir -p ${PHD_TMP_DIR}/pid ${PHD_TMP_DIR}/log
10 | ExecStart=/bin/sh -c "exec /var/www/{{ tasks_user }}/opt/phabricator/phabricator/scripts/daemon/phd-daemon < .config/phabricator-daemon-file"
11 |
12 | [Install]
13 | WantedBy=default.target
14 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/php-extopts.ini:
--------------------------------------------------------------------------------
1 | ; {{ ansible_managed }}
2 |
3 | [PHP]
4 | post_max_size=32M
5 |
6 | [opcache]
7 | opcache.validate_timestamps=0
8 |
--------------------------------------------------------------------------------
/roles/tasksite/templates/php-fcgi-starter:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # Set safe path
4 | export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
5 |
6 | # Set user environment
7 | export USER={{ tasks_user }}
8 | export HOME=/home/{{ tasks_user }}
9 |
10 | . $HOME/.local/bin/php_env.sh
11 |
12 | PHP_FCGI_CHILDREN=0
13 | export PHP_FCGI_CHILDREN
14 | PHP_FCGI_MAX_REQUESTS=250
15 | export PHP_FCGI_MAX_REQUESTS
16 | exec php-cgi
17 |
--------------------------------------------------------------------------------
/roles/tiles/README.md:
--------------------------------------------------------------------------------
1 | tiles
2 | =====
3 |
4 | Install tessera as a map tile server and configure Apache to cache its responses.
5 |
6 |
7 | Usage
8 | -----
9 |
10 | - hosts: servers
11 | roles:
12 | - tiles
13 |
14 |
15 | License
16 | -------
17 |
18 | BSD
19 |
--------------------------------------------------------------------------------
/roles/tiles/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | tiles_email: 'info@bremen.freifunk.net'
3 | tiles_user: tiles
4 | tiles_group: tiles
5 | tiles_subdomain: tiles
6 | tiles_domain: '{{ tiles_subdomain }}.{{ main_domain }}'
7 | tiles_tessera_port: 63114
8 | tiles_git_root: 'https://github.com/FreifunkBremen/mapbox-studio-osm-bright.tm2.git'
9 | tiles_git_commit: 'a3c2b948b8816a492660f6ee7b1b9667d0c4df2e'
10 |
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-Bold.ttf
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-Italic.ttf
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-Light.ttf
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-LightItalic.ttf
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/roles/tiles/files/OpenSans/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/tiles/files/OpenSans/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/roles/tiles/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart tessera
3 | systemd:
4 | name: tessera.service
5 | scope: user
6 | state: restarted
7 | become: yes
8 | become_user: "{{ tiles_user }}"
9 |
--------------------------------------------------------------------------------
/roles/tiles/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - apache
4 | - apt
5 | - git
6 | - letsencrypt
7 | - nodejs
8 | - ruby
9 | - sudo
10 | - tools
11 | galaxy_info:
12 | platforms:
13 | - name: Debian
14 | versions:
15 | - jessie
16 |
--------------------------------------------------------------------------------
/roles/tiles/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ tiles_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ tiles_subdomain }}.{{ alt_domain }}
6 |
7 | # set this to customers mail address
8 | ServerAdmin {{ tiles_email }}
9 |
10 | ErrorLog /var/log/apache2/{{ tiles_user }}/default-error.log
11 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
12 |
13 | ProxyPass / http://127.0.0.1:{{ tiles_tessera_port }}/
14 |
15 | # Don't add header to proxy
16 | ProxyAddHeaders Off
17 |
18 | # cache tiles for 7 days on disk, ignoring client refreshes
19 | CacheEnable disk /
20 | CacheDisable /.well-known/acme-challenge
21 | CacheDefaultExpire 604800
22 | CacheIgnoreCacheControl on
23 | CacheIgnoreQueryString on
24 | # this unifies the cache for HTTP and HTTPS
25 | CacheKeyBaseURL "http://{{ tiles_domain }}/"
26 |
27 | SSLEngine on
28 | SSLCertificateFile /etc/letsencrypt/certs/{{ tiles_domain }}/fullchain.pem
29 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ tiles_domain }}/privkey.pem
30 |
31 |
--------------------------------------------------------------------------------
/roles/tiles/templates/tessera.service:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | [Unit]
4 | Description=Tessera map tile renderer
5 |
6 | [Service]
7 | Environment=MAPNIK_FONT_PATH=%h/.fonts PORT={{ tiles_tessera_port }}
8 |
9 | MemoryMax=2G
10 | SyslogIdentifier=%p
11 | ExecStart=%h/node_modules/tessera/bin/tessera.js -b 127.0.0.1 tmstyle://./mapbox-studio-osm-bright.tm2
12 | Restart=always
13 | RestartSec=5
14 |
15 | [Install]
16 | WantedBy=default.target
17 |
--------------------------------------------------------------------------------
/roles/tmpfs/README.md:
--------------------------------------------------------------------------------
1 | tmpfs
2 | =========================
3 |
4 | Enable tmpfs for /tmp
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - tmpfs
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/tmpfs/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Copy tmp.mount
3 | copy:
4 | src: /usr/share/systemd/tmp.mount
5 | dest: /etc/systemd/system/tmp.mount
6 | remote_src: yes
7 |
8 | - name: Enable tmpfs for /tmp
9 | systemd:
10 | daemon_reload: yes
11 | enabled: yes
12 | name: tmp.mount
13 |
--------------------------------------------------------------------------------
/roles/tools/README.md:
--------------------------------------------------------------------------------
1 | tools
2 | =========================
3 |
4 | Installing several useful tools
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - tools
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/tools/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install a bunch of helpful tools
3 | apt:
4 | name:
5 | - ca-certificates
6 | - curl
7 | - less
8 | - molly-guard
9 | - screen
10 | - tcpdump
11 | - tmux
12 | - zsh
13 |
14 | - name: Download .zshrc from grml
15 | get_url:
16 | url: https://raw.githubusercontent.com/grml/grml-etc-core/v0.12.5/etc/zsh/zshrc
17 | dest: /etc/zsh/zshrc
18 | checksum: sha256:ad88c76951693c2f9c38773ed2602a9fd5c74431615c4a23aaff679b295919ce
19 | validate_certs: false
20 |
21 | - name: Change shell for root
22 | user:
23 | name: root
24 | shell: /bin/zsh
25 |
--------------------------------------------------------------------------------
/roles/unbound/README.md:
--------------------------------------------------------------------------------
1 | unbound
2 | =========================
3 |
4 | Install and configure unbound
5 |
6 |
7 | Usage
8 | -------------------------
9 |
10 | - hosts: servers
11 | roles:
12 | - unbound
13 |
14 |
15 | License
16 | -------------------------
17 |
18 | GPLv3
19 |
--------------------------------------------------------------------------------
/roles/unbound/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dns_root_hints: http://www.internic.net/domain/named.cache
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/firewall.sh:
--------------------------------------------------------------------------------
1 | ipt -A INPUT -p udp --dport 53 -j ACCEPT
2 | ipt -A INPUT -p tcp --dport 53 -j ACCEPT
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound-ip-up.d:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | PATH=/sbin:/usr/sbin:/bin:/usr/bin
4 |
5 | if ! pgrep unbound >/dev/null 2>&1; then
6 | service unbound restart
7 | fi
8 |
9 | exit 0
10 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/caching-timeouts.conf:
--------------------------------------------------------------------------------
1 | server:
2 | cache-min-ttl: 3600
3 | cache-max-ttl: 86400
4 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/caching-tweaking.conf:
--------------------------------------------------------------------------------
1 | server:
2 | # the number of slabs to use for cache and must be a power of 2 times the
3 | # number of num-threads set above. more slabs reduce lock contention, but
4 | # fragment memory usage.
5 | msg-cache-slabs: 8
6 | rrset-cache-slabs: 8
7 | infra-cache-slabs: 8
8 | key-cache-slabs: 8
9 |
10 | # Increase the memory size of the cache. Use roughly twice as much rrset cache
11 | # memory as you use msg cache memory. Due to malloc overhead, the total memory
12 | # usage is likely to rise to double (or 2.5x) the total cache memory. The test
13 | # box has 4gig of ram so 256meg for rrset allows a lot of room for cacheed objects.
14 | rrset-cache-size: 256m
15 | msg-cache-size: 128m
16 |
17 | # buffer size for UDP port 53 incoming (SO_RCVBUF socket option). This sets
18 | # the kernel buffer larger so that no messages are lost in spikes in the traffic.
19 | so-rcvbuf: 1m
20 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/disable-dnssec.conf:
--------------------------------------------------------------------------------
1 | server:
2 | module-config: "iterator"
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/edns-buffer-size.conf:
--------------------------------------------------------------------------------
1 | server:
2 | edns-buffer-size: 1280
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/harden-glue.conf:
--------------------------------------------------------------------------------
1 | server:
2 | harden-glue: yes
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/hide-version.conf:
--------------------------------------------------------------------------------
1 | server:
2 | hide-version: yes
3 | hide-identity: yes
4 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/jostle-timeout.conf:
--------------------------------------------------------------------------------
1 | server:
2 | jostle-timeout: 500
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/minimal-responses.conf:
--------------------------------------------------------------------------------
1 | server:
2 | minimal-responses: yes
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/no-logging.conf:
--------------------------------------------------------------------------------
1 | server:
2 | verbosity: 0
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/number-of-threads.conf:
--------------------------------------------------------------------------------
1 | server:
2 | num-threads: 4
3 |
--------------------------------------------------------------------------------
/roles/unbound/files/unbound.conf.d/root-hints.conf:
--------------------------------------------------------------------------------
1 | server:
2 | root-hints: "/var/lib/unbound/root.hints"
3 |
--------------------------------------------------------------------------------
/roles/unbound/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart unbound
3 | service:
4 | name: unbound
5 | state: restarted
6 | enabled: yes
7 |
--------------------------------------------------------------------------------
/roles/unbound/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - firewall
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - wheezy
9 | - jessie
10 |
--------------------------------------------------------------------------------
/roles/unbound/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Install unbound
3 | apt:
4 | name: unbound
5 |
6 | - name: Copy Configuration
7 | copy:
8 | src: "unbound.conf.d/"
9 | dest: "/etc/unbound/unbound.conf.d/"
10 | mode: 0644
11 | owner: root
12 | group: root
13 | notify: restart unbound
14 |
15 | - name: Fix unbound default config
16 | replace:
17 | dest: /etc/unbound/unbound.conf.d/qname-minimisation.conf
18 | regexp: "qname-minimisation: yes"
19 | replace: "qname-minimisation: no"
20 | when: (ansible_distribution == "Debian" and (ansible_distribution_version is version_compare("11", "<")))
21 |
22 | - name: Disable qname minimisation
23 | copy:
24 | content: "server:\n qname-minimisation: no\n"
25 | dest: /etc/unbound/unbound.conf.d/qname-minimisation.conf
26 | owner: root
27 | group: root
28 | mode: '0644'
29 | when: (ansible_distribution == "Debian" and (ansible_distribution_version is version_compare("11", ">=")))
30 |
31 | - name: Copy network hook
32 | copy:
33 | src: unbound-ip-up.d
34 | dest: /etc/network/if-up.d/unbound
35 | mode: 0755
36 | owner: root
37 | group: root
38 |
39 | - name: Generate Configuration
40 | template:
41 | src: "{{ item }}"
42 | dest: "/etc/unbound/unbound.conf.d/{{ item }}"
43 | mode: 0644
44 | owner: root
45 | group: root
46 | with_items:
47 | - access-control.conf
48 | - listen-on-all-interfaces.conf
49 | - remote-control.conf
50 | notify: restart unbound
51 |
52 | - name: Get root.hints
53 | get_url:
54 | url: '{{ dns_root_hints }}'
55 | dest: '/var/lib/unbound/root.hints'
56 | notify: restart unbound
57 |
58 | - name: Open firewall for DNS
59 | copy:
60 | src: firewall.sh
61 | dest: "{{ firewall_path }}/30-unbound"
62 | mode: 0644
63 | owner: root
64 | group: root
65 | when: firewall_enabled
66 | notify: reload firewall
67 |
--------------------------------------------------------------------------------
/roles/unbound/templates/access-control.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | server:
3 | access-control: 127.0.0.1 allow
4 | access-control: 10.196.0.0/16 allow
5 | access-control: fd2f:5119:f2c::/48 allow
6 | access-control: 2a06:8782::/32 allow
7 |
--------------------------------------------------------------------------------
/roles/unbound/templates/listen-on-all-interfaces.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | server:
3 | interface: 127.0.0.1
4 | interface: {{ batman_ipv4.address}}
5 | {% if batman_ipv6_global and batman_ipv6_global.address != batman_ipv6_local.address %}
6 | interface: {{ batman_ipv6_global.address }}
7 | {% endif %}
8 | interface: {{ batman_ipv6_local.address }}
9 | do-ip4: yes
10 | do-ip6: yes
11 | do-udp: yes
12 | do-tcp: yes
13 | ip-freebind: yes
14 |
--------------------------------------------------------------------------------
/roles/unbound/templates/remote-control.conf:
--------------------------------------------------------------------------------
1 | remote-control:
2 | control-enable: yes
3 | {% if (ansible_distribution == "Debian" and (ansible_distribution_version is version_compare("11", "<"))) %}
4 | control-interface: /run/unbound.sock
5 | {% else %}
6 | control-interface: 127.0.0.1
7 | control-port: 8953
8 | {% endif %}
9 |
--------------------------------------------------------------------------------
/roles/website/README.md:
--------------------------------------------------------------------------------
1 | website
2 | =========================
3 |
4 | Install Jeykll as used for the main website of Freifunk Bremen.
5 |
6 |
7 | Configuration
8 | -------------------------
9 |
10 | See `defaults/main.yml` for available parameters.
11 |
12 | Note that the `website_webhook_secret` parameter doesn't have a default value
13 | Since its value must remain secret, the value must be specified on command line when running ansible-playbook (with `-e "website_webhook_secret=thesecret"`)
14 |
15 |
16 | Configuration of Github webhook
17 | --------------------------------
18 |
19 | Go to the Webhook page at https://github.com/FreifunkBremen/bremen.freifunk.net/settings/hooks/ (you need admin permissions for this), and add a new webhook with these settings:
20 | * payload url: http://bremen.freifunk.net/webhook.php
21 | * content type: application/json
22 | * secret: the value that was passed on command line for `website_webhook_secret` parameter
23 | * for events: "Just the push event."
24 |
25 | The webhook will only work if it originates from the FreifunkBremen/bremen.freifunk.net repository and is for the master branch.
26 |
27 |
28 | Usage
29 | -------------------------
30 |
31 | - hosts: servers
32 | roles:
33 | - website
34 |
35 |
36 | License
37 | -------------------------
38 |
39 | GPLv3
40 |
--------------------------------------------------------------------------------
/roles/website/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | website_email: 'info@bremen.freifunk.net'
3 | website_user: 'website'
4 | website_group: 'website'
5 | website_domain: '{{ main_domain }}'
6 | #website_webhook_secret: '' # must be provided on command line
7 | website_git_root: 'https://github.com/FreifunkBremen/bremen.freifunk.net'
8 | website_git_commit: 'd8f757d21294234aa2b8c8cb2340719f0d3ace0d'
9 |
--------------------------------------------------------------------------------
/roles/website/files/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "dataPath": "https://downloads.bremen.freifunk.net/data/",
3 | "siteName": "Freifunk Bremen",
4 | "mapSigmaScale": 0.25,
5 | "showContact": false,
6 | "maxAge": 3,
7 | "globalInfos": [
8 | {
9 | "name": "Wochenstatistik",
10 | "href": "https://downloads.bremen.freifunk.net/data/nodes/globalGraph.png",
11 | "thumbnail": "https://downloads.bremen.freifunk.net/data/nodes/globalGraph.png",
12 | "caption": "Entwicklung der Anzahl der Knoten und der Clients innerhalb der letzten 7 Tage"
13 | }
14 | ],
15 | "mapLayers": [
16 | {
17 | "name": "Freifunk Bremen",
18 | "url": "//tiles.bremen.freifunk.net/{z}/{x}/{y}.png",
19 | "config": {
20 | "type": "osm",
21 | "attribution": "Design © Mapbox, CC-BY 3.0 — Daten © OpenStreetMap",
22 | "maxZoom": 20
23 | }
24 | },
25 | { "name": "OpenStreetMap.Mapnik" },
26 | { "name": "Stamen.TonerLite" }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/roles/website/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: install jekyll dependencies
3 | bundler:
4 | gem_path: .bundle
5 | chdir: "/home/{{ website_user }}/.var/jekyll-envs/{{ website_domain }}"
6 | become: yes
7 | become_user: "{{ website_user }}"
8 |
9 | - name: run jekyll
10 | command: "/home/{{ website_user }}/.local/bin/update-jekyll.sh"
11 | become: yes
12 | become_user: "{{ website_user }}"
13 |
--------------------------------------------------------------------------------
/roles/website/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - apt
4 | - sudo
5 | - tools
6 | - apache
7 | - letsencrypt
8 | - php
9 | - ruby
10 | - git
11 | - nodejs
12 | galaxy_info:
13 | platforms:
14 | - name: Debian
15 | versions:
16 | - jessie
17 |
--------------------------------------------------------------------------------
/roles/website/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ main_domain }}
5 | ServerAlias {{ alt_domain }} www.{{ main_domain }} www.{{ alt_domain }}
6 |
7 | # set this to customers mail address
8 | ServerAdmin {{ website_email }}
9 |
10 | SuexecUserGroup {{ website_user }} {{ website_group }}
11 |
12 | DocumentRoot /var/www/{{ website_user }}/domains/{{ website_domain }}
13 |
14 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
15 | Options +SymLinksIfOwnerMatch -Includes
16 |
17 |
18 | Alias /icons /usr/share/apache2/icons
19 | ScriptAlias /cgi-bin /var/www/{{ website_user }}/cgi-bin
20 | ScriptAlias /fcgi-bin /var/www/{{ website_user }}/fcgi-bin
21 | Include /etc/apache2/user-php-exec.conf
22 |
23 | ErrorLog /var/log/apache2/website/default-error.log
24 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
25 |
26 | SSLEngine on
27 | SSLCertificateFile /etc/letsencrypt/certs/{{ website_domain }}/fullchain.pem
28 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ website_domain }}/privkey.pem
29 |
30 |
--------------------------------------------------------------------------------
/roles/website/templates/php-fcgi-starter:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # Set safe path
4 | export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
5 |
6 | # Set user environment
7 | export USER={{ website_user }}
8 | export HOME=/home/{{ website_user }}
9 |
10 | PHP_FCGI_CHILDREN=0
11 | export PHP_FCGI_CHILDREN
12 | PHP_FCGI_MAX_REQUESTS=250
13 | export PHP_FCGI_MAX_REQUESTS
14 | exec php-cgi
15 |
--------------------------------------------------------------------------------
/roles/website/templates/update-jekyll.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env sh
2 |
3 | # shellcheck disable=SC1091
4 | . /etc/profile
5 |
6 | set -eu
7 |
8 | SOURCE="$HOME/.var/jekyll-envs/{{ website_domain }}/"
9 | DESTINATION="/var/www/{{ website_user }}/domains/{{ website_domain }}/"
10 |
11 | cd "$SOURCE"
12 |
13 | git fetch --quiet origin
14 | git reset --quiet --hard origin/master
15 | git submodule --quiet update --init
16 |
17 | bundle config set --local path .bundle
18 | bundle install --quiet
19 |
20 | exec bundle exec jekyll build --quiet --destination "$DESTINATION"
21 |
--------------------------------------------------------------------------------
/roles/wiki/README.md:
--------------------------------------------------------------------------------
1 | wiki
2 | =========================
3 |
4 | Install gollum
5 | used by Freifunk Bremen
6 | as wiki system
7 |
8 |
9 | Usage
10 | -------------------------
11 |
12 | - hosts: servers
13 | roles:
14 | - wiki
15 |
16 |
17 | Github SSH Deploy Key
18 | -------------------------
19 | During installation an SSH key will be created for the wiki user.
20 | The key will be created at /home/wiki/.ssh/id_rsa.pub .
21 | It must be added at https://github.com/FreifunkBremen/wiki/settings/keys
22 | as new key (with write access), so that wiki changes can be pushed to Github.
23 |
24 |
25 | Gollum Logs
26 | -------------------------
27 | Gollum log files are stored in /home/wiki/.config/service/gollum/log/main/.
28 | The "current" file contains the most recent log lines.
29 | To display human-readable timestamps, filter the log file through "tai64nlocal", eg. like this:
30 |
31 | tai64nlocal < current | less
32 |
33 |
34 | License
35 | -------------------------
36 |
37 | GPLv3
38 |
--------------------------------------------------------------------------------
/roles/wiki/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | wiki_gollum_git_root: 'https://github.com/FreifunkBremen/gollum.git'
3 | wiki_gollum_git_commit: '428b397389961b7f0069528b600816d5050cc364'
4 | wiki_content_git_root: 'https://github.com/FreifunkBremen/wiki.git'
5 | wiki_email: 'info@bremen.freifunk.net'
6 | wiki_user: 'wiki'
7 | wiki_group: 'wiki'
8 | wiki_subdomain: 'wiki'
9 | wiki_domain: '{{ wiki_subdomain }}.{{ main_domain }}'
10 | wiki_gollum_port: '63112'
11 | wiki_http_username: 'wellenfunk'
12 | wiki_http_password: 'foobar'
13 |
--------------------------------------------------------------------------------
/roles/wiki/files/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/roles/wiki/files/favicon.ico
--------------------------------------------------------------------------------
/roles/wiki/files/gitconfig:
--------------------------------------------------------------------------------
1 | [user]
2 | name = Anonymous
3 | email = anon@anon.com
4 |
--------------------------------------------------------------------------------
/roles/wiki/files/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /Treffen/
3 | Disallow: /Entwuerfe/
4 | Disallow: /edit/
5 | Disallow: /history/
6 | Disallow: /fileview
7 | Disallow: /latest_changes
8 |
--------------------------------------------------------------------------------
/roles/wiki/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - apache
4 | - apt
5 | - git
6 | - letsencrypt
7 | - ruby
8 | - sudo
9 | - tools
10 | galaxy_info:
11 | platforms:
12 | - name: Debian
13 | versions:
14 | - jessie
15 |
--------------------------------------------------------------------------------
/roles/wiki/templates/apache2.conf:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 |
4 | ServerName {{ wiki_subdomain }}.{{ main_domain }}
5 | ServerAlias {{ wiki_subdomain }}.{{ alt_domain }}
6 |
7 | # Don't add header to proxy
8 | ProxyAddHeaders Off
9 |
10 | # set this to customers mail address
11 | ServerAdmin {{ wiki_email }}
12 |
13 | DocumentRoot /var/www/{{ wiki_user }}/domains/{{ wiki_subdomain }}.{{ main_domain }}
14 |
15 | AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Indexes,MultiViews,SymLinksIfOwnerMatch
16 | Options +SymLinksIfOwnerMatch -Includes
17 |
18 |
19 | SuexecUserGroup {{ wiki_user }} {{ wiki_group }}
20 |
21 | ErrorLog /var/log/apache2/{{ wiki_user }}/default-error.log
22 | ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ ANONYMIZED] %M% ,\ referer\ %{Referer}i"
23 |
24 | SSLEngine on
25 | SSLCertificateFile /etc/letsencrypt/certs/{{ wiki_domain }}/fullchain.pem
26 | SSLCertificateKeyFile /etc/letsencrypt/certs/{{ wiki_domain }}/privkey.pem
27 |
28 |
--------------------------------------------------------------------------------
/roles/wiki/templates/gollum.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Gollum git based wiki
3 |
4 | [Service]
5 | WorkingDirectory=%h/.opt/gollum
6 | SyslogIdentifier=%p
7 | ExecStart=/usr/bin/bundle exec bin/gollum --port {{ wiki_gollum_port }} --host 127.0.0.1 --adapter rugged --css --h1-title --ref wiki "%h/.var/gollum-envs/ff-bremen"
8 | Restart=always
9 | RestartSec=5
10 |
11 | [Install]
12 | WantedBy=default.target
13 |
--------------------------------------------------------------------------------
/roles/wiki/templates/htaccess:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 |
3 | DirectoryIndex disabled
4 | RewriteEngine On
5 | RewriteCond %{REQUEST_FILENAME} !-f
6 | RewriteRule ^(.*)$ http://127.0.0.1:{{ wiki_gollum_port }}/$1 [P,L]
7 | RequestHeader set X-Forwarded-Proto "https" env=HTTPS
8 |
9 | SetEnvIfNoCase Request_URI ^/gollum/(create|edit|livepreview|delete|rename)/ require_auth=true
10 |
11 | AuthType basic
12 | AuthName "Dies ist ein Spamschutz. Benutzername: wellenfunk, Passwort: foobar"
13 | AuthUserFile /var/www/{{ wiki_user }}/domains/{{ wiki_domain }}/.htpasswd
14 | ErrorDocument 401 "Die Benutzerabfrage dient lediglich der Spamvermeidung. Die Benutzerdaten lauten: Benutzername: wellenfunk, Passwort: foobar"
15 |
16 | Order Deny,Allow
17 | Deny from All
18 | Satisfy any
19 | Allow from env=!require_auth
20 | Require valid-user
21 |
--------------------------------------------------------------------------------
/roles/yanic/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | yanic_publisher: false
3 | yanic_respondd: true
4 | yanic_respondd_collect_interval: "1m"
5 | yanic_respondd_interface: "eth0"
6 |
7 | yanic_webserver: false
8 | yanic_webserver_bind: "127.0.0.1:8080"
9 | yanic_webserver_webroot: "/var/www/html/meshviewer"
10 |
11 | yanic_nodes: true
12 | yanic_nodes_state_path: "/var/lib/yanic.json"
13 | yanic_nodes_save_interval: "5s"
14 | yanic_nodes_offline_after: "10m"
15 | yanic_nodes_prune_after: "7d"
16 |
17 | yanic_meshviewer_version: 2
18 | yanic_meshviewer_path: "/var/www/html/meshviewer/data"
19 | yanic_meshviewer_nodes: "{{yanic_meshviewer_path}}/nodes.json"
20 | yanic_meshviewer_graph: "{{yanic_meshviewer_path}}/graph.json"
21 |
22 | yanic_database_delete_after: "7d"
23 | yanic_database_delete_interval: "1h"
24 |
25 | yanic_socket:
26 | - enable: false
27 | type: unix
28 | address: "/var/lib/yanic/database.socket"
29 | yanic_influxdb:
30 | - enable: false
31 | host: http://localhost:8086
32 | database: ffhb
33 | username: ""
34 | password: ""
35 |
--------------------------------------------------------------------------------
/roles/yanic/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: restart yanic
3 | service:
4 | name: yanic
5 | state: restarted
6 |
7 | - name: restart yanic-publish
8 | service:
9 | name: yanic-publish.timer
10 | state: restarted
11 |
12 | - name: reload systemd
13 | systemd:
14 | daemon_reload: yes
15 |
--------------------------------------------------------------------------------
/roles/yanic/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 | - go
4 | galaxy_info:
5 | platforms:
6 | - name: Debian
7 | versions:
8 | - jessie
9 |
--------------------------------------------------------------------------------
/roles/yanic/templates/config.toml:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | [respondd]
3 | enable = {{ yanic_respondd | ternary('true','false') }}
4 | collect_interval = "{{ yanic_respondd_collect_interval }}"
5 | interface = "{{ yanic_respondd_interface }}"
6 |
7 | [webserver]
8 | enable = {{ yanic_webserver | ternary('true','false') }}
9 | bind = "{{ yanic_webserver_bind }}"
10 | webroot = "{{ yanic_webserver_webroot }}"
11 |
12 | [nodes]
13 | enable = {{yanic_nodes | ternary('true','false') }}
14 | state_path = "{{yanic_nodes_state_path}}"
15 | save_interval = "{{yanic_nodes_save_interval}}"
16 | offline_after = "{{yanic_nodes_offline_after}}"
17 | prune_after = "{{yanic_nodes_prune_after}}"
18 |
19 |
20 | [meshviewer]
21 | version = {{yanic_meshviewer_version}}
22 | nodes_path = "{{yanic_meshviewer_nodes}}"
23 | graph_path = "{{yanic_meshviewer_graph}}"
24 |
25 | [database]
26 | delete_after = "{{ yanic_database_delete_after }}"
27 | delete_interval = "{{ yanic_database_delete_interval }}"
28 |
29 | {% for db in yanic_influxdb %}
30 | [[database.connection.influxdb]]
31 | enable = {{ db.enable | ternary('true','false') }}
32 | address = "{{ db.host }}"
33 | database = "{{ db.database }}"
34 | username = "{{ db.username }}"
35 | password = "{{ db.password }}"
36 | {% endfor %}
37 |
38 | {% for db in yanic_socket %}
39 | [[database.connection.socket]]
40 | enable = {{ db.enable | ternary('true','false') }}
41 | type = "{{ db.type }}"
42 | address = "{{ db.address }}"
43 | {% endfor %}
44 |
--------------------------------------------------------------------------------
/roles/yanic/templates/yanic-publish-ssh-master.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Persistent SSH connection to webserver
3 | After=network-online.target
4 |
5 | [Service]
6 | ExecStart=/usr/bin/ssh -M -N ${REMOTE_HOST}
7 | EnvironmentFile=/etc/default/yanic-publish
8 | User=respond-collector
9 | Restart=always
10 | RestartSec=10
11 |
12 | [Install]
13 | WantedBy=multi-user.target
14 |
--------------------------------------------------------------------------------
/roles/yanic/templates/yanic-publish.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Publish data of yanic on downloads server
3 |
4 | [Service]
5 | ExecStart=/usr/bin/rsync --del -rt {{ yanic_nodes_path }}/ ${REMOTE_HOST}:${REMOTE_PATH}
6 | EnvironmentFile=/etc/default/yanic-publish
7 | User=yanic
8 | Type=oneshot
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/roles/yanic/templates/yanic-publish.timer:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=Publish data of yanic on downloads server every minute
3 |
4 | [Timer]
5 | OnBootSec=15min
6 | OnUnitActiveSec=1min
7 |
8 | [Install]
9 | WantedBy=timers.target
10 |
--------------------------------------------------------------------------------
/roles/yanic/templates/yanic.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=yanic
3 |
4 | [Service]
5 | Type=simple
6 | User=yanic
7 | ExecStart=/opt/go/bin/yanic -config /etc/yanic.conf
8 | Restart=always
9 | RestartSec=5s
10 | Environment=PATH=/usr/bin:/usr/local/bin
11 |
12 | [Install]
13 | WantedBy=multi-user.target
14 |
--------------------------------------------------------------------------------
/scripts/open.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
3 | gpg --batch --use-agent --decrypt "${SCRIPT_DIR}/../vault_passphrase.gpg"
4 |
--------------------------------------------------------------------------------
/scripts/resign.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
3 |
4 | ## key of:
5 | # genofire: 386ED1BF848ABB4A6B4A3C45FC83907C125BC2BC
6 | # janeric: BCD82B6C729A931C8CB382E5864F5B9B0642DF6F
7 | # jplitza: D7E72BFC9E133E0452DAFBCBB17F2106D8CCEC27
8 | # mortzu: 62D00A6960AC2256A24240BCD568B1E5EB1A6E50
9 | # ollibaba: D9E17720908282C3A8232361DB7D9F68F00F513E
10 |
11 |
12 | "${SCRIPT_DIR}/open.sh" | gpg -e \
13 | -r 386ED1BF848ABB4A6B4A3C45FC83907C125BC2BC \
14 | -r BCD82B6C729A931C8CB382E5864F5B9B0642DF6F \
15 | -r D7E72BFC9E133E0452DAFBCBB17F2106D8CCEC27 \
16 | -r 62D00A6960AC2256A24240BCD568B1E5EB1A6E50 \
17 | -r D9E17720908282C3A8232361DB7D9F68F00F513E \
18 | -o "${SCRIPT_DIR}/../vault_passphrase.gpg"
19 |
--------------------------------------------------------------------------------
/vagrant/.gitignore:
--------------------------------------------------------------------------------
1 | .vagrant
2 |
--------------------------------------------------------------------------------
/vagrant/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure
5 | # configures the configuration version (we support older styles for
6 | # backwards compatibility). Please don't change it unless you know what
7 | # you're doing.
8 | Vagrant.configure(2) do |config|
9 | # The most common configuration options are documented and commented below.
10 | # For a complete reference, please see the online documentation at
11 | # https://docs.vagrantup.com.
12 |
13 | # Every Vagrant development environment requires a box. You can search for
14 | # boxes at https://atlas.hashicorp.com/search.
15 | config.vm.box = "debian/jessie64"
16 |
17 | # Create a private network, which allows host-only access to the machine
18 | # using a specific IP.
19 | config.vm.network "private_network", ip: "192.168.33.10"
20 |
21 | # Create a public network, which generally matched to bridged network.
22 | # Bridged networks make the machine appear as another physical device on
23 | # your network.
24 | # config.vm.network "public_network"
25 |
26 | # Share an additional folder to the guest VM. The first argument is
27 | # the path on the host to the actual folder. The second argument is
28 | # the path on the guest to mount the folder. And the optional third
29 | # argument is a set of non-required options.
30 | # config.vm.synced_folder "../data", "/vagrant_data"
31 |
32 | # Install authorized keys
33 | authorized_keys = Dir.glob(ENV["HOME"] + "/.ssh/*.pub").map{|file| File.read(file) }.join
34 | config.vm.provision "shell", inline: <<-SHELL
35 | mkdir -p /root/.ssh
36 | echo "#{authorized_keys}" >> /root/.ssh/authorized_keys
37 | SHELL
38 | end
39 |
--------------------------------------------------------------------------------
/vault_passphrase.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreifunkBremen/ansible/37228a3d1c1cbab8d633b85266f6029a356bb3b7/vault_passphrase.gpg
--------------------------------------------------------------------------------