Compare commits
14 Commits
e06807ed37
...
93bc285f3d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93bc285f3d
|
||
|
|
c0a798837d
|
||
|
|
856704f9d7
|
||
|
|
f74482c400
|
||
|
|
a6218cbaef
|
||
|
|
8c88322621
|
||
|
|
960f54efca
|
||
|
|
a6039e2c13
|
||
|
|
c3eed3e396
|
||
|
|
4fad50c9dc
|
||
|
|
ea2346c41b | ||
|
|
8b2390a1b7
|
||
|
|
ee8a391d0e
|
||
|
|
460e3f42ce
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -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
|
||||||
@@ -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
9
playbooks/soft-init.yml
Normal 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:
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
39
roles/bootstrap/tasks/configure_ssl@linux.yml
Normal file
39
roles/bootstrap/tasks/configure_ssl@linux.yml
Normal 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"
|
||||||
|
|
||||||
|
|
||||||
@@ -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"
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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 %}
|
||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user