Compare commits
8 commits
c34b3c1d0f
...
c36f52e420
| Author | SHA1 | Date | |
|---|---|---|---|
| c36f52e420 | |||
| 03d9493e7a | |||
| dccb45168c | |||
| 0cdef8be5b | |||
| 1bd7ae2913 | |||
| 13d2513d87 | |||
| be2b2a7ca7 | |||
| e0b0f33c03 |
18 changed files with 95 additions and 76 deletions
|
|
@ -1,7 +0,0 @@
|
||||||
This is how I set up ppm.pfoe.be
|
|
||||||
|
|
||||||
This repository is currently created to serve
|
|
||||||
as an inspiration for creating your own ansible playbook to set up ppm
|
|
||||||
|
|
||||||
At this moment it is not intended to be used as is/it is a work in progress
|
|
||||||
|
|
||||||
5
all.yml
5
all.yml
|
|
@ -1,5 +0,0 @@
|
||||||
- name: Perform ppm server ansible playbook
|
|
||||||
hosts: all
|
|
||||||
roles:
|
|
||||||
- baseline
|
|
||||||
- ppm
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
[defaults]
|
|
||||||
inventory=inventory
|
|
||||||
retry_files_enabled = False
|
|
||||||
remote_user = root
|
|
||||||
deperaction_warnings = True
|
|
||||||
display_skipped_hosts = True
|
|
||||||
|
|
||||||
result_format=yaml
|
|
||||||
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
ppm_apps:
|
|
||||||
- on_server: ppm.pfoe.be
|
|
||||||
user: git
|
|
||||||
chicken_egg_appdefinition: ../forgejo/
|
|
||||||
appconfig:
|
|
||||||
restic:
|
|
||||||
url: "{{ lookup('file', 'passwords/ppm-forgejo-url') }}"
|
|
||||||
password: "{{ lookup('file', 'passwords/ppm-forgejo-password') }}"
|
|
||||||
backupname: "{{ lookup('file', 'passwords/ppm-forgejo-name') }}"
|
|
||||||
appinfo:
|
|
||||||
url: https://ppm.pfoe.be/ppm/forgejo.git
|
|
||||||
config:
|
|
||||||
publicurl: ppm.pfoe.be
|
|
||||||
|
|
||||||
- on_server: ppm.pfoe.be
|
|
||||||
user: nginx
|
|
||||||
chicken_egg_appdefinition: ../nginx/
|
|
||||||
appconfig:
|
|
||||||
appinfo:
|
|
||||||
url: https://ppm.pfoe.be/ppm/nginx.git
|
|
||||||
code:
|
|
||||||
type: localfiles
|
|
||||||
directory: nginx
|
|
||||||
|
|
||||||
- on_server: ppm.pfoe.be
|
|
||||||
user: runner
|
|
||||||
chicken_egg_appdefinition: ../forgejo-runner/
|
|
||||||
appconfig:
|
|
||||||
appinfo:
|
|
||||||
url: https://ppm.pfoe.be/ppm/forgejo-runner.git
|
|
||||||
code:
|
|
||||||
type: localfiles
|
|
||||||
directory: forgejo-runner
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# I prefer not to share the list of admins in a public repo, so refer to passwords...
|
|
||||||
# The format for the ssh ranges is as follows:
|
|
||||||
# - name: The name that is in a comment in the generated file. Not used anywhere else
|
|
||||||
# type: ipv4 # or ipv6
|
|
||||||
# range: 10.10.10.10/32 # The range, MUST be a valid range, not an ip address, ie there must be a / and the netmask
|
|
||||||
|
|
||||||
firewall_ssh_ranges: "{{ lookup('file', 'passwords/firewall_ssh_ranges.yml') | from_yaml }}"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
ppm_binary: "{{ lookup('pipe', 'pwd') }}/../ppm/out/ppm"
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
root_password: "{{ lookup('file', 'passwords/root_password_hashed') }}"
|
|
||||||
# ssh keys are public, but I prefer not to share the list of admins in a public repo
|
|
||||||
root_sshkeys: "{{ lookup('file', 'passwords/root_sshkeys.yml') | from_yaml }}"
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
zabbix_server: "{{ lookup('file', 'passwords/zabbix_server') }}"
|
|
||||||
zabbix_psk: "{{ lookup('file', 'passwords/zabbix_psk') }}"
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
[ppmserver]
|
|
||||||
ppm.pfoe.be
|
|
||||||
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
# Even if we "changed it", it's merely a cache, so ignore
|
# Even if we "changed it", it's merely a cache, so ignore
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Update system packages to lates
|
- name: Update system packages to latest
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
upgrade: dist
|
upgrade: dist
|
||||||
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
pkg:
|
pkg:
|
||||||
- apt-dater
|
- apt-dater
|
||||||
|
- man
|
||||||
- mosh
|
- mosh
|
||||||
- mc
|
- mc
|
||||||
- vim
|
- vim
|
||||||
|
|
@ -36,6 +37,9 @@
|
||||||
- iftop
|
- iftop
|
||||||
- htop
|
- htop
|
||||||
- ncdu
|
- ncdu
|
||||||
|
- acl
|
||||||
|
- sudo
|
||||||
|
- ntpsec-ntpdate
|
||||||
|
|
||||||
- name: Firewall for mosh
|
- name: Firewall for mosh
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: root
|
name: root
|
||||||
password: "{{ root_password }}"
|
password: "{{ root_password }}"
|
||||||
|
when: root_password is defined
|
||||||
|
|
||||||
- name: Ensure ssh directory for root
|
- name: Ensure ssh directory for root
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
|
|
@ -10,6 +11,7 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: "0700"
|
mode: "0700"
|
||||||
|
when: root_sshkeys is defined
|
||||||
|
|
||||||
- name: Set authorized keys for root
|
- name: Set authorized keys for root
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
|
|
@ -18,6 +20,7 @@
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
|
when: root_sshkeys is defined
|
||||||
|
|
||||||
- name: Only allow root ssh
|
- name: Only allow root ssh
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
|
|
@ -25,3 +28,4 @@
|
||||||
line: "PermitRootLogin prohibit-password"
|
line: "PermitRootLogin prohibit-password"
|
||||||
regexp: "^PermitRootLogin "
|
regexp: "^PermitRootLogin "
|
||||||
notify: Restart sshd
|
notify: Restart sshd
|
||||||
|
when: root_sshkeys is defined
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,16 @@ iptables -A INPUT -m limit --limit 1/s --limit-burst 2 -p icmp --icmp-type echo-
|
||||||
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
|
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
|
||||||
iptables -A INPUT -p icmp -j ACCEPT
|
iptables -A INPUT -p icmp -j ACCEPT
|
||||||
|
|
||||||
|
{% if firewall_ssh_ranges is defined %}
|
||||||
{% for range in firewall_ssh_ranges %}
|
{% for range in firewall_ssh_ranges %}
|
||||||
{%if range.type=="ipv4" %}
|
{%if range.type=="ipv4" %}
|
||||||
iptables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
|
iptables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
|
||||||
{%endif%}
|
{%endif%}
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
|
{% else %}
|
||||||
|
# This server has an open ssh policy
|
||||||
|
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
iptables -A OUTPUT -m state --state INVALID -j DROP
|
iptables -A OUTPUT -m state --state INVALID -j DROP
|
||||||
|
|
@ -48,11 +53,16 @@ ip6tables -A INPUT -m limit --limit 1/s --limit-burst 2 -p icmpv6 --icmpv6-type
|
||||||
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
|
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j DROP
|
||||||
ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
||||||
|
|
||||||
|
{% if firewall_ssh_ranges is defined %}
|
||||||
{% for range in firewall_ssh_ranges %}
|
{% for range in firewall_ssh_ranges %}
|
||||||
{%if range.type=="ipv6" %}
|
{%if range.type=="ipv6" %}
|
||||||
ip6tables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
|
ip6tables -A INPUT -p tcp --dport 22 -s {{range.range}} -j ACCEPT # {{range.name}}
|
||||||
{%endif%}
|
{%endif%}
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
|
{% else %}
|
||||||
|
# This server has an open ssh policy
|
||||||
|
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
ip6tables -A OUTPUT -m state --state INVALID -j DROP
|
ip6tables -A OUTPUT -m state --state INVALID -j DROP
|
||||||
|
|
@ -75,4 +85,11 @@ ip6tables -A INPUT -j REJECT
|
||||||
iptables -A FORWARD -j REJECT
|
iptables -A FORWARD -j REJECT
|
||||||
ip6tables -A FORWARD -j REJECT
|
ip6tables -A FORWARD -j REJECT
|
||||||
|
|
||||||
|
# Now *if* fail2ban has been installed, we would have destroyed it's setup.
|
||||||
|
# Restart it
|
||||||
|
if [ -e /etc/fail2ban/fail2ban.conf ]
|
||||||
|
then
|
||||||
|
systemctl restart fail2ban || true
|
||||||
|
fi
|
||||||
|
|
||||||
# This file is managed by ansible, do not modify!
|
# This file is managed by ansible, do not modify!
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
|
- name: delete appdefinition directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ppm_app_user.home }}/appdefinition"
|
||||||
|
state: absent
|
||||||
|
|
||||||
- name: Create directory
|
- name: Create directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ ppm_app_user.home }}/appdefinition"
|
path: "{{ ppm_app_user.home }}/appdefinition"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
dest: /home/.ppmfirewalltemplate
|
dest: /home/.ppmfirewalltemplate
|
||||||
group: root
|
group: root
|
||||||
owner: root
|
owner: root
|
||||||
mode: "0755"
|
mode: "0644"
|
||||||
src: ppmfirewall
|
src: ppmfirewall
|
||||||
|
|
||||||
- name: Render firewall
|
- name: Render firewall
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,10 @@
|
||||||
ansible.builtin.include_tasks: copyappdef.yml
|
ansible.builtin.include_tasks: copyappdef.yml
|
||||||
when: ppm_app.chicken_egg_appdefinition is defined and not appdefinition.stat.exists
|
when: ppm_app.chicken_egg_appdefinition is defined and not appdefinition.stat.exists
|
||||||
|
|
||||||
|
- name: "Update appdefinition ({{ ppm_app.user }})"
|
||||||
|
ansible.builtin.include_tasks: updateappdef.yml
|
||||||
|
when: ppm_app.chicken_egg_appdefinition is defined
|
||||||
|
|
||||||
- name: "Set up extra files for {{ ppm_app.user }}"
|
- name: "Set up extra files for {{ ppm_app.user }}"
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: "{{ item.from }}"
|
src: "{{ item.from }}"
|
||||||
|
|
|
||||||
58
roles/ppm/tasks/updateappdef.yml
Normal file
58
roles/ppm/tasks/updateappdef.yml
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
- name: Check local working tree for uncommitted changes
|
||||||
|
command: git status --porcelain
|
||||||
|
args:
|
||||||
|
chdir: "{{ ppm_app.chicken_egg_appdefinition }}"
|
||||||
|
register: local_status
|
||||||
|
changed_when: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Get local HEAD hash
|
||||||
|
command: git rev-parse HEAD
|
||||||
|
args:
|
||||||
|
chdir: "{{ ppm_app.chicken_egg_appdefinition }}"
|
||||||
|
register: local_hash
|
||||||
|
changed_when: false
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
|
||||||
|
- name: Check remote working tree for uncommitted changes
|
||||||
|
command: git status --porcelain
|
||||||
|
args:
|
||||||
|
chdir: "{{ ppm_app_user.home }}/appdefinition"
|
||||||
|
register: remote_status
|
||||||
|
changed_when: false
|
||||||
|
become: true
|
||||||
|
become_user: "{{ ppm_app_user.name }}"
|
||||||
|
|
||||||
|
- name: Get remote HEAD hash
|
||||||
|
command: git rev-parse HEAD
|
||||||
|
args:
|
||||||
|
chdir: "{{ ppm_app_user.home }}/appdefinition"
|
||||||
|
register: remote_hash
|
||||||
|
changed_when: false
|
||||||
|
become: true
|
||||||
|
become_user: "{{ ppm_app_user.name }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set helper facts
|
||||||
|
set_fact:
|
||||||
|
local_dirty: "{{ (local_status.stdout | default('')) != '' }}"
|
||||||
|
local_hash: "{{ local_hash.stdout }}"
|
||||||
|
remote_dirty: "{{ (remote_status.stdout | default('')) != '' }}"
|
||||||
|
remote_hash: "{{ remote_hash.stdout }}"
|
||||||
|
|
||||||
|
- name: Debug when remote is dirty (ignore remote dirty for sync decision)
|
||||||
|
debug:
|
||||||
|
msg: "Remote repository has uncommitted changes; ignoring for sync."
|
||||||
|
changed_when: true
|
||||||
|
when: remote_dirty
|
||||||
|
|
||||||
|
- name: Debug when local is dirty
|
||||||
|
debug:
|
||||||
|
msg: "Local repository has uncommitted changes; unconditional - non-idempotent sync."
|
||||||
|
changed_when: true
|
||||||
|
when: local_dirty and not remote_dirty
|
||||||
|
|
||||||
|
- name: Include copyappdef.yml when local dirty, hash retrieval failed, or hashes differ
|
||||||
|
include_tasks: copyappdef.yml
|
||||||
|
when: not remote_dirty and (local_hash!=remote_hash or local_dirty)
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
dest: /home/.zabbixagenttemplate
|
dest: /home/.zabbixagenttemplate
|
||||||
group: root
|
group: root
|
||||||
owner: root
|
owner: root
|
||||||
mode: "0755"
|
mode: "0644"
|
||||||
src: ppmzabbixagent
|
src: ppmzabbixagent
|
||||||
|
|
||||||
- name: Render zabbix template
|
- name: Render zabbix template
|
||||||
|
|
|
||||||
3
run
3
run
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
ansible-playbook --diff all.yml "$@"
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue