fix storage box permissions for backup-sync user
parent
7f3f811afb
commit
750241cd47
|
@ -0,0 +1 @@
|
||||||
|
.vault.secret filter=git-crypt diff=git-crypt
|
|
@ -1,6 +1,5 @@
|
||||||
[defaults]
|
[defaults]
|
||||||
vault_identity=62a40f49-7deb-45e3-8c17-639277033357
|
vault_password_file=.vault.secret
|
||||||
vault_password_file=scripts/gopass-client.py
|
|
||||||
host_key_checking = False
|
host_key_checking = False
|
||||||
inventory = inventories/hosts.ini
|
inventory = inventories/hosts.ini
|
||||||
roles_path = ~/.ansible/roles:./roles:/usr/share/ansible/roles:/etc/ansible/roles
|
roles_path = ~/.ansible/roles:./roles:/usr/share/ansible/roles:/etc/ansible/roles
|
||||||
|
|
|
@ -23,14 +23,14 @@ backup_group: "{{ backup_owner }}"
|
||||||
backup_chroot_dir: /mnt/backup
|
backup_chroot_dir: /mnt/backup
|
||||||
|
|
||||||
storage_box_enabled: no
|
storage_box_enabled: no
|
||||||
storage_box_host: storage.example.com
|
storage_box_host: "{{ storage_box_username.split('-') | first }}.your-storagebox.de"
|
||||||
storage_box_port: 23
|
storage_box_port: 23
|
||||||
storage_box_path: /home/backup
|
storage_box_path: /home/backup
|
||||||
storage_box_mount:
|
storage_box_mount:
|
||||||
path: "{{ backup_chroot_dir }}"
|
path: "{{ backup_chroot_dir }}"
|
||||||
owner: "{{ backup_owner }}"
|
owner: "{{ backup_owner }}"
|
||||||
group: "{{ backup_group }}"
|
group: "{{ backup_group }}"
|
||||||
options: [rw,default_permissions]
|
options: "{{ storage_box_default_mount_options }}"
|
||||||
storage_box_username: u123456-sub1
|
storage_box_username: u123456-sub1
|
||||||
storage_box_password: somesecret
|
storage_box_password: somesecret
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
name: "{{ backup_owner }}"
|
name: "{{ backup_owner }}"
|
||||||
groups: []
|
groups: []
|
||||||
|
|
||||||
- name: Ensure backup directory is read-only for backup user
|
- name: Create backup directory
|
||||||
file:
|
file:
|
||||||
path: "{{ backup_chroot_dir }}"
|
path: "{{ backup_chroot_dir }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: "og=rx"
|
mode: "755"
|
||||||
|
when: not storage_box_enabled
|
||||||
|
|
||||||
- name: Include Storage Box backup tasks
|
- name: Include Storage Box backup tasks
|
||||||
import_tasks: backup_storage_box.yml
|
import_tasks: backup_storage_box.yml
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
path: /etc/auto.backup.{{ storage_box_prefix }}
|
path: /etc/auto.backup.{{ storage_box_prefix }}
|
||||||
regex: "^{{ storage_box_mount.path }} "
|
regex: "^{{ storage_box_mount.path }} "
|
||||||
line: |
|
line: |
|
||||||
{{ storage_box_mount.path }} -fstype=fuse,{{ storage_box_mount.options | join(',') }},uid={{ storage_box_mount.owner }},gid={{ storage_box_mount.group }} :sshfs\#{{ storage_box_host }}\:{{ storage_box_path }}
|
{{ storage_box_mount.path }} -fstype=fuse,{{ storage_box_mount.options | join(',') }} :sshfs\#{{ storage_box_host }}\:{{ storage_box_path }}
|
||||||
state: present
|
state: present
|
||||||
create: yes
|
create: yes
|
||||||
notify: reload autofs
|
notify: reload autofs
|
||||||
|
|
|
@ -4,6 +4,13 @@ storage_box_packages:
|
||||||
- sshpass
|
- sshpass
|
||||||
- sshfs
|
- sshfs
|
||||||
- autofs
|
- autofs
|
||||||
|
storage_box_default_mount_options:
|
||||||
|
- rw
|
||||||
|
- default_permissions
|
||||||
|
- allow_other
|
||||||
|
- uid=root
|
||||||
|
- gid={{ backup_group }}
|
||||||
borg_packages:
|
borg_packages:
|
||||||
- borgbackup
|
- borgbackup
|
||||||
- borgmatic
|
- borgmatic
|
||||||
|
borg_umask: "{{ storage_box_enabled | ternary('0027', '0022') }}"
|
|
@ -1,97 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import configparser
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
ANSIBLE_ENV_DIR = os.getenv("ANSIBLE_CONFIG")
|
|
||||||
ANSIBLE_DIR = "/etc/ansible"
|
|
||||||
CURRENT_DIR = os.getcwd()
|
|
||||||
HOME_DIR = os.getenv("HOME")
|
|
||||||
|
|
||||||
ANSIBLE_CONFIG_SECTION = "gopass"
|
|
||||||
ANSIBLE_CONFIG_KEY = "key_path"
|
|
||||||
|
|
||||||
class ShutdownHandler(logging.Handler):
|
|
||||||
def emit(self, record):
|
|
||||||
logging.shutdown()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def find_ansible_config_value(section, key):
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
|
|
||||||
ansible_config_dirs = [CURRENT_DIR, HOME_DIR, ANSIBLE_DIR]
|
|
||||||
if ANSIBLE_ENV_DIR:
|
|
||||||
ansible_config_dirs.insert(0, ANSIBLE_ENV_DIR)
|
|
||||||
|
|
||||||
for ansible_config_dir in ansible_config_dirs:
|
|
||||||
ansible_config_path = os.path.join(ansible_config_dir, "ansible.cfg")
|
|
||||||
config.read(ansible_config_path)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return config[section][key]
|
|
||||||
except KeyError:
|
|
||||||
logging.debug(f"Cannot find '{key}' key in '{ansible_config_path}' config file")
|
|
||||||
|
|
||||||
ansible_config_paths = ':'.join(ansible_config_dirs)
|
|
||||||
raise RuntimeError(f"Cannot find key '{ANSIBLE_CONFIG_KEY}' in {ansible_config_paths}")
|
|
||||||
|
|
||||||
def build_arg_parser():
|
|
||||||
parser = argparse.ArgumentParser(description='Get a vault password from user keyring')
|
|
||||||
|
|
||||||
parser.add_argument('--vault-id', action='store', default='',
|
|
||||||
dest='vault_id',
|
|
||||||
help='Name of the vault secret to get from keyring')
|
|
||||||
return parser
|
|
||||||
|
|
||||||
def main():
|
|
||||||
logger = logging.getLogger()
|
|
||||||
logger.setLevel(logging.NOTSET)
|
|
||||||
|
|
||||||
formatter = logging.Formatter("%(levelname)s: %(message)s")
|
|
||||||
|
|
||||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
||||||
stdout_handler.setLevel(logging.INFO)
|
|
||||||
stdout_handler.addFilter(lambda record: record.levelno <= logging.INFO)
|
|
||||||
stdout_handler.setFormatter(formatter)
|
|
||||||
logger.addHandler(stdout_handler)
|
|
||||||
|
|
||||||
stderr_handler = logging.StreamHandler(sys.stderr)
|
|
||||||
stderr_handler.setLevel(logging.WARNING)
|
|
||||||
stderr_handler.setFormatter(formatter)
|
|
||||||
logger.addHandler(stderr_handler)
|
|
||||||
|
|
||||||
logger.addHandler(ShutdownHandler(level=logging.ERROR))
|
|
||||||
|
|
||||||
try:
|
|
||||||
ansible_config_value = find_ansible_config_value(ANSIBLE_CONFIG_SECTION, ANSIBLE_CONFIG_KEY)
|
|
||||||
except RuntimeError as e:
|
|
||||||
logging.error(e)
|
|
||||||
|
|
||||||
arg_parser = build_arg_parser()
|
|
||||||
args = arg_parser.parse_args()
|
|
||||||
|
|
||||||
ansible_vault_id = args.vault_id
|
|
||||||
gopass_key_path = os.path.join(ansible_config_value, ansible_vault_id)
|
|
||||||
|
|
||||||
gopass_keys_cmd = subprocess.run(["gopass", "ls", "--flat"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
if gopass_keys_cmd.returncode != 0:
|
|
||||||
logging.error(gopass_keys_cmd.stderr.decode())
|
|
||||||
gopass_keys = map(bytes.decode, gopass_keys_cmd.stdout.splitlines())
|
|
||||||
|
|
||||||
try:
|
|
||||||
gopass_keyname = next(key for key in gopass_keys if key.endswith(gopass_key_path))
|
|
||||||
except StopIteration:
|
|
||||||
logging.error(f"Cannot find '{gopass_key_path}' entry in gopass")
|
|
||||||
|
|
||||||
ansible_vault_pass_cmd = subprocess.run(["gopass", "show", "-o", gopass_keyname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
if ansible_vault_pass_cmd.returncode != 0:
|
|
||||||
logging.error(ansible_vault_pass_cmd.stderr.decode())
|
|
||||||
print(ansible_vault_pass_cmd.stdout.decode())
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
Loading…
Reference in New Issue