decided to start over
This commit is contained in:
@@ -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,3 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# defaults file for bootstrap
|
||||
@@ -1,16 +0,0 @@
|
||||
# fail2ban filter for the ProFTPD FTP daemon
|
||||
[INCLUDES]
|
||||
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
|
||||
_daemon = proftpd
|
||||
|
||||
failregex = \(\S+\[<HOST>\]\)[: -]+ USER \S+: no such user found from \S+ \[[0-9.]+\] to \S+:\S+\s*$
|
||||
\(\S+\[<HOST>\]\)[: -]+ USER \S+ \(Login failed\):.*\s+$
|
||||
\(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \([0-9]+\) exceeded, connection refused.*\s+$
|
||||
\(\S+\[<HOST>\]\)[: -]+ SECURITY VIOLATION: \S+ login attempted\.\s+$
|
||||
\(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \(\d+\) exceeded\s+$
|
||||
|
||||
ignoreregex =
|
||||
@@ -1,7 +0,0 @@
|
||||
[proftpd]
|
||||
|
||||
enabled = true
|
||||
port = 990
|
||||
filter = custom_proftpd
|
||||
logpath = /var/log/proftpd.log
|
||||
maxretry = 6
|
||||
@@ -1,35 +0,0 @@
|
||||
[sshd]
|
||||
|
||||
# ==========================
|
||||
# SSH Jail Configuration
|
||||
# ==========================
|
||||
|
||||
# Enable the SSH jail to monitor and protect against brute-force attacks.
|
||||
enabled = true
|
||||
|
||||
# Port Fail2Ban should monitor for SSH connections.
|
||||
# If you run SSH on a custom port, replace 'ssh' with the actual port number (e.g., 2222).
|
||||
port = ssh
|
||||
|
||||
# Filter definition to use.
|
||||
# 'sshd' refers to the default filter that matches common SSH authentication failures.
|
||||
filter = sshd
|
||||
|
||||
# Log file location.
|
||||
# '%(sshd_log)s' uses the default value set by the system, typically /var/log/auth.log or journalctl.
|
||||
logpath = %(sshd_log)s
|
||||
|
||||
# Backend for reading logs.
|
||||
# 'systemd' is recommended if your system uses journalctl for logging.
|
||||
backend = systemd
|
||||
|
||||
# ==========================
|
||||
# SSH-Specific Overrides
|
||||
# ==========================
|
||||
|
||||
# Time window to evaluate failed login attempts.
|
||||
# If 'maxretry' failures occur within this time, the IP will be banned.
|
||||
findtime = 5m
|
||||
|
||||
# Number of failed attempts allowed before triggering a ban.
|
||||
maxretry = 4
|
||||
@@ -1,9 +0,0 @@
|
||||
# @NOTE possible commit types: https://github.com/qoomon/git-conventional-commits?tab=readme-ov-file#config-file
|
||||
# @NOTE for description or body consider: motivation for or cause of change, impact and domain of change
|
||||
<type>[optional scope]: <description{<50char}>
|
||||
|
||||
[optional body]
|
||||
|
||||
# @NOTE footer should almost be treated as metadata of/for commit, or alerts of significant impact
|
||||
# @NOTE for footer purpose, see: https://dev.to/mochafreddo/a-comprehensive-guide-to-using-footers-in-conventional-commit-messages-37g6
|
||||
[optional footer(s)]
|
||||
@@ -1,18 +0,0 @@
|
||||
Match Group ftp
|
||||
ForceCommand internal-sftp -d /%u
|
||||
ChrootDirectory /srv/ftp
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
|
||||
Match User ftp
|
||||
ForceCommand internal-sftp -d /public
|
||||
AuthorizedKeysFile /srv/ftp/.ssh/authorized_keys
|
||||
|
||||
Match User caddy,www-data
|
||||
ForceCommand internal-sftp -d /domain1.tld
|
||||
AuthorizedKeysFile /srv/www/.ssh/authorized_keys
|
||||
ChrootDirectory /srv/www
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
@@ -1,49 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Configure Aria2
|
||||
listen: aria
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users.keys()
|
||||
block:
|
||||
- name: Create Aria2 user configuration directory
|
||||
block:
|
||||
- name: Create configuration directory
|
||||
ansible.builtin.file:
|
||||
force: false
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
path: "{{ ansible_facts['user_dir'] }}/.config"
|
||||
state: directory
|
||||
- name: Create configuration directory
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users.keys()
|
||||
ansible.builtin.file:
|
||||
force: false
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
path: "{{ ansible_facts['user_dir'] }}/.config/aria2"
|
||||
state: directory
|
||||
- name: Create Aria2 configuration
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.config/aria2/aria2.conf"
|
||||
force: true
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
src: aria2/aria2.conf.j2
|
||||
# validate: string
|
||||
- name: Create Aria2 SystemD user unit service
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.config/systemd/user/aria2cd.service"
|
||||
force: true
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
src: systemd/user/aria2cd.service.j2
|
||||
# validate: string
|
||||
- name: Start Aria2 SystemD user unit service
|
||||
ansible.builtin.systemd_service:
|
||||
daemon_reload: true
|
||||
enabled: true
|
||||
name: aria2cd
|
||||
scope: user
|
||||
state: started
|
||||
@@ -1,314 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Configure git
|
||||
listen: git
|
||||
block:
|
||||
# @NOTE below are system git configuration
|
||||
- name: Configure git aliases
|
||||
become: true
|
||||
block:
|
||||
- name: Configure non-coding alias for merge subcommand
|
||||
community.general.git_config:
|
||||
name: alias.assimilate
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: merge
|
||||
- name: Configure alias for merge subcommand
|
||||
community.general.git_config:
|
||||
name: alias.mrg
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: merge
|
||||
- name: Configure non-coding alias for add subcommand
|
||||
community.general.git_config:
|
||||
name: alias.approve
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: add
|
||||
- name: Configure non-coding alias for status subcommand
|
||||
community.general.git_config:
|
||||
name: alias.revisions
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: status
|
||||
- name: Configure alias for status subcommand
|
||||
community.general.git_config:
|
||||
name: alias.stat
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: status
|
||||
- name: Configure non-coding alias for commit subcommand
|
||||
community.general.git_config:
|
||||
name: alias.finalize
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: commit
|
||||
- name: Configure alias for commit subcommand
|
||||
community.general.git_config:
|
||||
name: alias.cit
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: commit
|
||||
- name: Configure alias for config subcommand
|
||||
community.general.git_config:
|
||||
name: alias.cfg
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: config
|
||||
- name: Configure non-coding alias for commit subcommand with signing flag
|
||||
community.general.git_config:
|
||||
name: alias.claim
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: commit -S
|
||||
- name: Configure alias for commit subcommand with signing flag
|
||||
community.general.git_config:
|
||||
name: alias.sig
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: commit -S
|
||||
- name: Configure non-coding alias for show subcommand
|
||||
community.general.git_config:
|
||||
name: alias.review
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: show
|
||||
- name: Configure alias for show subcommand
|
||||
community.general.git_config:
|
||||
name: alias.peek
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: show
|
||||
- name: Configure alias for add subcommand with universal staging flag
|
||||
community.general.git_config:
|
||||
name: alias.badd
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: add -A
|
||||
- name: Configure non-coding alias for add subcommand with universal staging flag
|
||||
community.general.git_config:
|
||||
name: alias.approve-all
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: add -A
|
||||
- name: Configure non-coding alias for rm subcommand
|
||||
community.general.git_config:
|
||||
name: alias.redact
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: rm
|
||||
- name: Configure non-coding alias for init subcommand
|
||||
community.general.git_config:
|
||||
name: alias.author
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: init
|
||||
- name: Configure non-coding alias for mv subcommand
|
||||
community.general.git_config:
|
||||
name: alias.revise
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: mv
|
||||
- name: Configure non-coding alias for rebase subcommand
|
||||
community.general.git_config:
|
||||
name: alias.retroact
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: rebase
|
||||
- name: Configure alias for rebase subcommand
|
||||
community.general.git_config:
|
||||
name: alias.rb
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: rebase
|
||||
- name: Configure non-coding alias for push subcommand
|
||||
community.general.git_config:
|
||||
name: alias.publish
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: push
|
||||
- name: Configure non-coding alias for pull subcommand
|
||||
community.general.git_config:
|
||||
name: alias.publication
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: pull
|
||||
- name: Configure non-coding alias for fetch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.manuscript
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: fetch
|
||||
- name: Configure alias for fetch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.get
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: fetch
|
||||
- name: Configure non-coding alias for clone subcommand
|
||||
community.general.git_config:
|
||||
name: alias.copy
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: clone
|
||||
- name: Configure alias for clone subcommand
|
||||
community.general.git_config:
|
||||
name: alias.cp
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: clone
|
||||
- name: Configure non-coding alias for branch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.draft
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: branch
|
||||
- name: Configure alias for branch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.br
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: branch
|
||||
- name: Configure non-coding alias for switch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.edit
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: switch
|
||||
- name: Configure alias for switch subcommand
|
||||
community.general.git_config:
|
||||
name: alias.cd
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: switch
|
||||
- name: Configure non-coding alias for restore subcommand
|
||||
community.general.git_config:
|
||||
name: alias.revert
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: restore
|
||||
- name: Configure alias for restore subcommand
|
||||
community.general.git_config:
|
||||
name: alias.rs
|
||||
add_mode: replace-all
|
||||
state: present
|
||||
value: restore
|
||||
- name: Set default editor for git
|
||||
become: true
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: core.editor
|
||||
state: present
|
||||
value: "{{ config.git.sys.editor }}"
|
||||
- name: Create a directory for storing system-level templates for git
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
group: root
|
||||
owner: root
|
||||
path: /etc/gitconfig.d
|
||||
state: directory
|
||||
- name: Create a commit message template file for git
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
owner: root
|
||||
group: root
|
||||
backup: true
|
||||
dest: /etc/gitconfig.d/commit.msg
|
||||
force: true
|
||||
src: gitconfig.d/commit.msg
|
||||
- name: Set system-level commit message template file path for git
|
||||
become: true
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: commit.template
|
||||
state: present
|
||||
value: /etc/gitconfig.d/commit.msg
|
||||
- name: Set UI to have color for git at system-level
|
||||
become: true
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: color.ui
|
||||
state: present
|
||||
value: "true"
|
||||
- name: Set line-end conversion behavior for git
|
||||
become: true
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: core.autocrlf
|
||||
state: present
|
||||
value: input
|
||||
# @NOTE below are user git configuration
|
||||
- name: Create a user directory for a user gitignore file for git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
ansible.builtin.file:
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
path: "{{ ansible_facts['user_dir'] }}/.config/git"
|
||||
state: directory
|
||||
- name: Create a user gitignore file for git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
ansible.builtin.copy:
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
backup: true
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.config/git/gitignore"
|
||||
force: true
|
||||
src: gitconfig.d/exclude.rules
|
||||
- name: Set user gitignore file path for git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: core.excludesfile
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ ansible_facts['user_dir'] }}/.config/git/gitignore"
|
||||
- name: Create link from user config directory git config file to user home directory git config file
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
community.general.file:
|
||||
src: "{{ ansible_facts['user_dir'] }}/.gitconfig"
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.config/git/config"
|
||||
# @TODO check whether below two attributes make sense for links
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
state: hard
|
||||
- name: Set format for keys used by git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: gpg.format
|
||||
scope: global
|
||||
state: present
|
||||
value: openpgp
|
||||
- name: Set signing key to be used by git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users and hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys is not None and len(hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys) > 0
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: user.signingkey
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys[hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keyid_pref].id | default((hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys | random).id) }}"
|
||||
- name: Set name of user of git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: user.name
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].git_profile.name }}"
|
||||
- name: Set email of user of git
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: user.email
|
||||
scope: global
|
||||
state: present
|
||||
value: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].git_profile.email }}"
|
||||
- name: Set default initial branch name
|
||||
become: true
|
||||
community.general.git_config:
|
||||
add_mode: replace-all
|
||||
name: init.defaultBranch
|
||||
scope: system
|
||||
state: present
|
||||
value: main
|
||||
@@ -1,20 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
# @NOTE below for packages
|
||||
- name: Postinstall set-up of git
|
||||
ansible.builtin.import_tasks:
|
||||
file: git.yml
|
||||
- name: Postinstall set-up of ProFTPd
|
||||
ansible.builtin.import_tasks:
|
||||
file: proftpd.yml
|
||||
- name: Postinstall set-up of ProFTPd
|
||||
ansible.builtin.import_tasks:
|
||||
file: proftpd.yml
|
||||
# @NOTE below for snaps
|
||||
- name: Postinstall set-up of snapd
|
||||
ansible.builtin.import_tasks:
|
||||
file: snapd.yml
|
||||
- name: Postinstall set-up of Nextcloud snap
|
||||
ansible.builtin.import_tasks:
|
||||
file: nextcloud.yml
|
||||
@@ -1,105 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Configure Nextcloud snap
|
||||
become: true
|
||||
listen: nextcloud
|
||||
block:
|
||||
- name: Enable monitoring of network hardware
|
||||
ansible.builtin.command:
|
||||
cmd: "snap connect nextcloud:network-observe"
|
||||
- name: Begin manual installation
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.manual-install
|
||||
- "{{ config.nextcloud.users.admin.username }}"
|
||||
- "{{ config.nextcloud.users.admin.password }}"
|
||||
# @TODO see if setting below is necessary given use of reverse proxy
|
||||
- name: Set trusted domains
|
||||
block:
|
||||
- name: Set FQDN as trusted domain
|
||||
ansible.builtin.command:
|
||||
cmd: "/snap/bin//snap/bin/nextcloud.occ config:system:set trusted_domains 1 --value='cloud.{{ hostvars[inventory_hostname].fqdn }}'"
|
||||
# @TODO configure perhaps for trusted (reverse) proxy instead of above
|
||||
- name: Set trusted reverse proxy addresses
|
||||
block:
|
||||
- name: Set trusted reverse proxy IPv4 address based on hostname
|
||||
# @TODO create config.trusted_revproxy_ips data structure in bootstrap role's vars dir--may include loopback addresses
|
||||
when: config.trusted_revproxy_ips.ipv4 is None or len(config.trusted_revproxy_ips.ipv4) < 1
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- trusted_proxies 0
|
||||
- "--value=$(hostname -I | awk -F ' ' '{ print $1 }')"
|
||||
- name: Set trusted reverse proxy IPv4 address
|
||||
when: config.trusted_revproxy_ips.ipv4 is not None and len(config.trusted_revproxy_ips.ipv4) > 0
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- "trusted_proxies {{ idx }}"
|
||||
- "--value={{ item }}"
|
||||
loop: "{{ config.trusted_revproxy_ips.ipv4 }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
- name: Set trusted reverse proxy IPv6 address based on hostname
|
||||
when: config.trusted_revproxy_ips.ipv6 is None or len(config.trusted_revproxy_ips.ipv6) < 1
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- trusted_proxies 1
|
||||
- --value=$(hostname -I | awk -F ' ' '{ print $2 }')
|
||||
- name: Set trusted reverse proxy IPv6 address
|
||||
when: config.trusted_revproxy_ips.ipv6 is not None and len(config.trusted_revproxy_ips.ipv6) > 0
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- "trusted_proxies {{ idx }}"
|
||||
- "--value={{ item }}"
|
||||
loop: "{{ config.trusted_revproxy_ips.ipv6 }}"
|
||||
loop_control:
|
||||
index_var: idx
|
||||
# @TODO create task based on shell command `sudo /snap/bin/nextcloud.occ config:system:set default_phone_region --value="US"`
|
||||
- name: Set default phone region
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- default_phone_region
|
||||
- "--value={{ config.nextcloud.phone_region }}"
|
||||
# @TODO create task based on shell command:
|
||||
# `sudo /snap/bin/nextcloud.occ config:system:set overwrite.cli.url --value="https://cloud.{{ fqdn }}"` for Caddy task
|
||||
- name: Set overwrite CLI URL
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- overwrite.cli.url
|
||||
- "--value=cloud.{{ hostvars[inventory_hostname].fqdn }}"
|
||||
# @TODO create task based on shell command `sudo /snap/bin/nextcloud.occ config:system:set overwriteprotocol --value="https"` for Caddy task
|
||||
- name: Overwrite protocol
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- /snap/bin/nextcloud.occ
|
||||
- "config:system:set"
|
||||
- overwriteprotocol
|
||||
- --value="https"
|
||||
# @TODO create system-level bash alias for `/snap/bin/nextcloud.occ` command
|
||||
- name: Get Nextcloud snap binaries
|
||||
ansible.builtin.find:
|
||||
paths:
|
||||
- /snap/bin
|
||||
patterns:
|
||||
- nextcloud\..*
|
||||
recurse: false
|
||||
use_regex: true
|
||||
register: nextcloud_snap_binaries
|
||||
- name: Create symbolic links for Nextcloud snap binaries
|
||||
ansible.builtin.file:
|
||||
dest: "/usr/sbin/{{ item.path | basename }}"
|
||||
src: "{{ item.path }}"
|
||||
state: link
|
||||
loop: "{{ nextcloud_snap_binaries.files }}"
|
||||
@@ -1,157 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Configure ProFTPd server
|
||||
listen: proftpd
|
||||
become: true
|
||||
block:
|
||||
- name: Create ProFTPd non-web user subdirectories
|
||||
when: "'ftps' in item[0]['services'] and not 'caddy' in item[1]['services'] and not 'httpd' in item[1]['services'] and not 'www-data' in item[1]['services'] and not 'http' in item[1]['services'] and not 'https' in item[1]['services']"
|
||||
ansible.builtin.file:
|
||||
# follow: true
|
||||
force: true
|
||||
owner: "{{ item[0]['username'] }}"
|
||||
group: "{{ item[0]['group'] | default(item[0]['username']) }}"
|
||||
path: "{{ item[0]['home'] | default('/home/' ~ item[0]['username']) }}/{{ item[1]['username'] }}"
|
||||
state: directory
|
||||
loop: "{{ hostvars[inventory_hostname]['users'].values() | product(config['proftpd']['users'].values()) }}"
|
||||
- name: Create ProFTPd FTP public directory for anonymous logins
|
||||
when: "'ftps' in item.value['services']"
|
||||
ansible.builtin.file:
|
||||
# follow: true
|
||||
force: true
|
||||
owner: "{{ item.value['username'] }}"
|
||||
group: "{{ item.value['group'] | default(item.value['username']) }}"
|
||||
path: "{{ item.value['home'] | default('/home/' ~ item.value['username']) }}/public"
|
||||
state: directory
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname]['users']) }}"
|
||||
- name: Configure ProFTPd main control server
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/proftpd/proftpd.conf
|
||||
follow: true
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: proftpd/proftpd.conf.j2
|
||||
validate: proftpd --configtest
|
||||
vars:
|
||||
ftp_server_name: init
|
||||
max_conns: 30
|
||||
- name: Configure ProFTPd global settings
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/proftpd/conf.d/global.conf
|
||||
follow: true
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: proftpd/conf.d/global.conf.j2
|
||||
validate: proftpd --configtest
|
||||
vars:
|
||||
pasv_ports: "49152 65534"
|
||||
allow_symlinks: false
|
||||
- name: Add virtual users to ProFTPd
|
||||
block:
|
||||
- name: Create virtual user authentication files
|
||||
ansible.builtin.file:
|
||||
force: true
|
||||
group: root
|
||||
mode: "0640"
|
||||
owner: root
|
||||
path: "{{ item.value }}"
|
||||
state: touch
|
||||
loop: "{{ lookup('ansible.builtin.dict', config['proftpd']['auth_paths']) }}"
|
||||
- name: Create the virtual users
|
||||
when: "not 'caddy' in item.value['services'] and not 'httpd' in item.value['services'] and not 'www-data' in item.value['services'] and not 'http' in item.value['services'] and not 'https' in item.value['services']"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- ftpasswd
|
||||
- --passwd
|
||||
- "--name={{ item.value['username'] }}"
|
||||
- "--uid=$(id -u {{ item.value['id'] }})"
|
||||
- "--gid=$(id -g {{ item.value['gid'] }})"
|
||||
- "--home={{ hostvars[inventory_hostname]['users']['ftp']['home'] | default('/srv/ftp') }}/{{ item.value['username'] }}"
|
||||
- --shell=/sbin/nologin
|
||||
- --file={{ config['proftpd']['auth_paths']['users'] }}
|
||||
- --stdin
|
||||
stdin: "{{ item.value['password'] }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', config['proftpd']['users']) }}"
|
||||
- name: Create the virtual groups of virtual users
|
||||
when: "not 'caddy' in item.value['services'] and not 'httpd' in item.value['services'] and not 'www-data' in item.value['services'] and not 'http' in item.value['services'] and not 'https' in item.value['services']"
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- ftpasswd
|
||||
- --group
|
||||
- "--name={{ item.value['username'] }}"
|
||||
- "--gid=$(id -g {{ item.value['gid'] }})"
|
||||
- "--member={{ item.value['username'] }}"
|
||||
- --file={{ config['proftpd']['auth_paths']['groups'] }}
|
||||
loop: "{{ lookup('ansible.builtin.dict', config['proftpd']['users']) }}"
|
||||
# @TODO create tasks in block integrating LDAP users to ProFTPd
|
||||
# - name: Integrate LDAP users into ProFTPd
|
||||
- name: Create ProFTPd FTPS virtual host
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: "/etc/proftpd/conf.d/{{ config['proftpd']['name'].lowercase() }}.conf"
|
||||
follow: true
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: "proftpd/conf.d/vhost@vps1-{{ hostvars[inventory_hostname].fqdn }}.conf.j2"
|
||||
validate: proftpd --configtest
|
||||
vars:
|
||||
ftp_server_name: "{{ config['proftpd']['name'].uppercase() }}'s Archive'"
|
||||
allowed_users: "{{ ','.join(list(map(lambda u: u['username'], filter(lambda u: not 'http' in u['services'] and not 'https' in u['services'] and not 'httpd' in u['services'] and not 'caddy' in u['services'] and not 'www-data' in u['services'], config['proftpd']['users'].values())))) }}"
|
||||
anon_root: "{{ map(lambda u: u['home'], filter(lambda u: 'ftps' in u['services'] or 'proftpd' in u['services'], hostvars[inventory_hostname]['users'].values())) | list | random }}/public"
|
||||
anon_user: "{{ config['proftpd']['users']['smuggler']['username'] }}"
|
||||
- name: Set ProFTPd jail in fail2ban
|
||||
block:
|
||||
- name: Create fail2ban system configuration directory
|
||||
ansible.builtin.file:
|
||||
force: false
|
||||
group: root
|
||||
mode: "0755"
|
||||
owner: root
|
||||
path: /etc/fail2ban
|
||||
state: directory
|
||||
- name: Create fail2ban filters system configuration directory
|
||||
ansible.builtin.file:
|
||||
force: false
|
||||
group: root
|
||||
mode: "0755"
|
||||
owner: root
|
||||
path: /etc/fail2ban/filter.d
|
||||
state: directory
|
||||
- name: Create fail2ban filter system configuration
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
dest: /etc/fail2ban/filter.d/custom_proftpd.conf
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: fail2ban/filter.d/custom_proftpd.conf
|
||||
# validate: string
|
||||
- name: Create fail2ban jails system configuration directory
|
||||
ansible.builtin.file:
|
||||
force: false
|
||||
group: root
|
||||
mode: "0755"
|
||||
owner: root
|
||||
path: /etc/fail2ban/jail.d
|
||||
state: directory
|
||||
- name: Create fail2ban jail system configuration
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
dest: /etc/fail2ban/jail.d/proftpd.local
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: fail2ban/jail.d/proftpd.local
|
||||
# validate: string
|
||||
@@ -1,24 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Configure RSyncD
|
||||
listen: rsync
|
||||
become: true
|
||||
block:
|
||||
# @TODO further construct the following commented task
|
||||
# - name: Add directories to be published by RSyncD
|
||||
- name: Create RSyncD configuration
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
dest: /etc/rsyncd.conf
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: rsyncd.conf.j2
|
||||
# validate: string
|
||||
- name: Start and enable RSyncD SystemD system unit service
|
||||
ansible.builtin.systemd_service:
|
||||
enabled: true
|
||||
name: rsync
|
||||
scope: system
|
||||
state: started
|
||||
@@ -1,17 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# handlers file for bootstrap
|
||||
- name: Install all snapd applications
|
||||
become: true
|
||||
listen: snapd
|
||||
block:
|
||||
- name: Install snaps
|
||||
community.general.snap:
|
||||
channel: "{{ item.value['channel'] | default('latest/stable') }}"
|
||||
name:
|
||||
- "{{ item.value['name'] }}"
|
||||
# @TODO test the below list extend method for list of lists
|
||||
options: "{{ item.value['opts'] }}"
|
||||
state: present
|
||||
notify: "{{ item.key }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', software.snaps) }}"
|
||||
@@ -1,25 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT-0
|
||||
galaxy_info:
|
||||
author: Alex Tavarez
|
||||
description: A role that aids in the deployment and bootstrapping of a new VPS.
|
||||
company: SUKAATO
|
||||
issue_tracker_url: https://git.sukaato.moe/admin/skato-ansible/issues
|
||||
|
||||
# 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"
|
||||
galaxy_tags:
|
||||
- sukaato
|
||||
- vps
|
||||
- server
|
||||
- web
|
||||
|
||||
dependencies:
|
||||
- community.general
|
||||
# - containers.podman
|
||||
@@ -1,38 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Create GNUPGP directory in user home directory
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users
|
||||
ansible.builtin.file:
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
mode: "0700"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
path: "{{ ansible_facts['user_dir'] }}/.gnupg"
|
||||
state: directory
|
||||
- name: Create GPG key files
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users and hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys is not None and len(hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys) > 0
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
dest: "{{ ansible_facts['user_dir'] }}/.gnupg/{{ item.id }}.key"
|
||||
force: true
|
||||
group: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].group | default(ansible_facts['user_id']) }}"
|
||||
mode: "0600"
|
||||
owner: "{{ ansible_facts['user_id'] }}"
|
||||
src: "gnupg/{{ item.id }}.key"
|
||||
# validate: "gpg --verify {{ item.id }}.sig %s"
|
||||
loop: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys }}"
|
||||
register: created_gpg_keys
|
||||
- name: Import GPG key files
|
||||
when: ansible_facts['user_id'] in hostvars[inventory_hostname].users and hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys is not None and len(hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys) > 0
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- gpg
|
||||
- --batch
|
||||
- --passphrase-fd 0
|
||||
- --import
|
||||
- "{{ ansible_facts['user_dir'] }}/.gnupg/{{ item.id }}.key"
|
||||
stdin: "{{ item.password }}"
|
||||
loop: "{{ hostvars[inventory_hostname].users[ansible_facts['user_id']].gpg_keys }}"
|
||||
|
||||
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Create directory for MOTD update scripts
|
||||
ansible.builtin.file:
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
path: /etc/update-motd.d
|
||||
state: directory
|
||||
- name: Create MOTD update scripts
|
||||
ansible.builtin.copy:
|
||||
force: true
|
||||
backup: true
|
||||
group: root
|
||||
mode: "0744"
|
||||
owner: root
|
||||
dest: "/etc/update-motd.d/{{ item }}"
|
||||
src: "update-motd.d/{{ item }}"
|
||||
state: present
|
||||
loop: "{{ hostvars[inventory_hostname].vps_service.ssh_motd_script_basenames }}"
|
||||
- name: Create hidden SSH directories under users' home directories
|
||||
when: hostvars[inventory_hostname].groups.remote.group_name in item.value.groups
|
||||
ansible.builtin.file:
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
mode: "0700"
|
||||
owner: "{{ item.value.username }}"
|
||||
path: "{{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh"
|
||||
state: directory
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
tags:
|
||||
- ensure_paths
|
||||
- ensure_files
|
||||
- name: Add authorized SSH public keys for users
|
||||
when: hostvars[inventory_hostname].groups.remote.group_name in item.value.groups and item.value.ssh_authorized_keys is not None and len(item.value.ssh_authorized_keys) > 0
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
content: "{{ '\n'.join(item.value.ssh_authorized_keys) }}"
|
||||
dest: "{{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh/authorized_keys"
|
||||
# follow: true
|
||||
force: true
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
mode: "0600"
|
||||
owner: "{{ item.value.username }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
tags:
|
||||
- ensure_files
|
||||
- name: Harden SSH security
|
||||
block:
|
||||
- name: Create public subdirectory for SSH's SFTP-exclusive user's chroot
|
||||
when: "'sftp' in item.value.services"
|
||||
ansible.builtin.file:
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
owner: "{{ item.value.username }}"
|
||||
path: "{{ item.value.home | default('/home/' ~ item.value.username) }}/public"
|
||||
state: directory
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
- name: Set users in group ftp to only be usable with SSH's SFTP service
|
||||
when: "'sftp' in item.value.services"
|
||||
ansible.builtin.blockinfile:
|
||||
backup: true
|
||||
block: |2
|
||||
Match User {{ item.value.username }}
|
||||
ForceCommand internal-sftp -d /public
|
||||
AuthorizedKeysFile {{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh/authorized_keys
|
||||
|
||||
Match Group {{ item.value.group | default(item.value.username) }}
|
||||
ForceCommand internal-sftp -d /%u
|
||||
ChrootDirectory {{ item.value.home | default('/home/' ~ item.value.username) }}
|
||||
AllowAgentForwarding no
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
create: true
|
||||
group: root
|
||||
insertafter: EOF
|
||||
marker: "# {mark} ANSIBLE-MANAGED SFTP BLOCK"
|
||||
marker_begin: BEGIN
|
||||
marker_end: END
|
||||
owner: root
|
||||
path: /etc/ssh/sshd_config.d/sftp.conf
|
||||
append_newline: true
|
||||
state: present
|
||||
validate: /bin/sshd -t
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
tags:
|
||||
- sftp_auth_step
|
||||
- name: Switch to preferred SSH authentication method
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/ssh/sshd_config.d/auth.conf
|
||||
# follow: true
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: sshd_config.d/auth.conf.j2
|
||||
validate: /bin/sshd -t
|
||||
vars:
|
||||
empty_auth_used: false
|
||||
pass_auth_used: false
|
||||
pam_auth_used: true
|
||||
key_auth_used: true
|
||||
tags:
|
||||
- ssh_auth_step
|
||||
- name: Constrain idle online user accounts
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/ssh/sshd_config.d/harden.conf
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: sshd_config.d/harden.conf.j2
|
||||
validate: /bin/sshd -t
|
||||
vars:
|
||||
client_subsistence: 900
|
||||
client_subsist_warn_max: 3
|
||||
tags:
|
||||
- ssh_timeout_step
|
||||
- name: Toggle ability to log in as root via SSH
|
||||
when: "hostvars[inventory_hostname].vps_service.root_fate == 'disposal'"
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/ssh/sshd_config.d/denyroot.conf
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: sshd_config.d/denyroot.conf.j2
|
||||
validate: /bin/sshd -t
|
||||
vars:
|
||||
root_login_allowed: false
|
||||
tags:
|
||||
- ssh_root_step
|
||||
- name: Specify users or groups to whitelist or blacklist for SSH login
|
||||
when: "hostvars[inventory_hostname].vps_service.root_fate == 'disposal'"
|
||||
ansible.builtin.template:
|
||||
backup: true
|
||||
comment_end_string: "#}"
|
||||
comment_start_string: "{#"
|
||||
dest: /etc/ssh/sshd_config.d/allowance.conf
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: sshd_config.d/allowance.conf.j2
|
||||
validate: /bin/sshd -t
|
||||
vars:
|
||||
list_type: whitelist
|
||||
policed_groups:
|
||||
- "{{ hostvars[inventory_hostname].groups.remote.group_name }}"
|
||||
tags:
|
||||
- ssh_gate_step
|
||||
tags:
|
||||
- ssh_harden_step
|
||||
@@ -1,39 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Provide requisite SSL signed certificate for FQDN
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
checksum: string
|
||||
dest: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.crt"
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: "ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.crt"
|
||||
# validate: string
|
||||
- name: Provide requisite SSL private key for FQDN
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
dest: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.key"
|
||||
force: true
|
||||
group: root
|
||||
mode: "0600"
|
||||
owner: root
|
||||
src: "ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.key"
|
||||
# validate: string
|
||||
- name: Provide requisite SSL public key for FQDN
|
||||
ansible.builtin.copy:
|
||||
backup: true
|
||||
checksum: string
|
||||
dest: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.pem"
|
||||
force: true
|
||||
group: root
|
||||
owner: root
|
||||
src: "ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.pem"
|
||||
# validate: string
|
||||
- name: Update system registration of SSL certificates
|
||||
ansible.builtin.command:
|
||||
cmd: update-ca-certificates
|
||||
creates: "/etc/ssl/certs/{{ hostvars[inventory_hostname].fqdn }}.pem"
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Create groups
|
||||
ansible.builtin.group:
|
||||
name: "{{ item.value.group_name }}"
|
||||
state: present
|
||||
system: "{{ item.value.type == 'system' }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].groups) }}"
|
||||
- name: Create users
|
||||
block:
|
||||
- name: Create administrative users
|
||||
when: "item.value.admin and item.value.type != 'system'"
|
||||
ansible.builtin.user:
|
||||
comment: "administrator for {{ fqdn.split('.')[0].lowercase }}"
|
||||
create_home: false
|
||||
home: "{{ item.value.home | default('/home/' ~ item.value.username) }}"
|
||||
generate_ssh_key: true
|
||||
ssh_key_comment: "ansible-generated for {{ item.value.username }}@{{ hostvars[inventory_hostname].fqdn.split('.')[0].lowercase() }}"
|
||||
ssh_key_type: "ed25519"
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
name: "{{ item.value.username }}"
|
||||
uid: "{{ item.value.id }}"
|
||||
shell: "{{ item.value.shell }}"
|
||||
password: "{{ item.value.password }}"
|
||||
state: present
|
||||
system: "{{ item.value.type == 'system' }}"
|
||||
update_password: always
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
- name: Create regular users
|
||||
when: "not item.value.admin and item.value.type != 'system'"
|
||||
ansible.builtin.user:
|
||||
comment: "user of {{ fqdn.split('.')[0].lowercase }}"
|
||||
create_home: true
|
||||
home: "{{ item.value.home | default('/home/' ~ item.value.username) }}"
|
||||
generate_ssh_key: true
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
name: "{{ item.value.username }}"
|
||||
uid: "{{ item.value.id }}"
|
||||
shell: "{{ item.value.shell }}"
|
||||
password: "{{ item.value.password }}"
|
||||
state: present
|
||||
system: "{{ item.value.type == 'system' }}"
|
||||
update_password: always
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
- name: Create users for managing data related to services
|
||||
when: "not item.value.admin and item.value.type == 'system' and item.value.service is not None"
|
||||
ansible.builtin.user:
|
||||
comment: "service data user for {{ item.value.services | random }} at {{ hostvars[inventory_hostname].fqdn.split('.')[0].lowercase() }}"
|
||||
create_home: false
|
||||
home: "{{ item.value.home | default('/home/' ~ item.value.username) }}"
|
||||
group: "{{ item.value.group | default(item.value.username) }}"
|
||||
name: "{{ item.value.username }}"
|
||||
uid: "{{ item.value.id }}"
|
||||
shell: "{{ item.value.shell }}"
|
||||
state: present
|
||||
system: "{{ item.value.type == 'system' }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
- name: Adjust users' groups
|
||||
when: item.value.groups is not None and len(item.value.groups) > 0
|
||||
ansible.builtin.user:
|
||||
name: "{{ item.value.username }}"
|
||||
append: true
|
||||
groups: "{{ item.value.groups }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', hostvars[inventory_hostname].users) }}"
|
||||
@@ -1,12 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Populate system with groups and user accounts
|
||||
ansible.builtin.import_tasks:
|
||||
file: "create_users@{{ ansible_facts['system'].lowercase() }}.yml"
|
||||
- name: Provide SSL certificate files
|
||||
ansible.builtin.import_tasks:
|
||||
file: "configure_ssl@{{ ansible_facts['system'].lowercase() }}.yml"
|
||||
- name: Configure SSH for root
|
||||
ansible.builtin.import_tasks:
|
||||
file: "configure_ssh@{{ ansible_facts['system'].lowercase() }}.yml"
|
||||
@@ -1,87 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
# @TODO create bootstrap tasks for installation and configuration of software
|
||||
- name: Update and upgrade software
|
||||
block:
|
||||
- name: Update Aptitude package cache and upgrade Aptitude packages
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
upgrade: yes
|
||||
update_cache: yes
|
||||
cache_valid_time: 86400
|
||||
- name: Install NeoVim editor
|
||||
become: true
|
||||
block:
|
||||
- name: Install NeoVim using Aptitude package manager
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
ansible.builtin.package:
|
||||
name: neovim
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
# @TODO create handler to notify to for configuring neovim
|
||||
# notify: neovim
|
||||
- name: Install kitty-terminfo for SSH client xterm-kitty compatibility
|
||||
become: true
|
||||
block:
|
||||
- name: Install kitty-terminfo using Aptitude package manager
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
ansible.builtin.package:
|
||||
name: kitty-terminfo
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
- name: Install necessary software managers and container engines
|
||||
become: true
|
||||
block:
|
||||
- name: Install snapd
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
block:
|
||||
- name: Install snapd using Aptitude package manager
|
||||
ansible.builtin.package:
|
||||
name: snapd
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
notify: snapd
|
||||
- name: Install flatpak
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
block:
|
||||
- name: Install flatpak using Aptitude package manager
|
||||
ansible.builtin.package:
|
||||
name: flatpak
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
- name: Install podman
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
block:
|
||||
- name: Install podman using Aptitude package manager
|
||||
ansible.builtin.package:
|
||||
name: podman
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
- name: Install podman-compose
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
block:
|
||||
- name: Install podman-compose using Aptitude package manager
|
||||
ansible.builtin.package:
|
||||
name: podman-compose
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
- name: Install git
|
||||
block:
|
||||
- name: Install git using Aptitude package manager
|
||||
when: "ansible_facts['pkg_mgr'] == 'apt'"
|
||||
ansible.builtin.package:
|
||||
name: git
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
notify: git
|
||||
- name: Install packages
|
||||
when: ansible_facts['pkg_mgr'] in item.value.name
|
||||
ansible.builtin.package:
|
||||
name: "{{ item.value.name[ansible_facts['pkg_mgr']] }}"
|
||||
use: "{{ ansible_facts['pkg_mgr'] }}"
|
||||
state: present
|
||||
# @TODO research what happens when nonexistent handler is called or notify field is null
|
||||
notify: "{{ item.key }}"
|
||||
loop: "{{ lookup('ansible.builtin.dict', software.pkgs) }}"
|
||||
@@ -1,9 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# tasks file for bootstrap
|
||||
- name: Configure GPG for user
|
||||
ansible.builtin.import_tasks:
|
||||
file: "configure_gpg@{{ ansible_facts['system'].lowercase() }}.yml"
|
||||
- name: Install and configure software on system
|
||||
ansible.builtin.import_tasks:
|
||||
file: "install@{{ ansible_facts['system'].lowercase() }}.yml"
|
||||
@@ -1,83 +0,0 @@
|
||||
# Global settings
|
||||
continue=true
|
||||
# check-integrity=true
|
||||
daemon=true
|
||||
human-readable=true
|
||||
dir=~/downloads
|
||||
file-allocation=falloc
|
||||
log-level=warn
|
||||
max-concurrent-downloads=3
|
||||
max-overall-download-limit=0
|
||||
|
||||
# RPC settings
|
||||
enable-rpc=true
|
||||
rpc-allow-origin-all=true
|
||||
rpc-max-request-size=10M
|
||||
rpc-listen-all=true
|
||||
rpc-listen-port=6800
|
||||
rpc-secret={{ config['aria']['api_key'] }}
|
||||
# rpc-certificate=
|
||||
# rpc-private-key=
|
||||
# rpc-secure=true
|
||||
|
||||
# HTTP/FTP/SFTP settings
|
||||
connect-timeout=120
|
||||
timeout=90
|
||||
server-stat-of=~/.config/aria2/dl.log
|
||||
server-stat-if=~/.config/aria2/dl.log
|
||||
server-stat-timeout=86400
|
||||
# checksum=sha-256={{ config.aria.checksum }}
|
||||
max-connection-per-server=5
|
||||
max-tries=10
|
||||
max-file-not-found=7
|
||||
min-split-size=100M
|
||||
split=7
|
||||
retry-wait=10
|
||||
netrc-path=~/.netrc
|
||||
reuse-uri=true
|
||||
uri-selector=feedback
|
||||
seed-ratio=1.5
|
||||
seed-time=75
|
||||
|
||||
# HTTP settings
|
||||
http-accept-gzip=true
|
||||
http-auth-challenge=true
|
||||
http-no-cache=true
|
||||
enable-http-pipelining=true
|
||||
enable-http-keep-alive=true
|
||||
save-cookies=~/.config/aria2/cookie.txt
|
||||
load-cookies=~/.config/aria2/cookie.txt
|
||||
# user-agent=Mozilla/5.0
|
||||
|
||||
# FTP/SFTP settings
|
||||
ftp-pasv=true
|
||||
ftp-type=binary
|
||||
ftp-reuse-connection=true
|
||||
# ssh-host-key-md=sha-256=
|
||||
|
||||
# Bittorrent settings
|
||||
listen-port=6881-6999
|
||||
# bt-hash-check-seed=true
|
||||
# bt-force-encryption=true
|
||||
bt-save-metadata=true
|
||||
bt-load-saved-metadata=true
|
||||
bt-max-open-files=50
|
||||
bt-max-peers=150
|
||||
bt-stop-timeout=7200
|
||||
|
||||
bt-tracker=udp://93.158.213.92:1337/announce,udp://23.134.88.9:6969/announce,udp://23.134.88.9:1337/announce,udp://185.243.218.213:80/announce,udp://89.234.156.205:451/announce,udp://44.30.4.4:6969/announce,udp://23.175.184.30:23333/announce,udp://51.222.82.36:6969/announce,udp://211.75.205.189:80/announce,udp://77.91.85.95:6969/announce,udp://45.13.119.213:6969/announce,udp://43.154.112.29:17272/announce,udp://209.141.59.25:6969/announce,udp://5.255.124.190:6969/announce,udp://152.53.152.105:1984/announce,udp://109.201.134.183:80/announce,udp://111.90.151.241:6969/announce,udp://152.53.152.105:54123/announce,udp://189.69.171.209:6969/announce,udp://151.243.109.110:6969/announce
|
||||
|
||||
bt-tracker-connect-timeout=120
|
||||
bt-tracker-timeout=333
|
||||
bt-tracker-interval=0
|
||||
enable-dht=true
|
||||
dht-listen-port=6881-6999
|
||||
dht-message-timeout=15
|
||||
enable-peer-exchange=true
|
||||
follow-torrent=mem
|
||||
|
||||
# Metalink settings
|
||||
follow-metalink=mem
|
||||
metalink-language=en,es,ja
|
||||
metalink-location=jp,us,ch
|
||||
# metalink-os=linux
|
||||
@@ -1,31 +0,0 @@
|
||||
<Global>
|
||||
# PassivePorts {{ pasv_ports }}
|
||||
RequireValidShell off
|
||||
{% if allow_symlinks %}
|
||||
ShowSymlinks on
|
||||
{% else %}
|
||||
ShowSymlinks off
|
||||
{% endif %}
|
||||
AllowRetrieveRestart on
|
||||
HiddenStores .%P- .frag
|
||||
|
||||
DisplayLogin /etc/proftpd/WELCOME.txt
|
||||
DisplayChdir .README.md true
|
||||
DisplayConnect /etc/proftpd/BANNER.txt
|
||||
DisplayFileTransfer /etc/proftpd/SUCCESS.txt
|
||||
DisplayReadme /etc/proftpd/ANNOUNCE.md
|
||||
DisplayQuit /etc/proftpd/BYE.txt
|
||||
|
||||
TimeoutNoTransfer 3600
|
||||
TimeoutStalled 210
|
||||
TimeoutIdle 1400
|
||||
|
||||
Umask 0022 0022
|
||||
AllowOverwrite on
|
||||
|
||||
<Directory />
|
||||
<Limit ALL>
|
||||
DenyAll
|
||||
</Limit>
|
||||
</Directory>
|
||||
</Global>
|
||||
@@ -1,93 +0,0 @@
|
||||
<IfModule !mod_tls.c>
|
||||
LoadModule mod_tls.c
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_tls.c>
|
||||
<VirtualHost 0.0.0.0>
|
||||
ServerName "{{ ftp_server_name }}"
|
||||
ServerIdent on "Our head librarians Furcas and Marbas welcome you!"
|
||||
ServerAlias {{ hostvars[inventory_hostname].fqdn }} ftp.{{ hostvars[inventory_hostname].fqdn }} {{ hostvars[inventory_hostname].fqdn.split('.')[0] }}
|
||||
ServerLog /var/log/proftpd/{{ hostvars[inventory_hostname].fqdn }}.log
|
||||
Protocols ftps
|
||||
Port 990
|
||||
DefaultRoot ~
|
||||
# AllowStoreRestart on
|
||||
MaxStoreFileSize 10 Gb
|
||||
MaxTransfersPerUser STOR,RETR 9
|
||||
MaxTransfersPerHost STOR,RETR 36
|
||||
DirFakeUser on ~
|
||||
DirFakeGroup on ~
|
||||
|
||||
# AuthOrder mod_auth_pam.c mod_auth_unix.c*
|
||||
AuthOrder mod_auth_file.c
|
||||
AuthUserFile {{ config.proftpd.auth_paths.users }}
|
||||
AuthGroupFile {{ config.proftpd.auth_paths.groups }}
|
||||
AuthFileOptions SyntaxCheck
|
||||
|
||||
TLSEngine on
|
||||
TLSLog /var/log/proftpd/tls.log
|
||||
# @NOTE: "SSLv23" means all SSL versions
|
||||
TLSProtocol SSLv23
|
||||
TLSOptions AllowClientRenegotiations
|
||||
TLSVerifyClient off
|
||||
TLSRequired on
|
||||
TLSRenegotiate required off
|
||||
|
||||
TLSECCertificateFile {{ config.proftpd.tls_paths.cert }}
|
||||
TLSECCertificateKeyFile {{ config.proftpd.tls_paths.privkey }}
|
||||
TLSCACertificateFile {{ config.proftpd.tls_paths.cert }}
|
||||
|
||||
<Limit LOGIN>
|
||||
AllowUser OR {{ allowed_users}}
|
||||
</Limit>
|
||||
|
||||
<Directory ~>
|
||||
<Limit READ DIRS>
|
||||
AllowAll
|
||||
</Limit>
|
||||
</Directory>
|
||||
|
||||
<Directory ~/*>
|
||||
UserOwner ftp
|
||||
GroupOwner ftp
|
||||
HideUser !~
|
||||
HideFiles ^\.(.+)?
|
||||
HideNoAccess on
|
||||
|
||||
<Limit ALL>
|
||||
AllowAll
|
||||
</Limit>
|
||||
</Directory>
|
||||
|
||||
<Anonymous {{ anon_root }}>
|
||||
User ftp
|
||||
Group ftp
|
||||
RequireValidShell off
|
||||
DirFakeUser on anon
|
||||
DirFakeGroup on anon
|
||||
DirFakeMode 0444
|
||||
UserAlias anon {{ anon_user }}
|
||||
AllowStoreRestart off
|
||||
MaxStoreFileSize 4 Gb
|
||||
MaxTransfersPerUser STOR,RETR 3
|
||||
MaxTransfersPerHost STOR,RETR 10
|
||||
HideUser !~
|
||||
HideNoAccess on
|
||||
|
||||
<Directory {{ anon_root }}>
|
||||
<Limit READ DIRS>
|
||||
AllowAll
|
||||
</Limit>
|
||||
</Directory>
|
||||
|
||||
<Directory {{ anon_root }}/*>
|
||||
# <Limit READ DIRS MKD RMD XMKD XRMD>
|
||||
<Limit READ DIRS>
|
||||
AllowAll
|
||||
</Limit>
|
||||
|
||||
HideFiles ^\.(.+)?
|
||||
</Directory>
|
||||
</Anonymous>
|
||||
</VirtualHost>
|
||||
</IfModule>
|
||||
@@ -1,185 +0,0 @@
|
||||
#
|
||||
# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
|
||||
# To really apply changes, reload proftpd after modifications, if
|
||||
# it runs in daemon mode. It is not required in inetd/xinetd mode.
|
||||
#
|
||||
|
||||
# Includes DSO modules
|
||||
Include /etc/proftpd/modules.conf
|
||||
|
||||
# Set off to disable IPv6 support which is annoying on IPv4 only boxes.
|
||||
UseIPv6 on
|
||||
# If set on you can experience a longer connection delay in many cases.
|
||||
<IfModule mod_ident.c>
|
||||
IdentLookups on
|
||||
</IfModule>
|
||||
|
||||
ServerName "{{ ftp_server_name }}"
|
||||
# Set to inetd only if you would run proftpd by inetd/xinetd/socket.
|
||||
# Read README.Debian for more information on proper configuration.
|
||||
ServerType standalone
|
||||
DeferWelcome off
|
||||
MaxInstances {{ max_conns }}
|
||||
|
||||
# Disable MultilineRFC2228 per https://github.com/proftpd/proftpd/issues/1085
|
||||
# MultilineRFC2228on
|
||||
DefaultServer on
|
||||
DefaultRoot ~
|
||||
|
||||
DenyFilter \*.*/
|
||||
|
||||
# Users require a valid shell listed in /etc/shells to login.
|
||||
# Use this directive to release that constrain.
|
||||
# RequireValidShell off
|
||||
|
||||
# Port 21 is the standard FTP port.
|
||||
Port 21
|
||||
|
||||
# If your host was NATted, this option is useful in order to
|
||||
# allow passive tranfers to work. You have to use your public
|
||||
# address and opening the passive ports used on your firewall as well.
|
||||
# MasqueradeAddress 1.2.3.4
|
||||
|
||||
# This is useful for masquerading address with dynamic IPs:
|
||||
# refresh any configured MasqueradeAddress directives every 8 hours
|
||||
# <IfModule mod_dynmasq.c>
|
||||
# DynMasqRefresh 28800
|
||||
# </IfModule>
|
||||
|
||||
# Set the user and group that the server normally runs at.
|
||||
User proftpd
|
||||
Group nogroup
|
||||
|
||||
# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
|
||||
# PersistentPasswd off
|
||||
|
||||
# This is required to use both PAM-based authentication and local passwords
|
||||
# AuthOrder mod_auth_pam.c* mod_auth_unix.c
|
||||
|
||||
# Be warned: use of this directive impacts CPU average load!
|
||||
# Uncomment this if you like to see progress and transfer rate with ftpwho
|
||||
# in downloads. That is not needed for uploads rates.
|
||||
#
|
||||
# UseSendFile off
|
||||
|
||||
TransferLog /var/log/proftpd/transfer.log
|
||||
SystemLog /var/log/proftpd/connection.log
|
||||
|
||||
# Logging onto /var/log/lastlog is enabled but set to off by default
|
||||
#UseLastlog on
|
||||
|
||||
# In order to keep log file dates consistent after chroot, use timezone info
|
||||
# from /etc/localtime. If this is not set, and proftpd is configured to
|
||||
# chroot (e.g. DefaultRoot or <Anonymous>), it will use the non-daylight
|
||||
# savings timezone regardless of whether DST is in effect.
|
||||
#SetEnv TZ :/etc/localtime
|
||||
|
||||
<IfModule mod_quotatab.c>
|
||||
QuotaEngine off
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_ratio.c>
|
||||
Ratios off
|
||||
</IfModule>
|
||||
|
||||
|
||||
# Delay engine reduces impact of the so-called Timing Attack described in
|
||||
# http://www.securityfocus.com/bid/11430/discuss
|
||||
# It is on by default.
|
||||
<IfModule mod_delay.c>
|
||||
DelayEngine on
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_ctrls.c>
|
||||
ControlsEngine off
|
||||
ControlsMaxClients 2
|
||||
ControlsLog /var/log/proftpd/controls.log
|
||||
ControlsInterval 5
|
||||
ControlsSocket /var/run/proftpd/proftpd.sock
|
||||
</IfModule>
|
||||
|
||||
<IfModule mod_ctrls_admin.c>
|
||||
AdminControlsEngine off
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# Alternative authentication frameworks
|
||||
#
|
||||
#Include /etc/proftpd/ldap.conf
|
||||
#Include /etc/proftpd/sql.conf
|
||||
|
||||
#
|
||||
# This is used for FTPS connections
|
||||
#
|
||||
#Include /etc/proftpd/tls.conf
|
||||
|
||||
#
|
||||
# This is used for SFTP connections
|
||||
#
|
||||
#Include /etc/proftpd/sftp.conf
|
||||
|
||||
#
|
||||
# This is used for other add-on modules
|
||||
#
|
||||
#Include /etc/proftpd/dnsbl.conf
|
||||
#Include /etc/proftpd/geoip.conf
|
||||
#Include /etc/proftpd/snmp.conf
|
||||
|
||||
#
|
||||
# Useful to keep VirtualHost/VirtualRoot directives separated
|
||||
#
|
||||
#Include /etc/proftpd/virtuals.conf
|
||||
|
||||
# A basic anonymous configuration, no upload directories.
|
||||
|
||||
# <Anonymous ~ftp>
|
||||
# User ftp
|
||||
# Group nogroup
|
||||
# # We want clients to be able to login with "anonymous" as well as "ftp"
|
||||
# UserAlias anonymous ftp
|
||||
# # Cosmetic changes, all files belongs to ftp user
|
||||
# DirFakeUser on ftp
|
||||
# DirFakeGroup on ftp
|
||||
#
|
||||
# RequireValidShell off
|
||||
#
|
||||
# # Limit the maximum number of anonymous logins
|
||||
# MaxClients 10
|
||||
#
|
||||
# # We want 'welcome.msg' displayed at login, and '.message' displayed
|
||||
# # in each newly chdired directory.
|
||||
# DisplayLogin welcome.msg
|
||||
# DisplayChdir .message
|
||||
#
|
||||
# # Limit WRITE everywhere in the anonymous chroot
|
||||
# <Directory *>
|
||||
# <Limit WRITE>
|
||||
# DenyAll
|
||||
# </Limit>
|
||||
# </Directory>
|
||||
#
|
||||
# # Uncomment this if you're brave.
|
||||
# # <Directory incoming>
|
||||
# # # Umask 022 is a good standard umask to prevent new files and dirs
|
||||
# # # (second parm) from being group and world writable.
|
||||
# # Umask 022 022
|
||||
# # <Limit READ WRITE>
|
||||
# # DenyAll
|
||||
# # </Limit>
|
||||
# # <Limit STOR>
|
||||
# # AllowAll
|
||||
# # </Limit>
|
||||
# # </Directory>
|
||||
#
|
||||
# </Anonymous>
|
||||
|
||||
<Limit LOGIN>
|
||||
DenyAll
|
||||
</Limit>
|
||||
|
||||
# Include other custom configuration files
|
||||
# !! Please note, that this statement will read /all/ file from this subdir,
|
||||
# i.e. backup files created by your editor, too !!!
|
||||
# Eventually create file patterns like this: /etc/proftpd/conf.d/*.conf
|
||||
#
|
||||
Include /etc/proftpd/conf.d/
|
||||
@@ -1,41 +0,0 @@
|
||||
port = 873
|
||||
use chroot = true
|
||||
max connections = 17
|
||||
ignore nonreadable = true
|
||||
pid file = /var/run/rsyncd.pid
|
||||
|
||||
[{{ ansible_facts['user_id'] }}-dl]
|
||||
path = {{ ansible_facts['user_dir'] }}/downloads/public
|
||||
uid = rika
|
||||
gid = rika
|
||||
timeout = 90
|
||||
comment = Personal download inventory
|
||||
read only = true
|
||||
exclude = .nextcloudsync.log .calnotes .caltrash .stfolder .stignore .directory .ssh *.pub
|
||||
|
||||
[{{ ansible_facts['user_id'] }}-public]
|
||||
path = {{ ansible_facts['user_dir'] }}/public/rsync
|
||||
uid = rika
|
||||
gid = rika
|
||||
timeout = 90
|
||||
comment = Public share point
|
||||
read only = true
|
||||
exclude = .nextcloudsync.log .calnotes .caltrash .stfolder .stignore .directory .ssh *.pub
|
||||
|
||||
[{{ ansible_facts['user_id'] }}-soulseek]
|
||||
path = {{ ansible_facts['user_dir'] }}/public/soulseek
|
||||
uid = rika
|
||||
gid = rika
|
||||
timeout = 90
|
||||
comment = Personal SoulSeek inventory
|
||||
read only = true
|
||||
exclude = .nextcloudsync.log .calnotes .caltrash .stfolder .stignore .directory .ssh *.pub
|
||||
|
||||
[{{ ansible_facts['user_id'] }}-portfolio]
|
||||
path = {{ ansible_facts['user_dir'] }}/portfolio
|
||||
uid = rika
|
||||
gid = rika
|
||||
timeout = 90
|
||||
comment = Personal portfolio
|
||||
read only = true
|
||||
exclude = .nextcloudsync.log .calnotes .caltrash .stfolder .stignore .directory .ssh *.pub
|
||||
@@ -1,15 +0,0 @@
|
||||
{% if list_type == 'whitelist' %}
|
||||
{% if policed_groups is not None and len(policed_groups) > 0 %}
|
||||
AllowGroups {{ ' '.join(policed_groups) }}
|
||||
{% endif %}
|
||||
{% if policed_users is not None and len(policed_users) > 0 %}
|
||||
AllowUsers {{ ' '.join(policed_users) }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if policed_groups is not None and len(policed_groups) > 0 %}
|
||||
DenyGroups {{ ' '.join(policed_groups) }}
|
||||
{% endif %}
|
||||
{% if policed_users is not None and len(policed_users) > 0 %}
|
||||
DenyGroups {{ ' '.join(policed_users) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -1,28 +0,0 @@
|
||||
{% if empty_auth_used %}
|
||||
PermitEmptyPasswords yes
|
||||
{% else %}
|
||||
PermitEmptyPasswords no
|
||||
{% endif %}
|
||||
{% if pass_auth_used %}
|
||||
PasswordAuthentication yes
|
||||
{% else %}
|
||||
PasswordAuthentication no
|
||||
{% endif %}
|
||||
{% if kbd_auth_used is not None %}
|
||||
{% if kbd_auth_used %}
|
||||
KbdInteractiveAuthentication yes
|
||||
{% else %}
|
||||
KbdInteractiveAuthentication no # enable if implementing TOTP 2FA
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if pam_auth_used %}
|
||||
UsePAM yes
|
||||
{% else %}
|
||||
UsePAM no # enable if implementing TOTP 2FA
|
||||
{% endif %}
|
||||
{% if key_auth_used %}
|
||||
PubkeyAuthentication yes
|
||||
{% else %}
|
||||
PubkeyAuthentication no
|
||||
{% endif %}
|
||||
PrintMotd yes
|
||||
@@ -1,5 +0,0 @@
|
||||
{% if root_login_allowed %}
|
||||
PermitRootLogin yes
|
||||
{% else %}
|
||||
PermitRootLogin no
|
||||
{% endif %}
|
||||
@@ -1,2 +0,0 @@
|
||||
ClientAliveInterval {{ client_subsistence }}
|
||||
ClientAliveCountMax {{ client_subsist_warn_max }}
|
||||
@@ -1,13 +0,0 @@
|
||||
[Unit]
|
||||
Description=aria2 Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/aria2c --conf-path={{ ansible_facts['user_dir'] }}/.config/aria2/aria2.conf
|
||||
ExecReload=/usr/bin/kill -HUP $MAINPID
|
||||
RestartSec=1min
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -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:
|
||||
- bootstrap
|
||||
@@ -1,297 +0,0 @@
|
||||
#SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# vars file for bootstrap
|
||||
# @TODO make list or dictionary of software to be installed in bootstrap task
|
||||
software:
|
||||
pkgs:
|
||||
# @NOTE keep fields or keys constant; otherwise will have to edit handler notifiers and listeners elsewhere
|
||||
failtwoban:
|
||||
name:
|
||||
apt: fail2ban
|
||||
gocryptfs:
|
||||
name:
|
||||
apt: gocryptfs
|
||||
lua-lang:
|
||||
name:
|
||||
apt: lua5.4
|
||||
lua-docs:
|
||||
name:
|
||||
apt: luadoc
|
||||
lua-pkg:
|
||||
name:
|
||||
apt: luarocks
|
||||
python-lang:
|
||||
name:
|
||||
apt: python3
|
||||
python-pkg:
|
||||
name:
|
||||
apt: python3-pip
|
||||
python-linter:
|
||||
name:
|
||||
apt: python3-doc8
|
||||
python-docs:
|
||||
name:
|
||||
apt: python3-doc
|
||||
rust-lang:
|
||||
name:
|
||||
apt: rustc # @NOTE alternative: rustup
|
||||
rust-pkg:
|
||||
name:
|
||||
apt: cargo
|
||||
rust-debugger:
|
||||
name:
|
||||
apt: rust-analyzer
|
||||
rust-linter:
|
||||
name:
|
||||
apt: rust-clippy
|
||||
rust-docs:
|
||||
name:
|
||||
apt: rust-doc
|
||||
java-lang:
|
||||
name:
|
||||
apt: default-jdk-headless
|
||||
java-docs:
|
||||
name:
|
||||
apt: default-jdk-doc
|
||||
java-runtime:
|
||||
name:
|
||||
apt: default-jre-headless
|
||||
kotlin-lang:
|
||||
name:
|
||||
apt: kotlin
|
||||
swift-lang:
|
||||
name:
|
||||
apt: swiftlang
|
||||
swift-docs:
|
||||
name:
|
||||
apt: swiftlang-doc
|
||||
erlang-lang:
|
||||
name:
|
||||
apt: erlang
|
||||
erlang-pkg:
|
||||
name:
|
||||
apt: erlang-hex
|
||||
erlang-docs:
|
||||
name:
|
||||
apt: erlang-doc
|
||||
elixir-lang:
|
||||
name:
|
||||
apt: elixir
|
||||
crystal-lang:
|
||||
name:
|
||||
apt: crystal
|
||||
crystal-docs:
|
||||
name:
|
||||
apt: crystal-doc
|
||||
# @TODO replace below commented with an NVM-style installation (v22): https://nodejs.org/en/download
|
||||
# javascript-lang:
|
||||
# name:
|
||||
# apt: nodejs
|
||||
# javascript-pkg:
|
||||
# name:
|
||||
# apt: npm
|
||||
# javascript-linter:
|
||||
# name:
|
||||
# apt: eslint
|
||||
javascript-docs:
|
||||
name:
|
||||
apt: nodejs-doc
|
||||
php-lang:
|
||||
name:
|
||||
apt: php
|
||||
php-docs:
|
||||
name:
|
||||
apt: php-common
|
||||
php-debugger:
|
||||
name:
|
||||
apt: php-xdebug
|
||||
php-pkg:
|
||||
name:
|
||||
apt: composer
|
||||
# php-ldap:
|
||||
# name:
|
||||
# apt: php-ldap
|
||||
html-linter:
|
||||
name:
|
||||
apt: tidy
|
||||
json-linter:
|
||||
name:
|
||||
apt: jsonlint
|
||||
yaml-linter:
|
||||
name:
|
||||
apt: yamllint
|
||||
pandoc:
|
||||
name:
|
||||
apt: pandoc
|
||||
distrobox:
|
||||
name:
|
||||
apt: distrobox
|
||||
fastfetch:
|
||||
name:
|
||||
apt: fastfetch
|
||||
# @TODO manually install the commented below on current active new VPS, then uncomment
|
||||
# duplicity:
|
||||
# name:
|
||||
# apt: duplicity
|
||||
# pass:
|
||||
# name:
|
||||
# apt: pass
|
||||
# sonicpi:
|
||||
# name:
|
||||
# apt: sonic-pi-server
|
||||
# sonicpi-docs:
|
||||
# name:
|
||||
# apt: sonic-pi-server-doc
|
||||
# supercollider:
|
||||
# name:
|
||||
# apt: supercollider
|
||||
# supercollider-docs:
|
||||
# name:
|
||||
# apt: supercollider-common
|
||||
# supercollider-plugins:
|
||||
# name:
|
||||
# apt: sc3-plugins-language
|
||||
qrencode:
|
||||
name:
|
||||
apt: qrencode
|
||||
ffmpeg:
|
||||
name:
|
||||
apt: ffmpeg
|
||||
ffmpeg-docs:
|
||||
name:
|
||||
apt: ffmpeg-doc
|
||||
graphicsmagick:
|
||||
name:
|
||||
apt: graphicsmagick
|
||||
graphicsmagick-compatibility:
|
||||
name:
|
||||
apt: graphicsmagick-imagemagick-compat
|
||||
timg:
|
||||
name:
|
||||
apt: timg
|
||||
tmux:
|
||||
name:
|
||||
apt: tmux
|
||||
# @TODO add glow apt repository in install@linux bootstrap role play before uncommenting the below
|
||||
# glow:
|
||||
# name:
|
||||
# apt: glow
|
||||
# @TODO add ZFS apt repository in install@linux bootstrap role play before uncommenting the below
|
||||
# zfs:
|
||||
# name:
|
||||
# apt: zfsutils-linux
|
||||
# @TODO manually install the commented below on current active new VPS, then uncomment
|
||||
# dpkg-dev:
|
||||
# name:
|
||||
# apt: dpkg-dev
|
||||
# ldap-utils:
|
||||
# name:
|
||||
# apt: ldap-utils
|
||||
# slapd:
|
||||
# name:
|
||||
# apt: slapd
|
||||
proftpd-mod-crypto:
|
||||
name:
|
||||
apt: proftpd-mod-crypto
|
||||
# @TODO write configuration files and handler for below two package installations
|
||||
# based on:
|
||||
clamav:
|
||||
name:
|
||||
apt: clamav
|
||||
clamd:
|
||||
name:
|
||||
apt: clamav-daemon
|
||||
proftpd:
|
||||
name:
|
||||
apt: proftpd
|
||||
proftpd-docs:
|
||||
name:
|
||||
apt: proftpd-doc
|
||||
rsync:
|
||||
name:
|
||||
apt: rsync
|
||||
# rclone:
|
||||
# name:
|
||||
# apt: rclone
|
||||
aria:
|
||||
name:
|
||||
apt: aria2
|
||||
# mopidy:
|
||||
# name:
|
||||
# apt: mopidy
|
||||
# mopidy-mpd:
|
||||
# name:
|
||||
# apt: mopidy-mpd
|
||||
# caddy:
|
||||
# name:
|
||||
# apt: caddy
|
||||
snaps:
|
||||
nextcloud:
|
||||
name: nextcloud
|
||||
channel: ~
|
||||
opts:
|
||||
- "nextcloud:php.memory-limit=512M"
|
||||
- "nextcloud:nextcloud.cron-interval=10m"
|
||||
- "nextcloud:http.compression=true"
|
||||
- "nextcloud:ports.http=81"
|
||||
# @TODO see how to set these options: https://help.nextcloud.com/t/how-to-configure-nextcloud-snap/216036#p-649442-trusted-domains-configuration-8
|
||||
# @TODO see how to set these options: https://help.nextcloud.com/t/how-to-configure-nextcloud-snap/216036#p-649442-trusted-proxy-configuration-9
|
||||
links:
|
||||
quartz:
|
||||
name: quartz
|
||||
src: https://github.com/jackyzha0/quartz.git
|
||||
branch: v4
|
||||
version: ~
|
||||
output: ~
|
||||
config:
|
||||
git:
|
||||
sys:
|
||||
editor: nvim
|
||||
proftpd:
|
||||
name: "{{ hostvars[inventory_hostname].fqdn.split('.')[0] }}"
|
||||
auth_paths:
|
||||
users: /etc/proftpd/ftpd.passwd
|
||||
groups: /etc/proftpd/ftpd.group
|
||||
msg:
|
||||
welcome: "Our head librarians Furcas and Marbas welcome you!"
|
||||
users:
|
||||
webmaster:
|
||||
username: webmaster
|
||||
id: "{{ ['caddy', 'www-data'][0] }}"
|
||||
gid: "{{ ['caddy', 'www-data'][0] }}"
|
||||
# @TODO create vaulted password for this ProFTPd virtual user
|
||||
password: !vault |
|
||||
$ANSIBLE_VAULT;1.2;AES256;vps1-webmaster
|
||||
63633938633139636663623166343836643839306538373762393834393230336334383334303163
|
||||
3465323831366163386265353664313932383664373838660a363463303364373963353638396462
|
||||
65356135623030653533333766623865643065303739386538636662303537376466333039613363
|
||||
3932313334643163650a303336623031613964356433363536373236303266663735343939383930
|
||||
3636
|
||||
services: [http,https]
|
||||
smuggler:
|
||||
username: smuggler
|
||||
id: "{{ hostvars[inventory_hostname].users.ftp.username }}"
|
||||
gid: "{{ hostvars[inventory_hostname].users.ftp.group | default(hostvars[inventory_hostname].users.ftp.username) }}"
|
||||
# @TODO create vaulted password for this ProFTPd virtual user
|
||||
password: !vault |
|
||||
$ANSIBLE_VAULT;1.2;AES256;vps1-smuggler
|
||||
38396565313866383761303137343431613830643436666431316434393362623035623031656263
|
||||
6537313630393433336133643166363564383163616232320a623034636664353864613862353366
|
||||
38303663363665663366336131663431383936306131616262376162653837326163393561323465
|
||||
3734333031323330300a353562353035323731303732323534613938353935393433646235356137
|
||||
62336333666362383665623466353337303134623966663061366235303261653333
|
||||
services: []
|
||||
tls_paths:
|
||||
cert: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.crt"
|
||||
privkey: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.key"
|
||||
nextcloud:
|
||||
users:
|
||||
admin:
|
||||
username: admin
|
||||
# @TODO change this password to ansible-vaulted actual choice password later
|
||||
password: password123 # @NOTE placeholder
|
||||
phone_region: US
|
||||
aria:
|
||||
checksum: ~
|
||||
api_key: ~
|
||||
|
||||
Reference in New Issue
Block a user