add ansible

This commit is contained in:
Graham McIntire 2025-05-30 13:24:38 -05:00
parent f93b508fd9
commit 4c205165ac
No known key found for this signature in database
78 changed files with 5577 additions and 0 deletions

BIN
ansible/.DS_Store vendored Normal file

Binary file not shown.

2
ansible/.ansible-lint Normal file
View file

@ -0,0 +1,2 @@
skip_list:
- '403'

3
ansible/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
site.retry
fact_cache

3
ansible/.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
}

4
ansible/LICENSE.md Executable file
View file

@ -0,0 +1,4 @@
Copyright (C) 2013 AnsibleWorks, Inc.
This work is licensed under the Creative Commons Attribution 3.0 Unported License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/deed.en_US.

63
ansible/Makefile Normal file
View file

@ -0,0 +1,63 @@
ANSIBLE_CMD = ansible-playbook
build-local:
docker build -t docker.nsnw.ca/ansible:local .
build-latest:
docker build -t docker.nsnw.ca/ansible:latest .
run-local:
docker run --rm -it -e ANSIBLE_SETUP_OPTIONS -e SSH_PRIVATE_KEY -e ANSIBLE_OPTIONS -e SKIP_SETUP -e SKIP_PLAYBOOK -v ${PWD}/run/fact_cache:/app/fact_cache docker.nsnw.ca/ansible:local
run-local-shell:
docker run --rm -it -e ANSIBLE_SETUP_OPTIONS -e SSH_PRIVATE_KEY -e ANSIBLE_OPTIONS -e SKIP_SETUP -e SKIP_PLAYBOOK docker.nsnw.ca/ansible:local /bin/bash
run-latest:
docker run --rm -it -e ANSIBLE_SETUP_OPTIONS -e SSH_PRIVATE_KEY -e ANSIBLE_OPTIONS -e SKIP_SETUP -e SKIP_PLAYBOOK docker.nsnw.ca/ansible:latest
push-latest:
docker push docker.nsnw.ca/ansible:latest
clean:
rm -rfv tmp
dirs:
mkdir -pv tmp/fact_cache
chmod a+rxw tmp/fact_cache
base-latest: build-base-latest push-base-latest
base-local: build-base-local
latest: build-latest push-latest
local: dirs build-local run-local
facts:
ansible -m setup all
bootstrap-network:
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_host=$(ANSIBLE_HOST) -t network --skip-tags network_restart general.yml
bootstrap-reboot:
ssh -i ~/.ssh/ansible ansible@$(ANSIBLE_HOST) -t "sudo reboot" || true
bootstrap-init:
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_user=graham -e ansible_host=$(ANSIBLE_HOST) -k -K bootstrap.yml
bootstrap: bootstrap-init bootstrap-network bootstrap-reboot
run-all:
$(ANSIBLE_CMD) -l $(HOSTNAME) -e ansible_host=$(ANSIBLE_HOST) general.yml
install-ssh-key:
ssh-copy-id $(ANSIBLE_HOST)
setup-user: install-ssh-key
./setup-user.sh install $(ANSIBLE_HOST)
reboot:
ssh -i ~/.ssh/ansible ansible@$(ANSIBLE_HOST) -t "sudo reboot"
qc-web:
$(ANSIBLE_CMD) -l qc_web -t caddy general.yml

1
ansible/README.md Executable file
View file

@ -0,0 +1 @@
Ansible things

File diff suppressed because one or more lines are too long

31
ansible/ansible.cfg Normal file
View file

@ -0,0 +1,31 @@
[defaults]
forks = 20
# display_skipped_hosts=False
# deprecation_warnings=False
retry_files_enabled = False
#callback_whitelist = profile_tasks
#stdout_callback = yaml
#bin_ansible_callbacks = True
nocows = True
host_key_checking = False
inventory = hosts
fact_caching=jsonfile
fact_caching_connection=fact_cache
fact_caching_timeout=0
no_log = false
[inventory]
cache_plugin=jsonfile
[ssh_connection]
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it, -C controls compression use
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -i ~/.ssh/ansible
pipelining = true
ansible_user = ansible

View file

@ -0,0 +1,23 @@
---
- name: Clone cloud-init template
community.general.proxmox_kvm:
node: opti-hst-01 # Changed from value: proxmox
vmid: 9000 # This happened to be the same value as my cloudinit VM
clone: gemini # Left this as is, later discovering the value doesn't matter since a vmid is specified above..
name: cloud-1
api_user: root@pam # Changed from value: ansible@pam
api_token_id: "{{ proxmox_token_id }}" # Changed from value: ansible_pve_token
api_token_secret: "{{ proxmox_token_secret }}" # Changed from value: 1daf3b05-5f94-4f10-b924-888ba30b038b
api_host: 192.168.0.100 # Changed from value: your.proxmox.host
storage: ceph-pool-01 # Changed from value: ZFS01
timeout: 90
- name: Start VM
community.general.proxmox_kvm:
node: opti-hst-01 # Changed from value: proxmox
name: cloud-1
api_user: root@pam # Changed from value: ansible@pam
api_token_id: "{{ proxmox_token_id}}" # Changed from value: ansible_pve_token
api_token_secret: "{{ proxmox_token_secret }}" # Changed from value: 1daf3b05-5f94-4f10-b924-888ba30b038b
api_host: 192.168.0.100 # Changed from value: your.proxmox.host
state: started

View file

@ -0,0 +1,27 @@
---
- name: Initial setup for proxmox servers
hosts: proxmox
user: root
become: true
tasks:
- name: Update apt and install required system packages
apt:
pkg:
- aptitude
- curl
- nano
- vim
- git
- ufw
- lsof
- python3-proxmoxer
- python3-requests
state: latest
update_cache: true
# - name: Basic security hardening
# import_tasks: security.yml
# - name: Deploy VMs
# import_tasks: machines.yml

View file

6
ansible/bootstrap-hosts Normal file
View file

@ -0,0 +1,6 @@
[all:vars]
ansible_user=ansible
ansible_python_interpreter=/usr/bin/python3
[bootstrap]
lab01.w5isp.com ansible_host=10.0.16.231

1
ansible/bootstrap.sh Executable file
View file

@ -0,0 +1 @@
ansible-playbook -v -i bootstrap-hosts bootstrap.yml

10
ansible/bootstrap.yml Normal file
View file

@ -0,0 +1,10 @@
---
- name: Bootstrap new host
hosts: all
tags: bootstrap
roles:
- bootstrap
become: yes
# become_method: "{{ 'su' if (ansible_distribution | default('')) == 'Debian' else 'sudo' }}"
# become_method: "sudo"
become_method: "su"

View file

@ -0,0 +1,5 @@
---
collections:
- ansible.posix
- netbox.netbox
# - devsec.hardening

14
ansible/env.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
if [[ -z ${SSH_PRIVATE_KEY} ]]; then
echo "! No SSH private key found."
exit 1
fi
echo "> Writing out SSH private key..."
echo ${SSH_PRIVATE_KEY} | base64 -d >id_ed25519
chmod 400 id_ed25519
echo "> Running: $*"
$*

60
ansible/general.yml Normal file
View file

@ -0,0 +1,60 @@
---
- name: Base setup
hosts: all
become: yes
become_method: sudo
roles:
- general
vars_files:
- vars/base.yml
tags:
- base
- name: SNMP clients
hosts: snmp_clients
become: yes
become_method: sudo
roles:
- snmp_clients
tags:
- snmp
- name: k3s
hosts: k3s_servers
become: yes
become_method: sudo
tags: k3s
roles:
- k3s_servers
- name: Docker servers
hosts: docker
become: yes
become_method: sudo
tags: docker
roles:
- docker
vars:
gpg_fingerprint: "9DC858229FC7DD38854AE2D88D81803C0EBFCD88"
- name: Netboot servers
hosts: netboot
become: yes
become_method: sudo
vars_files:
- vars/base.yml
- vars/netboot.yml
- vars/network.yml
vars:
netboot_arch_dist: "{{ netboot.dist | product(netboot.arch) }}"
tags:
- netboot
roles:
- netboot_servers
- hosts: syslog
become: yes
become_method: sudo
tags: syslog
roles:
- syslog_servers

View file

23
ansible/handlers/main.yml Normal file
View file

@ -0,0 +1,23 @@
- name: Restart ntp
ansible.builtin.service:
name: ntp
state: restarted
become: true
- name: Restart ssh
ansible.builtin.service:
name: ssh
state: restarted
become: true
- name: Restart unbound
ansible.builtin.service:
name: unbound
state: restarted
become: true
- name: Restart firewalld
ansible.builtin.service:
name: firewalld
state: restarted
become: true

34
ansible/hosts Executable file
View file

@ -0,0 +1,34 @@
[vntx]
#logs.vntx.net
#unimus.vntx.net
monitor.vntx.net
radius.vntx.net
vpn.vntx.net
librenms.vntx.net
netbox.vntx.net
ns1.vntx.net
ns2.vntx.net
#ntp.vntx.net
[common]
#aprs.me
dallas.aprs2.net ansible_host=204.110.191.232
apps.w5isp.com
[home]
skippy.w5isp.com
g.w5isp.com ansible_user=ansible
#[proxmox]
#lab01 ansible_host=10.0.16.231 #ansible_user=root
#lab02 ansible_host=10.0.16.232 #ansible_user=root
#lab03 ansible_host=10.0.16.233 #ansible_user=root
[tailscale_home]
lab01.w5isp.com ansible_host=10.0.16.231 #ansible_user=root
lab02.w5isp.com ansible_host=10.0.16.232 #ansible_user=root
lab03.w5isp.com ansible_host=10.0.16.233 #ansible_user=root
g.w5isp.com
[caddy]
g.w5isp.com ansible_user=ansible

4
ansible/notes.txt Normal file
View file

@ -0,0 +1,4 @@
bootstrap
ansible-playbook -l ns1.vntx.net -e ansible_user=graham -e ansible_host=ns1.vntx.net -k -K bootstrap.yml

126
ansible/playbook.yml Executable file
View file

@ -0,0 +1,126 @@
---
- name: Apply common configuration to all nodes
hosts: all
become: true
# become_method: sudo
gather_facts: true
remote_user: ansible
roles:
- common
vars_files:
- vars/common.yml
tags:
- common
tasks:
- name: Set timezone
community.general.timezone:
name: America/Chicago
- name: Install Graham SSH keys
ansible.posix.authorized_key:
user: graham
state: present
key: https://github.com/gmcintire.keys
- name: Install Andys SSH keys
ansible.posix.authorized_key:
user: andy
state: present
key: https://github.com/nsnw.keys
- name: Apply resolver config
hosts: resolvers
gather_facts: true
roles:
- { role: resolvers, become: true }
- name: Apply ns config
hosts: ns
gather_facts: true
become: true
roles:
- role: ns
- name: Apply netbox config
hosts: netbox
gather_facts: true
become: true
roles:
- role: caddy_ansible.caddy_ansible
caddy_systemd_network_dependency: true
caddy_setcap: true
caddy_systemd_capabilities_enabled: true
caddy_systemd_capabilities: "CAP_NET_BIND_SERVICE"
caddy_config: |
netbox.vntx.net {
bind tcp4/0.0.0.0
log {
level error
}
route /static* {
uri strip_prefix /static
root * /opt/netbox/netbox/static
file_server
}
@notStatic not path /static*
encode gzip zstd
reverse_proxy @notStatic http://localhost:8001 {
header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote.host}
header_up X-Forwarded-For {http.request.remote.host}
header_up X-Forwarded-Port {http.request.port}
header_up X-Forwarded-Proto {http.request.scheme}
}
}
- name: Apply firewall rules to netbox
hosts: netbox
become: true
# remote_user: graham
tasks:
- name: Permit traffic in default zone for http service
ansible.posix.firewalld:
zone: public
service: http
permanent: true
state: enabled
- name: Permit traffic in default zone for https service
ansible.posix.firewalld:
zone: public
service: https
permanent: true
state: enabled
notify:
- Restart firewalld
- name: Tailscale
hosts: tailscale_home
roles:
- role: artis3n.tailscale
vars:
# Pull Tailscale auth key from environment variable
tailscale_authkey: "{{ lookup('ansible.builtin.env', 'TAILSCALE_KEY') }}"
tailscale_args: "--ssh --advertise-exit-node"
pre_tasks:
- name: Debug - Check Tailscale key (will be partially redacted)
debug:
msg: "Key exists and starts with: {{ lookup('ansible.builtin.env', 'TAILSCALE_KEY')[0:10] }}..."
- name: Install and configure Caddy
hosts: caddy
become: true
roles:
- caddy
# - import_playbook: baseline/proxmox/main.yml
# - name: Tailscale Home
# hosts: tailscale_home
# roles:
# - role: artis3n.tailscale
# vars:
# # Example pulling the API key from the env vars on the host running Ansible
# tailscale_authkey: "{{ lookup('env', 'TAILSCALE_KEY') }}"
# tailscale_args: "--ssh --advertise-exit-node --advertise-routes=10.0.16.0/22"

BIN
ansible/roles/.DS_Store vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,12 @@
---
- name: Restart unbound
ansible.builtin.service:
name: unbound
state: restarted
become: true
- name: Restart firewalld
ansible.builtin.service:
name: firewalld
state: restarted
become: true

View file

@ -0,0 +1,54 @@
---
- name: "Enable passwordless sudo on AlmaLinux"
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
regexp: "^%wheel"
line: "%wheel ALL=(ALL) NOPASSWD: ALL"
validate: "visudo -cf %s"
- name: Install EPEL repo
ansible.builtin.yum:
name: epel-release
state: present
- name: Upgrade all packages
ansible.builtin.dnf:
name: "*"
state: latest
- name: Install required software
ansible.builtin.dnf:
state: present
name:
- bind-utils
- lsof
- htop
- btop
- mosh
- rsync
- tmux
- nano
- the_silver_searcher
- net-tools
- mlocate
- fail2ban
- munin-node
- nethogs
- pv
- selinux-policy
- tar
- unzip
- qemu-guest-agent
- python3-libselinux
- name: Create a user for andys
ansible.builtin.user:
name: andy
groups:
- wheel
state: present
# - name: Put SELinux in permissive mode, logging actions that would be blocked.
# ansible.posix.selinux:
# policy: targeted
# state: permissive

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb Ansible SSH Key

View file

@ -0,0 +1,44 @@
- name: Install sudo
apt:
name: sudo
when: ansible_distribution == "Debian"
- name: Ensure the 'ansible' group exists
group:
name: ansible
gid: 10001
state: present
- name: Ensure the 'ansible' user exists
user:
name: ansible
comment: Ansible User
uid: 10001
group: ansible
- name: Ensure the 'graham' user exists
user:
name: graham
comment: Graham
- name: Ensure the 'andy' user exists
user:
name: andy
comment: Andy
- name: Ensure that 'authorized_keys' is set correctly for the 'ansible' user
authorized_key:
user: ansible
state: present
key: "{{ lookup('file', 'files/ansible.pub') }}"
- name: Ensure sudo is configured for the 'ansible' user
template:
src: templates/etc/sudoers.d/ansible
dest: /etc/sudoers.d/ansible
owner: root
group: root
mode: '0440'
tags:
- sudoers

View file

@ -0,0 +1,11 @@
- name: Dump host information
debug:
msg:
- "Host : {{ inventory_hostname }}"
# - "Distro : {{ ansible_lsb.id }}"
# - "Release: {{ ansible_lsb.codename }}"
- "IPv4 : {{ ansible_all_ipv4_addresses }}"
- "IPv6 : {{ ansible_all_ipv6_addresses }}"
- name: Ansible setup
import_tasks: ansible.yml

View file

@ -0,0 +1 @@
{{ inventory_hostname }}

View file

@ -0,0 +1,6 @@
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.1.1 {{ inventory_hostname }} {{ inventory_hostname | split('.') | first }}

View file

@ -0,0 +1 @@
ansible ALL=NOPASSWD: ALL

View file

@ -0,0 +1,8 @@
---
# Default Caddy configuration
caddy_config_dir: /etc/caddy
caddy_data_dir: /var/lib/caddy
caddy_user: caddy
caddy_group: caddy
caddy_default_site_port: 80
caddy_default_site_root: /var/www/html

View file

@ -0,0 +1,6 @@
---
- name: restart caddy
service:
name: caddy
state: restarted

View file

@ -0,0 +1,43 @@
---
- name: Install required packages
apt:
name:
- debian-keyring
- debian-archive-keyring
- apt-transport-https
- curl
- gnupg2
state: present
update_cache: yes
- name: Add Caddy GPG key
apt_key:
url: "https://dl.cloudsmith.io/public/caddy/stable/gpg.key"
state: present
- name: Add Caddy repository
apt_repository:
repo: "deb https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main"
state: present
filename: caddy-stable
- name: Install Caddy
apt:
name: caddy
state: present
update_cache: yes
- name: Ensure Caddy service is enabled and started
service:
name: caddy
state: started
enabled: yes
- name: Configure Caddy
template:
src: Caddyfile.j2
dest: /etc/caddy/Caddyfile
owner: root
group: root
mode: '0644'
notify: restart caddy

View file

@ -0,0 +1,21 @@
{
# Global options
admin off
persist_config off
}
:{{ caddy_default_site_port }} {
root * {{ caddy_default_site_root }}
file_server
encode gzip
# Basic logging
log {
output file /var/log/caddy/access.log
format json
}
}
truck.w5isp.com {
reverse_proxy http://100.105.74.2
}

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb Ansible SSH Key

View file

@ -0,0 +1,14 @@
---
# Handler to handle common notifications. Handlers are called by other plays.
# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
- name: Restart ntp
ansible.builtin.service:
name: ntp
state: restarted
become: true
# - name: Restart ssh
# ansible.builtin.service:
# name: ssh
# state: restarted
# become: true

View file

@ -0,0 +1,39 @@
---
- name: "Enable passwordless sudo"
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
regexp: "^%sudo"
line: "%sudo ALL=(ALL) NOPASSWD: ALL"
validate: "visudo -cf %s"
- name: "Apply AlmaLinux specific config"
when: ansible_distribution == 'AlmaLinux'
ansible.builtin.import_role:
name: almalinux
- name: "Apply Debian specific config"
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
ansible.builtin.import_role:
name: debian
- name: Install sshd banner
ansible.builtin.template:
src: issue.net.j2
dest: /etc/issue.net
mode: "644"
- name: Setup sshd banner
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
line: "Banner /etc/issue.net"
state: present
notify: Restart ssh
- name: Disallow root SSH access
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
state: present
# notify: Restart ssh

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,25 @@
8b d8
`8b d8'
`8b d8'
`8b d8' ,adPPYba, 8b,dPPYba, ,adPPYba, 8b,dPPYba, ,adPPYYba,
`8b d8' a8P_____88 88P' "Y8 a8" "8a 88P' `"8a "" `Y8
`8b d8' 8PP""""""" 88 8b d8 88 88 ,adPPPPP88
`888' "8b, ,aa 88 "8a, ,a8" 88 88 88, ,88
`8' `"Ybbd8"' 88 `"YbbdP"' 88 88 `"8bbdP"Y8
888b 88 88
8888b 88 ,d 88
88 `8b 88 88 88
88 `8b 88 ,adPPYba, MM88MMM 8b db d8 ,adPPYba, 8b,dPPYba, 88 ,d8 ,adPPYba,
88 `8b 88 a8P_____88 88 `8b d88b d8' a8" "8a 88P' "Y8 88 ,a8" I8[ ""
88 `8b 88 8PP""""""" 88 `8b d8'`8b d8' 8b d8 88 8888[ `"Y8ba,
88 `8888 "8b, ,aa 88, `8bd8' `8bd8' "8a, ,a8" 88 88`"Yba, aa ]8I
88 `888 `"Ybbd8"' "Y888 YP YP `"YbbdP"' 88 88 `Y8a `"YbbdP"'
###############################################################
# Welcome to Verona Networks #
# All connections are monitored and recorded #
# Disconnect IMMEDIATELY if you are not an authorized user! #
###############################################################

View file

@ -0,0 +1,49 @@
{% if ansible_fqdn in groups['ntp'] %}
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# GPS Serial data reference
#server 127.127.28.0 minpoll 4 maxpoll 4
#fudge 127.127.28.0 time1 0.0 refid GPS
# GPS PPS reference
server 127.127.28.1 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.1 refid PPS
pool us.pool.ntp.org iburst
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1
# Needed for adding pool entries
restrict source notrap nomodify noquery
{% else %}
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1
server {{ ntpserver }}
# Needed for adding pool entries
restrict source notrap nomodify noquery
{% endif %}

View file

@ -0,0 +1,15 @@
- name: "Install updates"
ansible.builtin.apt:
name: "*"
state: latest
update_cache: true
cache_valid_time: 3600
force_apt_get: true
autoremove: true
autoclean: true
- name: "Secure shared memory"
ansible.builtin.lineinfile:
path: /etc/fstab
state: present
line: "tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0"

View file

@ -0,0 +1,12 @@
- name: create /tmp/ansible-debug
file:
path: /tmp/ansible-debug
state: directory
- name: collect vars
template:
src: templates/data.j2
dest: "/tmp/ansible-debug/{{ item.key }}.json"
vars:
data: "{{ item.value }}"
loop: "{{ {'hostvars': hostvars, 'groups': groups, 'vars': vars} | dict2items }}"

View file

@ -0,0 +1 @@
{{ data | to_nice_json }}

BIN
ansible/roles/general/.DS_Store vendored Normal file

Binary file not shown.

BIN
ansible/roles/general/files/.DS_Store vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,94 @@
# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging
module(load="imklog") # provides kernel logging support
#module(load="immark") # provides --MARK-- message capability
# provides UDP syslog reception
#module(load="imudp")
#input(type="imudp" port="514")
# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
#
# Set the default permissions for all log files.
#
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
#
# Some "catch-all" log files.
#
*.=debug;\
auth,authpriv.none;\
news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron,daemon.none;\
mail,news.none -/var/log/messages
#
# Emergencies are sent to everybody logged in.
#
*.emerg :omusrmsg:*
*.* @@syslog.vm.qc.nsnw.ca

View file

@ -0,0 +1,61 @@
# /etc/rsyslog.conf configuration file for rsyslog
#
# For more information install rsyslog-doc and see
# /usr/share/doc/rsyslog-doc/html/configuration/index.html
#
# Default logging rules can be found in /etc/rsyslog.d/50-default.conf
#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging
#module(load="immark") # provides --MARK-- message capability
# provides UDP syslog reception
#module(load="imudp")
#input(type="imudp" port="514")
# provides TCP syslog reception
#module(load="imtcp")
#input(type="imtcp" port="514")
# provides kernel logging support and enable non-kernel klog messages
module(load="imklog" permitnonkernelfacility="on")
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# Filter duplicated messages
$RepeatedMsgReduction on
#
# Set the default permissions for all log files.
#
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
*.* @@syslog.vm.qc.nsnw.ca

View file

@ -0,0 +1,7 @@
# Log kernel generated UFW log messages to file
:msg,contains,"[UFW " /var/log/ufw.log
# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
#& stop

View file

@ -0,0 +1,48 @@
# Default rules for rsyslog.
#
# For more information see rsyslog.conf(5) and /etc/rsyslog.conf
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
#daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
#lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
#mail.info -/var/log/mail.info
#mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
#
# Some "catch-all" log files.
#
#*.=debug;\
# auth,authpriv.none;\
# news.none;mail.none -/var/log/debug
#*.=info;*.=notice;*.=warn;\
# auth,authpriv.none;\
# cron,daemon.none;\
# mail,news.none -/var/log/messages
#
# Emergencies are sent to everybody logged in.
#
*.emerg :omusrmsg:*
#
# I like to have messages displayed on the console, but only on a virtual
# console I usually leave idle.
#
#daemon,mail.*;\
# news.=crit;news.=err;news.=notice;\
# *.=debug;*.=info;\
# *.=notice;*.=warn /dev/tty8

View file

@ -0,0 +1 @@
%linux-admins ALL=NOPASSWD: ALL

View file

@ -0,0 +1,235 @@
#!/bin/bash
set -e
# Define some colours
BOLD=""
FBLK=""
FRED=""
FGRN=""
FYLW=""
FBLU=""
FPPL=""
FCYN=""
FWHT=""
F_ORANGE=""
F_ORANGE2=""
F_PURPLE=""
F_TEAL=""
F_SEA=""
F_YELLOW=""
F_GREEN=""
F_GREEN2=""
F_RED=""
F_CYAN=""
F_DARKBLUE=""
F_DARKPURPLE=""
F_PURPLE=""
F_DARKGREY=""
F_MIDGREY=""
F_MIDGREY2=""
F_BLUE=""
F_LIGHTBLUE=""
F_GOLD=""
F_LIGHTCYAN=""
F_LIGHTYELLOW=""
B_DARKBLUE=""
F_BRIGHTYELLOW=""
F_DARKGREY=""
F_BRIGHTGREEN=""
F_BRIGHTORANGE=""
F_MIDGREEN=""
F_PINK=""
F_BRIGHTPINK=""
F_VIOLET=""
F_DARKRED=""
F_STEEL=""
CLR=""
BRED=""
BGRN=""
#ARROW="►"
ARROW=">"
PRIMARY_COLOUR="${F_BRIGHTYELLOW}"
COLON="${F_DARKGREY}:${CLR}"
NA="${F_DARKGREY}N/A${CLR}"
section() {
TITLE="$1"
TEXT="$2"
#ARROW_COLOUR="${F_LIGHTYELLOW}"
ARROW_COLOUR=""
TITLE_COLOUR="${F_LIGHTCYAN}"
echo " ${ARROW_COLOUR}${ARROW}${CLR} ${TITLE_COLOUR}${TITLE}${CLR}|${TEXT}"
}
subsection() {
TEXT="$1"
echo " ${F_DARKGREY}>${CLR}|${TEXT}"
}
format() {
COLOUR="$1"
TEXT="$2"
echo "${COLOUR}${TEXT}${CLR}"
}
in_brackets() {
TEXT="$1"
echo "${F_DARKGREY}(${CLR}${TEXT}${F_DARKGREY})${CLR}"
}
prefix() {
COLOUR="$1"
PREFIX="$2"
TEXT="$3"
echo "${COLOUR}${PREFIX}${COLON} ${TEXT}"
}
show_hostname() {
HOSTNAME="$(format ${F_BRIGHTYELLOW} $(hostname -f))"
section "Host" "${HOSTNAME}"
}
show_os() {
OS_DESCRIPTION=$(lsb_release -s -d)
COLOUR_1=${F_BRIGHTORANGE}
COLOUR_2=${F_ORANGE2}
COLOUR_3=${F_ORANGE}
DESCRIPTION=$(format ${COLOUR_1} "${OS_DESCRIPTION}")
RELEASE=$(format ${COLOUR_2} "$(lsb_release -s -r)")
CODENAME=$(format ${COLOUR_2} "$(lsb_release -s -c)")
KERNEL=$(format ${COLOUR_2} "$(uname -r)")
ARCH=$(format ${COLOUR_2} "$(uname -m)")
OS_RELEASE=$(prefix ${COLOUR_3} Release "${RELEASE}")
OS_CODENAME=$(in_brackets ${CODENAME})
OS_KERNEL=$(prefix ${COLOUR_3} "Kernel " "${KERNEL}")
OS_ARCH=$(in_brackets ${ARCH})
section "OS" "${DESCRIPTION}"
subsection "${OS_RELEASE} ${OS_CODENAME}"
subsection "${OS_KERNEL} ${OS_ARCH}"
}
show_net() {
INET_DEFAULT=$(ip ro show default | grep -Po "dev \w+" | head -n1 | awk '{ print $2 }')
INET6_DEFAULT=$(ip -6 ro show default | grep -Po "dev \w+" | head -n1 | awk '{ print $2 }')
MAC_ADDR=$(ip addr show dev ${INET_DEFAULT} | grep "link/ether" | awk '{ print $2 }')
INET_ADDR=$(ip addr show dev ${INET_DEFAULT} | grep "inet " | grep "scope global" | awk '{ print $2 }' | head -n1)
INET6_ADDR=$(ip addr show dev ${INET6_DEFAULT} | grep "inet6 " | grep "scope global" | awk '{ print $2 }' | head -n1)
if [[ -z ${INET6_ADDR} ]]; then
INET6_ADDR=${NA}
fi
PRIMARY_IFACE="$(format ${F_LIGHTBLUE} ${INET_DEFAULT})"
PRIMARY_IP4="$(format ${F_LIGHTBLUE} ${INET_ADDR})"
PRIMARY_IP6="$(format ${F_LIGHTBLUE} ${INET6_ADDR})"
PRIMARY_MAC="$(format ${F_LIGHTBLUE} ${MAC_ADDR})"
PRIMARY="$(prefix ${F_STEEL} NIC ${PRIMARY_IFACE})"
MAC="$(in_brackets ${PRIMARY_MAC})"
section "Net" "${PRIMARY} ${MAC}"
subsection "$(prefix ${F_STEEL} IP4 ${PRIMARY_IP4})"
subsection "$(prefix ${F_STEEL} IP6 ${PRIMARY_IP6})"
}
show_hardware() {
if [[ "$(lsb_release -i)" =~ "Raspbian" ]]; then
SYSINFO="$(pinout | egrep -o '(Pi Model [0-9][A-Z]\+?\s? V[0-9]\.[0-9])')"
SYSTEM=$(format ${F_VIOLET} "${SYSINFO}")
else
MANUFACTURER=$(dmidecode -s system-manufacturer)
PRODUCT_NAME=$(dmidecode -s system-product-name)
SYSINFO=$(format ${F_VIOLET} "${MANUFACTURER}")
if [[ -z ${MANUFACTURER} ]]; then
SYSTEM=${NA}
else
if [[ ! -z ${PRODUCT_NAME} ]]; then
PRODUCT=$(format ${F_VIOLET} "${PRODUCT_NAME}")
PRODUCT_DISPLAY=$(in_brackets "${PRODUCT}")
SYSINFO="${SYSINFO} ${PRODUCT_DISPLAY}"
fi
SYSTEM=$(format ${F_VIOLET} "${SYSINFO}")
fi
fi
MEM_B=$(cat /proc/meminfo | grep MemTotal | awk '{ print $2 }')
let MEM_MB="${MEM_B}/1024"
MEMORY=$(format ${F_VIOLET} "${MEM_MB}M")
PROCESSOR=$(format ${F_VIOLET} "$(cat /proc/cpuinfo | grep 'model name' | head -n1 | awk -F': ' '{ print $2 }')")
CPUS=$(in_brackets $(format ${F_VIOLET} x$(cat /proc/cpuinfo | grep processor | wc -l)))
DISKS=$(lsblk | grep disk | awk '{ print $1"|"$4 }')
STORAGE=""
for DISK in ${DISKS}; do
DEVICE=$(format ${F_VIOLET} $(echo ${DISK} | cut -f1 -d"|"))
SIZE=$(in_brackets $(format ${F_VIOLET} $(echo ${DISK} | cut -f2 -d"|")))
STORAGE="${STORAGE}${DEVICE} ${SIZE} "
done
if [[ -z ${STORAGE} ]]; then
STORAGE=${NA}
fi
SYS=$(prefix ${F_BRIGHTPINK} Sys "${SYSTEM}")
CPU=$(prefix ${F_BRIGHTPINK} CPU "${PROCESSOR} ${CPUS}")
MEM=$(prefix ${F_BRIGHTPINK} Mem "${MEMORY}")
DSK=$(prefix ${F_BRIGHTPINK} Disk "${STORAGE}")
section "H/w" "${SYS}"
subsection "${CPU}"
subsection "${MEM} ${DSK}"
}
show_uptime() {
COLOUR_1=${F_BRIGHTGREEN}
COLOUR_2=${F_GREEN2}
COLOUR_3=${F_GREEN}
AGO=$(format ${COLOUR_1} "$(uptime -p | cut -c4-)")
BOOT=$(format ${COLOUR_2} "$(uptime -s)")
BUILT=$(format ${COLOUR_2} "$(stat / | grep "Birth" | sed 's/Birth: //g' | cut -b 2-20)")
BOOT_DATE=$(prefix ${COLOUR_3} Booted "${BOOT}")
BUILT_DATE=$(prefix ${COLOUR_3} "Built " "${BUILT}")
section "Up" "${AGO}"
subsection "${BOOT_DATE}"
subsection "${BUILT_DATE}"
}
sections() {
show_hostname
show_os
show_uptime
show_net
show_hardware
}
cat <<EOF
  northstar networks*  https://nsnw.ca/ 
 support@nsnw.ca · +1 403 808 9371 
--System----------------------------------------------------------------------
$(sections | column -t -s "|")
EOF

BIN
ansible/roles/general/tasks/.DS_Store vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,126 @@
- name: Install icinga2
apt:
pkg:
- icinga2
- monitoring-plugins
- nagios-plugins-contrib
update_cache: yes
state: latest
cache_valid_time: 3600
when: monitoring.icinga2 | default(True) == True
register: icinga2_install
tags:
- icinga2_install
- name: Uninstall icinga2
apt:
pkg:
- icinga2
- monitoring-plugins
- nagios-plugins-contrib
state: absent
when: monitoring.icinga2 | default(True) == False
register: icinga2_uninstall
tags:
- icinga2_install
- name: ensure certificate directory exists
file:
path: "{{ base.monitoring.cert_dir }}"
state: directory
owner: 'nagios'
group: 'nagios'
mode: '0700'
when: monitoring.icinga2 | default(True) == True
tags:
- icinga2_cert_dir
- name: install icinga2 CA certificate
copy:
src: var/lib/icinga2/certs/ca.crt
dest: "{{ base.monitoring.cert_dir }}/ca.crt"
owner: 'nagios'
group: 'nagios'
when: monitoring.icinga2 | default(True) == True
- name: check for trusted master certificate
stat:
path: "{{ base.monitoring.cert_dir }}/trusted-master.crt }}"
register: trusted_master_cert
when: monitoring.icinga2 | default(True) == True
- name: check trusted master certificate hash
shell:
cmd: "openssl x509 -in {{ base.monitoring.cert_dir }}/trusted-master.crt -noout -hash"
register: trusted_master_cert_hash
when: monitoring.icinga2 | default(True) == True and trusted_master_cert.stat.exists
- name: delete old certificates
file:
path: "{{ item }}"
state: absent
when: (monitoring.icinga2 | default(True) == True) and trusted_master_cert.stat.exists and trusted_master_cert_hash.stdout != trusted_master_hash
loop:
- "{{ base.monitoring.cert_dir }}/trusted-master.crt"
- "{{ base.monitoring.cert_dir }}/{{ inventory_hostname }}.crt"
- "{{ base.monitoring.cert_dir }}/{{ inventory_hostname }}.key"
- name: get trusted master certificate
shell:
cmd: "icinga2 pki save-cert --trustedcert {{ base.monitoring.cert_dir }}/trusted-master.crt --host {{ base.monitoring.server }}"
when: (monitoring.icinga2 | default(True) == True) and (not trusted_master_cert.stat.exists or trusted_master_cert_hash.stdout != trusted_master_hash)
- name: check for client certificate
stat:
path: "/var/lib/icinga2/certs/{{ inventory_hostname }}.crt"
register: client_certificate
when: monitoring.icinga2 | default(True) == True
- name: icinga2 setup
shell:
cmd: "icinga2 node setup --zone {{ inventory_hostname }} --endpoint {{ base.monitoring.server }} --parent_host {{ base.monitoring.server }} --parent_zone master --cn {{ inventory_hostname }} --accept-config --accept-commands --disable-confd --trustedcert {{ base.monitoring.cert_dir }}/trusted-master.crt"
when: (monitoring.icinga2 | default(True) == True) and not client_certificate.stat.exists
register: setup
- name: zones.conf
template:
src: templates/etc/icinga2/zones.conf.j2
dest: /etc/icinga2/zones.conf
owner: nagios
group: nagios
mode: "0644"
register: zones_config
when: monitoring.icinga2 | default(True) == True
- name: icinga2.conf
template:
src: templates/etc/icinga2/icinga2.conf.j2
dest: /etc/icinga2/icinga2.conf
owner: nagios
group: nagios
mode: "0644"
register: icinga2_config
when: monitoring.icinga2 | default(True) == True
- name: checks.conf
template:
src: templates/etc/icinga2/conf.d/checks.conf.j2
dest: /etc/icinga2/conf.d/checks.conf
owner: nagios
group: nagios
mode: "0644"
register: checks_config
when: monitoring.icinga2 | default(True) == True
- name: check if certificate has been signed
shell:
cmd: "openssl x509 -in {{ base.monitoring.cert_dir }}/{{ inventory_hostname }}.crt -noout -issuer_hash -hash | uniq -d | wc -l"
register: signed
when: monitoring.icinga2 | default(True) == True
- name: restart icinga2
service:
name: icinga2
state: reloaded
enabled: yes
when: monitoring.icinga2 | default(True) == True

View file

@ -0,0 +1,33 @@
- name: Install k3s.sh setup script
copy:
src: roles/k3s_servers/files/k3s.sh
dest: /usr/local/bin/k3s.sh
owner: root
group: root
mode: '00755'
tags:
- k3s_setup
- name: Install required packages
apt:
pkg:
- netscript-ipfilter
tags:
- k3s_packages
- name: Check for node token
file:
path: /var/lib/rancher/k3s/server/node-token
register: token
ignore_errors: true
tags:
- k3s_token
- name: Run k3s installer
shell:
cmd: /usr/local/bin/k3s.sh
environment:
INSTALL_K3S_EXEC: "server --flannel-backend={{ k3s.flannel_backend }} --cluster-cidr={{ k3s.cluster_cidr }} --service-cidr={{ k3s.service_cidr }}"
when: token.state == "absent"
tags:
- k3s_install

View file

@ -0,0 +1,4 @@
---
- name: install apt-transport-https
apt:
name: apt-transport-https

View file

@ -0,0 +1,15 @@
- name: Configure MOTD banner update script
copy:
src: files/20-banner
dest: /etc/update-motd.d/20-banner
owner: root
group: root
mode: 0755
- name: Configure MOTD tail
template:
src: templates/etc/motd.j2
dest: /etc/motd
owner: root
group: root
mode: 0644

View file

@ -0,0 +1,132 @@
#- name: "Create base network configuration"
# copy:
# src: files/etc/network/interfaces
# dest: /etc/network/interfaces
# owner: root
# group: root
# mode: 00644
# tags:
# - network_interfaces
- name: "Create systemd interface files"
template:
src: templates/etc/systemd/network/link.j2
dest: "/etc/systemd/network/10-{{ interface.name }}-nic.link"
owner: root
group: root
mode: 00644
loop: "{{ interfaces }}"
loop_control:
loop_var: interface
vars:
interfaces: "{{ network.interfaces | default([]) | selectattr('bridge', 'undefined') }}"
register: network_systemd_interface
tags:
- network_systemd_interface
when: network.skip | default(False) != True
- name: "Build split network configuration (interfaces)"
template:
src: templates/etc/network/interfaces.d/interface.j2
dest: "/etc/network/interfaces.d/{{ interface.name }}"
owner: root
group: root
mode: 00644
loop: "{{ interfaces }}"
loop_control:
loop_var: interface
vars:
interfaces: "{{ network.interfaces | default([]) }}"
interface_network: "{{ interface.network | default(False) }}"
register: network_interfaces_split
when: network.skip | default(False) != True and network.single_file | default(False) == False
tags:
- network_interfaces
- name: "Build split network configuration (main)"
template:
src: templates/etc/network/interfaces.j2
dest: "/etc/network/interfaces"
owner: root
group: root
mode: 00644
vars:
interfaces: "{{ [] }}"
register: network_interfaces_split_main
when: network.skip | default(False) != True and network.single_file | default(False) == False
tags:
- network_interfaces
- name: "Build combined network configuration"
template:
src: templates/etc/network/interfaces.j2
dest: "/etc/network/interfaces"
owner: root
group: root
mode: 00644
vars:
interfaces: "{{ network.interfaces | default([]) }}"
register: network_interfaces_single
when: network.skip | default(False) != True and network.single_file | default(False) == True
tags:
- network_interfaces
- name: "Remove split network configuration files"
file:
path: "/etc/network/interfaces.d/{{ interface.name }}"
state: absent
loop: "{{ interfaces }}"
loop_control:
loop_var: interface
vars:
interfaces: "{{ network.interfaces | default([]) }}"
interface_network: "{{ interface.network | default(False) }}"
register: network_interfaces_split_removed
when: network.skip | default(False) != True and network.single_file | default(False) == True
tags:
- network_interfaces
- name: "Set hostname (/etc/hosts)"
template:
src: templates/etc/hosts.j2
dest: "/etc/hosts"
owner: root
group: root
mode: 00644
tags:
- network_hostname
- name: "Set hostname (/etc/hostname)"
template:
src: templates/etc/hostname.j2
dest: "/etc/hostname"
owner: root
group: root
mode: 00644
tags:
- network_hostname
- name: "Restart networking"
systemd_service:
name: networking
daemon_reload: true
state: restarted
when: network.skip | default(False) != True and (network_systemd_interface.changed or network_interfaces_split.changed or network_interfaces_split_main.changed or network_interfaces_single.changed or network_interfaces_split_removed.changed)
tags:
- network_restart
- name: "Configure /etc/resolv.conf"
template:
src: templates/etc/resolv.conf.j2
dest: /etc/resolv.conf
owner: root
group: root
mode: 00644
vars:
first_network_name: "{{ (network.interfaces | selectattr('network', 'defined') | first).network }}"
first_network: "{{ networks | selectattr('name', 'eq', first_network_name) | first }}"
domain: "{{ network.domain | default(first_network.zone) }}"
search_domains: "{{ [domain] + (first_network.search_domains | default([])) }}"
nameservers: "{{ network.nameservers | default(first_network.nameservers) }}"
tags:
- network_resolv_conf

View file

@ -0,0 +1,61 @@
- name: Install rsyslog
apt:
name: rsyslog
register: syslog_install
tags:
- syslog_install
- name: Add rsyslog.conf (Debian)
template:
src: templates/etc/rsyslog.conf.debian.j2
dest: /etc/rsyslog.conf
owner: root
group: root
mode: 0644
vars:
server: "{{ syslog.server | default(base.syslog.server) }}"
when: ansible_facts['os_family']|lower == 'debian'
register: syslog_config
tags:
- syslog_config
# - name: Add rsyslog.conf (Ubuntu)
# tags: rsyslog
# when: ansible_facts['os_family']|lower == 'ubuntu'
# template:
# src: templates/etc/rsyslog.conf.ubuntu
# dest: /etc/rsyslog.conf
# owner: root
# group: root
# mode: 0644
#
# - name: Add rsyslog.d/20-ufw.conf (Ubuntu)
# tags: rsyslog
# when: ansible_facts['os_family']|lower == 'ubuntu'
# copy:
# backup: yes
# src: files/etc/rsyslog.d/20-ufw.conf.ubuntu
# dest: /etc/rsyslog.d/20-ufw.ubuntu
# owner: root
# group: root
# mode: 0644
#
# - name: Add rsyslog.d/50-default.conf (Ubuntu)
# tags: rsyslog
# when: ansible_facts['os_family']|lower == 'ubuntu'
# copy:
# backup: yes
# src: files/etc/rsyslog.d/50-default.conf.ubuntu
# dest: /etc/rsyslog.d/50-default.ubuntu
# owner: root
# group: root
# mode: 0644
- name: reload rsyslog
systemd:
name: rsyslog
state: restarted
enabled: yes
when: syslog_install.changed or syslog_config.changed
tags:
- syslog_reload

View file

@ -0,0 +1,11 @@
# Main
deb http://{{ deb_mirror }}/debian/ {{ ansible_distribution_release }} main
deb-src http://{{ deb_mirror }}/debian/ {{ ansible_distribution_release }} main
# Security
deb http://security.debian.org/debian-security {{ ansible_distribution_release }}-security main
deb-src http://security.debian.org/debian-security {{ ansible_distribution_release }}-security main
# Updates
deb http://{{ deb_mirror }}/debian/ {{ ansible_distribution_release }}-updates main
deb-src http://{{ deb_mirror }}/debian/ {{ ansible_distribution_release }}-updates main

View file

@ -0,0 +1 @@
{{ inventory_hostname | split(".") | first }}

View file

@ -0,0 +1,11 @@
127.0.0.1 localhost
{% if network.loopback_in_hosts | default(True) %}
127.0.1.1 {{ inventory_hostname }} {{ inventory_hostname | split(".") | first }}
{% else %}
{{ "%-15s" | format(ansible_default_ipv4.address) }} {{ inventory_hostname }} {{ inventory_hostname | split(".") | first }}
{% endif %}
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

View file

@ -0,0 +1,3 @@
--MOTD------------------------------------------------------------------------
> Last Ansible run: {{ template_run_date.strftime("%Y-%m-%d %H:%M:%S") }}

View file

@ -0,0 +1,16 @@
driftfile /var/lib/ntp/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server {{ base.ntp.server }}
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
restrict 127.0.0.1
restrict ::1
restrict source notrap nomodify noquery

View file

@ -0,0 +1,89 @@
# Host: {{ inventory_hostname }}
# Built from templates/etc/ssh/sshd_config.j2
# ------------------------------------------------------------------------------
Include /etc/ssh/sshd_config.d/*.conf
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
PermitRootLogin {{ sshd.permit_root_login }}
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
#HostbasedAuthentication no
#IgnoreUserKnownHosts no
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
KbdInteractiveAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
UsePAM yes
AllowAgentForwarding {{ sshd.forwarding.agent }}
AllowTcpForwarding {{ sshd.forwarding.tcp }}
GatewayPorts {{ sshd.forwarding.gateway }}
X11Forwarding {{ sshd.forwarding.x11 }}
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# SFTP
Subsystem sftp /usr/lib/openssh/sftp-server

View file

@ -0,0 +1 @@
ansible ALL=NOPASSWD: ALL

View file

@ -0,0 +1,15 @@
---
# Handler for the webtier: handlers are called by other plays.
# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
- name: Restart bind
ansible.builtin.service:
name: bind
state: restarted
become: true
- name: Restart firewalld
ansible.builtin.service:
name: firewalld
state: restarted
become: true

2093
ansible/roles/ns/tasks/main.yml Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
- src: graylog2.graylog
- src: caddy_ansible.caddy_ansible
- src: m4rcu5nl.zerotier-one
- src: bertvv.bind

View file

@ -0,0 +1,15 @@
---
# Handler for the webtier: handlers are called by other plays.
# See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
- name: Restart unbound
ansible.builtin.service:
name: unbound
state: restarted
become: true
- name: Restart firewalld
ansible.builtin.service:
name: firewalld
state: restarted
become: true

View file

@ -0,0 +1,44 @@
---
- name: Install unbound
ansible.builtin.dnf:
name:
- unbound
- certbot
state: present
- name: Enable service Unbound and ensure it is not masked
ansible.builtin.systemd:
name: unbound
enabled: true
masked: false
- name: Create Unbound config
ansible.builtin.template:
src: unbound.conf.j2
dest: /etc/unbound/unbound.conf
mode: "644"
notify:
- Restart unbound
- name: Permit traffic in default zone for dns service
ansible.posix.firewalld:
zone: public
service: dns
permanent: true
state: enabled
- name: Permit traffic in default zone for http service
ansible.posix.firewalld:
zone: public
service: http
permanent: true
state: enabled
- name: Permit traffic in default zone for https service
ansible.posix.firewalld:
zone: public
service: https
permanent: true
state: enabled
notify:
- Restart firewalld

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
---
- name: Restart unbound
ansible.builtin.service:
name: unbound
state: restarted
become: true
- name: Restart firewalld
ansible.builtin.service:
name: firewalld
state: restarted
become: true

View file

@ -0,0 +1,70 @@
---
- name: "Enable passwordless sudo on Ubuntu"
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
regexp: "^%sudo"
line: "%sudo ALL=(ALL) NOPASSWD: ALL"
validate: "visudo -cf %s"
- name: "Install updates on Ubuntu"
ansible.builtin.apt:
name: "*"
state: latest
update_cache: true
cache_valid_time: 0
force_apt_get: true
autoremove: true
autoclean: true
- name: Install required software
ansible.builtin.apt:
autoremove: true
autoclean: true
state: present
name:
- lsof
- htop
- mosh
- rsync
- tmux
- unattended-upgrades
- silversearcher-ag
- net-tools
- locate
- fail2ban
- munin-node
- nethogs
- pv
- fzf
- qemu-guest-agent
- name: Remove ubuntu advantage
ansible.builtin.apt:
autoremove: true
autoclean: true
state: absent
name:
- ubuntu-advantage-tools
- name: Create a user for andys
ansible.builtin.user:
name: andy
groups:
- sudo
state: present
# - name: Allow SSH in ufw
# community.general.ufw:
# rule: limit
# port: ssh
# proto: tcp
# - name: Allow localhost in ufw
# community.general.ufw:
# rule: allow
# from_ip: 172.27.0.0/16
# - name: Allow everything and enable UFW
# community.general.ufw:
# state: enabled
# policy: allow

19
ansible/run.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
if [[ -z ${ANSIBLE_SETUP_OPTIONS} ]]; then
ANSIBLE_SETUP_OPTIONS="all"
fi
if [[ -z ${SKIP_SETUP} ]]; then
echo "> Running setup (with ${ANSIBLE_SETUP_OPTIONS})..."
ansible -m setup -o all 2>&1 | awk -F'=' '{ print $1 }'
fi
if [[ -z ${SKIP_PLAYBOOK} ]]; then
if [[ -z ${ANSIBLE_OPTIONS} ]]; then
ANSIBLE_OPTIONS="playbook.yml"
fi
echo "> Running playbook (with ${ANSIBLE_OPTIONS})..."
ansible-playbook ${ANSIBLE_OPTIONS} | tee ansible-playbook.log
fi

50
ansible/setup-host.sh Executable file
View file

@ -0,0 +1,50 @@
#!/bin/bash
create_ansible_group() {
groupadd -g 10000 ansible
}
create_ansible_user() {
useradd -g 10000 -u 10000 -c "Ansible User" -m ansible
}
add_ansible_user_to_sudoers() {
echo -e "ansible\tALL=NOPASSWD: ALL" >/etc/sudoers.d/ansible
}
add_ansible_ssh_key() {
mkdir -v ~ansible/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb Ansible SSH Key" >~ansible/.ssh/authorized_keys
chown -vR ansible:ansible ~ansible/.ssh
chmod 700 ~ansible/.ssh
chmod 600 ~ansible/.ssh/authorized_keys
}
copy_setup_to_host() {
local HOST=$1
scp $0 ${HOST}:/tmp
}
install() {
local HOST=$1
if [[ -z ${HOST} ]]; then
echo "No host given."
exit 1
fi
copy_setup_to_host ${HOST}
ssh -t ${HOST} "sudo /tmp/$0 setup"
}
setup() {
create_ansible_group
create_ansible_user
add_ansible_user_to_sudoers
add_ansible_ssh_key
}
CMD=$1
shift
eval $CMD $*

46
ansible/vars/base.yml Normal file
View file

@ -0,0 +1,46 @@
base:
packages:
- git
- fzf
- zsh
- jq
- sysstat
- smartmontools
- lm-sensors
- debconf-utils
- ntp
- ntpdate
- samba
- samba-common
- sssd
- krb5-user
- zsh
- wget
- vim
- htop
- mosh
- tmux
ntp:
server: 0.us.pool.ntp.org
# ad:
# realm: OPS.NSNW.CA
# admin_server: DC1.OPS.NSNW.CA
# kdc: DC1.OPS.NSNW.CA
# user: domainjoin
# pass: hqFTIjgEjcQ1XRN6
# ntp:
# server: dc1.ops.nsnw.ca
# monitoring:
# icinga2_key_id: "D1EE8AC60D1C44CA6B8FEDF417D5C53472D73F56"
# server: monitor.srv.ab.nsnw.ca
# cert_dir: "/var/lib/icinga2/certs"
# ca_hash: 2e63b2bb
# trusted_master_hash: 7100b6a2
# syslog:
# server: log.srv.ab.nsnw.ca
# preseed:
# dir: /data/build/preseed
# pxeboot:
# dir: /data/build/pxeboot