Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Felix Stupp | fdf19c4e26 | 5 years ago |
@ -1,3 +0,0 @@
|
|||||||
[submodule "misc/mitogen"]
|
|
||||||
path = misc/mitogen
|
|
||||||
url = https://git.banananet.work/archive/mitogen.git
|
|
@ -1,16 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"search.usePCRE2": true,
|
||||||
|
"files.associations": {
|
||||||
|
"*.yml": "ansible"
|
||||||
|
},
|
||||||
"[ansible]": {
|
"[ansible]": {
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"editor.autoIndent": false
|
"editor.autoIndent": false
|
||||||
},
|
},
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2
|
||||||
"search.exclude": {
|
|
||||||
"**/node_modules": true,
|
|
||||||
"**/bower_components": true,
|
|
||||||
"playbooks/{credentials,filter_plugins,group_vars,helpers,host_vars,public_keys,roles}/": true
|
|
||||||
},
|
|
||||||
"files.exclude": {
|
|
||||||
"playbooks/{credentials,filter_plugins,group_vars,helpers,host_vars,public_keys,roles}/": true
|
|
||||||
},
|
|
||||||
"python.pythonPath": "/home/zocker/Repositories/ansible2/venv/bin/python",
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 Felix Stupp
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,12 +0,0 @@
|
|||||||
#!/bin/echo You need to source this script! Use something like: source
|
|
||||||
|
|
||||||
# (re-)create env if required (e.g. requirements.txt changed)
|
|
||||||
make setup
|
|
||||||
|
|
||||||
# enable coloring on these tools
|
|
||||||
export ANSIBLE_FORCE_COLORS=1
|
|
||||||
export PY_COLORS=1
|
|
||||||
|
|
||||||
# enter venv
|
|
||||||
. ./venv/bin/activate
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
from ansible.module_utils._text import to_native
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
ENTRY_RE = re.compile(r'^\s*(?P<domain>\S+)(\s+(?P<ttl>\d+))?(\s+(?P<class>[a-zA-Z]+))?\s+(?P<type>[a-zA-Z]+)\s+(?P<data>\S(.*\S)?)\s*$')
|
|
||||||
|
|
||||||
def dns_entry_interpeter(entry):
|
|
||||||
if isinstance(entry, dict):
|
|
||||||
return entry
|
|
||||||
m = ENTRY_RE.match(entry)
|
|
||||||
if not m:
|
|
||||||
raise Exception("Entry not in expected format: %s" % to_native(entry))
|
|
||||||
ret = {}
|
|
||||||
for key, val in m.groupdict().items():
|
|
||||||
if val is not None:
|
|
||||||
if key in ["ttl"]:
|
|
||||||
ret[key] = int(val)
|
|
||||||
else:
|
|
||||||
ret[key] = val
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def dns_entry_equal(a, b):
|
|
||||||
return a.get("domain", "@") == b.get("domain", "@") and a.get("ttl", -1) == b.get("ttl", -1) and a.get("class", "IN") == b.get("class", "IN") and a["type"] == b["type"]
|
|
||||||
|
|
||||||
def dns_entries_combiner(entries):
|
|
||||||
ret = []
|
|
||||||
for a in entries:
|
|
||||||
found = False
|
|
||||||
for b in ret:
|
|
||||||
if dns_entry_equal(a, b):
|
|
||||||
found = True
|
|
||||||
if not isinstance(b["data"], list):
|
|
||||||
b["data"] = [b["data"]]
|
|
||||||
if isinstance(a["data"], list):
|
|
||||||
b["data"] += a["data"]
|
|
||||||
else:
|
|
||||||
b["data"].append(a["data"])
|
|
||||||
break
|
|
||||||
if not found:
|
|
||||||
ret.append(a)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def dns_entries_interpreter(entries):
|
|
||||||
if isinstance(entries, str):
|
|
||||||
entries = [e for e in entries.splitlines() if e]
|
|
||||||
return dns_entries_combiner(map(dns_entry_interpeter, entries))
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'dns_entry_interpreter': dns_entry_interpeter,
|
|
||||||
'dns_entries_combiner': dns_entries_combiner,
|
|
||||||
'dns_entries_interpreter': dns_entries_interpreter,
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
def domain_relative_to(domain, zone):
|
|
||||||
if domain == '@':
|
|
||||||
return zone
|
|
||||||
if domain[-1] != '.':
|
|
||||||
return f"{domain}.{zone}"
|
|
||||||
return domain
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {'domain_relative_to': domain_relative_to}
|
|
@ -1,25 +0,0 @@
|
|||||||
from pathlib import Path
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
NOT_ALLOWED_CHARS = re.compile(r'[^A-Za-z0-9-]+')
|
|
||||||
DOMAIN_SHORTS = Path(__file__).parent / '..' / 'public_keys/domain_shorts'
|
|
||||||
|
|
||||||
def rreplace(text, to_replace, replacement, count=1):
|
|
||||||
return replacement.join(text.rsplit(to_replace, count))
|
|
||||||
|
|
||||||
def domain_to_username(domain):
|
|
||||||
with DOMAIN_SHORTS.open() as f:
|
|
||||||
for l in f:
|
|
||||||
long_domain, _, short_domain = l.strip().partition(' ')
|
|
||||||
if domain.endswith(long_domain):
|
|
||||||
domain = rreplace(domain, long_domain, short_domain)
|
|
||||||
break
|
|
||||||
return NOT_ALLOWED_CHARS.sub('-', domain)
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {'domain_to_username': domain_to_username}
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
print(domain_to_username(sys.argv[1]))
|
|
@ -1,29 +0,0 @@
|
|||||||
from netaddr import IPNetwork, IPSet
|
|
||||||
|
|
||||||
def ip_rev(orig, rev, net):
|
|
||||||
if orig.isdisjoint(IPSet(net)):
|
|
||||||
rev.add(net)
|
|
||||||
return
|
|
||||||
elif orig.issuperset(IPSet(net)):
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
for net in net.subnet(net.prefixlen + 1):
|
|
||||||
ip_rev(orig, rev, net)
|
|
||||||
|
|
||||||
def ip_net_rev(addresses, version=None):
|
|
||||||
orig = IPSet(addresses)
|
|
||||||
rev = IPSet()
|
|
||||||
if version in [None, 4]:
|
|
||||||
ip_rev(orig, rev, IPNetwork('0.0.0.0/0'))
|
|
||||||
if version in [None, 6]:
|
|
||||||
ip_rev(orig, rev, IPNetwork('::/0'))
|
|
||||||
return [str(net) for net in rev.iter_cidrs()]
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {'ip_net_rev': ip_net_rev}
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import sys
|
|
||||||
for ip in ip_net_rev(sys.argv[1:]):
|
|
||||||
print(ip)
|
|
@ -1,8 +0,0 @@
|
|||||||
from collections import Mapping
|
|
||||||
|
|
||||||
def mapping(val):
|
|
||||||
return isinstance(val, Mapping)
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {'mapping': mapping}
|
|
@ -1,33 +0,0 @@
|
|||||||
from functools import partial
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from ansible.errors import AnsibleFilterError
|
|
||||||
|
|
||||||
def systemd_escape(text, instance=False, mangle=False, path=False, suffix=None, template=None, unescape=False):
|
|
||||||
options_map = {
|
|
||||||
"instance": instance,
|
|
||||||
"mangle": mangle,
|
|
||||||
"path": path,
|
|
||||||
"unescape": unescape,
|
|
||||||
}
|
|
||||||
args_map = {
|
|
||||||
"suffix": suffix,
|
|
||||||
"template": template,
|
|
||||||
}
|
|
||||||
args = ["/usr/bin/env", "systemd-escape"] + [f"--{name}" for name, val in options_map.items() if val] + [f"--{name}={val}" for name, val in args_map.items() if val is not None] + [text]
|
|
||||||
result = subprocess.run(args, capture_output=True, text=True)
|
|
||||||
if result.returncode != 0:
|
|
||||||
raise AnsibleFilterError(re.sub('\u001b\\[.*?[@-~]', '', result.stderr.rstrip('\n')))
|
|
||||||
return result.stdout.rstrip('\n')
|
|
||||||
|
|
||||||
class FilterModule(object):
|
|
||||||
def filters(self):
|
|
||||||
return {
|
|
||||||
'systemd_escape': systemd_escape,
|
|
||||||
'systemd_escape_mount': partial(systemd_escape, path=True, suffix='mount')
|
|
||||||
}
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
print(systemd_escape(sys.argv[1]))
|
|
@ -1,92 +0,0 @@
|
|||||||
---
|
|
||||||
# === Constants defined by OS packages / applications
|
|
||||||
# seperated in arbitary system/kernel and applications/packages
|
|
||||||
# each group is sorted alphabetically
|
|
||||||
|
|
||||||
# general system/kernel constants
|
|
||||||
|
|
||||||
global_fstab_file: "/etc/fstab"
|
|
||||||
|
|
||||||
global_resolv_conf: "/etc/resolv.conf"
|
|
||||||
global_pamd: "/etc/pam.d"
|
|
||||||
|
|
||||||
global_proc_hidepid_service_whitelist:
|
|
||||||
- "{{ global_systemd_login_service_name }}"
|
|
||||||
- "{{ global_systemd_user_service_name }}"
|
|
||||||
|
|
||||||
global_users_directory: "/home"
|
|
||||||
|
|
||||||
# application constants
|
|
||||||
|
|
||||||
global_ansible_facts_directory: "/etc/ansible/facts.d"
|
|
||||||
|
|
||||||
global_apparmor_profiles_directory: "/etc/apparmor.d"
|
|
||||||
global_apparmor_profiles_local_directory: "{{ global_apparmor_profiles_directory }}/local"
|
|
||||||
|
|
||||||
global_apt_sources_directory: "/etc/apt/sources.list.d"
|
|
||||||
|
|
||||||
global_bind_service_name: "named.service"
|
|
||||||
global_bind_configuration_directory: "/etc/bind"
|
|
||||||
global_bind_data_directory: "/var/lib/bind"
|
|
||||||
|
|
||||||
global_certbot_configuration_directory: "/etc/letsencrypt"
|
|
||||||
global_certbot_configuration_file: "{{ global_certbot_configuration_directory }}/cli.ini"
|
|
||||||
global_certbot_certificates_directory: "/etc/letsencrypt/live"
|
|
||||||
|
|
||||||
global_chromium_configuration_directory: "/etc/chromium"
|
|
||||||
global_chromium_managed_policies_file: "{{ global_chromium_configuration_directory }}/policies/managed/managed_policies.json"
|
|
||||||
|
|
||||||
global_dnsmasq_configuration_file: "/etc/dnsmasq.conf"
|
|
||||||
global_dnsmasq_configuration_directory: "/etc/dnsmasq.d"
|
|
||||||
|
|
||||||
global_docker_service_name: "docker.service"
|
|
||||||
global_docker_configuration_directory: "/etc/docker"
|
|
||||||
global_docker_daemon_configuration_file: "{{ global_docker_configuration_directory }}/daemon.json"
|
|
||||||
|
|
||||||
global_fail2ban_service_name: "fail2ban.service"
|
|
||||||
global_fail2ban_system_directory: "/etc/fail2ban"
|
|
||||||
global_fail2ban_configuration_directory: "{{ global_fail2ban_system_directory }}/fail2ban.d"
|
|
||||||
global_fail2ban_actions_directory: "{{ global_fail2ban_system_directory }}/action.d"
|
|
||||||
global_fail2ban_filters_directory: "{{ global_fail2ban_system_directory }}/filter.d"
|
|
||||||
global_fail2ban_jails_directory: "{{ global_fail2ban_system_directory }}/jail.d"
|
|
||||||
|
|
||||||
global_interfaces_directory: "/etc/network/interfaces.d"
|
|
||||||
|
|
||||||
global_lightdm_configuration_directory: "/etc/lightdm"
|
|
||||||
|
|
||||||
global_log_directory: "/var/log"
|
|
||||||
|
|
||||||
global_mysql_socket_path: "/var/run/mysqld/mysqld.sock"
|
|
||||||
|
|
||||||
global_nfs_port: "2049" # for version 4
|
|
||||||
global_nfs_directory: "{{ global_webservers_directory }}/nfs"
|
|
||||||
|
|
||||||
global_nginx_system_user: www-data
|
|
||||||
global_nginx_service_name: "nginx.service"
|
|
||||||
global_nginx_installation_directory: "/etc/nginx"
|
|
||||||
|
|
||||||
global_plymouth_themes_directory: "/usr/share/plymouth/themes"
|
|
||||||
|
|
||||||
global_redis_configuration_directory: "/etc/redis"
|
|
||||||
global_redis_service_name: "redis-server.service"
|
|
||||||
|
|
||||||
global_ssh_service_name: "sshd.service"
|
|
||||||
global_ssh_configuration_directory: "/etc/ssh/"
|
|
||||||
global_ssh_configuration_environment_directory: "{{ global_configuration_environment_directory }}/ssh"
|
|
||||||
global_ssh_configuration_link_name: "config"
|
|
||||||
global_ssh_configuration_link: "{{ global_ssh_configuration_environment_directory }}/{{ global_ssh_configuration_link_name }}"
|
|
||||||
|
|
||||||
global_sudoers_directory: "/etc/sudoers.d"
|
|
||||||
|
|
||||||
global_wireguard_configuration_directory: "/etc/wireguard"
|
|
||||||
|
|
||||||
global_systemd_preset_directory: "/lib/systemd/system"
|
|
||||||
global_systemd_configuration_directory: "/etc/systemd/system"
|
|
||||||
global_systemd_journal_configuration_directory: "/etc/systemd/journald.conf.d"
|
|
||||||
global_systemd_login_service_name: "systemd-logind.service"
|
|
||||||
global_systemd_network_directory: "/etc/systemd/network"
|
|
||||||
global_systemd_network_service_name: "systemd-networkd.service"
|
|
||||||
global_systemd_network_system_user: "systemd-network"
|
|
||||||
global_systemd_user_service_name: "user@.service"
|
|
||||||
|
|
||||||
global_zsh_antigen_source: "/usr/share/zsh-antigen/antigen.zsh"
|
|
@ -1,38 +1,18 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
66386430666466343732636663313264663933613563643231323066383261616361353234366534
|
64333965353537646136656630316237636563383764356461623238323836383466313230333531
|
||||||
3337323862636537663538343062333064383838653138340a343662326139396634343261396230
|
6131306336633661373335653663613538633662663438360a343839666263396139343735333462
|
||||||
65666533626263386465616466663431333339613162373766363937333564323233353930303836
|
62333564383633326131646533313566306534623539393533333366356264623562643438653231
|
||||||
6332366434333437370a666636656534653031303237633863356630393836386137353837303039
|
6133396364663765300a343766643036613262613062326532373738653538623333303933323237
|
||||||
33323433343065313135323462316163343364656562303962373634656666353235363537366361
|
36313864346161356332663664386635333764393161646332643938623332386562313836653436
|
||||||
35383031343138376439316365306337636264346434363863623765356161663133653363633533
|
63353136373866373238356334363762363961653964333565343364306135616363376565623536
|
||||||
30613430613333666561303935663833396265363931653133373934363263323362333839366662
|
31353737643366353330343266613466343231653033336433343632353465353836616638636231
|
||||||
62373533643535323430353032386431346462363566323637613736313336373665666631326633
|
34313138633238313839616139633431653630306338373065623961656462316432353966363661
|
||||||
34343830653535623262333730356164636131623735333839663336623735353138313962656564
|
30393862373634373161326262363162343139313334613939613636633665613839353862346533
|
||||||
35643231303461653236373665613339313332386535376665623130646637626531306366316266
|
34353366333733303363323164613934633634353866393831333566626565383036373964386633
|
||||||
36613961653162633639333536333434383332363061653062396163623664316363303561636634
|
39316131363732353663626530333634616435316464633937656136386534383635643337323262
|
||||||
63353263313730313133613537386536616338323533303666653131656262323763616432343664
|
33643336616237323533353639666465363563363437306232313266646238623130616235623265
|
||||||
65626130383432326663303238383233633265393936633934623634366663333862643562383736
|
65323665383038343732643064316533666239633738666539373463626332386431303633333934
|
||||||
38313265306138303431363634656334656530393539636232613962386238613963643161306234
|
65386662346361653232643437346663303362623834623063363061396361303861363739373139
|
||||||
35646136613764353138666431363337393765343233303332663530336261316331383665643536
|
36346365366537356565373165663238626335616336373433343834346138656562333464323037
|
||||||
30663831656566663239656565613535316438666632663236666636383762333432303964333833
|
65613336336135343938373064623766353666623763323364343836643262653032626230383566
|
||||||
33353661623965633630383536613633313437666430623565636635633634646338633666356234
|
3466
|
||||||
66323966396638316236626234326364633366666266643832333066383735306330366234383533
|
|
||||||
63386563626264303234303832356662363732356438306234656561373637376137346565653966
|
|
||||||
65373465303032393939383833386333353461633732623232393761353236306331626164386238
|
|
||||||
35353464373732346537626464663532653434386564636532623838383937363463633332366534
|
|
||||||
35613137613933636434336432653964353536303366353832356161653535353165613964333339
|
|
||||||
30646139316661656363383832313765326234316134393732636262373730386562626233633439
|
|
||||||
39643862393336653533373731333938343164363233323638353265656139333465363831333431
|
|
||||||
62323332396537656432343235633735636631646334306265376566343364646566396563386537
|
|
||||||
32366335313335666436613531356535623364336135636665623233363763663537393538666233
|
|
||||||
35643431396430336533396137303763333332626439316265383138663639343061656631626463
|
|
||||||
39386461303866373862626361373836643437346365343531323264386631313834613166393833
|
|
||||||
34656537326531643962636436393236393537373935346135663335656666343430313335373633
|
|
||||||
65393066636233653262623031383564393038353730393363356561363936356366636330386264
|
|
||||||
37383064636433646265396365373330613833623338666638653532363061316261343639323937
|
|
||||||
33623665316161353035366438663337346532653262366434366138306364343966653235383636
|
|
||||||
38666263623633356463373963636135656637613164353265613635353733316138626637623364
|
|
||||||
34386338633363653231643334323161653933613864636338626638323035323233643137353964
|
|
||||||
35666332346264613136343039336261303964343237373136393139376234363833376164643839
|
|
||||||
33316566353033363333633966643366303537653766623935643933373062313830316166303961
|
|
||||||
37393638653064623935356564303236343766393939323561356461656636626534
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
bootstrap_user: "debian"
|
|
||||||
|
|
||||||
mysql_query_cache_size: 1G
|
|
||||||
|
|
||||||
# Currently disabled because upstream servers do not support forwarding DNSSEC related records
|
|
||||||
#global_dns_upstream_servers:
|
|
||||||
# - 129.143.2.1
|
|
||||||
# - 129.143.2.4
|
|
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
global_dns_upstream_servers:
|
|
||||||
- 213.136.95.10
|
|
||||||
- 213.136.95.11
|
|
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
bootstrap_user: "root"
|
|
||||||
|
|
||||||
global_dns_upstream_servers:
|
|
||||||
- 213.133.100.100
|
|
||||||
- 213.133.99.99
|
|
||||||
- 213.133.98.98
|
|
||||||
- "2a01:4f8:0:1::add:1010"
|
|
||||||
- "2a01:4f8:0:1::add:9898"
|
|
||||||
- "2a01:4f8:0:1::add:9999"
|
|
||||||
|
|
||||||
debian_repository_mirror: "http://mirror.hetzner.de/debian/packages"
|
|
||||||
debian_repository_use_sources: no # Not supported by Hetzner mirrors, but also not required
|
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_python_interpreter: "/usr/bin/python3"
|
|
||||||
ansible_distribution_name: "debian"
|
|
||||||
|
|
||||||
# debian_repository_mirror
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_distribution_name: "raspbian"
|
|
||||||
|
|
||||||
bootstrap_user: "pi"
|
|
||||||
bootstrap_become_pass: ""
|
|
||||||
ansible_ssh_pass: "raspberry"
|
|
||||||
|
|
||||||
# raspbian_repository_mirror
|
|
||||||
# raspbian_archive_repository_mirror
|
|
||||||
|
|
||||||
global_systemd_journal_max_storage: 256M
|
|
@ -0,0 +1,4 @@
|
|||||||
|
FILES = $(shell ls | grep -vE "^dns$$")
|
||||||
|
|
||||||
|
dns: $(FILES)
|
||||||
|
echo "$(FILES)" | xargs --max-args 1 ssh-keygen -r "$$(basename "$$(pwd)")." -f > "$@"
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_host: "10.11.11.64"
|
|
||||||
debian_repository_mirror: "http://10.11.11.64:9999/debian/"
|
|
||||||
|
|
||||||
wireguard_ipv4_address: "10.162.4.64"
|
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
ansible_host: "193.196.36.223"
|
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_host: "193.196.37.200"
|
|
||||||
|
|
||||||
wireguard_ipv4_address: "10.162.4.2"
|
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
ansible_host: "193.196.36.154"
|
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_host: "193.196.38.137"
|
|
||||||
|
|
||||||
wireguard_ipv4_address: "10.162.4.3"
|
|
@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
ansible_host: "10.11.11.194"
|
|
@ -0,0 +1,9 @@
|
|||||||
|
[bootstrap]
|
||||||
|
nvak.banananet.work
|
||||||
|
morska.banananet.work
|
||||||
|
rurapenthe.banananet.work
|
||||||
|
|
||||||
|
[wireguard_nodes]
|
||||||
|
nvak.banananet.work
|
||||||
|
morska.banananet.work
|
||||||
|
rurapenthe.banananet.work
|
@ -1,212 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import json
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
|
|
||||||
class LoopPrevention:
|
|
||||||
|
|
||||||
def __init__(self, obj):
|
|
||||||
self.__obj = obj
|
|
||||||
self.__entered = False
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
if self.__entered:
|
|
||||||
raise Exception("detected and prevented infinite loop")
|
|
||||||
self.__entered = True
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, *args):
|
|
||||||
self.__entered = False
|
|
||||||
return False # forward exception
|
|
||||||
|
|
||||||
|
|
||||||
class Group:
|
|
||||||
|
|
||||||
def __init__(self, inv):
|
|
||||||
self.__inv = inv
|
|
||||||
self.__hosts = set()
|
|
||||||
self.__children = set()
|
|
||||||
|
|
||||||
def add_host(self, host):
|
|
||||||
if not host in self.__hosts:
|
|
||||||
self.__hosts.add(host)
|
|
||||||
|
|
||||||
def add_hosts(self, hosts):
|
|
||||||
self.__hosts |= hosts
|
|
||||||
|
|
||||||
@property
|
|
||||||
def direct_hosts(self):
|
|
||||||
return set(self.__hosts)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def all_hosts(self):
|
|
||||||
with LoopPrevention(self):
|
|
||||||
hosts = self.direct_hosts
|
|
||||||
for child in self.children:
|
|
||||||
hosts |= self.__inv._group(child).all_hosts
|
|
||||||
return hosts
|
|
||||||
|
|
||||||
def add_child(self, group_name):
|
|
||||||
if not group_name in self.__children:
|
|
||||||
self.__children.add(group_name)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def children(self):
|
|
||||||
return set(self.__children)
|
|
||||||
|
|
||||||
def export(self):
|
|
||||||
return { "hosts": list(self.__hosts), "vars": dict(), "children": list(self.__children) }
|
|
||||||
|
|
||||||
|
|
||||||
class Inventory:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.__groups = dict()
|
|
||||||
self.add_group("all")
|
|
||||||
|
|
||||||
def __group(self, group_name):
|
|
||||||
if group_name not in self.__groups:
|
|
||||||
self.__groups[group_name] = Group(self)
|
|
||||||
return self.__groups[group_name]
|
|
||||||
|
|
||||||
def _group(self, group_name):
|
|
||||||
if group_name not in self.__groups:
|
|
||||||
raise Exception(f'Unknown group "{group_name}"')
|
|
||||||
return self.__groups[group_name]
|
|
||||||
|
|
||||||
def add_host(self, host):
|
|
||||||
self.__group("all").add_host(host)
|
|
||||||
|
|
||||||
def add_hosts(self, hosts):
|
|
||||||
self.__group("all").add_hosts(hosts)
|
|
||||||
|
|
||||||
def add_group(self, group_name):
|
|
||||||
self.__group(group_name)
|
|
||||||
|
|
||||||
def add_host_to_group(self, host, group_name):
|
|
||||||
self.add_host(host)
|
|
||||||
self.__group(group_name).add_host(host)
|
|
||||||
|
|
||||||
def add_hosts_to_group(self, hosts, group_name):
|
|
||||||
self.add_hosts(hosts)
|
|
||||||
self.__group(group_name).add_hosts(hosts)
|
|
||||||
|
|
||||||
def add_child_to_group(self, child_name, parent_name):
|
|
||||||
self.__group(child_name)
|
|
||||||
self.__group(parent_name).add_child(child_name)
|
|
||||||
|
|
||||||
def all_hosts_of_group(self, group_name):
|
|
||||||
return self._group(group_name).all_hosts
|
|
||||||
|
|
||||||
def export(self):
|
|
||||||
meta_dict = {
|
|
||||||
"_meta": {
|
|
||||||
"hostvars": {},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
group_dict = { group_name: group.export() for group_name, group in self.__groups.items() }
|
|
||||||
return { **meta_dict , **group_dict }
|
|
||||||
|
|
||||||
|
|
||||||
def _read_yaml(path):
|
|
||||||
with open(path, 'r') as stream:
|
|
||||||
try:
|
|
||||||
return yaml.safe_load(stream)
|
|
||||||
except yaml.YAMLError as e:
|
|
||||||
return AnsibleError(e)
|
|
||||||
|
|
||||||
GROUPS_PATTERN_OPS = {
|
|
||||||
"": lambda old, add: old | add,
|
|
||||||
"&": lambda old, add: old & add,
|
|
||||||
"!": lambda old, add: old - add,
|
|
||||||
}
|
|
||||||
GROUPS_PATTERN_OPS_NAMES = "".join(GROUPS_PATTERN_OPS.keys())
|
|
||||||
GROUPS_PATTERN = re.compile(r'^(?P<operation>[' + GROUPS_PATTERN_OPS_NAMES + r']?)(?P<group_name>[^' + GROUPS_PATTERN_OPS_NAMES + r'].*)$')
|
|
||||||
def _parse_group_aliasses(inv, data):
|
|
||||||
for group, syntax in data.items():
|
|
||||||
if isinstance(syntax, str):
|
|
||||||
group_list = syntax.split(':')
|
|
||||||
elif isinstance(syntax, list):
|
|
||||||
group_list = syntax
|
|
||||||
else:
|
|
||||||
raise Exception(f'Unknown syntax for alias "{group}": {syntax}')
|
|
||||||
if len(syntax) <= 0 or len(group_list) <= 0:
|
|
||||||
raise Exception(f'Empty syntax for alias "{group}": {syntax}')
|
|
||||||
if group_list[0][0] == '!': # if first entry is an inversion
|
|
||||||
group_list.insert(0, 'all') # remove group from all for inversion
|
|
||||||
hosts = set()
|
|
||||||
for group_name in group_list:
|
|
||||||
group_matched = GROUPS_PATTERN.match(group_name)
|
|
||||||
add = inv.all_hosts_of_group(group_matched.group('group_name'))
|
|
||||||
op = GROUPS_PATTERN_OPS[group_matched.group('operation')]
|
|
||||||
hosts = op(hosts, add)
|
|
||||||
inv.add_hosts_to_group(hosts, group)
|
|
||||||
|
|
||||||
def _parse_groups(inv, data):
|
|
||||||
for group, children in data.items():
|
|
||||||
inv.add_group(group)
|
|
||||||
if children is None:
|
|
||||||
continue # as if no children are given
|
|
||||||
for child in children:
|
|
||||||
inv.add_child_to_group(child, group)
|
|
||||||
if isinstance(children, dict):
|
|
||||||
_parse_groups(inv, children)
|
|
||||||
|
|
||||||
def _parse_host_groups(inv, data):
|
|
||||||
GROUPS_KEY = "_all"
|
|
||||||
for host_group, hosts in data.items():
|
|
||||||
inv.add_group(host_group)
|
|
||||||
if hosts is None:
|
|
||||||
continue
|
|
||||||
for host in hosts:
|
|
||||||
if host != GROUPS_KEY:
|
|
||||||
inv.add_host_to_group(host, host_group)
|
|
||||||
if isinstance(hosts, dict):
|
|
||||||
hosts = dict(hosts) # copy dict for further edits
|
|
||||||
parents = hosts.pop(GROUPS_KEY, None)
|
|
||||||
if parents is not None:
|
|
||||||
for parent in parents:
|
|
||||||
inv.add_child_to_group(host_group, parent)
|
|
||||||
_parse_single_hosts(inv, hosts)
|
|
||||||
|
|
||||||
def _parse_single_hosts(inv, data):
|
|
||||||
for host, groups in data.items():
|
|
||||||
inv.add_host(host)
|
|
||||||
if groups is not None:
|
|
||||||
for group in groups:
|
|
||||||
inv.add_host_to_group(host, group)
|
|
||||||
|
|
||||||
def _parse_version_0(inv, data):
|
|
||||||
return _parse_single_hosts(inv, data)
|
|
||||||
|
|
||||||
parser_mapping_v1 = { "groups": _parse_groups, "host_groups": _parse_host_groups, "single_hosts": _parse_single_hosts }
|
|
||||||
def _parse_version_1(inv, data):
|
|
||||||
for key_name, parser in parser_mapping_v1.items():
|
|
||||||
if key_name in data:
|
|
||||||
parser(inv, data[key_name])
|
|
||||||
|
|
||||||
def _parse_version_2(inv, data):
|
|
||||||
_parse_version_1(inv, data)
|
|
||||||
_parse_group_aliasses(inv, data["group_aliasses"])
|
|
||||||
|
|
||||||
parser_version_mapping = {
|
|
||||||
None: _parse_version_0, # legacy version without version number, only hosts list with tags
|
|
||||||
1: _parse_version_1, # adds support for default, inversed group dependencies and host_groups aside single_hosts (ignores aliases supported with version 2)
|
|
||||||
2: _parse_version_2, # adds support for aliases (thus destroying the common graph structures where aliasses were used)
|
|
||||||
}
|
|
||||||
def parse(path):
|
|
||||||
data = _read_yaml(path)
|
|
||||||
inv = Inventory()
|
|
||||||
version = data.get("version", None)
|
|
||||||
# detect that version was used as hostname
|
|
||||||
if not isinstance(version, (int, float, complex)):
|
|
||||||
version = None
|
|
||||||
if version not in parser_version_mapping:
|
|
||||||
raise AnsibleError(Exception("Version not supported"))
|
|
||||||
parser_version_mapping[version](inv, data)
|
|
||||||
return inv.export()
|
|
||||||
|
|
||||||
print(json.dumps(parse("hosts.yml")))
|
|
@ -1,85 +0,0 @@
|
|||||||
version: 2
|
|
||||||
|
|
||||||
groups: # a:b meaning b is a, can be nested
|
|
||||||
|
|
||||||
# hardware structure
|
|
||||||
dev_known:
|
|
||||||
barebones:
|
|
||||||
- rented_barebones # sub group
|
|
||||||
# list of all known barebone device groups
|
|
||||||
- dev_surface3 # Microsoft Surface 3
|
|
||||||
virtual:
|
|
||||||
- rented_vserver # sub group
|
|
||||||
dev_unknown: # for unknown device kinds
|
|
||||||
|
|
||||||
# structure of rented servers
|
|
||||||
rented:
|
|
||||||
rented_barebones:
|
|
||||||
- hetzner_server # https://robot.your-server.de/server
|
|
||||||
rented_vserver:
|
|
||||||
- bwcloud_vserver # https://portal.bw-cloud.org/
|
|
||||||
- contabo_vserver # https://my.contabo.com/vps
|
|
||||||
|
|
||||||
# OS structure
|
|
||||||
os_known: # list of all known OS derivates
|
|
||||||
- os_debian
|
|
||||||
- os_raspbian
|
|
||||||
|
|
||||||
# applications
|
|
||||||
|
|
||||||
bootstrapable: # which OSes/hosts can be bootstraped
|
|
||||||
- os_debian
|
|
||||||
- os_raspbian
|
|
||||||
|
|
||||||
|
|
||||||
group_aliasses: # a:b meaning a equals b, should only depend on groups not defined here
|
|
||||||
|
|
||||||
# unknown groups
|
|
||||||
dev_unknown: "!dev_known"
|
|
||||||
os_unknown: "!os_known"
|
|
||||||
|
|
||||||
# applications
|
|
||||||
bootstrap: "bootstrapable:!no_bootstrap" # which hosts should be bootstraped
|
|
||||||
common_roles: "!no_common_roles"
|
|
||||||
wireguard_backbones: "public_available:!no_wireguard_automatic"
|
|
||||||
wireguard_clients: "!public_available:!no_wireguard_automatic"
|
|
||||||
|
|
||||||
|
|
||||||
host_groups: # group: host: [*groups]
|
|
||||||
|
|
||||||
no_defaults: # do not include in all default playbooks / roles
|
|
||||||
_all:
|
|
||||||
- no_bootstrap # do not setup sudo bootstrap
|
|
||||||
- no_common_roles # do not include in common roles
|
|
||||||
- no_wireguard_automatic # do not assign wireguard role automatic, hosts may be excluded from wireguard or assigned to their wireguard role manually
|
|
||||||
|
|
||||||
rented:
|
|
||||||
_all:
|
|
||||||
- public_available # rented are public available
|
|
||||||
|
|
||||||
# to group similar devices together
|
|
||||||
|
|
||||||
common_server: # public common servers
|
|
||||||
_all:
|
|
||||||
- os_debian
|
|
||||||
hatoria.banananet.work:
|
|
||||||
- hetzner_server
|
|
||||||
nvak.banananet.work:
|
|
||||||
- contabo_vserver
|
|
||||||
morska.banananet.work:
|
|
||||||
- bwcloud_vserver
|
|
||||||
rurapenthe.banananet.work:
|
|
||||||
- bwcloud_vserver
|
|
||||||
|
|
||||||
|
|
||||||
single_hosts: # a:b meaning a is b, cannot be nested
|
|
||||||
|
|
||||||
# Local Servers
|
|
||||||
hardie.eridon.banananet.work:
|
|
||||||
- os_debian
|
|
||||||
|
|
||||||
# Embedded Devices
|
|
||||||
wgpanel.eridon.banananet.work:
|
|
||||||
- dev_surface3
|
|
||||||
- os_debian
|
|
||||||
- no_wireguard_automatic # no wireguard
|
|
@ -1,115 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# Copyright: (c) 2018, Terry Jones <terry.jones@example.org>
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
DOCUMENTATION = r'''
|
|
||||||
---
|
|
||||||
module: tsig_interpreter
|
|
||||||
|
|
||||||
short_description: Reads BIND9 tsig key files and outputs content to register
|
|
||||||
|
|
||||||
# If this is part of a collection, you need to use semantic versioning,
|
|
||||||
# i.e. the version is of the form "2.5.0" and not "2.4".
|
|
||||||
version_added: "1.0.0"
|
|
||||||
|
|
||||||
description: This is my longer description explaining my test module.
|
|
||||||
|
|
||||||
options:
|
|
||||||
path:
|
|
||||||
description: Path the keyfile should be found
|
|
||||||
required: true
|
|
||||||
type: str
|
|
||||||
aliases:
|
|
||||||
- file
|
|
||||||
- key_file
|
|
||||||
|
|
||||||
author:
|
|
||||||
- Felix Stupp (@zocker1999net)
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = r'''
|
|
||||||
# Gain and use key
|
|
||||||
- name: Gain key
|
|
||||||
my_namespace.my_collection.tsig_interpreter:
|
|
||||||
path: '/etc/bind/rndc.key'
|
|
||||||
register: key_data
|
|
||||||
|
|
||||||
- name: Use key
|
|
||||||
nsupdate:
|
|
||||||
key_algorithm: key_data.key_algorithm
|
|
||||||
key_name: key_data.key_name
|
|
||||||
key_secret: key_data.key_secret
|
|
||||||
'''
|
|
||||||
|
|
||||||
RETURN = r'''
|
|
||||||
key_algorithm:
|
|
||||||
description: The algorithm used for the key
|
|
||||||
type: str
|
|
||||||
returned: always
|
|
||||||
sample: 'hmac-md5'
|
|
||||||
key_file:
|
|
||||||
description: The file that contained the extracted key
|
|
||||||
type: str
|
|
||||||
returned: always
|
|
||||||
sample: '/my/path/my.key'
|
|
||||||
key_name:
|
|
||||||
description: The name of the key
|
|
||||||
type: str
|
|
||||||
returned: always
|
|
||||||
sample: 'key.example.com'
|
|
||||||
key_secret:
|
|
||||||
description: The secret of the key
|
|
||||||
type: str
|
|
||||||
returned: always
|
|
||||||
sample: 'ABCDEFG=='
|
|
||||||
'''
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
|
|
||||||
def main():
|
|
||||||
content_regex = re.compile(r'^\s*key\s+"?(?P<name>[^"\s{};]+)"?\s+\{\s*algorithm\s+"?(?P<algo>[^"\s{};]+)"?\s*;\s*secret\s+"?(?P<secret>[^"\s{};]+)"?\s*;\s*}\s*;\s*$')
|
|
||||||
module_args = {
|
|
||||||
"path": {
|
|
||||||
"type": "str",
|
|
||||||
"required": True,
|
|
||||||
"aliases": ["file", "key_file"],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
module = AnsibleModule(
|
|
||||||
argument_spec=module_args,
|
|
||||||
supports_check_mode=True, # ignored because only data is retrieved
|
|
||||||
)
|
|
||||||
# get params
|
|
||||||
path = module.params["path"]
|
|
||||||
# prepare result
|
|
||||||
result = {
|
|
||||||
"changed": False,
|
|
||||||
"key_file": path,
|
|
||||||
}
|
|
||||||
# check file
|
|
||||||
if not os.path.exists(path):
|
|
||||||
module.fail_json(msg="file not found: %s" % path)
|
|
||||||
if not os.access(path, os.R_OK):
|
|
||||||
module.fail_json(msg="file is not readable: %s" % path)
|
|
||||||
# gain content
|
|
||||||
with open(path, 'r') as fh:
|
|
||||||
content = fh.read()
|
|
||||||
# interpret content
|
|
||||||
content = content.replace("\n", " ")
|
|
||||||
match = content_regex.match(content)
|
|
||||||
if not match:
|
|
||||||
module.fail_json(msg="content of file not in expected syntax: %s" % path)
|
|
||||||
result["key_algorithm"] = match.group("algo")
|
|
||||||
result["key_name"] = match.group("name")
|
|
||||||
result["key_secret"] = match.group("secret")
|
|
||||||
# exit
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,53 +1,17 @@
|
|||||||
vault:=group_vars/all/vault.yml
|
vault:=group_vars/all/vault.yml
|
||||||
playbooks_dir:=playbooks
|
playbooks_dir:=playbooks
|
||||||
playbooks:=$(wildcard ${playbooks_dir}/*.yml)
|
playbooks:=$(wildcard ${playbooks_dir}/*.yml)
|
||||||
credentials_dir:=credentials
|
|
||||||
credentials_file:=misc/credentials.tar.gpg
|
|
||||||
venv_dir:=venv
|
|
||||||
|
|
||||||
# Default Target (must be first target)
|
.PHONY: main list vault ${playbooks}
|
||||||
|
|
||||||
.PHONY: main
|
|
||||||
main:
|
main:
|
||||||
ansible-playbook site.yml
|
ansible-playbook site.yml
|
||||||
|
|
||||||
# Virtual Environment's Setup
|
|
||||||
|
|
||||||
.PHONY: setup
|
|
||||||
setup: ansible_collections ${venv_dir}
|
|
||||||
|
|
||||||
ansible_collections: collection-requirements.yml ${venv_dir}
|
|
||||||
mkdir --parent $@
|
|
||||||
. ./${venv_dir}/bin/activate && ansible-galaxy install -r $<
|
|
||||||
|
|
||||||
${venv_dir}: pip-requirements.txt
|
|
||||||
python3 -m venv $@
|
|
||||||
. ./$@/bin/activate && python3 -m pip install -r $<
|
|
||||||
|
|
||||||
# Playbook Execution
|
|
||||||
|
|
||||||
.PHONY: list
|
|
||||||
list:
|
list:
|
||||||
@echo ${playbooks}
|
@echo ${playbooks}
|
||||||
|
|
||||||
.PHONY: ${playbooks}
|
|
||||||
${playbooks}:
|
|
||||||
ansible-playbook ${playbooks_dir}/$@.yml
|
|
||||||
|
|
||||||
# Vault Handling
|
|
||||||
|
|
||||||
.PHONY: vault
|
|
||||||
vault:
|
vault:
|
||||||
ansible-vault edit ${vault}
|
ansible-vault edit ${vault}
|
||||||
|
|
||||||
# Credential Handling
|
${playbooks}:
|
||||||
|
ansible-playbook ${playbooks_dir}/$@.yml
|
||||||
.PHONY: store-credentials
|
|
||||||
store-credentials: ${credentials_file}
|
|
||||||
|
|
||||||
${credentials_file}: $(shell find "${credentials_dir}")
|
|
||||||
tar -cf - "${credentials_dir}" | gpg --encrypt --recipient 73D09948B2392D688A45DC8393E1BD26F6B02FB7 > "$@"
|
|
||||||
|
|
||||||
.PHONY: load-credentials
|
|
||||||
load-credentials:
|
|
||||||
< "${credentials_file}" gpg --decrypt | tar -xf -
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail;
|
|
||||||
|
|
||||||
LIST_FILE="$(dirname "$0")/ipv4.txt";
|
|
||||||
TMP_FILE="$(mktemp)";
|
|
||||||
|
|
||||||
IP_REGEX='(?<!\d)\d+(\.\d+){3}(/\d+)?(?!\d)';
|
|
||||||
|
|
||||||
cat "$LIST_FILE" "$@" |
|
|
||||||
grep --only-matching --perl-regexp "$IP_REGEX" |
|
|
||||||
sort --version-sort |
|
|
||||||
uniq > "$TMP_FILE";
|
|
||||||
|
|
||||||
echo "$TMP_FILE";
|
|
||||||
if diff "$LIST_FILE" "$TMP_FILE"; then
|
|
||||||
echo "No differences found!";
|
|
||||||
exit 0;
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Press enter to approve changes, ^C to abort";
|
|
||||||
read;
|
|
||||||
|
|
||||||
mv "$TMP_FILE" "$LIST_FILE";
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
Subproject commit 36f3e3b28c82611c72a867cdc1f5ddc8bd9325e9
|
|
@ -1,27 +0,0 @@
|
|||||||
#### Python / PiP Requirements ####
|
|
||||||
|
|
||||||
# each group either sorted by alphabet or, if applicable, sorted by hierachy
|
|
||||||
|
|
||||||
|
|
||||||
### Main Runtime Dependencies ###
|
|
||||||
|
|
||||||
# Ansible itself
|
|
||||||
ansible ~= 2.10.0 # pinned to 2.10 because upgrade may bring issues
|
|
||||||
|
|
||||||
|
|
||||||
### Test Frameworks ###
|
|
||||||
|
|
||||||
ansible-lint # simple linter
|
|
||||||
yamllint # linter for YAML files in general
|
|
||||||
|
|
||||||
## molecule ##
|
|
||||||
# role based test framework for Ansible
|
|
||||||
|
|
||||||
molecule
|
|
||||||
|
|
||||||
# enable docker for test environments, requires Docker to be installed on host and usuable without additional permissions
|
|
||||||
molecule-docker
|
|
||||||
|
|
||||||
# allows using Vagrant (VMs) for creating test environments, requires Vagrant and any hypervisor (e.g. VirtualBox) to be installed
|
|
||||||
molecule-vagrant
|
|
||||||
python-vagrant # extra module required as not always installed with vagrant
|
|
@ -1 +0,0 @@
|
|||||||
../credentials
|
|
@ -1,143 +0,0 @@
|
|||||||
- name: Configure hatoria as dns server
|
|
||||||
hosts: hatoria.banananet.work
|
|
||||||
vars:
|
|
||||||
# Source: https://docs.hetzner.com/dns-console/dns/general/authoritative-name-servers
|
|
||||||
hetzner_authoritatives:
|
|
||||||
- ns1.first-ns.de.
|
|
||||||
- robotns2.second-ns.de.
|
|
||||||
- robotns3.second-ns.com.
|
|
||||||
hetzner_authoritatives_ip:
|
|
||||||
# ns1.first-ns.de.
|
|
||||||
- "213.239.242.238"
|
|
||||||
- "2a01:4f8:0:a101::a:1"
|
|
||||||
# robotns2.second-ns.de.
|
|
||||||
- "213.133.105.6"
|
|
||||||
- "2a01:4f8:d0a:2004::2"
|
|
||||||
# robotns3.second-ns.com.
|
|
||||||
- "193.47.99.3"
|
|
||||||
- "2001:67c:192c::add:a3"
|
|
||||||
mailbox_mx:
|
|
||||||
- 10 mxext1.mailbox.org.
|
|
||||||
- 10 mxext2.mailbox.org.
|
|
||||||
- 20 mxext3.mailbox.org.
|
|
||||||
mailbox_spf: >-
|
|
||||||
"v=spf1 include:mailbox.org"
|
|
||||||
mailbox_dkim_keys:
|
|
||||||
- name: MBO0001
|
|
||||||
data: >-
|
|
||||||
"v=DKIM1; k=rsa; "
|
|
||||||
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2K4PavXoNY8eGK2u61"
|
|
||||||
"LIQlOHS8f5sWsCK5b+HMOfo0M+aNHwfqlVdzi/IwmYnuDKuXYuCllrgnxZ4fG4yV"
|
|
||||||
"aux58v9grVsFHdzdjPlAQfp5rkiETYpCMZwgsmdseJ4CoZaosPHLjPumFE/Ua2WA"
|
|
||||||
"QQljnunsM9TONM9L6KxrO9t5IISD1XtJb0bq1lVI/e72k3mnPd/q77qzhTDmwN4T"
|
|
||||||
"SNJZN8sxzUJx9HNSMRRoEIHSDLTIJUK+Up8IeCx0B7CiOzG5w/cHyZ3AM5V8lkqB"
|
|
||||||
"aTDK46AwTkTVGJf59QxUZArG3FEH5vy9HzDmy0tGG+053/x4RqkhqMg5/ClDm+lp"
|
|
||||||
"ZqWwIDAQAB"
|
|
||||||
- name: MBO0002
|
|
||||||
data: >-
|
|
||||||
"v=DKIM1; k=rsa; "
|
|
||||||
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqxEKIg2c48ecfmy/+r"
|
|
||||||
"j35sBOhdfIYGNDCMeHy0b36DX6MNtS7zA/VDR2q5ubtHzraL5uUGas8kb/33wtrW"
|
|
||||||
"FYxierLRXy12qj8ItdYCRugu9tXTByEED05WdBtRzJmrb8YBMfeK0E0K3wwoWfhI"
|
|
||||||
"k/wzKbjMkbqYBOTYLlIcVGQWzOfN7/n3n+VChfu6sGFK3k2qrJNnw22iFy4C8Ks7"
|
|
||||||
"j77+tCpm0PoUwA2hOdLrRw3ldx2E9PH0GVwIMJRgekY6cS7DrbHrj/AeGlwfwwCS"
|
|
||||||
"i9T23mYvc79nVrh2+82ZqmkpZSTD2qq+ukOkyjdRuUPck6e2b+x141Nzd81dIZVf"
|
|
||||||
"OEiwIDAQAB"
|
|
||||||
roles:
|
|
||||||
- role: dns/master
|
|
||||||
domain: banananet.work
|
|
||||||
main_nameserver_domain: "ns1.banananet.work" # required glue entry already configured
|
|
||||||
responsible_mail_name: hostmaster.banananet.work
|
|
||||||
slaves_ip: "{{ hetzner_authoritatives_ip }}"
|
|
||||||
entries:
|
|
||||||
# main NS entry
|
|
||||||
- type: NS
|
|
||||||
data: ns1.banananet.work.
|
|
||||||
# Hetzner NS entries
|
|
||||||
- type: NS
|
|
||||||
data: "{{ hetzner_authoritatives }}"
|
|
||||||
# limit CA
|
|
||||||
- type: CAA
|
|
||||||
data: 0 issue "letsencrypt.org"
|
|
||||||
# Mailbox Mail configuration
|
|
||||||
- domain: bca8c01774fd59c9756c68532174fd5b85762fee # domain verification
|
|
||||||
type: TXT
|
|
||||||
data: 7a99f795a552c812b55c7f809920bf25db96137b
|
|
||||||
- type: MX
|
|
||||||
data: "{{ mailbox_mx }}"
|
|
||||||
- type: TXT
|
|
||||||
data: "{{ mailbox_spf }}"
|
|
||||||
- domain: "{{ mailbox_dkim_keys[0].name }}._domainkey"
|
|
||||||
type: TXT
|
|
||||||
data: "{{ mailbox_dkim_keys[0].data }}"
|
|
||||||
- domain: "{{ mailbox_dkim_keys[1].name }}._domainkey"
|
|
||||||
type: TXT
|
|
||||||
data: "{{ mailbox_dkim_keys[1].data }}"
|
|
||||||
- domain: _dmarc
|
|
||||||
type: TXT
|
|
||||||
data: v=DMARC1;p=none
|
|
||||||
- domain: autoconfig
|
|
||||||
type: CNAME
|
|
||||||
data: mailbox.org.
|
|
||||||
- domain: _autodiscover._tcp
|
|
||||||
type: SRV
|
|
||||||
data: "0 0 443 mailbox.org."
|
|
||||||
- domain: _submission._tcp
|
|
||||||
type: SRV
|
|
||||||
data: "10 10 465 smtp.mailbox.org."
|
|
||||||
- domain: _imaps._tcp
|
|
||||||
type: SRV
|
|
||||||
data: "10 10 993 imap.mailbox.org."
|
|
||||||
- domain: _hkps.tcp
|
|
||||||
type: SRV
|
|
||||||
data: "10 10 443 pgp.mailbox.org."
|
|
||||||
# other entries
|
|
||||||
- domain: _minecraft._tcp.wg
|
|
||||||
type: SRV
|
|
||||||
data: "10 10 10110 mc.wg.{{ domain }}."
|
|
||||||
- role: dns/master
|
|
||||||
domain: forumderschan.de
|
|
||||||
main_nameserver_domain: "ns1.banananet.work"
|
|
||||||
responsible_mail_name: hostmaster.banananet.work
|
|
||||||
slaves_ip: "{{ hetzner_authoritatives_ip }}"
|
|
||||||
entries:
|
|
||||||
# main NS entry
|
|
||||||
- type: NS
|
|
||||||
data: ns1.banananet.work.
|
|
||||||
# Hetzner NS entries
|
|
||||||
- type: NS
|
|
||||||
data: "{{ hetzner_authoritatives }}"
|
|
||||||
# limit CA
|
|
||||||
- type: CAA
|
|
||||||
data: 0 issue "letsencrypt.org"
|
|
||||||
- role: dns/master
|
|
||||||
domain: stadtpiraten-karlsruhe.de
|
|
||||||
main_nameserver_domain: "ns1.banananet.work"
|
|
||||||
responsible_mail_name: hostmaster.banananet.work
|
|
||||||
entries:
|
|
||||||
# main NS entry
|
|
||||||
- type: NS
|
|
||||||
data: ns1.banananet.work.
|
|
||||||
# limit CA
|
|
||||||
- type: CAA
|
|
||||||
data: 0 issue "letsencrypt.org"
|
|
||||||
|
|
||||||
- name: Add public available hosts to dns zones
|
|
||||||
hosts: public_available
|
|
||||||
roles:
|
|
||||||
- role: dns/server_entries
|
|
||||||
domain: "{{ inventory_hostname }}"
|
|
||||||
|
|
||||||
- name: Arbitary entries
|
|
||||||
# all tasks/roles here must be local only
|
|
||||||
hosts: all # select any host as not important
|
|
||||||
run_once: yes # run only once "for first host"
|
|
||||||
gather_facts: no # do not gather facts from host as these may not be used
|
|
||||||
roles:
|
|
||||||
- role: ext_mail/mailjet
|
|
||||||
tags:
|
|
||||||
- mailjet
|
|
||||||
- wg.banananet.work
|
|
||||||
domain: wg.banananet.work
|
|
||||||
verification_name: 5803f0f5
|
|
||||||
verification_data: 5803f0f5f4278d66327350f7a8141b70
|
|
@ -1 +0,0 @@
|
|||||||
*.yml
|
|
@ -1 +0,0 @@
|
|||||||
../filter_plugins
|
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure bwcloud nodes
|
|
||||||
hosts: bwcloud_vserver
|
|
||||||
tasks:
|
|
||||||
- name: Install special packages for bw cloud nodes
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- linux-headers-cloud-amd64
|
|
||||||
state: present
|
|
||||||
- name: Configure cloud-kernel to preserve hostname
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
preserve_hostname: yes
|
|
||||||
dest: "/etc/cloud/cloud.cfg.d/preserve_hostname.cfg"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: u=rw,g=r,o=r
|
|
||||||
|
|
||||||
# If something goes wrong with mouting or /etc/hosts, add this back to cloud.cfg using directory:
|
|
||||||
#mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
|
|
||||||
#manage_etc_hosts: true
|
|
@ -1,42 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure Surface 3 device
|
|
||||||
hosts: dev_surface3
|
|
||||||
tasks:
|
|
||||||
- name: Install packages for hardware
|
|
||||||
apt:
|
|
||||||
state: present
|
|
||||||
name:
|
|
||||||
- intel-media-va-driver-non-free
|
|
||||||
- intel-microcode
|
|
||||||
- firmware-linux
|
|
||||||
- firmware-linux-free
|
|
||||||
- firmware-linux-nonfree
|
|
||||||
- xserver-xorg-video-intel
|
|
||||||
- name: Add apt key for special kernel
|
|
||||||
apt_key:
|
|
||||||
state: present
|
|
||||||
id: 87DEFA4AB94A99A4C8C3112556C464BAAC421453
|
|
||||||
url: https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc
|
|
||||||
- name: Add apt repository for special kernel
|
|
||||||
apt_repository:
|
|
||||||
state: present
|
|
||||||
filename: linux-surface
|
|
||||||
repo: "deb [arch=amd64] https://pkg.surfacelinux.com/debian release main"
|
|
||||||
update_cache: yes
|
|
||||||
- name: Install special kernel
|
|
||||||
apt:
|
|
||||||
state: present
|
|
||||||
name:
|
|
||||||
- libwacom-surface
|
|
||||||
- linux-headers-surface
|
|
||||||
- linux-image-surface
|
|
||||||
- linux-surface-secureboot-mok # Password: surface
|
|
||||||
- name: Disable evbug module debug logging # https://ralph.blog.imixs.com/2013/10/02/evbug-auf-die-blacklist-setzen/
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
blacklist evbug
|
|
||||||
dest: "{{ global_modprode_configuration_directory }}/disable-evbug.conf"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: u=rw,g=r,o=
|
|
@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure Raspberry Pi nodes
|
|
||||||
hosts: os_raspbian
|
|
||||||
tasks:
|
|
||||||
- name: Configure default boot to console shell
|
|
||||||
file:
|
|
||||||
state: link
|
|
||||||
src: "{{ global_systemd_preset_directory }}/multi-user.target"
|
|
||||||
dest: "{{ global_systemd_configuration_directory }}/default.target"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
- name: Remove raspian specific apt source file
|
|
||||||
file:
|
|
||||||
state: absent
|
|
||||||
path: "{{ global_apt_sources_directory }}/raspi.list"
|
|
@ -1 +0,0 @@
|
|||||||
../group_vars
|
|
@ -1 +0,0 @@
|
|||||||
../helpers
|
|
@ -1,386 +0,0 @@
|
|||||||
- name: Configure hatoria.banananet.work
|
|
||||||
hosts: hatoria.banananet.work
|
|
||||||
vars:
|
|
||||||
bnet_cloud_domain: "cloud.banananet.work"
|
|
||||||
bnet_cloud_username: "{{ bnet_cloud_domain | domain_to_username }}"
|
|
||||||
roles:
|
|
||||||
- role: nginx/default_server # Would not be configurable otherwise
|
|
||||||
tags:
|
|
||||||
- default_server
|
|
||||||
# Git Server
|
|
||||||
- role: server/gitea
|
|
||||||
tags:
|
|
||||||
- git.banananet.work
|
|
||||||
domain: git.banananet.work
|
|
||||||
gitea_system_user: git
|
|
||||||
database_user: gitea
|
|
||||||
- role: server/drone.io/server
|
|
||||||
domain: ci.git.banananet.work
|
|
||||||
bind_port: 12824
|
|
||||||
gitea_server_url: https://git.banananet.work
|
|
||||||
gitea_client_id: "{{ drone_ci_gitea_main_oauth2_client_id }}"
|
|
||||||
gitea_client_secret: "{{ drone_ci_gitea_main_oauth2_client_secret }}"
|
|
||||||
- role: server/drone.io/runner
|
|
||||||
drone_server_host: ci.git.banananet.work
|
|
||||||
# Banananet.work
|
|
||||||
- role: server/static
|
|
||||||
tags:
|
|
||||||
- banananet.work
|
|
||||||
domain: banananet.work
|
|
||||||
repo: git@git.banananet.work:banananetwork/main-static.git
|
|
||||||
- role: nginx/forward
|
|
||||||
tags:
|
|
||||||
- banananet.work
|
|
||||||
domain: www.banananet.work
|
|
||||||
dest: banananet.work
|
|
||||||
# SpotMe Server
|
|
||||||
- role: server/spotme
|
|
||||||
tags:
|
|
||||||
- spotme.banananet.work
|
|
||||||
domain: spotme.banananet.work
|
|
||||||
bind_port: 12820
|
|
||||||
# Firefox Sync Server
|
|
||||||
- role: server/firefox-sync
|
|
||||||
tags:
|
|
||||||
- firefox.banananet.work
|
|
||||||
domain: firefox.banananet.work
|
|
||||||
# RSS Server
|
|
||||||
# TODO Manual initialization of database required
|
|
||||||
- role: server/tt-rss
|
|
||||||
tags:
|
|
||||||
- rss.banananet.work
|
|
||||||
domain: rss.banananet.work
|
|
||||||
# Linx Server
|
|
||||||
- role: server/linx
|
|
||||||
tags:
|
|
||||||
- drop.banananet.work
|
|
||||||
domain: drop.banananet.work
|
|
||||||
bind_port: 12840
|
|
||||||
use_hdd_directory: yes
|
|
||||||
site_name: "BananaNetwork Drop Server"
|
|
||||||
# # Admin Panel
|
|
||||||
# - role: server/php
|
|
||||||
# domain: nvak.banananet.work
|
|
||||||
# repo: PHPMYADMIN # TODO
|
|
||||||
# BananaNetwork Keys
|
|
||||||
# - role: server/node
|
|
||||||
# domain: keys.banananet.work
|
|
||||||
# repo: https://git.banananet.work/banananetwork/keys.git
|
|
||||||
# bind_port: 12822
|
|
||||||
# system_user: keys-banananet-work
|
|
||||||
# Nextcloud Server
|
|
||||||
- role: server/nextcloud
|
|
||||||
tags:
|
|
||||||
- cloud.banananet.work
|
|
||||||
domain: "{{ bnet_cloud_domain }}"
|
|
||||||
system_user: "{{ bnet_cloud_username }}"
|
|
||||||
nextcloud_admin_user: "{{ global_username }}"
|
|
||||||
enabled_apps_list:
|
|
||||||
- accessibility
|
|
||||||
- activity
|
|
||||||
- admin_audit
|
|
||||||
- apporder
|
|
||||||
- bruteforcesettings
|
|
||||||
- calendar
|
|
||||||
- checksum
|
|
||||||
- cloud_federation_api
|
|
||||||
- comments
|
|
||||||
- contacts
|
|
||||||
- contactsinteraction
|
|
||||||
- cospend
|
|
||||||
- dav
|
|
||||||
- deck
|
|
||||||
- external
|
|
||||||
- federatedfilesharing
|
|
||||||
- federation
|
|
||||||
- files
|
|
||||||
- files_automatedtagging
|
|
||||||
- files_external
|
|
||||||
- files_markdown
|
|
||||||
- files_pdfviewer
|
|
||||||
- files_rightclick
|
|
||||||
- files_sharing
|
|
||||||
- files_trashbin
|
|
||||||
- files_versions
|
|
||||||
- files_videoplayer
|
|
||||||
- firstrunwizard
|
|
||||||
- logreader
|
|
||||||
- lookup_server_connector
|
|
||||||
- mail
|
|
||||||
- metadata
|
|
||||||
- nextcloud_announcements
|
|
||||||
- notes
|
|
||||||
- notifications
|
|
||||||
- oauth2
|
|
||||||
- ocdownloader
|
|
||||||
- password_policy
|
|
||||||
- phonetrack
|
|
||||||
- photos
|
|
||||||
- polls
|
|
||||||
- privacy
|
|
||||||
- provisioning_api
|
|
||||||
- quota_warning
|
|
||||||
- ransomware_protection
|
|
||||||
- serverinfo
|
|
||||||
- settings
|
|
||||||
- sharebymail
|
|
||||||
- sociallogin
|
|
||||||
- socialsharing_email
|
|
||||||
- support
|
|
||||||
- suspicious_login
|
|
||||||
- systemtags
|
|
||||||
- tasks
|
|
||||||
- text
|
|
||||||
- theming
|
|
||||||
- twofactor_admin
|
|
||||||
- twofactor_backupcodes
|
|
||||||
- twofactor_gateway
|
|
||||||
- twofactor_nextcloud_notification
|
|
||||||
- twofactor_totp
|
|
||||||
- twofactor_u2f
|
|
||||||
- updatenotification
|
|
||||||
- viewer
|
|
||||||
- workflowengine
|
|
||||||
disabled_apps_list:
|
|
||||||
- encryption
|
|
||||||
- files_readmemd
|
|
||||||
- recommendations
|
|
||||||
- spreed
|
|
||||||
- survey_client
|
|
||||||
- user_ldap
|
|
||||||
# Forum der Schande
|
|
||||||
- role: server/php
|
|
||||||
tags:
|
|
||||||
- forumderschan.de
|
|
||||||
domain: forumderschan.de
|
|
||||||
repo: git@git.banananet.work:strichliste/strichliste-php.git
|
|
||||||
root: html
|
|
||||||
installation_includes:
|
|
||||||
- includes
|
|
||||||
- role: nginx/forward
|
|
||||||
tags:
|
|
||||||
- forumderschan.de
|
|
||||||
domain: www.forumderschan.de
|
|
||||||
dest: forumderschan.de
|
|
||||||
# Monitors
|
|
||||||
- role: misc/tg_monitor_cmd
|
|
||||||
tags: tg-monitor-cmd
|
|
||||||
monitor_name: forumderschan.de-NS
|
|
||||||
description: "NS entries of forumderschan.de"
|
|
||||||
command_str: >-
|
|
||||||
/usr/bin/dig
|
|
||||||
@a.nic.de.
|
|
||||||
forumderschan.de. NS
|
|
||||||
| grep --only-matching --perl-regexp '(?<=\s)(\S+\.)+(?=$)'
|
|
||||||
| sort
|
|
||||||
use_shell: yes
|
|
||||||
# WG Nextcloud
|
|
||||||
- role: server/nextcloud
|
|
||||||
tags:
|
|
||||||
- wg.banananet.work
|
|
||||||
domain: wg.banananet.work
|
|
||||||
nextcloud_admin_user: felix
|
|
||||||
enabled_apps_list:
|
|
||||||
- accessibility
|
|
||||||
- activity
|
|
||||||
- apporder
|
|
||||||
- bruteforcesettings
|
|
||||||
- calendar
|
|
||||||
- checksum
|
|
||||||
- cloud_federation_api
|
|
||||||
- comments
|
|
||||||
- contacts
|
|
||||||
- cookbook
|
|
||||||
- cospend
|
|
||||||
- dav
|
|
||||||
- deck
|
|
||||||
- encryption
|
|
||||||
- external
|
|
||||||
- federatedfilesharing
|
|
||||||
- federation
|
|
||||||
- files
|
|
||||||
- files_automatedtagging
|
|
||||||
- files_external
|
|
||||||
- files_pdfviewer
|
|
||||||
- files_rightclick
|
|
||||||
- files_sharing
|
|
||||||
- files_trashbin
|
|
||||||
- files_versions
|
|
||||||
- files_videoplayer
|
|
||||||
- firstrunwizard
|
|
||||||
- logreader
|
|
||||||
- lookup_server_connector
|
|
||||||
- metadata
|
|
||||||
- nextcloud_announcements
|
|
||||||
- notes
|
|
||||||
- notifications
|
|
||||||
- oauth2
|
|
||||||
- ocdownloader
|
|
||||||
- password_policy
|
|
||||||
- photos
|
|
||||||
- polls
|
|
||||||
- privacy
|
|
||||||
- provisioning_api
|
|
||||||
- quota_warning
|
|
||||||
- ransomware_protection
|
|
||||||
- serverinfo
|
|
||||||
- settings
|
|
||||||
- sharebymail
|
|
||||||
- side_menu
|
|
||||||
- sociallogin
|
|
||||||
- socialsharing_email
|
|
||||||
- support
|
|
||||||
- suspicious_login
|
|
||||||
- systemtags
|
|
||||||
- tasks
|
|
||||||
- text
|
|
||||||
- theming
|
|
||||||
- twofactor_admin
|
|
||||||
- twofactor_backupcodes
|
|
||||||
- twofactor_gateway
|
|
||||||
- twofactor_nextcloud_notification
|
|
||||||
- twofactor_totp
|
|
||||||
- twofactor_u2f
|
|
||||||
- updatenotification
|
|
||||||
- viewer
|
|
||||||
- workflowengine
|
|
||||||
disabled_apps_list:
|
|
||||||
- admin_audit
|
|
||||||
- recommendations
|
|
||||||
- spreed
|
|
||||||
- survey_client
|
|
||||||
- user_ldap
|
|
||||||
# WG Minecraft
|
|
||||||
- role: server/minecraft
|
|
||||||
tags:
|
|
||||||
- mc.wg.banananet.work
|
|
||||||
domain: mc.wg.banananet.work
|
|
||||||
minecraft_version: "1.16.4"
|
|
||||||
minecraft_ram: "16G"
|
|
||||||
minecraft_port: 25566
|
|
||||||
config:
|
|
||||||
difficulty: normal
|
|
||||||
motd: ChaosCraft
|
|
||||||
view-distance: 16
|
|
||||||
# # Stadtpiraten
|
|
||||||
# - role: server/typo3
|
|
||||||
# domain: piraten.dev.banananet.work
|
|
||||||
# - role: server/php
|
|
||||||
# domain: forum.piraten.dev.banananet.work
|
|
||||||
# repo: PHPBB # TODO
|
|
||||||
# version: master
|
|
||||||
# # Stadtpiraten (prod)
|
|
||||||
# - role: nginx/forward
|
|
||||||
# domain: www.stadtpiraten-karlsruhe.de
|
|
||||||
# dest: stadtpiraten-karlsruhe.de
|
|
||||||
# SMD/SFC HST 2020
|
|
||||||
- role: nginx/forward
|
|
||||||
tags:
|
|
||||||
- proj-hst
|
|
||||||
- hst21.banananet.work
|
|
||||||
domain: hst20.banananet.work
|
|
||||||
dest: hst21.banananet.work
|
|
||||||
- role: server/nextcloud
|
|
||||||
tags:
|
|
||||||
- proj-hst
|
|
||||||
- hst21.banananet.work
|
|
||||||
domain: hst21.banananet.work
|
|
||||||
system_user: nc-hst21
|
|
||||||
nextcloud_admin_user: felix
|
|
||||||
enabled_apps_list:
|
|
||||||
- accessibility
|
|
||||||
- activity
|
|
||||||
- apporder
|
|
||||||
- bruteforcesettings
|
|
||||||
- calendar
|
|
||||||
- checksum
|
|
||||||
- cloud_federation_api
|
|
||||||
- comments
|
|
||||||
- contacts
|
|
||||||
- contactsinteraction
|
|
||||||
- cospend
|
|
||||||
- dav
|
|
||||||
- deck
|
|
||||||
- encryption
|
|
||||||
- external
|
|
||||||
- federatedfilesharing
|
|
||||||
- federation
|
|
||||||
- files
|
|
||||||
- files_automatedtagging
|
|
||||||
- files_linkeditor
|
|
||||||
- files_mindmap
|
|
||||||
- files_pdfviewer
|
|
||||||
- files_rightclick
|
|
||||||
- files_sharing
|
|
||||||
- files_trashbin
|
|
||||||
- files_versions
|
|
||||||
- files_videoplayer
|
|
||||||
- firstrunwizard
|
|
||||||
- forms
|
|
||||||
- logreader
|
|
||||||
- lookup_server_connector
|
|
||||||
- mail
|
|
||||||
- maps
|
|
||||||
- metadata
|
|
||||||
- nextcloud_announcements
|
|
||||||
- notes
|
|
||||||
- notifications
|
|
||||||
- oauth2
|
|
||||||
- password_policy
|
|
||||||
- photos
|
|
||||||
- polls
|
|
||||||
- privacy
|
|
||||||
- provisioning_api
|
|
||||||
- quota_warning
|
|
||||||
- ransomware_protection
|
|
||||||
- serverinfo
|
|
||||||
- settings
|
|
||||||
- sharebymail
|
|
||||||
- socialsharing_email
|
|
||||||
- spreed
|
|
||||||
- support
|
|
||||||
- suspicious_login
|
|
||||||
- systemtags
|
|
||||||
- tasks
|
|
||||||
- text
|
|
||||||
- theming
|
|
||||||
- twofactor_admin
|
|
||||||
- twofactor_backupcodes
|
|
||||||
- twofactor_gateway
|
|
||||||
- twofactor_totp
|
|
||||||
- twofactor_u2f
|
|
||||||
- updatenotification
|
|
||||||
- viewer
|
|
||||||
- whiteboard
|
|
||||||
- workflowengine
|
|
||||||
disabled_apps_list:
|
|
||||||
- admin_audit
|
|
||||||
- dashboard
|
|
||||||
- files_external
|
|
||||||
- recommendations
|
|
||||||
- sociallogin
|
|
||||||
- survey_client
|
|
||||||
- user_ldap
|
|
||||||
- user_status
|
|
||||||
- weather_status
|
|
||||||
tasks:
|
|
||||||
- name: Configure custom archive Nextcloud directory on hdd for personal usages
|
|
||||||
tags:
|
|
||||||
- cloud.banananet.work
|
|
||||||
- custom_archive_directory
|
|
||||||
vars:
|
|
||||||
archive_directory: "{{ global_hdd_directory }}/{{ bnet_cloud_domain }}~personal-archive"
|
|
||||||
block:
|
|
||||||
- name: Create archive directory
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "{{ archive_directory }}"
|
|
||||||
owner: "{{ bnet_cloud_username }}"
|
|
||||||
group: "{{ bnet_cloud_username }}"
|
|
||||||
mode: "u=rwx,g=rx,o="
|
|
||||||
register: archive_directory_task
|
|
||||||
- name: Show message to user about path on changes
|
|
||||||
debug:
|
|
||||||
msg: >-
|
|
||||||
Changed custom archive directory: Please ensure you (re-)configure this directory properly on your Nextcloud instance: {{ archive_directory | quote }}
|
|
||||||
when: archive_directory_task.changed
|
|
@ -1,10 +0,0 @@
|
|||||||
- name: Configure nvak.banananet.work
|
|
||||||
hosts: nvak.banananet.work
|
|
||||||
roles:
|
|
||||||
- role: nginx/default_server # Would not be configurable otherwise
|
|
||||||
# DSA Seite
|
|
||||||
# - role: server/node
|
|
||||||
# domain: dsa.banananet.work
|
|
||||||
# repo: git@git.banananet.work:dsaGroup/dsaPage.git
|
|
||||||
# bind_port: 12821
|
|
||||||
# system_user: dsaPage
|
|
@ -1,27 +0,0 @@
|
|||||||
- name: Configure rurapenthe
|
|
||||||
hosts: rurapenthe.banananet.work
|
|
||||||
roles:
|
|
||||||
- role: nginx/default_server # Would not be configurable otherwise
|
|
||||||
# - role: dns/slave
|
|
||||||
# domain: banananet.work
|
|
||||||
# masters:
|
|
||||||
# - nvak.banananet.work
|
|
||||||
# - role: dns/slave
|
|
||||||
# domain: forumderschan.de
|
|
||||||
# masters:
|
|
||||||
# - nvak.banananet.work
|
|
||||||
# - role: dns/slave
|
|
||||||
# domain: stadtpiraten-karlsruhe.de
|
|
||||||
# masters:
|
|
||||||
# - nvak.banananet.work
|
|
||||||
# - role: dns/slave
|
|
||||||
# domain: spotme.fun
|
|
||||||
# masters:
|
|
||||||
# - nvak.banananet.work
|
|
||||||
- role: server/node
|
|
||||||
domain: keys.banananet.work
|
|
||||||
repo: https://git.banananet.work/banananetwork/keys.git
|
|
||||||
bind_port: 12822
|
|
||||||
system_user: keys-banananet-work
|
|
||||||
environment_vars:
|
|
||||||
REGISTER_PASS: "{{ global_ip_discover_register_pass }}"
|
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure thinkie ThinkPad Tablet
|
|
||||||
hosts: thinkie.eridon.banananet.work
|
|
||||||
tasks:
|
|
||||||
- name: Increase tty font for readability
|
|
||||||
debconf:
|
|
||||||
name: console-setup
|
|
||||||
question: "{{ item.key }}"
|
|
||||||
value: "{{ item.value }}"
|
|
||||||
vtype: select
|
|
||||||
loop:
|
|
||||||
- key: console-setup/fontsize-fb47
|
|
||||||
value: 16x32 (framebuffer only)
|
|
||||||
- key: console-setup/fontface47
|
|
||||||
value: Terminus
|
|
||||||
- key: console-setup/fontsize
|
|
||||||
value: 16x32
|
|
||||||
- key: console-setup/fontsize-text47
|
|
||||||
value: 16x32 (framebuffer only)
|
|
||||||
loop_control:
|
|
||||||
label: "{{ item.key }}"
|
|
@ -1 +0,0 @@
|
|||||||
../host_vars
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure wgpanel
|
|
||||||
hosts: wgpanel.eridon.banananet.work
|
|
||||||
roles:
|
|
||||||
- role: kiosk/boot
|
|
||||||
system_name: WG Panel
|
|
||||||
plymouth_theme_pack: pack_1
|
|
||||||
plymouth_theme: colorful_sliced
|
|
||||||
- role: kiosk/website
|
|
||||||
kiosk_website: "http://10.11.11.70:8123/wg-dashboard/default"
|
|
||||||
zoom_factor: 1.5
|
|
@ -1 +0,0 @@
|
|||||||
../library
|
|
@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure local repository
|
|
||||||
hosts: 127.0.0.1
|
|
||||||
connection: local
|
|
||||||
gather_facts: no
|
|
||||||
tasks:
|
|
||||||
- name: Create local directory for credentials & keys
|
|
||||||
file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
owner: "{{ global_local_user }}"
|
|
||||||
group: "{{ global_local_user }}"
|
|
||||||
mode: "u=rwx,g=rx,o=rx"
|
|
||||||
state: directory
|
|
||||||
loop:
|
|
||||||
- "{{ global_credentials_directory }}"
|
|
||||||
- "{{ global_public_key_directory }}"
|
|
||||||
- "{{ global_dns_list_directory }}"
|
|
||||||
- "{{ global_ssh_key_directory }}"
|
|
||||||
- "{{ global_ssh_host_key_directory }}"
|
|
||||||
- "{{ global_wireguard_private_directory }}"
|
|
||||||
- "{{ global_wireguard_public_directory }}"
|
|
||||||
- name: Configure shorts table
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
banananet.work bnet
|
|
||||||
forumderschan.de striche
|
|
||||||
stadtpiraten-karlsruhe.de pirat-ka
|
|
||||||
dest: "{{ global_public_key_directory }}/domain_shorts"
|
|
||||||
owner: "{{ global_local_user }}"
|
|
||||||
group: "{{ global_local_user }}"
|
|
||||||
mode: u=rw,g=r,o=r
|
|
||||||
- name: Install required tools
|
|
||||||
become: yes
|
|
||||||
become_user: root
|
|
||||||
become_method: sudo
|
|
||||||
apt:
|
|
||||||
name:
|
|
||||||
- sshpass
|
|
||||||
- wireguard-tools
|
|
||||||
state: present
|
|
@ -1 +0,0 @@
|
|||||||
../public_keys
|
|
@ -1 +0,0 @@
|
|||||||
../roles
|
|
@ -1,22 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Store facts of hosts
|
|
||||||
hosts: all
|
|
||||||
gather_facts: yes
|
|
||||||
tasks:
|
|
||||||
- name: Create directory for facts
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "./facts"
|
|
||||||
owner: "{{ local_user }}"
|
|
||||||
group: "{{ local_user }}"
|
|
||||||
mode: "u=rwx,g=rx,o=rx"
|
|
||||||
delegate_to: localhost
|
|
||||||
- name: Download facts to file
|
|
||||||
copy:
|
|
||||||
content: "{{ ansible_facts | to_nice_yaml(indent=2) }}"
|
|
||||||
dest: "./facts/{{ ansible_fqdn }}.yml"
|
|
||||||
owner: "{{ local_user }}"
|
|
||||||
group: "{{ local_user }}"
|
|
||||||
mode: "u=rw,g=r,o=r"
|
|
||||||
delegate_to: localhost
|
|
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Configure wireguard backbones
|
|
||||||
hosts: wireguard_backbones
|
|
||||||
tags:
|
|
||||||
- wireguard
|
|
||||||
- wireguard_backbones
|
|
||||||
roles:
|
|
||||||
- role: wireguard/backbone
|
|
||||||
|
|
||||||
- name: Configure wireguard clients
|
|
||||||
hosts: wireguard_clients
|
|
||||||
tags:
|
|
||||||
- wireguard
|
|
||||||
- wireguard_clients
|
|
||||||
roles:
|
|
||||||
- role: wireguard/client
|
|
||||||
|
|
||||||
- name: Reload all configurations
|
|
||||||
hosts:
|
|
||||||
- wireguard_backbones
|
|
||||||
- wireguard_clients
|
|
||||||
tags:
|
|
||||||
- wireguard
|
|
||||||
- wireguard_backbones
|
|
||||||
- wireguard_clients
|
|
||||||
roles:
|
|
||||||
- name: misc/handlers
|
|
||||||
tasks:
|
|
||||||
- name: Reload systemd wireguard network always
|
|
||||||
become: no
|
|
||||||
command: /bin/true
|
|
||||||
delegate_to: localhost
|
|
||||||
notify:
|
|
||||||
- restart systemd network
|
|
@ -1,13 +0,0 @@
|
|||||||
# `/public_keys` for Ansible project
|
|
||||||
|
|
||||||
This directory is here to store all facts and public keys generated by Ansible on remotes.
|
|
||||||
In difference to the `/facts` directory,
|
|
||||||
this directory is here to store each fact in a single file
|
|
||||||
so Ansible itself and other scripts can use them more easily.
|
|
||||||
Also, if this directory needs to be restored,
|
|
||||||
the full current Ansible playbook needs to be run
|
|
||||||
|
|
||||||
## Scripts
|
|
||||||
|
|
||||||
This directory contains scripts tracked by the repository to allow easier lookups in the given data by Ansible or other scripts.
|
|
||||||
Each script itself will contain a short description of its usage.
|
|
@ -1,39 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
class DnsRootNoParentError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_dns_parent(domain):
|
|
||||||
s = domain.split('.', 1)
|
|
||||||
if len(s) < 2:
|
|
||||||
raise DnsRootNoParentError()
|
|
||||||
return domain.split('.', 1)[1]
|
|
||||||
|
|
||||||
def find_dns_zone(map_dir, domain):
|
|
||||||
dns_file = Path(map_dir) / domain
|
|
||||||
if dns_file.exists():
|
|
||||||
return domain
|
|
||||||
else:
|
|
||||||
return find_dns_zone(map_dir, get_dns_parent(domain))
|
|
||||||
|
|
||||||
def main():
|
|
||||||
dns_map_dir = Path(sys.argv[0]).parent / "dns"
|
|
||||||
if len(sys.argv) >= 1:
|
|
||||||
domains = sys.argv[1:]
|
|
||||||
else:
|
|
||||||
domains = []
|
|
||||||
for domain in sys.stdin:
|
|
||||||
domains.append(domain.strip())
|
|
||||||
for domain in domains:
|
|
||||||
domain = domain.strip('.')
|
|
||||||
try:
|
|
||||||
print(find_dns_zone(dns_map_dir, domain))
|
|
||||||
except DnsRootNoParentError:
|
|
||||||
print(f'No dns zone found for "{domain}"', file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,26 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
from pathlib import Path
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def gen_sshfp_rr(keys_dir, host, domain):
|
|
||||||
key_dir = Path(keys_dir) / host
|
|
||||||
res = []
|
|
||||||
for key in key_dir.iterdir():
|
|
||||||
if key.name != "dns":
|
|
||||||
res.append(subprocess.check_output(["ssh-keygen", "-r", domain, "-f", str(key)]).decode('utf-8').strip())
|
|
||||||
return '\n'.join(res)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
ssh_hosts_keys = Path(sys.argv[0]).parent / "ssh/hosts"
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--domain', default=None)
|
|
||||||
parser.add_argument('--host', required=True)
|
|
||||||
args = parser.parse_args()
|
|
||||||
args.domain = (args.domain + ".") if args.domain else "@"
|
|
||||||
print(gen_sshfp_rr(ssh_hosts_keys, args.host, args.domain))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,5 +1,15 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
acme_account_mail: "{{ global_admin_mail }}"
|
acme_system_user: "acme"
|
||||||
|
acme_user_directory: "/var/{{ acme_system_user }}"
|
||||||
|
|
||||||
acme_key_size: 4096
|
acme_source_directory: "{{ acme_user_directory }}/repository"
|
||||||
|
acme_source_repository: "https://github.com/Neilpang/acme.sh.git"
|
||||||
|
acme_source_version: "master"
|
||||||
|
|
||||||
|
acme_account_mail: felix.stupp@outlook.com
|
||||||
|
|
||||||
|
acme_installation_directory: "{{ acme_user_directory }}/application"
|
||||||
|
acme_configuration_directory: "{{ acme_user_directory }}/configuration"
|
||||||
|
acme_internal_certificates_directory: "{{ acme_configuration_directory }}/certificates"
|
||||||
|
acme_certificates_directory: "{{ acme_user_directory }}/certificates"
|
||||||
|
@ -1,15 +1,40 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: Install required packages
|
- name: Download acme.sh
|
||||||
apt:
|
become_user: "{{ acme_system_user }}"
|
||||||
state: present
|
git:
|
||||||
name:
|
repo: "{{ acme_source_repository }}"
|
||||||
- certbot # main package
|
version: "{{ acme_source_version }}"
|
||||||
|
dest: "{{ acme_source_directory }}"
|
||||||
- name: Configure certbot
|
update: no
|
||||||
template:
|
|
||||||
src: cli.ini
|
- name: Configure acme.sh
|
||||||
dest: "{{ global_certbot_configuration_file }}"
|
become_user: "{{ acme_system_user }}"
|
||||||
owner: root
|
command: >-
|
||||||
group: root
|
./acme.sh --install
|
||||||
mode: u=rw,g=r,o=r
|
--home {{ acme_installation_directory | quote }}
|
||||||
|
--config-home {{ acme_configuration_directory | quote }}
|
||||||
|
--cert-home {{ acme_internal_certificates_directory | quote }}
|
||||||
|
--accountemail {{ acme_account_mail | quote }}
|
||||||
|
args:
|
||||||
|
chdir: "{{ acme_source_directory }}"
|
||||||
|
creates: "{{ acme_installation_directory }}"
|
||||||
|
|
||||||
|
- name: Upgrade acme.sh
|
||||||
|
become_user: "{{ acme_system_user }}"
|
||||||
|
command:
|
||||||
|
./acme.sh --upgrade
|
||||||
|
--home {{ acme_installation_directory | quote }}
|
||||||
|
--config-home {{ acme_configuration_directory | quote }}
|
||||||
|
args:
|
||||||
|
chdir: "{{ acme_installation_directory }}"
|
||||||
|
register: acme_upgrade_results
|
||||||
|
changed_when: acme_upgrade_results.rc == 0 and "Upgrade success" in acme_upgrade_results.stdout
|
||||||
|
|
||||||
|
- name: Create directory for certificates
|
||||||
|
file:
|
||||||
|
path: "{{ acme_certificates_directory }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ acme_system_user }}"
|
||||||
|
group: "{{ acme_system_user }}"
|
||||||
|
mode: "u=rwx,g=,o="
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# Accept service terms
|
|
||||||
agree-tos
|
|
||||||
|
|
||||||
# Default RSA key size
|
|
||||||
rsa-key-size = {{ acme_key_size }}
|
|
||||||
|
|
||||||
# E-Mail Address for registration
|
|
||||||
email = {{ acme_account_mail }}
|
|
||||||
|
|
||||||
# Use webroot per default
|
|
||||||
authenticator = webroot
|
|
||||||
webroot-path = {{ acme_validation_root_directory }}
|
|
@ -1,25 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
# at least one of domain or domains is required
|
acme_certificate_prefix: "{{ acme_certificates_directory }}/{{ domain }}"
|
||||||
domain: "{{ domains[0] }}"
|
acme_certificate_location: "{{ acme_certificate_prefix }}.crt"
|
||||||
domains:
|
acme_key_location: "{{ acme_certificate_prefix }}.key"
|
||||||
- "{{ effective_domain }}"
|
|
||||||
# effective_domain from all/vars.yml
|
|
||||||
|
|
||||||
acme_must_staple: yes
|
|
||||||
|
|
||||||
certificate_name: "{{ effective_domain }}"
|
|
||||||
|
|
||||||
# acme_validation_root_directory from nginx/application
|
|
||||||
|
|
||||||
acme_certificate_directory: "{{ global_certbot_certificates_directory }}/{{ certificate_name }}"
|
|
||||||
acme_certificate_location: "{{ acme_certificate_directory }}/cert.pem"
|
|
||||||
acme_chain_location: "{{ acme_certificate_directory }}/chain.pem"
|
|
||||||
acme_fullchain_location: "{{ acme_certificate_directory }}/fullchain.pem"
|
|
||||||
acme_key_location: "{{ acme_certificate_directory }}/privkey.pem"
|
|
||||||
acme_keyfullchain_location: "{{ acme_certificate_directory }}/keyfullchain.pem"
|
|
||||||
|
|
||||||
# at maximun one of is used
|
|
||||||
reload_command: "systemctl reload-or-restart {{ global_nginx_service_name | quote }}"
|
|
||||||
reload_commands:
|
|
||||||
- "{{ reload_command }}"
|
|
||||||
|
@ -1,17 +1,35 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: Issue certificate for {{ certificate_name }}
|
- meta: flush_handlers
|
||||||
command:
|
|
||||||
cmd: >-
|
- name: "Issue certificate for {{ domain }}"
|
||||||
certbot certonly
|
become_user: "{{ acme_system_user }}"
|
||||||
--non-interactive
|
command: >-
|
||||||
--cert-name {{ certificate_name | quote }}
|
./acme.sh --issue
|
||||||
{% if acme_must_staple %}--must-staple{% endif %}
|
--home {{ acme_installation_directory | quote }}
|
||||||
--disable-hook-validation
|
--config-home {{ acme_configuration_directory | quote }}
|
||||||
--post-hook {{ ( '(' + (all_reload_commands | join(') && (')) + ')' ) | quote }}
|
--domain "{{ domain | quote }}"
|
||||||
{% for d in domains %}
|
--webroot "{{ nginx_validation_root_directory | quote }}"
|
||||||
--domain {{ d | quote }}
|
--ecc
|
||||||
{% endfor %}
|
--ocsp-must-staple
|
||||||
creates: "{{ acme_certificate_location }}"
|
args:
|
||||||
tags:
|
chdir: "{{ acme_installation_directory }}"
|
||||||
- certificate
|
register: acme_issue_result
|
||||||
|
changed_when: acme_issue_result.rc != 2 or "Domains not changed" not in acme_issue_result.stdout
|
||||||
|
failed_when: acme_issue_result.rc != 0 and "Domains not changed" not in acme_issue_result.stdout
|
||||||
|
|
||||||
|
- name: "Install certificate for {{ domain }}"
|
||||||
|
become_user: "{{ acme_system_user }}"
|
||||||
|
command: >-
|
||||||
|
./acme.sh --install-cert
|
||||||
|
--home {{ acme_installation_directory | quote }}
|
||||||
|
--config-home {{ acme_configuration_directory | quote }}
|
||||||
|
--domain "{{ domain | quote }}"
|
||||||
|
--key-file "{{ acme_key_location | quote }}"
|
||||||
|
--fullchain-file "{{ acme_certificate_location | quote }}"
|
||||||
|
--reloadcmd "systemctl force-reload nginx"
|
||||||
|
args:
|
||||||
|
chdir: "{{ acme_installation_directory }}"
|
||||||
|
creates: "{{ acme_key_location }}"
|
||||||
|
register: acme_install_result
|
||||||
|
failed_when: acme_install_result.rc != 0 and "Reload error for" not in acme_install_result.stderr
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
required_reload_commands:
|
|
||||||
- "cat {{ acme_key_location | quote }} {{ acme_fullchain_location | quote }} > {{ acme_keyfullchain_location | quote }}"
|
|
||||||
all_reload_commands: "{{ required_reload_commands + reload_commands }}"
|
|
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
dest: ""
|
@ -0,0 +1 @@
|
|||||||
|
---
|
@ -1,10 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/sh
|
||||||
|
|
||||||
set -euxo pipefail;
|
set -e;
|
||||||
|
|
||||||
dir="$(dirname "$1")";
|
dir=$(dirname "$1");
|
||||||
date="$(date +%Y-%m-%d-%H-%M)";
|
date=$(date +%Y-%m-%d-%H-%M);
|
||||||
name="$(basename "$1")";
|
name=$(basename "$1");
|
||||||
ext="${name##latest.}";
|
|
||||||
|
|
||||||
mv "$1" "$dir/$date.$ext";
|
mv "$1" "$dir/$date-$name";
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Create custom facts directory
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "{{ global_ansible_facts_directory }}"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "u=rwx,g=rx,o=rx"
|
|
||||||
|
|
||||||
- name: Store custom apt fact
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
#!/bin/sh
|
|
||||||
echo "{\"architecture\": \"$(dpkg --print-architecture)\"}";
|
|
||||||
dest: "{{ global_ansible_facts_directory }}/dpkg.fact"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "u=rwx,g=rx,o=rx"
|
|
||||||
notify: reload facts
|
|
@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Create directory for journald config
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "{{ global_systemd_journal_configuration_directory }}"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: u=rwx,g=rx,o=rx
|
|
||||||
|
|
||||||
- name: Configure journald log
|
|
||||||
template:
|
|
||||||
src: journald.conf
|
|
||||||
dest: "{{ global_systemd_journal_configuration_directory }}/main.conf"
|
|
||||||
notify:
|
|
||||||
- restart systemd-journald
|
|
@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
# protecting process list of users different than root
|
|
||||||
# Source: https://wiki.archlinux.org/index.php/Security#hidepid
|
|
||||||
|
|
||||||
- name: Configure group for reading other processes
|
|
||||||
group:
|
|
||||||
state: present
|
|
||||||
name: proc
|
|
||||||
system: yes
|
|
||||||
|
|
||||||
- name: Configure proc mounting in fstab
|
|
||||||
lineinfile:
|
|
||||||
path: "{{ global_fstab_file }}"
|
|
||||||
regexp: '^\S+\s+/proc\s+proc\s+'
|
|
||||||
line: >-
|
|
||||||
proc /proc proc
|
|
||||||
nosuid,nodev,noexec,hidepid=2,gid=proc
|
|
||||||
0 0
|
|
||||||
|
|
||||||
- name: Ensure configuration directory for whitelisted services exist
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
path: "{{ global_systemd_configuration_directory }}/{{ item }}.d"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: u=rwx,g=rx,o=rx
|
|
||||||
loop: "{{ global_proc_hidepid_service_whitelist }}"
|
|
||||||
|
|
||||||
- name: Configure whitelisted services to adapt to hidepid setting
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
[Service]
|
|
||||||
SupplementaryGroups=proc
|
|
||||||
dest: "{{ global_systemd_configuration_directory }}/{{ item }}.d/proc_hidepid_whitelist.conf"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: u=rw,g=r,o=r
|
|
||||||
loop: "{{ global_proc_hidepid_service_whitelist }}"
|
|
@ -1,51 +0,0 @@
|
|||||||
# This is the ssh client system-wide configuration file. See
|
|
||||||
# ssh_config(5) for more information. This file provides defaults for
|
|
||||||
# users, and the values can be changed in per-user configuration files
|
|
||||||
# or on the command line.
|
|
||||||
|
|
||||||
# Configuration data is parsed as follows:
|
|
||||||
# 1. command line options
|
|
||||||
# 2. user-specific file
|
|
||||||
# 3. system-wide file
|
|
||||||
# Any configuration value is only changed the first time it is set.
|
|
||||||
# Thus, host-specific definitions should be at the beginning of the
|
|
||||||
# configuration file, and defaults at the end.
|
|
||||||
|
|
||||||
# Site-wide defaults for some commonly used options. For a comprehensive
|
|
||||||
# list of available options, their meanings and defaults, please see the
|
|
||||||
# ssh_config(5) man page.
|
|
||||||
|
|
||||||
Host *
|
|
||||||
# ForwardAgent no
|
|
||||||
# ForwardX11 no
|
|
||||||
# ForwardX11Trusted yes
|
|
||||||
# PasswordAuthentication yes
|
|
||||||
# HostbasedAuthentication no
|
|
||||||
# GSSAPIAuthentication no
|
|
||||||
# GSSAPIDelegateCredentials no
|
|
||||||
# GSSAPIKeyExchange no
|
|
||||||
# GSSAPITrustDNS no
|
|
||||||
# BatchMode no
|
|
||||||
# CheckHostIP yes
|
|
||||||
# AddressFamily any
|
|
||||||
# ConnectTimeout 0
|
|
||||||
# StrictHostKeyChecking ask
|
|
||||||
# IdentityFile ~/.ssh/id_rsa
|
|
||||||
# IdentityFile ~/.ssh/id_dsa
|
|
||||||
# IdentityFile ~/.ssh/id_ecdsa
|
|
||||||
# IdentityFile ~/.ssh/id_ed25519
|
|
||||||
# Port 22
|
|
||||||
# Protocol 2
|
|
||||||
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
|
|
||||||
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com
|
|
||||||
# EscapeChar ~
|
|
||||||
# Tunnel no
|
|
||||||
# TunnelDevice any:any
|
|
||||||
# PermitLocalCommand no
|
|
||||||
# VisualHostKey no
|
|
||||||
# ProxyCommand ssh -q -W %h:%p gateway.example.com
|
|
||||||
# RekeyLimit 1G 1h
|
|
||||||
SendEnv LANG LC_*
|
|
||||||
HashKnownHosts yes
|
|
||||||
GSSAPIAuthentication yes
|
|
||||||
VerifyHostKeyDNS yes
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euxo pipefail;
|
|
||||||
|
|
||||||
backupsToKeep={{ backups_to_keep | quote }};
|
|
||||||
|
|
||||||
function onlyDatedFiles() {
|
|
||||||
grep --perl-regexp '/\d+(-\d+)*(\.[^/]+)*$';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDirName() {
|
|
||||||
grep --only-matching --perl-regexp '^.+(?=/[^/]+)';
|
|
||||||
}
|
|
||||||
|
|
||||||
find -H {{ backups_directory | quote }} -type f |
|
|
||||||
onlyDatedFiles |
|
|
||||||
getDirName |
|
|
||||||
sort --unique |
|
|
||||||
while read -r dir; do
|
|
||||||
find "$dir" -type f | onlyDatedFiles | sort --reverse | tail --lines=+$((backupsToKeep + 1)) | xargs rm --force;
|
|
||||||
done
|
|
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e;
|
||||||
|
|
||||||
|
file={{ backups_databases_directory | quote }}"/$1.sql.gpg";
|
||||||
|
|
||||||
|
mysqldump --opt --databases "$1" | buffer -m 128M -s 128K | gpg --quiet --no-verbose --encrypt --recipient 73D09948B2392D688A45DC8393E1BD26F6B02FB7 --trust-model always > "$file";
|
||||||
|
chmod u+r-wx,g+r-wx,o+r-wx "$file";
|
||||||
|
{{ global_helper_directory | quote }}/backup_rename.sh "$file";
|
@ -1,19 +1,17 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/sh
|
||||||
|
|
||||||
set -euxo pipefail;
|
set -e;
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
path="$1";
|
path="$1";
|
||||||
target="$2";
|
name="$2";
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
dir="$(dirname "$path")";
|
dir="$(dirname "$path")";
|
||||||
base="$(basename "$path")";
|
base="$(basename "$path")";
|
||||||
dest="$target/latest.tar.gpg";
|
dest={{ backups_files_directory | quote }}"/$name.tar.gpg";
|
||||||
|
|
||||||
# Execution
|
# Execution
|
||||||
tar --directory="$dir" --create --dereference --file=- "$base" |
|
tar -C "$dir" -cf - "$base" | buffer -m 128M -s 128K | gpg --quiet --no-verbose --encrypt --recipient 73D09948B2392D688A45DC8393E1BD26F6B02FB7 --trust-model always > "$dest";
|
||||||
pv --quiet --buffer-size 256M |
|
|
||||||
gpg --quiet --no-verbose --compress-level 0 --encrypt --recipient {{ backup_gpg_fingerprint | quote }} --trust-model always > "$dest";
|
|
||||||
chmod u+r-wx,g+r-wx,o+r-wx "$dest";
|
chmod u+r-wx,g+r-wx,o+r-wx "$dest";
|
||||||
{{ global_helper_directory | quote }}/backup_rename.sh "$dest";
|
{{ global_helper_directory | quote }}/backup_rename.sh "$dest";
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euxo pipefail;
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
db="$1";
|
|
||||||
|
|
||||||
# Variables
|
|
||||||
file={{ backups_mysql_database_directory | quote }}"/$db/latest.sql.gpg";
|
|
||||||
|
|
||||||
# Execution
|
|
||||||
mysqldump --opt "$db" |
|
|
||||||
pv --quiet --buffer-size 256M |
|
|
||||||
gpg --quiet --no-verbose --encrypt --recipient {{ backup_gpg_fingerprint | quote }} --trust-model always > "$file";
|
|
||||||
chmod u+r-wx,g+r-wx,o+r-wx "$file";
|
|
||||||
{{ global_helper_directory | quote }}/backup_rename.sh "$file";
|
|
@ -1,3 +0,0 @@
|
|||||||
[Journal]
|
|
||||||
Storage=persistent
|
|
||||||
SystemMaxUse={{ global_systemd_journal_max_storage }}
|
|
@ -1,23 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -euxo pipefail;
|
|
||||||
|
|
||||||
if [[ -z "${1+x}" ]]; then
|
|
||||||
echo "Usage: $(basename "$0") HOST [PATH]" >&2
|
|
||||||
exit 2;
|
|
||||||
fi
|
|
||||||
|
|
||||||
key_path="${2:-1}";
|
|
||||||
if [[ "$key_path" = /* ]]; then
|
|
||||||
target="$key_path";
|
|
||||||
else
|
|
||||||
target="$PWD/$key_path";
|
|
||||||
fi
|
|
||||||
|
|
||||||
tmpdir="$(mktemp --directory)";
|
|
||||||
cd "$tmpdir";
|
|
||||||
name="$(dnssec-keygen -a {{ global_dns_update_key_algorithm }} -n HOST -T KEY "$1")";
|
|
||||||
for suffix in "key" "private"; do
|
|
||||||
mv "$tmpdir/$name.$suffix" "$target.$suffix";
|
|
||||||
done
|
|
||||||
rm -rf "$tmpdir";
|
|
@ -1,17 +1,11 @@
|
|||||||
# Main Repository
|
# Main Repository
|
||||||
deb {{ debian_repository_mirror }} {{ ansible_distribution_release }} main non-free contrib
|
deb {{ debian_repository_mirror }} {{ ansible_distribution_release }} main non-free contrib
|
||||||
{% if debian_repository_use_sources %}
|
|
||||||
deb-src {{ debian_repository_mirror }} {{ ansible_distribution_release }} main non-free contrib
|
deb-src {{ debian_repository_mirror }} {{ ansible_distribution_release }} main non-free contrib
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Security Repository
|
# Security Repository
|
||||||
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main non-free contrib
|
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main non-free contrib
|
||||||
{% if debian_repository_use_sources %}
|
|
||||||
deb-src http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main non-free contrib
|
deb-src http://security.debian.org/debian-security {{ ansible_distribution_release }}/updates main non-free contrib
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Updates Repository
|
# Updates Repository
|
||||||
deb {{ debian_repository_mirror }} {{ ansible_distribution_release }}-updates main non-free contrib
|
deb {{ debian_repository_mirror }} {{ ansible_distribution_release }}-updates main non-free contrib
|
||||||
{% if debian_repository_use_sources %}
|
|
||||||
deb-src {{ debian_repository_mirror }} {{ ansible_distribution_release }}-updates main non-free contrib
|
deb-src {{ debian_repository_mirror }} {{ ansible_distribution_release }}-updates main non-free contrib
|
||||||
{% endif %}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue