Compare commits

...

14 Commits

Author SHA1 Message Date
Alex Tavarez
93bc285f3d Started creation of play after VPS has been made and initial configuration of main services has been done 2025-11-16 14:02:09 -05:00
Alex Tavarez
c0a798837d Added a new major task for later 2025-11-16 14:01:14 -05:00
Alex Tavarez
856704f9d7 Added some configuration information for ProFTPd to be used by its configuration file templates ireferred to by its handler 2025-11-16 14:00:43 -05:00
Alex Tavarez
f74482c400 Re-added a line specifying a default root for default server and moved MaxInstances line into here due to it being more appropriate context 2025-11-16 13:59:49 -05:00
Alex Tavarez
a6218cbaef fix: changed join function sytnax to correct Python method syntax 2025-11-16 13:58:37 -05:00
Alex Tavarez
8c88322621 Renamed file and edited to render it exemplar 2025-11-16 13:57:30 -05:00
Alex Tavarez
960f54efca Added more directives to file to increase security of and friendliness of ProFTPd FTP server 2025-11-16 13:55:15 -05:00
Alex Tavarez
a6039e2c13 Added an import of task transfering over SSL/TLS certificates 2025-11-16 13:53:51 -05:00
Alex Tavarez
c3eed3e396 Added a task to transfer over and register FQDN certificates from Ansible to remote machine 2025-11-16 13:53:02 -05:00
Alex Tavarez
4fad50c9dc Created a task for creating public FTP directory, created MOTD script transfer tasks 2025-11-16 13:51:47 -05:00
Alex Tavarez
ea2346c41b Added importing of ProFTPd handler task to main bootstraps role handler 2025-11-16 13:49:15 -05:00
Alex Tavarez
8b2390a1b7 Added a handler for configuring ProFTPd after it has been installed 2025-11-16 13:47:56 -05:00
Alex Tavarez
ee8a391d0e Added list of basenames for SSH MOTD scripts for ease of selection, and added a service to a user 2025-11-16 13:47:06 -05:00
Alex Tavarez
460e3f42ce Added exclusions of files with variable values specific to my use case, rather than being generic 2025-11-16 13:45:27 -05:00
15 changed files with 311 additions and 100 deletions

6
.gitignore vendored
View File

@@ -7,8 +7,10 @@ hosts.yml
**/*.asc **/*.asc
**/*.pem **/*.pem
**/*.ppk **/*.ppk
**/*.crt
**/*.cert
log.txt log.txt
**/update-motd.d/00-logo.sh **/update-motd.d/*.sh
**/update-motd.d/01-server.sh **/vhost@vps1-sukaato.moe.conf.j2
motd motd
banner banner

View File

@@ -39,6 +39,10 @@ vps_service:
- ~/.ssh/id_ecdsa-sha2_sukaato_yubikey.ppk - ~/.ssh/id_ecdsa-sha2_sukaato_yubikey.ppk
- ~/.ssh/id_ecdsa-sha2_sukaato_miniyubikey.ppk - ~/.ssh/id_ecdsa-sha2_sukaato_miniyubikey.ppk
ssh_private_key_path_pref: 0 ssh_private_key_path_pref: 0
ssh_motd_script_basenames:
- 00-logo.sh
- 01-server.sh
- 02-info.sh
keywords: keywords:
- social media - social media
- internet - internet
@@ -76,7 +80,7 @@ users:
groups: groups:
- sudo - sudo
- "{{ groups.remote.group_name }}" - "{{ groups.remote.group_name }}"
services: [] services: [sshd]
ssh_authorized_keys: "{{ custom_vars.generality.ssh_authorized_keys }}" ssh_authorized_keys: "{{ custom_vars.generality.ssh_authorized_keys }}"
ssh_private_key_paths: "{{ custom_vars.generality.ssh_private_key_paths }}" ssh_private_key_paths: "{{ custom_vars.generality.ssh_private_key_paths }}"
ssh_private_key_path_pref: 0 ssh_private_key_path_pref: 0
@@ -123,7 +127,7 @@ users:
group: ~ group: ~
groups: groups:
- "{{ groups.remote.group_name }}" - "{{ groups.remote.group_name }}"
services: [proftpd,sftp] services: [proftpd,sftp,ftps]
ssh_authorized_keys: "{{ custom_vars.generality.ssh_authorized_keys }}" ssh_authorized_keys: "{{ custom_vars.generality.ssh_authorized_keys }}"
ssh_private_key_paths: "{{ custom_vars.generality.ssh_private_key_paths }}" ssh_private_key_paths: "{{ custom_vars.generality.ssh_private_key_paths }}"
ssh_private_key_path_pref: 0 ssh_private_key_path_pref: 0

9
playbooks/soft-init.yml Normal file
View File

@@ -0,0 +1,9 @@
---
- name: Configure the rest of the system for the administrative user(s)
hosts: vps1
# remote_user: # @NOTE can be uncommented to insert known administrative user
# @NOTE below can be uncommented to insert known administrative user
# vars:
# ansible_user: root
tasks:

View File

@@ -4,3 +4,6 @@
- name: Postinstall set-up of git - name: Postinstall set-up of git
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: git.yml file: git.yml
- name: Postinstall set-up of ProFTPd
ansible.builtin.import_tasks:
file: proftpd.yml

View File

@@ -6,17 +6,25 @@
become: true become: true
block: block:
- name: Create ProFTPd non-web user subdirectories - 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: ansible.builtin.file:
follow: true # follow: true
force: true force: true
group: "{{ item.value.chown.split(':')[0] }}" owner: "{{ item[0]['username'] }}"
owner: "{{ item.value.chown.split(':')[1] }}" group: "{{ item[0]['group'] | default(item[0]['username']) }}"
path: "{{ item.value.chroot }}" path: "{{ item[0]['home'] | default('/home/' ~ item[0]['username']) }}/{{ item[1]['username'] }}"
state: directory state: directory
loop: "{{ lookup('ansible.builtin.dict', config.proftpd.vusers) }}" loop: "{{ hostvars[inventory_hostname]['users'].values() | product(config['proftpd']['vusers'].values()) }}"
# @TODO complete below commented out tasks - name: Create ProFTPd FTP public directory for anonymous logins
# - name: Provide TLS/SSL resources for FTPS capabilities with ProFTPd when: "'ftps' in item.value['services']"
# - name: Load prerequisite modules for intended configuration 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 - name: Configure ProFTPd main control server
ansible.builtin.template: ansible.builtin.template:
backup: true backup: true
@@ -31,6 +39,7 @@
validate: proftpd --configtest validate: proftpd --configtest
vars: vars:
ftp_server_name: init ftp_server_name: init
max_conns: 30
- name: Configure ProFTPd global settings - name: Configure ProFTPd global settings
ansible.builtin.template: ansible.builtin.template:
backup: true backup: true
@@ -45,25 +54,60 @@
validate: proftpd --configtest validate: proftpd --configtest
vars: vars:
pasv_ports: "49152 65534" pasv_ports: "49152 65534"
max_conns: 30
allow_symlinks: false 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_filepaths']) }}"
- 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_of'] }})"
- "--gid=$(id -g {{ item.value['gid_of'] }})"
- "--home={{ hostvars[inventory_hostname]['users']['ftp']['home'] | default('/srv/ftp') }}/{{ item.value['username'] }}"
- --shell=/sbin/nologin
- --file={{ config['proftpd']['auth_filepaths']['users_path'] }}
- --stdin
stdin: "{{ item.value['password'] }}"
loop: "{{ lookup('ansible.builtin.dict', config['proftpd']['vusers']) }}"
- 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_of'] }})"
- "--member={{ item.value['username'] }}"
- --file={{ config['proftpd']['auth_filepaths']['groups_path'] }}
loop: "{{ lookup('ansible.builtin.dict', config['proftpd']['vusers']) }}"
# @TODO create tasks in block integrating LDAP users to ProFTPd
# - name: Integrate LDAP users into ProFTPd
- name: Create ProFTPd FTPS virtual host - name: Create ProFTPd FTPS virtual host
ansible.builtin.template: ansible.builtin.template:
backup: true backup: true
comment_end_string: "#}" comment_end_string: "#}"
comment_start_string: "{#" comment_start_string: "{#"
dest: "/etc/proftpd/conf.d/{{ config.proftpd.name.lowercase() }}.conf" dest: "/etc/proftpd/conf.d/{{ config['proftpd']['name'].lowercase() }}.conf"
follow: true follow: true
force: true force: true
group: root group: root
owner: root owner: root
src: proftpd/conf.d/vhost@vps1.conf.j2 src: "proftpd/conf.d/vhost@vps1-{{ hostvars[inventory_hostname].fqdn }}.conf.j2"
validate: proftpd --configtest validate: proftpd --configtest
vars: vars:
ftp_server_name: "{{ config.proftpd.name.uppercase() }}'s Archive'" ftp_server_name: "{{ config['proftpd']['name'].uppercase() }}'s Archive'"
# @TODO finish constructing below block task 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']['vusers'].values())))) }}"
# - name: Add virtual users to ProFTPd FTPS virtual host 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"
# block: anon_user: "{{ config['proftpd']['vusers']['smuggler']['username'] }}"
# - name: Create the virtual users
# - name: Specify what virtual users are allowed login
# - name: Specify restrictions for virtual users on the directories they will reside in

View File

@@ -1,6 +1,24 @@
#SPDX-License-Identifier: MIT-0 #SPDX-License-Identifier: MIT-0
--- ---
# tasks file for bootstrap # 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 - name: Create hidden SSH directories under users' home directories
when: hostvars[inventory_hostname].groups.remote.group_name in item.value.groups when: hostvars[inventory_hostname].groups.remote.group_name in item.value.groups
ansible.builtin.file: ansible.builtin.file:
@@ -17,7 +35,7 @@
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 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: ansible.builtin.copy:
backup: true backup: true
content: "{{ item.value.ssh_authorized_keys.join('\n') }}" content: "{{ '\n'.join(item.value.ssh_authorized_keys) }}"
dest: "{{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh/authorized_keys" dest: "{{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh/authorized_keys"
# follow: true # follow: true
force: true force: true
@@ -29,21 +47,29 @@
- ensure_files - ensure_files
- name: Harden SSH security - name: Harden SSH security
block: 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 - name: Set users in group ftp to only be usable with SSH's SFTP service
when: "'sftp' in item.value.services" when: "'sftp' in item.value.services"
ansible.builtin.blockinfile: ansible.builtin.blockinfile:
backup: true backup: true
block: | 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) }} Match Group {{ item.value.group | default(item.value.username) }}
ForceCommand internal-sftp -d /%u ForceCommand internal-sftp -d /%u
ChrootDirectory {{ item.value.home | default('/home/' ~ item.value.username) }} ChrootDirectory {{ item.value.home | default('/home/' ~ item.value.username) }}
AllowAgentForwarding no AllowAgentForwarding no
AllowTcpForwarding no AllowTcpForwarding no
X11Forwarding no X11Forwarding no
Match User {{ item.value.username }}
ForceCommand internal-sftp -d /public
AuthorizedKeysFile {{ item.value.home | default('/home/' ~ item.value.username) }}/.ssh/authorized_keys
create: true create: true
group: root group: root
insertafter: EOF insertafter: EOF

View File

@@ -0,0 +1,39 @@
#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"

View File

@@ -4,6 +4,9 @@
- name: Populate system with groups and user accounts - name: Populate system with groups and user accounts
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: "create_users@{{ ansible_facts['system'].lowercase() }}.yml" 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 - name: Configure SSH for root
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: "configure_ssh@{{ ansible_facts['system'].lowercase() }}.yml" file: "configure_ssh@{{ ansible_facts['system'].lowercase() }}.yml"

View File

@@ -1,22 +1,31 @@
<Global> <Global>
PassivePorts {{ pasv_ports }} # PassivePorts {{ pasv_ports }}
RequireValidShell off RequireValidShell off
MaxInstances {{ max_conns }}
{% if allow_symlinks %} {% if allow_symlinks %}
ShowSymlinks on ShowSymlinks on
{% else %} {% else %}
ShowSymlinks off ShowSymlinks off
{% endif %} {% endif %}
AllowRetrieveRestart on
HiddenStores .%P- .frag
DisplayLogin WELCOME.msg DisplayLogin /etc/proftpd/WELCOME.txt
DisplayChdir .README.md true DisplayChdir .README.md true
DisplayConnect BANNER.msg DisplayConnect /etc/proftpd/BANNER.txt
DisplayFileTransfer SUCCESS.msg DisplayFileTransfer /etc/proftpd/SUCCESS.txt
DisplayReadme /etc/proftpd/ANNOUNCE.md
DisplayQuit /etc/proftpd/BYE.txt
TimeoutNoTransfer 3600 TimeoutNoTransfer 3600
TimeoutStalled 210 TimeoutStalled 210
TimeoutIdle 1400 TimeoutIdle 1400
Umask 022 022 Umask 0022 0022
AllowOverwrite on AllowOverwrite on
<Directory />
<Limit ALL>
DenyAll
</Limit>
</Directory>
</Global> </Global>

View File

@@ -0,0 +1,93 @@
<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_filepaths.users_path }}
AuthGroupFile {{ config.proftpd.auth_filepaths.groups_path }}
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>

View File

@@ -1,41 +0,0 @@
<VirtualHost 0.0.0.0>
ServerName {{ ftp_server_name }}
ServerIdent on "You have arrived at {{ ftp_server_name }}!"
ServerAlias {{ hostvars[inventory_hostname].fqdn }}
ServerAlias ftp.{{ hostvars[inventory_hostname].fqdn }}
ServerAlias {{ hostvars[inventory_hostname].fqdn.split('.')[0] }}
ServerLog /var/log/proftpd/{{ hostvars[inventory_hostname].fqdn.split('.')[0] }}.log
Protocols ftps
Port 990
# AuthOrder mod_auth_pam.c mod_auth_unix.c*
AuthOrder mod_auth_file.c
AuthUserFile /etc/proftpd/ftpd.passwd
AuthGroupFile /etc/proftpd/ftpd.group
AuthFileOptions SyntaxCheck
TLSEngine on
TLSLog /var/log/proftpd/tls.log
# @NOTE: "AALv23" 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 }}
<Anonymous /srv/ftp/public>
<Directory *>
<Limit WRITE CDUP CWD PWD>
DenyAll
</Limit>
<Limit READ>
AllowAll
</Limit>
</Directory>
</Anonymous>
<VirtualHost>

View File

@@ -11,7 +11,7 @@ Include /etc/proftpd/modules.conf
UseIPv6 on UseIPv6 on
# If set on you can experience a longer connection delay in many cases. # If set on you can experience a longer connection delay in many cases.
<IfModule mod_ident.c> <IfModule mod_ident.c>
IdentLookups off IdentLookups on
</IfModule> </IfModule>
ServerName "{{ ftp_server_name }}" ServerName "{{ ftp_server_name }}"
@@ -19,16 +19,15 @@ ServerName "{{ ftp_server_name }}"
# Read README.Debian for more information on proper configuration. # Read README.Debian for more information on proper configuration.
ServerType standalone ServerType standalone
DeferWelcome off DeferWelcome off
MaxInstances {{ max_conns }}
# Disable MultilineRFC2228 per https://github.com/proftpd/proftpd/issues/1085 # Disable MultilineRFC2228 per https://github.com/proftpd/proftpd/issues/1085
# MultilineRFC2228on # MultilineRFC2228on
DefaultServer on DefaultServer on
DefaultRoot ~
DenyFilter \*.*/ DenyFilter \*.*/
# Use this to jail all users in their homes
DefaultRoot ~
# Users require a valid shell listed in /etc/shells to login. # Users require a valid shell listed in /etc/shells to login.
# Use this directive to release that constrain. # Use this directive to release that constrain.
# RequireValidShell off # RequireValidShell off

View File

@@ -1,15 +1,15 @@
{% if list_type == 'whitelist' %} {% if list_type == 'whitelist' %}
{% if policed_groups is not None and len(policed_groups) > 0 %} {% if policed_groups is not None and len(policed_groups) > 0 %}
AllowGroups {{ policed_groups.join(' ') }} AllowGroups {{ ' '.join(policed_groups) }}
{% endif %} {% endif %}
{% if policed_users is not None and len(policed_users) > 0 %} {% if policed_users is not None and len(policed_users) > 0 %}
AllowUsers {{ policed_users.join(' ') }} AllowUsers {{ ' '.join(policed_users) }}
{% endif %} {% endif %}
{% else %} {% else %}
{% if policed_groups is not None and len(policed_groups) > 0 %} {% if policed_groups is not None and len(policed_groups) > 0 %}
DenyGroups {{ policed_groups.join(' ') }} DenyGroups {{ ' '.join(policed_groups) }}
{% endif %} {% endif %}
{% if policed_users is not None and len(policed_users) > 0 %} {% if policed_users is not None and len(policed_users) > 0 %}
DenyGroups {{ policed_users.join(' ') }} DenyGroups {{ ' '.join(policed_users) }}
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@@ -186,6 +186,13 @@ software:
proftpd-mod-crypto: proftpd-mod-crypto:
name: name:
apt: proftpd-mod-crypto apt: proftpd-mod-crypto
proftpd-mod-ldap:
name:
apt: proftpd-mod-ldap
# @TODO manually install the commented below on current active new VPS, then uncomment
# proftpd-mod-clamav:
# name:
# apt: proftpd-mod-clamav
proftpd: proftpd:
name: name:
apt: proftpd apt: proftpd
@@ -216,20 +223,39 @@ config:
editor: nvim editor: nvim
proftpd: proftpd:
name: "{{ hostvars[inventory_hostname].fqdn.split('.')[0] }}" name: "{{ hostvars[inventory_hostname].fqdn.split('.')[0] }}"
auth_filepaths:
users_path: /etc/proftpd/ftpd.passwd
groups_path: /etc/proftpd/ftpd.group
msg:
welcome: "Our head librarians Furcas and Marbas welcome you!"
vusers: vusers:
# webmaster: webmaster:
# username: webmaster username: webmaster
# chroot: "/srv/www/{{ fqdn }}" id_of: "{{ ['caddy', 'www-data'][0] }}"
# chown: "caddy:caddy" gid_of: "{{ ['caddy', 'www-data'][0] }}"
# # @TODO create vaulted password for this ProFTPd virtual user # @TODO create vaulted password for this ProFTPd virtual user
# password: ~ password: !vault |
$ANSIBLE_VAULT;1.2;AES256;vps1-webmaster
63633938633139636663623166343836643839306538373762393834393230336334383334303163
3465323831366163386265353664313932383664373838660a363463303364373963353638396462
65356135623030653533333766623865643065303739386538636662303537376466333039613363
3932313334643163650a303336623031613964356433363536373236303266663735343939383930
3636
services: [http,https]
smuggler: smuggler:
username: smuggler username: smuggler
chroot: /srv/ftp/smuggler id_of: "{{ hostvars[inventory_hostname].users.ftp.username }}"
chown: "{{ hostvars[inventory_hostname].users.ftp.username }}:{{ hostvars[inventory_hostname].users.ftp.group | default(hostvars[inventory_hostname].users.ftp.username) }}" gid_of: "{{ hostvars[inventory_hostname].users.ftp.group | default(hostvars[inventory_hostname].users.ftp.username) }}"
# @TODO create vaulted password for this ProFTPd virtual user # @TODO create vaulted password for this ProFTPd virtual user
password: ~ password: !vault |
$ANSIBLE_VAULT;1.2;AES256;vps1-smuggler
38396565313866383761303137343431613830643436666431316434393362623035623031656263
6537313630393433336133643166363564383163616232320a623034636664353864613862353366
38303663363665663366336131663431383936306131616262376162653837326163393561323465
3734333031323330300a353562353035323731303732323534613938353935393433646235356137
62336333666362383665623466353337303134623966663061366235303261653333
services: []
tls_paths: tls_paths:
cert: /etc/proftpd/certs/cert.pem cert: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.crt"
privkey: /etc/proftpd/certs/private-key.pem privkey: "/usr/local/share/ca-certificates/{{ hostvars[inventory_hostname].fqdn }}.key"

View File

@@ -3,12 +3,7 @@
#+language: en #+language: en
* PLANNED * PLANNED
** TODO [#A] Add more sections to ~README.md~, as enlisted below ** TODO [#A] Rewrite dot notation usage of keys for accessing values in custom dictionary variables to bracket notation usage of keys across whole project
- Section about inventory conventional groups, with subsection on essential or avaialble host/group variables
- Section about available roles, with subsection on essential or available role variables
- Section about available playbooks, with subsection on essential or available playbook variables
- Section about conventional external variable files, their location(s) and the semantics of their filenames
- Section about conventions for handling sensitive information, and for directory tree structures under ~${SUKAATO_ANSIBLE_PROJECT}/playbooks/{files,templates}~ or ~${SUKAATO_ANSIBLE_PROJECT}/.ansible/roles/**/{files,templates}~
* IN PROGRESS * IN PROGRESS