refactor: restructured project for higher-utility naming practices and optimized data structures for variables
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
collections:
|
||||
- name: community.general
|
||||
version: "11.2.1"
|
||||
source: "https://galaxy.ansible.com"
|
||||
@@ -1,3 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for bootstrap
|
||||
@@ -1,8 +0,0 @@
|
||||
Match Group ftp
|
||||
ForceCommand internal-sftp -u 003 -d /%u
|
||||
AuthorizedKeysFile /srv/.ftp/authorized_keys
|
||||
ChrootDirectory /srv/ftp
|
||||
PasswordAuthentication no
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
@@ -1,38 +0,0 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -1,16 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for lockdown
|
||||
files_mode: no
|
||||
create_users:
|
||||
- username: "{{ hostvars[inventory_hostname]['passwords'][0].username }}"
|
||||
password: "{{ hostvars[inventory_hostname]['passwords'][0].password }}"
|
||||
ssh_pubkey_filename_pattern: '.*\.pub'
|
||||
include_root_lock: yes
|
||||
gpg_private_keys_origin_host: localhost
|
||||
ssh_keypairs_origin_host: localhost
|
||||
gpg_origin_private_keyids: [] # @NOTE list of gpg key ids from origin or source server
|
||||
gpg_origin_private_key_passwords: "{{ vaulted_gpg_origin_private_key_passwords }}" # @NOTE list of gpg key passwords from origin or source server
|
||||
ssh_origin_keypairs_filenames: [] # @NOTE list of basenames (filename sans extension) of SSH keypairs
|
||||
git_config_name: ~ # @NOTE: has equivalent field under lockdown role vars example YAML file, but different value
|
||||
git_config_email: ~ # @NOTE: has equivalent field under lockdown role vars example YAML file, but different value
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
# ssh aliases
|
||||
alias ssh_send="scp -C"
|
||||
# @NOTE consider adding aliases for scp source or destination hosts
|
||||
|
||||
# flatpak aliases
|
||||
alias clone="rsync -pogAXtlHrDx --stats --info=progress2"
|
||||
alias flatshell="flatpak run --user --command=sh"
|
||||
alias codium="flatpak run --user com.vscodium.codium"
|
||||
|
||||
# podman aliases
|
||||
alias docker="podman"
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
# podman bash function
|
||||
conman () {
|
||||
if command -v podman &> /dev/null; then
|
||||
CONTAINER_MANAGER="podman"
|
||||
elif command -v docker &> /dev/null; then
|
||||
CONTAINER_MANAGER="docker"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$CONTAINER_MANAGER
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
Host local
|
||||
HostName localhost
|
||||
Port 22
|
||||
# IdentitiesOnly yes
|
||||
# IdentityFile ~/.ssh/*.ppk
|
||||
# AddKeysToAgent yes
|
||||
|
||||
Host local.me
|
||||
HostName localhost
|
||||
Port 22
|
||||
# User admin
|
||||
# IdentitiesOnly yes
|
||||
# IdentityFile ~/.ssh/*.ppk
|
||||
# AddKeysToAgent yes
|
||||
|
||||
Host *.local.local
|
||||
HostName localhost
|
||||
# IdentitiesOnly yes
|
||||
# IdentityFile ~/.ssh/*.ppk
|
||||
# AddKeysToAgent yes
|
||||
|
||||
Host ip4.local.local
|
||||
# HostName 127.0.0.1
|
||||
Port 22
|
||||
AddressFamily inet
|
||||
|
||||
Host ip6.local.local
|
||||
# HostName ::1
|
||||
Port 22
|
||||
AddressFamily inet6
|
||||
@@ -1,2 +0,0 @@
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
@@ -1 +0,0 @@
|
||||
PermitRootLogin no
|
||||
@@ -1,15 +0,0 @@
|
||||
# This file is written by xdg-user-dirs-update
|
||||
# If you want to change or add directories, just edit the line you're
|
||||
# interested in. All local changes will be retained on the next run.
|
||||
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
|
||||
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
|
||||
# absolute path. No other format is supported.
|
||||
#
|
||||
XDG_DESKTOP_DIR="$HOME/Desktop"
|
||||
XDG_DOWNLOAD_DIR="$HOME/Downloads"
|
||||
XDG_TEMPLATES_DIR="$HOME/Templates"
|
||||
XDG_PUBLICSHARE_DIR="$HOME/Public"
|
||||
XDG_DOCUMENTS_DIR="$HOME/Documents"
|
||||
XDG_MUSIC_DIR="$HOME/Music"
|
||||
XDG_PICTURES_DIR="$HOME/Pictures"
|
||||
XDG_VIDEOS_DIR="$HOME/Videos"
|
||||
@@ -1,13 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for lockdown
|
||||
- name: Restart SSH server
|
||||
when: ansible_facts["user_id"] == "root"
|
||||
ansible.builtin.service:
|
||||
name: ssh
|
||||
state: restarted
|
||||
tags:
|
||||
- default
|
||||
- finalize
|
||||
register: restarted_ssh
|
||||
listen: "restart ssh"
|
||||
@@ -1,35 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
@@ -1,12 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for lockdown
|
||||
- name: Disable shell for root user
|
||||
when: ansible_facts["user_id"] != "root"
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: root
|
||||
shell: /sbin/nologin
|
||||
tags:
|
||||
- deshell_root
|
||||
register: root_shell_disabled
|
||||
@@ -1,128 +0,0 @@
|
||||
# 'preferred_signing_key' -> 'gpg_preferred_signing'
|
||||
# 'gpg_or_ssh_git_signing' -> 'git_signing_key_type'
|
||||
- name: Install git package
|
||||
ansible.builtin.package:
|
||||
name: git
|
||||
state: latest
|
||||
- name: Configure git name and email
|
||||
block:
|
||||
- name: Configure git name
|
||||
community.general.git_config:
|
||||
name: user.name
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ git_config_name }}"
|
||||
- name: Configure git email
|
||||
community.general.git_config:
|
||||
name: user.email
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ git_config_email }}"
|
||||
- name: Configure git signing GPG key
|
||||
when: git_signing_key_type == "gpg"
|
||||
block:
|
||||
- name: Configure specified git signing GPG key
|
||||
when: preferred_signing_key > -1
|
||||
community.general.git_config:
|
||||
name: user.signingkey
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ gpg_origin_private_keyids[preferred_signing_key] }}"
|
||||
register: selected_signing_key
|
||||
- name: Configure random git signing GPG key
|
||||
when: preferred_signing_key <= -1
|
||||
community.general.git_config:
|
||||
name: user.signingkey
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ gpg_origin_private_keyids | random }}"
|
||||
register: selected_signing_key
|
||||
- name: Configure git signing SSH key
|
||||
when: git_signing_key_type == "ssh"
|
||||
block:
|
||||
- name: Acquire SSH key-pairs from other system
|
||||
when: not files_mode
|
||||
block:
|
||||
- name: Acquire private SSH keys from other system
|
||||
delegate_to: "{{ ssh_keypairs_origin_host }}"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cat
|
||||
- "~/.ssh/{{ item }}.ppk"
|
||||
loop: "{{ ssh_origin_keypairs_filenames }}"
|
||||
register: ssh_secrets
|
||||
- name: Find SSH public keys in other system
|
||||
delegate_to: "{{ ssh_keypairs_origin_host }}"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cat
|
||||
- "~/.ssh/{{ item }}.pub"
|
||||
loop: "{{ ssh_origin_keypairs_filenames }}"
|
||||
register: ssh_nonsecrets
|
||||
- name: Create private SSH keys
|
||||
ansible.builtin.copy:
|
||||
content: "{{ item }}"
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.ssh/{{ ssh_origin_keypairs_filenames[idx] }}.ppk"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0600"
|
||||
state: present
|
||||
loop: "{{ ssh_secrets.results }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_ssh_private_keys
|
||||
- name: Create public SSH keys
|
||||
ansible.builtin.copy:
|
||||
content: "{{ item }}"
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.ssh/{{ ssh_origin_keypairs_filenames[idx] }}.pub"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0644"
|
||||
state: present
|
||||
loop: "{{ ssh_nonsecrets.results }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_ssh_public_keys
|
||||
- name: Acquire SSH key-pairs
|
||||
when: files_mode
|
||||
block:
|
||||
- name: Transfer private SSH keys
|
||||
ansible.builtin.copy:
|
||||
src: ssh/{{ ansible_facts['user_id'] }}/{{ item }}.ppk
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.ssh/{{ item }}.ppk"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0600"
|
||||
state: present
|
||||
loop: "{{ ssh_origin_keypairs_filenames }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_ssh_private_keys
|
||||
- name: Transfer public SSH keys
|
||||
ansible.builtin.copy:
|
||||
src: ssh/{{ ansible_facts['user_id'] }}/{{ item }}.pub
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.ssh/{{ item }}.pub"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0644"
|
||||
state: present
|
||||
loop: "{{ ssh_origin_keypairs_filenames }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_ssh_public_keys
|
||||
- name: Configure acquired, specified SSH public key as git signing key
|
||||
when: preferred_signing_key > -1
|
||||
community.general.git_config:
|
||||
name: user.signingkey
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ created_ssh_public_keys.results[preferred_signing_key] }}"
|
||||
register: selected_signing_key
|
||||
- name: Configure acquired, random SSH public key as git signing key
|
||||
when: preferred_signing_key <= -1
|
||||
community.general.git_config:
|
||||
name: user.signingkey
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ created_ssh_public_keys.results | random }}"
|
||||
register: selected_signing_key
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
- name: Acquire GPG private keys from other system
|
||||
when: not files_mode
|
||||
block:
|
||||
- name: Acquire GPG private keys' contents from other system
|
||||
delegate_to: "{{ gpg_private_keys_origin_host }}"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- gpg
|
||||
- -a
|
||||
- --export-secret-key
|
||||
- "{{ item }}"
|
||||
loop: "{{ gpg_origin_private_keyids }}"
|
||||
register: gpg_secrets
|
||||
- name: Create GPG private keys using acquired GPG private keys' contents
|
||||
ansible.builtin.copy:
|
||||
content: "{{ item }}"
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.gnupg/{{ gpg_origin_private_keyids[idx] }}.priv.asc"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0600"
|
||||
state: present
|
||||
loop: "{{ gpg_secrets.results }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_gpg_private_keys
|
||||
- name: Acquire GPG private keys
|
||||
when: files_mode
|
||||
ansible.builtin.copy:
|
||||
src: gnupg/{{ ansible_facts['user_id'] }}/{{ item }}.asc
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.gnupg/{{ item }}.priv.asc"
|
||||
force: yes
|
||||
backup: yes
|
||||
mode: "0600"
|
||||
state: present
|
||||
loop: "{{ gpg_origin_private_keyids }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
register: created_gpg_private_keys
|
||||
- name: Import GPG private keys
|
||||
when: (gpg_origin_private_key_passwords | length) == (gpg_origin_private_keyids | length)
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- gpg
|
||||
- --batch
|
||||
- --import
|
||||
- --yes
|
||||
- --passphrase-fd
|
||||
- 0
|
||||
- "{{ item.dest }}"
|
||||
stdin: "{{ gpg_origin_private_key_passwords[idx] }}"
|
||||
loop: "{{ created_gpg_private_keys.results }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
@@ -1,172 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for lockdown
|
||||
# @NOTE: assumes one logged in to SSH server as root to begin with, hence no need for privilege escalation
|
||||
- name: Create users
|
||||
when: ansible_facts["user_id"] == "root"
|
||||
block:
|
||||
- name: Create sys-admin user
|
||||
ansible.builtin.user:
|
||||
name: "{{ create_users[0].username }}"
|
||||
uid: 1000
|
||||
password: "{{ create_users[0].password }}"
|
||||
append: yes
|
||||
groups:
|
||||
- sudo
|
||||
shell: /bin/bash
|
||||
generate_ssh_key: yes
|
||||
password_expire_min: 93
|
||||
password_expire_max: 186
|
||||
password_expire_warn: 45
|
||||
comment: sysadmin
|
||||
# ssh_key_passphrase: "{{ item.password }}"
|
||||
state: present
|
||||
tags:
|
||||
- default
|
||||
- administrative_user
|
||||
register: created_admin
|
||||
- name: Create new user
|
||||
ansible.builtin.user:
|
||||
name: "{{ item.username }}"
|
||||
uid: 1000
|
||||
password: "{{ item.password }}"
|
||||
append: yes
|
||||
shell: /bin/bash
|
||||
generate_ssh_key: yes
|
||||
password_expire_min: 93
|
||||
password_expire_max: 186
|
||||
password_expire_warn: 45
|
||||
comment: administrator
|
||||
# ssh_key_passphrase: "{{ item.password }}"
|
||||
state: present
|
||||
loop: "{{ create_users[1:] }}"
|
||||
tags:
|
||||
- other_users
|
||||
register: created_users
|
||||
- name: Specify authorized SSH keys for users based on local public keys
|
||||
when: not files_mode and ansible_facts["user_id"] == "root"
|
||||
block:
|
||||
- name: Acquire list of SSH public keys for sys-admin user
|
||||
delegate_to: "{{ ssh_keypairs_origin_host }}"
|
||||
ansible.builtin.find:
|
||||
paths: "{{ lookup('env', 'HOME') }}/.ssh"
|
||||
patterns:
|
||||
- '{{ ssh_pubkey_filename_pattern }}'
|
||||
use_regex: yes
|
||||
recurse: no
|
||||
tags:
|
||||
- default
|
||||
- administrative_user
|
||||
- admin_ssh
|
||||
register: ssh_public_keys
|
||||
- name: Acquire contents of SSH public keys for sys-admin user
|
||||
delegate_to: "{{ ssh_keypairs_origin_host }}"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cat
|
||||
- "{{ item.path }}"
|
||||
loop: "{{ ssh_public_keys.files }}"
|
||||
register: ssh_public_keys_contents
|
||||
- name: Register SSH public keys as sys-admin user's authorized keys
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ created_admin.home }}/.ssh/authorized_keys"
|
||||
line: "{{ item }}"
|
||||
owner: "{{ created_admin.name }}"
|
||||
group: "{{ created_admin.name }}"
|
||||
mode: "0600"
|
||||
create: yes
|
||||
insertafter: EOF
|
||||
state: present
|
||||
tags:
|
||||
- default
|
||||
- administrative_user
|
||||
- admin_ssh
|
||||
loop: "{{ ssh_public_keys_contents.results }}"
|
||||
- name: Register SSH public keys as other users' authorized keys
|
||||
ansible.builtin.copy:
|
||||
src: "ssh/{{ item.name }}/authorized_keys"
|
||||
dest: "{{ item.home }}/.ssh/authorized_keys"
|
||||
force: yes
|
||||
backup: yes
|
||||
owner: "{{ item.name }}"
|
||||
group: "{{ item.name }}"
|
||||
mode: "0600"
|
||||
state: present
|
||||
tags:
|
||||
- other_users
|
||||
- others_ssh
|
||||
loop: "{{ created_users.results }}"
|
||||
register: authorized_ssh_pubkeys
|
||||
- name: Specify authorized SSH keys for users
|
||||
when: files_mode and ansible_facts["user_id"] == "root"
|
||||
block:
|
||||
- name: Specify authorized keys file for sys-admin user
|
||||
ansible.builtin.copy:
|
||||
src: ssh/authorized_keys
|
||||
dest: "{{ created_admin.home }}/.ssh/authorized_keys"
|
||||
force: yes
|
||||
backup: yes
|
||||
owner: "{{ created_admin.name }}"
|
||||
group: "{{ created_admin.name }}"
|
||||
mode: "0600"
|
||||
state: present
|
||||
tags:
|
||||
- default
|
||||
- administrative_user
|
||||
- admin_ssh
|
||||
register: authorized_admin_ssh_pubkeys
|
||||
- name: Specify authorized keys file for other users
|
||||
ansible.builtin.copy:
|
||||
src: "ssh/{{ item.name }}/authorized_keys"
|
||||
dest: "{{ item.home }}/.ssh/authorized_keys"
|
||||
force: yes
|
||||
backup: yes
|
||||
owner: "{{ item.name }}"
|
||||
group: "{{ item.name }}"
|
||||
mode: "0600"
|
||||
tags:
|
||||
- other_users
|
||||
- others_ssh
|
||||
loop: "{{ created_users.results }}"
|
||||
register: authorized_ssh_pubkeys
|
||||
- name: Lock down root SSH access
|
||||
when: ansible_facts["user_id"] == "root"
|
||||
block:
|
||||
- name: Constrain SSH authentication methods to using SSH key
|
||||
ansible.builtin.copy:
|
||||
src: sshd_config.d/auth.conf
|
||||
dest: /etc/ssh/sshd_config.d/auth.conf
|
||||
force: yes
|
||||
backup: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
state: present
|
||||
tags:
|
||||
- depass_root
|
||||
register: constrained_auth
|
||||
- name: Prohibit access to root via SSH
|
||||
ansible.builtin.copy:
|
||||
src: sshd_config.d/denyroot.conf
|
||||
dest: /etc/ssh/sshd_config.d/denyroot.conf
|
||||
force: yes
|
||||
backup: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
state: present
|
||||
tags:
|
||||
- prohib_root_ssh
|
||||
register: prohibited_root_ssh_login
|
||||
- name: Lock the root account
|
||||
when: include_root_lock
|
||||
ansible.builtin.user:
|
||||
name: root
|
||||
password_lock: yes
|
||||
tags:
|
||||
- delog_root
|
||||
register: prohibited_root_login
|
||||
tags:
|
||||
- default
|
||||
- deroot
|
||||
notify: "restart ssh"
|
||||
@@ -1,3 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
localhost
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- lockdown
|
||||
Reference in New Issue
Block a user