initial commit

This commit is contained in:
Peter 2024-10-16 21:13:17 +02:00
commit 6f50de798b
24 changed files with 1082 additions and 0 deletions

View file

@ -0,0 +1,8 @@
- name: Restart firewall
ansible.builtin.command: /etc/network/if-pre-up.d/firewall
changed_when: true
- name: Restart sshd
ansible.builtin.systemd:
name: ssh
state: restarted

View file

@ -0,0 +1,16 @@
- name: Directory for firewall parts
ansible.builtin.file:
group: root
owner: root
name: /etc/firewall.d/
mode: "0700"
state: directory
- name: Firewall template
ansible.builtin.template:
dest: /etc/network/if-pre-up.d/firewall
group: root
owner: root
mode: "0755"
src: firewall.j2
notify: Restart firewall

View file

@ -0,0 +1,11 @@
- name: Manage apt packages
ansible.builtin.import_tasks: packages.yml
- name: Manage global firewall
ansible.builtin.import_tasks: firewall.yml
- name: Manage root user
ansible.builtin.import_tasks: rootuser.yml
- name: Ensure handlers have ran
ansible.builtin.meta: flush_handlers

View file

@ -0,0 +1,47 @@
- name: Keep apt repository list uptodate
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
# Even if we "changed it", it's merely a cache, so ignore
changed_when: false
- name: Update system packages to lates
ansible.builtin.apt:
upgrade: dist
- name: Remove unused packages
ansible.builtin.apt:
autoremove: true
# The following is a list of utilities that I personally use
# to make my life easier. It is opiniated and not needed...
- name: Install utilities to make life easier
ansible.builtin.apt:
pkg:
- apt-dater
- mosh
- mc
- vim
- curl
- jq
- host
- telnet
- screen
- tmux
- tcpdump
- sqlite3
- bash-completion
- mtr-tiny
- iotop
- iftop
- htop
- ncdu
- name: Firewall for mosh
ansible.builtin.template:
dest: /etc/firewall.d/mosh
group: root
owner: root
mode: "0755"
src: mosh.j2
notify: Restart firewall

View file

@ -0,0 +1,27 @@
- name: Set root password
ansible.builtin.user:
name: root
password: "{{ root_password }}"
- name: Ensure ssh directory for root
ansible.builtin.file:
state: directory
path: /root/.ssh
owner: root
group: root
mode: "0700"
- name: Set authorized keys for root
ansible.builtin.copy:
content: "{{ root_sshkeys | join('\n') }}"
dest: /root/.ssh/authorized_keys
owner: root
group: root
mode: "0600"
- name: Only allow root ssh
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
line: "PermitRootLogin prohibit-password"
regexp: "^PermitRootLogin "
notify: Restart sshd

View file

@ -0,0 +1,78 @@
#!/bin/bash
# {{ ansible_managed }}
# IPv4:
iptables -F
iptables -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t nat -F
iptables -t nat -X
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m limit --limit 1/s --limit-burst 2 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A INPUT -p icmp -j ACCEPT
{% for range in firewall_ssh_ranges %}
{%if range.type=="ipv4" %}
iptables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
{%endif%}
{%endfor%}
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state INVALID -j DROP
# IPv6:
ip6tables -F
ip6tables -X
ip6tables -t mangle -F
ip6tables -t mangle -X
ip6tables -t nat -F
ip6tables -t nat -X
ip6tables -P INPUT ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -m state --state INVALID -j DROP
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A INPUT -m limit --limit 1/s --limit-burst 2 -p icmpv6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
ip6tables -A INPUT -p icmpv6 -j ACCEPT
{% for range in firewall_ssh_ranges %}
{%if range.type=="ipv6" %}
ip6tables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
{%endif%}
{%endfor%}
ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ip6tables -A OUTPUT -m state --state INVALID -j DROP
# Disable all forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
echo 0 > /proc/sys/net/ipv6/conf/all/forwarding
# Customisation:
{# we use run-parts as it guarantees order and ignores backups etc. We use --list as it would otherwise run them concurently, causing iptables to exit with EAGAIN as changing the firewall is not possible by 2 prococesses #}
for i in $(run-parts --list /etc/firewall.d/)
do
$i
done
# Finish off with a block
iptables -A INPUT -j REJECT
ip6tables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT
ip6tables -A FORWARD -j REJECT
# {{ansible_managed}}

View file

@ -0,0 +1,6 @@
#!/bin/sh
# {{ansible_managed}}
# Firewall to allow mosh sessions
ip6tables -A INPUT -p udp --match multiport --dports 60001:60020 -j ACCEPT
iptables -A INPUT -p udp --match multiport --dports 60001:60020 -j ACCEPT

View file

@ -0,0 +1,3 @@
- name: Restart firewall
ansible.builtin.command: /etc/network/if-pre-up.d/firewall
changed_when: true

View file

@ -0,0 +1,43 @@
# The chicken-egg should not be used. I use ppm to setup ppm.pfoe.be
# so I cannot clone the appdefinition using git. So this chicken-egg
# makes it possible to install apps when I'm still installing ppm.pfoe.be
# However, it's easier to just git clone directly from the source.
# You will need a local copy of the git repository to use this
- name: Create temporary build directory
ansible.builtin.tempfile:
state: directory
suffix: build
register: temp_dir
delegate_to: localhost
become: false
- name: Create a .tar.gz archive from the chicken-egg directory
community.general.archive:
dest: "{{ temp_dir.path }}/appdef.tar.gz"
path: "{{ ppm_app.chicken_egg_appdefinition }}"
mode: "0600"
delegate_to: localhost
become: false
- name: Create directory
ansible.builtin.file:
path: "{{ ppm_app_user.home }}/appdefinition"
state: directory
mode: "0755"
owner: "{{ ppm_app_user.name }}"
group: "{{ ppm_app_user.group }}"
- name: Unzip the files to server
ansible.builtin.unarchive:
src: "{{ temp_dir.path }}/appdef.tar.gz"
dest: "{{ ppm_app_user.home }}/appdefinition"
owner: "{{ ppm_app_user.name }}"
group: "{{ ppm_app_user.group }}"
- name: Remove temp dir
ansible.builtin.file:
path: "{{ temp_dir.path }}"
state: absent
delegate_to: localhost
become: false

19
roles/ppm/tasks/main.yml Normal file
View file

@ -0,0 +1,19 @@
- name: Install PPM program as root
ansible.builtin.import_tasks: ppminstall.yml
- name: Go over all projects for this server
ansible.builtin.include_tasks: oneapp.yml
loop: "{{ ppm_apps }}"
loop_control:
loop_var: ppm_app
label: "{{ ppm_app.user }}"
when: ppm_app.on_server == inventory_hostname
- name: Configure firewall options
ansible.builtin.template:
dest: /etc/firewall.d/ppmfirewall
group: root
owner: root
mode: "0755"
src: ppmfirewall.j2
notify: Restart firewall

View file

@ -0,0 +1,36 @@
- name: "Create user ({{ ppm_app.user }})"
ansible.builtin.user:
name: "{{ ppm_app.user }}"
shell: /bin/bash
register: ppm_app_user
# Enabling linger will make systemd start the user-systemd for this user at bootup time
# Enabling this will allow us to run programs automatically and independently of any user login
- name: "Linger user ({{ ppm_app.user }})"
ansible.builtin.command:
cmd: "loginctl enable-linger {{ ppm_app_user.name }}"
creates: "/var/lib/systemd/linger/{{ ppm_app_user.name }}"
- name: "Ensure we have a XDG_RUNTIME_DIR variable ({{ ppm_app.user }})"
ansible.builtin.lineinfile:
dest: "{{ ppm_app_user.home }}/.bashrc"
state: present
line: "export XDG_RUNTIME_DIR=/run/user/$(id -u)"
regexp: ^export XDG_RUNTIME_DIR=
- name: "Place configuration ({{ ppm_app.user }})"
ansible.builtin.copy:
content: "{{ ppm_app.appconfig | dict2items | selectattr('key', 'ne', 'code') | items2dict | to_nice_yaml }}"
dest: "{{ ppm_app_user.home }}/config.yml"
owner: "{{ ppm_app_user.name }}"
group: "{{ ppm_app_user.group }}"
mode: "0600"
- name: "See if app definition exists ({{ ppm_app.user }})"
ansible.builtin.stat:
path: "{{ ppm_app_user.home }}/appdefinition"
register: appdefinition
- name: "Bootstrap the app definition ({{ ppm_app.user }})"
ansible.builtin.include_tasks: copyappdef.yml
when: ppm_app.chicken_egg_appdefinition is defined and not appdefinition.stat.exists

View file

@ -0,0 +1,37 @@
- name: Install ppm dependencies
ansible.builtin.apt:
pkg:
# We hard depend on podman, as this is the workhorse of most apps
# We also depend on podman unshare in ppm itself
- podman
# Required for rootless operation
- uidmap
# Use the newer network backend instead of the default CNI backend
- netavark
# Required for rootless networking
- slirp4netns
# podman-compose is also used in many apps we can install
- podman-compose
# Restic is currently the only supported backup system
- restic
# The python dependencies of ppm are baked in. However, jsonschema is
# not pure python, so it must be installed from system package
- python3-jsonschema
# Git is required for checking out the app definitions
- git
- name: Create state directory
ansible.builtin.file:
state: directory
owner: root
group: root
mode: "1777"
path: /home/.ppmstate
- name: Copy ppm
ansible.builtin.copy:
src: "{{ ppm_binary }}"
dest: /usr/local/bin/ppm
owner: root
group: root
mode: "0755"

View file

@ -0,0 +1,15 @@
#!/bin/bash
# PPM Firewal, written by ansible
{% for ppm_app in ppm_apps %}
# Firewall for {{ ppm_app.user }}
{% for redirect in ppm_app.firewall_redirect | default([]) %}
# Redirect {{ redirect.from }} to {{ redirect.to }}
iptables -A INPUT -p tcp --dport {{ redirect.from }} -j ACCEPT
ip6tables -A INPUT -p tcp --dport {{ redirect.from }} -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport {{ redirect.to }} -j REDIRECT --to-ports {{ redirect.from }}
ip6tables -t nat -A PREROUTING -p tcp --dport {{ redirect.to }} -j REDIRECT --to-ports {{ redirect.from }}
{% endfor %}
{% endfor %}