Compare commits

..
15 Commits
Author SHA1 Message Date
Justin 891549d3fe fixed permisson 2026-08-29 18:36:51 -05:00
Justin a91cfa46ba fixed permissions 2026-08-29 18:34:36 -05:00
Justin 382ba812c4 fixed files that are not needed 2026-08-29 18:19:54 -05:00
Justin 63d79f7f76 Updated 2026-08-29 18:16:21 -05:00
Justin 1c6c25f442 update 2026-04-23 21:23:26 -05:00
Justin 70b51c9575 updates 2026-04-23 21:21:54 -05:00
Justin e22094ed62 Added the a maint 2026-04-16 10:42:27 -05:00
Justin 86d343e75a removed some old swap files and added cleanup cache and log files 2026-04-16 10:39:16 -05:00
Justin 2577db04be feat: add windows host group with winrm configuration to inventory 2026-04-14 16:25:16 -05:00
Justin 56edb6a70d feat: add Ansible playbooks for Docker management, system updates, and host configuration 2026-04-14 15:56:26 -05:00
Justin 473065199f worked on the updating the docker 2026-02-09 23:06:01 -06:00
Justin bccc5b0d5f Update the issues. 2026-01-19 15:24:15 -06:00
Justin e4da8e7ce6 update 2025-11-12 21:38:47 -06:00
Justin bee972ff5f updated 2025-09-03 20:45:17 -05:00
Justin 79df365f95 update 2025-05-07 18:45:45 -05:00
36 changed files with 1044 additions and 392 deletions

No files matched your search

+1 -1
View File
@@ -284,7 +284,7 @@ interpreter_python=auto_silent
;verbosity=0 ;verbosity=0
# (boolean) Toggle to control the showing of deprecation warnings # (boolean) Toggle to control the showing of deprecation warnings
;deprecation_warnings=True deprecation_warnings=False
# (boolean) Toggle to control showing warnings related to running devel. # (boolean) Toggle to control showing warnings related to running devel.
;devel_warning=True ;devel_warning=True
-23
View File
@@ -1,23 +0,0 @@
---
- name: Add ssh key
hosts: all
become: true
tasks:
- name: create id_rsa
file:
path: "~/.ssh/id_rsa.pub"
state: touch
- name: Install public keys
ansible.posix.authorized_key:
user: "{{ lookup('env', 'USER') }}"
state: present
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
- name: Change sudoers file
ansible.builtin.lineinfile:
path: /etc/sudoers
state: present
regexp: '^%sudo'
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
validate: /usr/sbin/visudo -cf %s
+26
View File
@@ -0,0 +1,26 @@
---
- name: Install Docker and Docker Compose plugin
hosts: killer2.ki5bhv.com
become: true
tasks:
- name: Update apt package index
ansible.builtin.apt:
update_cache: true
- name: Ensure required packages for Docker are installed
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
# The following steps are typically part of a full Docker installation playbook
# to set up the official Docker repository, but are omitted here for brevity.
# If you install Docker from the standard Ubuntu repos, the following task is sufficient:
- name: Install the Docker Compose plugin
ansible.builtin.apt:
name: docker-compose-plugin
state: present
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Install docker - name: Install docker
hosts: "{{ my_hosts | d([]) }}" hosts: mail-cow.k5bss.com
become: true become: true
tasks: tasks:
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Clean docker - name: Clean docker
hosts: "{{ my_hosts | d([]) }}" hosts: ki5bhv.com
tasks: tasks:
- name: Prune non-dangling images - name: Prune non-dangling images
+20
View File
@@ -0,0 +1,20 @@
---
- name: Deploy Docker Compose stack with pull and restart
hosts: ki5bhv.com
become: true
tasks:
- name: Qbits
community.docker.docker_compose_v2:
project_src: /home/justin/docker/qbits/
recreate: always
- name: Prune non-dangling images
community.docker.docker_prune:
containers: false
images: true
images_filters:
dangling: false
networks: false
volumes: false
builder_cache: false
+356
View File
@@ -0,0 +1,356 @@
---
- name: Deploy Docker Compose stack with pull and restart
hosts: killer2.ki5bhv.com
become: true
tasks:
- name: Qbits
community.docker.docker_compose_v2:
project_src: /home/justin/docker/qbits
pull: always
register: result
retries: 3
delay: 3
until: result is not failed
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: homarr
community.docker.docker_compose_v2:
project_src: /home/justin/docker/homarr/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: wireguard
community.docker.docker_compose_v2:
project_src: /home/justin/docker/wireguard/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: beszel
community.docker.docker_compose_v2:
project_src: /home/justin/docker/beszel/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: cup
community.docker.docker_compose_v2:
project_src: /home/justin/docker/cup/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: ntfy
community.docker.docker_compose_v2:
project_src: /home/justin/docker/ntfy/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: vaultwarden
community.docker.docker_compose_v2:
project_src: /home/justin/docker/vaultwarden/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: uptime-kuma
community.docker.docker_compose_v2:
project_src: /home/justin/docker/uptime-kuma/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: overseerr
community.docker.docker_compose_v2:
project_src: /home/justin/docker/overseerr/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: portainer
community.docker.docker_compose_v2:
project_src: /home/justin/docker/portainer/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: it-tools
community.docker.docker_compose_v2:
project_src: /home/justin/docker/it-tools/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: termix
community.docker.docker_compose_v2:
project_src: /home/justin/docker/termix/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: ntfy
community.docker.docker_compose_v2:
project_src: /home/justin/docker/ntfy/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: netalertx
community.docker.docker_compose_v2:
project_src: /home/justin/docker/netalertx/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: homarr
community.docker.docker_compose_v2:
project_src: /home/justin/docker/homarr/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: wireguard
community.docker.docker_compose_v2:
project_src: /home/justin/docker/wireguard/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: beszel
community.docker.docker_compose_v2:
project_src: /home/justin/docker/beszel/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: cup
community.docker.docker_compose_v2:
project_src: /home/justin/docker/cup/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: ntfy
community.docker.docker_compose_v2:
project_src: /home/justin/docker/ntfy/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: vaultwarden
community.docker.docker_compose_v2:
project_src: /home/justin/docker/vaultwarden/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: uptime-kuma
community.docker.docker_compose_v2:
project_src: /home/justin/docker/uptime-kuma/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: overseerr
community.docker.docker_compose_v2:
project_src: /home/justin/docker/overseerr/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: portainer
community.docker.docker_compose_v2:
project_src: /home/justin/docker/portainer/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: it-tools
community.docker.docker_compose_v2:
project_src: /home/justin/docker/it-tools/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: termix
community.docker.docker_compose_v2:
project_src: /home/justin/docker/termix/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: ntfy
community.docker.docker_compose_v2:
project_src: /home/justin/docker/ntfy/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: netalertx
community.docker.docker_compose_v2:
project_src: /home/justin/docker/netalertx/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: Wavelog
community.docker.docker_compose_v2:
project_src: /home/justin/docker/wavelog/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: Kometa
community.docker.docker_compose_v2:
project_src: /home/justin/docker/kometa/
pull: always
recreate: auto
- name: Pause
ansible.builtin.pause:
seconds: 1
- name: Tautulli
community.docker.docker_compose_v2:
project_src: /home/justin/docker/tautulli/
pull: always
recreate: auto
- name: Prune non-dangling images
community.docker.docker_prune:
containers: false
images: true
images_filters:
dangling: false
networks: false
volumes: false
builder_cache: false
- name: Deploy Docker Compose stack with pull and restart
hosts: docker.ki5bhv.com
become: true
tasks:
- name: code
community.docker.docker_compose_v2:
project_src: /home/justin/Docker/code-server
pull: always
recreate: auto
- name: Prune non-dangling images
community.docker.docker_prune:
containers: false
images: true
images_filters:
dangling: false
networks: false
volumes: false
builder_cache: false
- name: Deploy Docker Compose stack with pull and restart
hosts: proxy-server.ki5bhv.com
become: true
tasks:
- name: nginx proxy
community.docker.docker_compose_v2:
project_src: /home/justin/docker/nginx-proxy
pull: always
recreate: auto
- name: Prune non-dangling images
community.docker.docker_prune:
containers: false
images: true
images_filters:
dangling: false
networks: false
volumes: false
builder_cache: false
+5 -6
View File
@@ -1,13 +1,12 @@
--- ---
- name: Git update
hosts: localhost - name: Git update k5bss
hosts: webhost
tasks: tasks:
- name: Git Pull - name: Git Pull
ansible.builtin.git: ansible.builtin.git:
repo: https://git.ki5bhv.com/justin/Ansible.git repo: https://git.ki5bhv.com/justin/k5bss.com.git
dest: /home/justin/Ansible dest: /var/www/k5bss.com
single_branch: yes single_branch: yes
version: main version: main
:
-110
View File
@@ -1,110 +0,0 @@
---
- name: Installing Nvim
hosts: all
tasks:
- name: make sure git is installed
become: yes
apt:
update_cache: yes
name: git
state: latest
- name: Pulling from github
ansible.builtin.command:
cmd: "curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz --output-dir /tmp"
- name: Removing and older verson
become: true
ansible.builtin.command:
cmd: "sudo rm -rf /opt/nvim"
- name: Unziping Nvim
become: true
ansible.builtin.command:
cmd: "sudo tar -C /opt -xzf /tmp/nvim-linux-x86_64.tar.gz"
- name: Setting the path
ansible.builtin.lineinfile:
line: 'export PATH="$PATH:/opt/nvim-linux64/bin"'
path: "~/.bashrc"
insertafter: EOF
- name: Check if there is a config
ansible.builtin.stat:
path: /home/justin/.config/nvim
register: nvim_config
- name: Checking if there is a backup Nvim config
ansible.builtin.stat:
path: /home/justin/.config/nvim.bak
register: nvim_backup_config
- name: Removing backup config
ansible.builtin.command:
cmd: "rm -r home/justin/.config/nvim.bak"
when: nvim_backup_config.stat.exists
- name: Backup configs
ansible.builtin.command:
cmd: "mv /home/justin/.config/nvim /home/justin/.config/nvim.bak"
when: nvim_config.stat.exists
- name: Pulling config
ansible.builtin.command:
cmd: "git clone https://github.com/LazyVim/starter ~/.config/nvim"
- name: removing the git file
ansible.builtin.command:
cmd: "rm -rf /home/justin/.config/nvim/.git"
- name: Cleanup
ansible.builtin.command:
cmd: "rm /tmp/nvim-linux-x86_64.tar.gz"
- name: installing unzip
become: true
when: ansible_pkg_mgr == "apt"
ansible.builtin.apt:
name: unzip
state: latest
- name: Check if Font folder is there
ansible.builtin.stat:
path: ~/.local/share/fonts
register: fonts_folder
- name: Making font folder
ansible.builtin.command:
cmd: "mkdir /home/justin/.local/share/fonts"
when: fonts_folder.stat.exists != True
- name: Nerd font zip
ansible.builtin.command:
cmd: "wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/3270.zip"
- name: Unzipping
ansible.builtin.command:
cmd: "unzip 3270.zip -d /home/justin/.local/share/fonts/ "
- name: Font Cleanup
ansible.builtin.command:
cmd: "rm 3270.zip"
- name: installing font config
become: true
when: ansible_pkg_mgr == "apt"
ansible.builtin.apt:
name: fontconfig
state: latest
- name: Set Fonts
ansible.builtin.command:
cmd: "fc-cache -fv"
- name: installing fzf for nvim
become: true
when: ansible_pkg_mgr == "apt"
ansible.builtin.apt:
name: fzf
state: latest
-25
View File
@@ -1,25 +0,0 @@
---
- name: Check disk space
hosts: "all"
tasks:
- name: Check disk space available
ansible.builtin.shell:
cmd: |
set -euo pipefail
df -Ph / | awk 'NR==2 {print $5}'
executable: /bin/bash
changed_when: false
check_mode: false
register: disk_usage
- name: Diskspace is over 80%
ansible.builtin.debug:
msg: "Disk is over 80%"
when: disk_usage.stdout[:-1]|int>80
- name: Posting
ansible.builtin.command:
cmd: 'curl -d "Disk space on {{ inventory_hostname }} is above 80%!" ntfy.ki5bhv.com/server'
when: disk_usage.stdout[:-1]|int>80
-16
View File
@@ -1,16 +0,0 @@
---
- name: Check if system reboot is required
hosts: "all"
become: true
tasks:
- name: Check if system reboot is required
become: true
ansible.builtin.stat:
path: /run/reboot-required
register: reboot_required
- name: Report if reboot is required
ansible.builtin.command:
cmd: 'curl -d "Reboot is required for {{inventory_hostname}}" ntfy.ki5bhv.com/server'
when: reboot_required.stat.exists
+9
View File
@@ -0,0 +1,9 @@
---
- hosts: all
gather_facts: false
tasks:
- name: Ping
ansible.builtin.ping:
data: pong
-11
View File
@@ -1,11 +0,0 @@
---
- name: Update Plex Sever
hosts: killer1
become: yes
tasks:
- name: Ensure Plex is at the latest version
apt:
update_cache: yes
name: plexmediaserver
state: latest
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Setting time zone - name: Setting time zone
hosts: all hosts: linux
become: yes become: yes
tasks: tasks:
+14
View File
@@ -0,0 +1,14 @@
- name: Ubuntu Server Cleanup
hosts: linux
become: true
serial: 1
tasks:
- name: Remove unused packages and dependencies
ansible.builtin.apt:
autoremove: yes
- name: Clean APT cache
ansible.builtin.apt:
clean: yes
+1 -1
View File
@@ -12,7 +12,7 @@
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: "{{ lookup('env', 'USER') }}" user: "{{ lookup('env', 'USER') }}"
state: present state: present
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}" key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: Change sudoers file - name: Change sudoers file
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
+7
View File
@@ -0,0 +1,7 @@
- name: Flush DNS Cache on Remote Hosts
hosts: all
become: yes # Requires root privileges
tasks:
- name: Flush DNS cache using resolvectl (for systemd-resolved)
ansible.builtin.command: resolvectl flush-caches
+70
View File
@@ -0,0 +1,70 @@
---
# fix-ssh-host-keys.yaml
#
# Detects cloned VMs that share the same SSH host key and regenerates a
# unique key set on each one, then refreshes the controller's known_hosts.
#
# Run with host key checking disabled for this one remediation pass,
# since known_hosts is currently in a conflicted state:
#
# ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook fix-ssh-host-keys.yaml
#
# The `duplicate_fingerprint` guard means only hosts presenting the shared
# key get touched. Hosts with an already-unique key are left alone.
- name: Regenerate shared SSH host keys on cloned guests
hosts: all
become: true
gather_facts: false
vars:
# The shared key every clone is currently presenting.
duplicate_fingerprint: "SHA256:AZekUU+Wwn6S6sCjGD0SdkhVgj3WVqVdiVYa1AXYW8A"
tasks:
- name: Read current ED25519 host key fingerprint
ansible.builtin.command:
cmd: ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
register: hostkey_fp
changed_when: false
failed_when: false
- name: Regenerate host keys if this host shares the duplicate key
when: duplicate_fingerprint in (hostkey_fp.stdout | default(''))
block:
- name: Remove existing host keys
ansible.builtin.shell:
cmd: rm -f /etc/ssh/ssh_host_*
# rm on a glob isn't idempotent-reportable; treat as changed.
changed_when: true
- name: Generate a fresh unique set of host keys
ansible.builtin.command:
cmd: ssh-keygen -A
changed_when: true
- name: Restart SSH so the new key is served
ansible.builtin.service:
name: ssh
state: restarted
- name: Note that this host was remediated
ansible.builtin.debug:
msg: "{{ inventory_hostname }} had the shared key and was regenerated."
- name: Refresh known_hosts on the Ansible controller
hosts: localhost
gather_facts: false
vars:
known_hosts_path: "{{ lookup('env', 'HOME') }}/.ssh/known_hosts"
target_hosts: "{{ groups['all'] | difference(['localhost']) }}"
tasks:
- name: Remove stale entries for every managed host
ansible.builtin.command:
cmd: "ssh-keygen -f {{ known_hosts_path }} -R {{ item }}"
loop: "{{ target_hosts }}"
changed_when: false
- name: Rescan and add current keys
ansible.builtin.shell:
cmd: "ssh-keyscan -t ed25519,rsa,ecdsa {{ item }} >> {{ known_hosts_path }}"
loop: "{{ target_hosts }}"
changed_when: true
View File
Whitespace-only changes.
View File
Whitespace-only changes.
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Install core packages for virtual machines - name: Install core packages for virtual machines
hosts: "{{ my_hosts | d([]) }}" hosts: 192.168.1.15
become: true become: true
tasks: tasks:
+2 -44
View File
@@ -1,6 +1,7 @@
--- ---
- name: Installing Nvim - name: Installing Nvim
hosts: localhost hosts: 192.168.1.15
tasks: tasks:
- name: make sure git is installed - name: make sure git is installed
@@ -62,46 +63,6 @@
ansible.builtin.command: ansible.builtin.command:
cmd: "rm /tmp/nvim-linux-x86_64.tar.gz" cmd: "rm /tmp/nvim-linux-x86_64.tar.gz"
- name: installing unzip
become: true
when: ansible_pkg_mgr == "apt"
ansible.builtin.apt:
name: unzip
state: latest
- name: Check if Font folder is there
ansible.builtin.stat:
path: ~/.local/share/fonts
register: fonts_folder
- name: Making font folder
ansible.builtin.command:
cmd: "mkdir /home/justin/.local/share/fonts"
when: fonts_folder.stat.exists != True
- name: Nerd font zip
ansible.builtin.command:
cmd: "curl -LO https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/3270.zip --output-dir /tmp"
- name: Unzipping
ansible.builtin.command:
cmd: "unzip /tmp/3270.zip -d /home/justin/.local/share/fonts/ "
- name: Font Cleanup
ansible.builtin.command:
cmd: "rm /tmp/3270.zip"
- name: installing font config
become: true
when: ansible_pkg_mgr == "apt"
ansible.builtin.apt:
name: fontconfig
state: latest
- name: Set Fonts
ansible.builtin.command:
cmd: "fc-cache -fv"
- name: installing fzf for nvim - name: installing fzf for nvim
become: true become: true
when: ansible_pkg_mgr == "apt" when: ansible_pkg_mgr == "apt"
@@ -121,9 +82,6 @@
path: "~/.bashrc" path: "~/.bashrc"
insertafter: EOF insertafter: EOF
- name: Reload bashrc
ansible.builtin.command:
cmd: "source /home/justin/.bashrc"
+72
View File
@@ -0,0 +1,72 @@
- name: Clean Old Log Files and Cache
hosts: linux
become: true
serial: 1
vars:
log_dirs:
- /var/log
log_age_days: 30
tasks:
- name: Remove compressed/rotated log files older than {{ log_age_days }} days
ansible.builtin.find:
paths: "{{ log_dirs }}"
patterns: "*.gz,*.1,*.2,*.3,*.4,*.5,*.old"
age: "{{ log_age_days }}d"
recurse: true
register: old_logs
- name: Delete found old log files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
- name: Truncate large active log files (> 100MB) without deleting them
ansible.builtin.shell: |
find /var/log -type f -name "*.log" -size +100M | while read f; do
truncate -s 0 "$f"
done
changed_when: false
- name: Clean journal logs older than 30 days
ansible.builtin.command: journalctl --vacuum-time=30d
changed_when: false
- name: Limit journal size to 500MB
ansible.builtin.command: journalctl --vacuum-size=500M
changed_when: false
- name: Remove unused packages and dependencies
ansible.builtin.apt:
autoremove: yes
- name: Clean APT package cache
ansible.builtin.apt:
clean: yes
- name: Remove obsolete package files from APT cache
ansible.builtin.apt:
autoclean: yes
- name: Clean user thumbnail/cache directories
ansible.builtin.shell: |
find /home -maxdepth 3 -type d -name ".cache" | while read d; do
find "$d" -type f -atime +{{ log_age_days }} -delete 2>/dev/null || true
done
changed_when: false
- name: Clean /tmp files older than 7 days
ansible.builtin.find:
paths: /tmp
age: 7d
recurse: true
register: tmp_files
- name: Delete old /tmp files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ tmp_files.files }}"
ignore_errors: true
@@ -0,0 +1,30 @@
---
- name: Check if system reboot is required
hosts: "proxmox"
become: true
serial: 1
tasks:
- name: Check if system reboot is required
become: true
ansible.builtin.stat:
path: /run/reboot-required
register: reboot_required
- name: rebooting
become: true
ansible.builtin.reboot:
reboot_timeout: 3600
when: reboot_required.stat.exists
- name: wait for server to resert
ansible.builtin.wait_for_connection:
delay: 30
timeout: 3600
when: reboot_required.stat.exists
- name: Report if reboot is required
ansible.builtin.command:
cmd: 'curl -d "Reboot was required for {{inventory_hostname}} and it was rebooted" ntfy.ki5bhv.com/server'
when: reboot_required.stat.exists
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Reboot machine - name: Reboot machine
hosts: "{{ my_hosts | d([]) }}" hosts: ["mqtt-server.ki5bhv.com", "git-server.ki5bhv.com", "webhost.ki5bhv.com", "clouflare.ki5bhv.com", "coding.ki5bhv.com",pi-hole-server.ki5bhv.com, "killer2.ki5bhv.com"]
become: true become: true
tasks: tasks:
+38
View File
@@ -0,0 +1,38 @@
---
# open-all-ports.yml
#
# Opens all inbound ports on the target Ubuntu servers.
#
# Default behavior: UFW stays enabled but its default incoming
# policy is set to allow, so every port is reachable.
#
# To turn the firewall OFF entirely instead, run with:
# ansible-playbook -i inventory.ini open-all-ports.yml -e "disable_ufw=true"
#
# Uses the community.general.ufw module.
#
# Usage:
# ansible-playbook -i inventory.ini open-all-ports.yml
- name: Open all inbound ports
hosts: ubuntu_servers
become: true
vars:
disable_ufw: false
tasks:
- name: Set default incoming policy to allow (opens all ports)
community.general.ufw:
direction: incoming
policy: allow
- name: Set default outgoing policy to allow
community.general.ufw:
direction: outgoing
policy: allow
- name: Optionally disable UFW entirely
community.general.ufw:
state: disabled
when: disable_ufw | bool
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Update Plex Sever - name: Update Plex Sever
hosts: media.ki5bhv.com hosts: mediaserver.ki5bhv.com
become: yes become: yes
tasks: tasks:
+17
View File
@@ -0,0 +1,17 @@
---
- name: Rebooting Machines Proxmox
hosts: proxmox
become: true
tasks:
- name: Checking Reboot is needed
become: true
ansible.builtin.stat:
path: /run/reboot-required
register: reboot_required
- name: Reboot Machine
become: true
ansible.builtin.reboot:
reboot_timeout: 3600
when: reboot_required.stat.exists
+60
View File
@@ -0,0 +1,60 @@
---
# restrict-ssh.yml
#
# Restricts SSH access on Ubuntu servers to a single IP range using UFW.
# Uses the community.general.ufw module.
#
# Usage:
# ansible-playbook -i inventory.ini restrict-ssh.yml
#
# Override the range or port at runtime:
# ansible-playbook -i inventory.ini restrict-ssh.yml -e "ssh_allowed_range=10.0.0.0/24 ssh_port=2222"
- name: Restrict SSH access to an allowed IP range
hosts: ubuntu_servers
become: true
vars:
ssh_allowed_range: "192.168.1.0/24"
ssh_port: 22
tasks:
- name: Ensure UFW is installed
ansible.builtin.apt:
name: ufw
state: present
update_cache: true
- name: Set default policy to deny incoming traffic
community.general.ufw:
direction: incoming
policy: deny
- name: Set default policy to allow outgoing traffic
community.general.ufw:
direction: outgoing
policy: allow
- name: Allow SSH only from the permitted range
community.general.ufw:
rule: allow
from_ip: "{{ ssh_allowed_range }}"
to_port: "{{ ssh_port }}"
proto: tcp
- name: Remove any rule allowing SSH from anywhere (by port)
community.general.ufw:
rule: allow
to_port: "{{ ssh_port }}"
proto: tcp
delete: true
- name: Remove any rule allowing the OpenSSH application profile from anywhere
community.general.ufw:
rule: allow
name: OpenSSH
delete: true
- name: Enable UFW
community.general.ufw:
state: enabled
+47
View File
@@ -0,0 +1,47 @@
---
# revert-ssh.yml
#
# Reverts the SSH IP-range restriction applied by restrict-ssh.yml.
# Removes the range-limited SSH rule and re-opens SSH from anywhere so
# you don't lose access. Optionally disables UFW entirely.
#
# Uses the community.general.ufw module.
#
# Usage:
# ansible-playbook -i inventory.ini revert-ssh.yml
#
# To also disable UFW completely:
# ansible-playbook -i inventory.ini revert-ssh.yml -e "disable_ufw=true"
#
# Override the range or port to match what restrict-ssh.yml used:
# ansible-playbook -i inventory.ini revert-ssh.yml -e "ssh_allowed_range=10.0.0.0/24 ssh_port=2222"
- name: Revert SSH IP-range restriction
hosts: ubuntu_servers
become: true
vars:
ssh_allowed_range: "192.168.1.0/24"
ssh_port: 22
disable_ufw: false
tasks:
- name: Remove the range-restricted SSH rule
community.general.ufw:
rule: allow
from_ip: "{{ ssh_allowed_range }}"
to_port: "{{ ssh_port }}"
proto: tcp
delete: true
- name: Re-open SSH from anywhere
community.general.ufw:
rule: allow
to_port: "{{ ssh_port }}"
proto: tcp
when: not disable_ufw | bool
- name: Disable UFW entirely (optional)
community.general.ufw:
state: disabled
when: disable_ufw | bool
+233
View File
@@ -0,0 +1,233 @@
---
# ssh-hardening.yml
# =============================================================================
# Disable SSH password authentication and apply baseline hardening on Ubuntu.
#
# Usage:
# ansible-playbook -i inventory.ini ssh-hardening.yml
# ansible-playbook -i inventory.ini ssh-hardening.yml --limit coding
# ansible-playbook -i inventory.ini ssh-hardening.yml --check # dry run
#
# Example inventory.ini:
# [servers]
# coding ansible_host=192.168.1.21 ansible_user=justin
#
# SAFETY FEATURES:
# * Refuses to run if the login user has no authorized_keys (no lockout).
# * Fixes the cloud-init "first value wins" precedence trap automatically.
# * Validates config with `sshd -t` BEFORE restarting.
# * Verifies password auth is actually off at the end via `sshd -T`.
#
# Optional extras (fail2ban / UFW) use the community.general collection:
# ansible-galaxy collection install community.general
# =============================================================================
- name: Harden SSH (key-only authentication + baseline)
hosts: all
become: true
vars:
# User whose key access is verified before passwords are disabled.
# Defaults to whoever Ansible connects as.
ssh_login_user: "{{ ansible_user | default(lookup('env', 'USER')) }}"
# ---- Core SSH settings -------------------------------------------------
ssh_permit_root_login: "prohibit-password" # "no" to block root entirely
ssh_allow_users: [] # e.g. ["justin", "deploy"]; [] = no restriction
ssh_port: 22 # change to move SSH off 22
# ---- Optional hardening toggles ---------------------------------------
manage_firewall: false # true = install + enable UFW
install_fail2ban: false
install_unattended_upgrades: false
handlers:
# Handlers run in the order defined here, so validation always precedes restart.
- name: Validate sshd config
ansible.builtin.command: sshd -t
changed_when: false
listen: "restart ssh stack"
- name: Restart ssh
ansible.builtin.systemd:
name: ssh
state: restarted
listen: "restart ssh stack"
- name: Restart ssh.socket
ansible.builtin.systemd:
name: ssh.socket
state: restarted
when: ssh_socket_present | default(false) | bool
listen: "restart ssh stack"
tasks:
# ---- Pre-flight: prove we won't lock ourselves out --------------------
- name: Resolve login user's home directory
ansible.builtin.getent:
database: passwd
key: "{{ ssh_login_user }}"
- name: Set authorized_keys path
ansible.builtin.set_fact:
ssh_authorized_keys_path: "{{ getent_passwd[ssh_login_user][4] }}/.ssh/authorized_keys"
- name: Stat the login user's authorized_keys
ansible.builtin.stat:
path: "{{ ssh_authorized_keys_path }}"
register: ak
- name: Refuse to continue if no SSH key is present
ansible.builtin.assert:
that:
- ak.stat.exists
- (ak.stat.size | default(0) | int) > 0
fail_msg: >-
{{ ssh_login_user }} has no authorized_keys at {{ ssh_authorized_keys_path }}.
Aborting so you don't get locked out. Run `ssh-copy-id {{ ssh_login_user }}@<host>`
first, verify key login works, then re-run this playbook.
success_msg: "Key-based auth verified for {{ ssh_login_user }} - safe to proceed."
# ---- Detect socket activation (Ubuntu 22.10+ / 24.04 / 26.04) ---------
- name: Check whether ssh.socket exists
ansible.builtin.command: systemctl list-unit-files ssh.socket
register: ssh_socket_check
changed_when: false
failed_when: false
- name: Record socket-activation state
ansible.builtin.set_fact:
ssh_socket_present: "{{ 'ssh.socket' in ssh_socket_check.stdout }}"
# ---- Fix the cloud-init precedence trap -------------------------------
# sshd uses the FIRST value it sees for a directive. Files load in
# alphanumeric order, so 50-cloud-init.conf (PasswordAuthentication yes)
# beats a later 99-hardening.conf. Neutralize it at the source.
- name: Check for the cloud-init SSH drop-in
ansible.builtin.stat:
path: /etc/ssh/sshd_config.d/50-cloud-init.conf
register: cloud_init_conf
- name: Force PasswordAuthentication off in the cloud-init drop-in
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/50-cloud-init.conf
regexp: '^\s*PasswordAuthentication\s+'
line: "PasswordAuthentication no"
state: present
when: cloud_init_conf.stat.exists
notify: "restart ssh stack"
# ---- Authoritative hardening drop-in ----------------------------------
- name: Deploy SSH hardening drop-in
ansible.builtin.copy:
dest: /etc/ssh/sshd_config.d/99-hardening.conf
owner: root
group: root
mode: "0644"
validate: "sshd -t -f %s"
content: |
# Managed by Ansible - ssh-hardening.yml. Do not edit by hand.
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
PermitRootLogin {{ ssh_permit_root_login }}
{% if ssh_allow_users | length > 0 %}
AllowUsers {{ ssh_allow_users | join(' ') }}
{% endif %}
{% if ssh_port != 22 %}
Port {{ ssh_port }}
{% endif %}
notify: "restart ssh stack"
# ---- Stop cloud-init from re-enabling passwords on rebuild ------------
- name: Check for cloud-init config directory
ansible.builtin.stat:
path: /etc/cloud/cloud.cfg.d
register: cloud_init_dir
- name: Pin ssh_pwauth off for cloud-init
ansible.builtin.copy:
dest: /etc/cloud/cloud.cfg.d/99-disable-password-auth.cfg
owner: root
group: root
mode: "0644"
content: |
# Managed by Ansible - ssh-hardening.yml
ssh_pwauth: false
when: cloud_init_dir.stat.exists
# ---- Optional: UFW firewall -------------------------------------------
- name: Configure UFW firewall
when: manage_firewall | bool
block:
- name: Install UFW
ansible.builtin.apt:
name: ufw
state: present
update_cache: true
- name: Allow the SSH port through UFW
community.general.ufw:
rule: allow
port: "{{ ssh_port }}"
proto: tcp
- name: Enable UFW with a default-deny inbound policy
community.general.ufw:
state: enabled
policy: deny
direction: incoming
# ---- Optional: fail2ban -----------------------------------------------
- name: Install and enable fail2ban
when: install_fail2ban | bool
block:
- name: Install fail2ban
ansible.builtin.apt:
name: fail2ban
state: present
update_cache: true
- name: Enable and start fail2ban
ansible.builtin.systemd:
name: fail2ban
enabled: true
state: started
# ---- Optional: unattended security upgrades ---------------------------
- name: Enable unattended security upgrades
when: install_unattended_upgrades | bool
block:
- name: Install unattended-upgrades
ansible.builtin.apt:
name: unattended-upgrades
state: present
update_cache: true
- name: Turn on periodic update + upgrade
ansible.builtin.copy:
dest: /etc/apt/apt.conf.d/20auto-upgrades
owner: root
group: root
mode: "0644"
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
# ---- Apply restarts, then verify the result ---------------------------
- name: Apply any pending SSH restarts now
ansible.builtin.meta: flush_handlers
- name: Read the effective sshd configuration
ansible.builtin.command: sshd -T
register: sshd_effective
changed_when: false
- name: Confirm password authentication is actually disabled
ansible.builtin.assert:
that:
- "'passwordauthentication no' in sshd_effective.stdout"
fail_msg: >-
Password auth is STILL enabled in the effective config.
Check drop-in precedence with: sudo sshd -T | grep -i passwordauth
success_msg: "Confirmed: password authentication is disabled."
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
- name: Update cloud Flare Tunnel - name: Update cloud Flare Tunnel
hosts: cloudflare-tunnel.ki5bhv.com hosts: cloudflare.ki5bhv.com
tasks: tasks:
- name: Pull the newest package - name: Pull the newest package
+20 -34
View File
@@ -1,44 +1,36 @@
--- ---
- name: Send Start update
hosts: localhost
tasks:
- name: send ntfy
ansible.builtin.command:
cmd: 'curl -d "Starting updating with ansible" ntfy.ki5bhv.com/server'
- name: Proxmox Update and upgrade apt packages - name: Proxmox Update and upgrade apt packages
hosts: proxmox hosts: proxmox
become: yes become: yes
serial: 1
tasks: tasks:
- name: Update packages with apt - name: Update packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
update_cache: true update_cache: true
cache_valid_time: 3600
lock_timeout: 600
- name: Installing proxmox guest agent - name: Installing proxmox guest agent
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
name: qemu-guest-agent name: qemu-guest-agent
state: latest state: latest
- name: Enable proxmox agent - name: Enable and restart proxmox agent
ansible.builtin.command: ansible.builtin.service:
cmd: systemctl enable qemu-guest-agent name: qemu-guest-agent
state: restarted
- name: Restart proxmox agent
ansible.builtin.command:
cmd: systemctl restart qemu-guest-agent
- name: Upgrade packages with apt - name: Upgrade packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
upgrade: dist upgrade: dist
- name: Clean up packages with apt - name: Clean up packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
autoclean: true autoclean: true
autoremove: true autoremove: true
@@ -48,19 +40,21 @@
become: yes become: yes
tasks: tasks:
- name: Update packages with apt - name: Update packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
update_cache: true update_cache: true
cache_valid_time: 3600
lock_timeout: 600
- name: Upgrade packages with apt - name: Upgrade packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
upgrade: dist upgrade: dist
- name: Clean up packages with apt - name: Clean up packages with apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
autoclean: true autoclean: true
autoremove: true autoremove: true
@@ -68,19 +62,11 @@
- name: installing net-tools on all - name: installing net-tools on all
hosts: all hosts: all
become: yes become: yes
tasks: tasks:
- name: running apt - name: running apt
when: ansible_pkg_mgr == 'apt' when: ansible_facts['pkg_mgr'] == 'apt'
ansible.builtin.apt: ansible.builtin.apt:
name: net-tools name: net-tools
state: latest state: latest
- name: Send completed update
hosts: localhost
tasks:
- name: send ntfy
ansible.builtin.command:
cmd: 'curl -d "Updated with ansible" ntfy.ki5bhv.com/server'
-28
View File
@@ -1,28 +0,0 @@
---
- name: Update cloud Flare Tunnel
hosts: 192.168.1.119
tasks:
- name: Pull the newest package
ansible.builtin.command:
cmd: "curl --location --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb"
- name: installing package
become: true
ansible.builtin.command:
cmd: "dpkg -i cloudflared.deb"
- name: Restart the service
become: true
ansible.builtin.command:
cmd: "systemctl restart cloudflared.service"
- name: check before cleanup
ansible.builtin.stat:
path: cloudflared.deb
register: cloudflaredfile
- name: Cleanup
when: cloudflaredfile.stat.exists
ansible.builtin.command:
cmd: "rm cloudflared.deb"
-86
View File
@@ -1,86 +0,0 @@
---
- name: Send Start update
hosts: localhost
tasks:
- name: send ntfy
ansible.builtin.command:
cmd: 'curl -d "Starting updating with ansible" ntfy.ki5bhv.com/server'
- name: Proxmox Update and upgrade apt packages
hosts: proxmox
become: yes
tasks:
- name: Update packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
update_cache: true
- name: Installing proxmox guest agent
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
name: qemu-guest-agent
state: latest
- name: Enable proxmox agent
ansible.builtin.command:
cmd: systemctl enable qemu-guest-agent
- name: Restart proxmox agent
ansible.builtin.command:
cmd: systemctl restart qemu-guest-agent
- name: Upgrade packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
upgrade: dist
- name: Clean up packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
autoclean: true
autoremove: true
- name: Hardware Update and upgrade apt packages
hosts: hardware
become: yes
tasks:
- name: Update packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
update_cache: true
- name: Upgrade packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
upgrade: dist
- name: Clean up packages with apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
autoclean: true
autoremove: true
- name: installing net-tools on all
hosts: all
become: yes
tasks:
- name: running apt
when: ansible_pkg_mgr == 'apt'
ansible.builtin.apt:
name: net-tools
state: latest
- name: Send completed update
hosts: localhost
tasks:
- name: send ntfy
ansible.builtin.command:
cmd: 'curl -d "Updated with ansible" ntfy.ki5bhv.com/server'
+9
View File
@@ -0,0 +1,9 @@
---
# This playbook uses the win_ping module to test connectivity to Windows hosts
- name: Ping
hosts: all
tasks:
- name: ping
win_ping: