Vendor Galaxy Roles and Collections
Some checks failed
/ Ansible Lint (push) Failing after 5m45s
/ Ansible Lint (pull_request) Failing after 4m59s

This commit is contained in:
Stefan Bethke 2026-02-06 22:07:16 +01:00
commit 2aed20393f
3553 changed files with 387444 additions and 2 deletions

View file

@ -0,0 +1,19 @@
debops.boxbackup - Manage BoxBackup backup service
Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
Copyright (C) 2015-2019 DebOps <https://debops.org/>
SPDX-License-Identifier: GPL-3.0-only
This Ansible role is part of DebOps.
DebOps is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3, as
published by the Free Software Foundation.
DebOps is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DebOps. If not, see https://www.gnu.org/licenses/.

View file

@ -0,0 +1,124 @@
---
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
# .. Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# .. Copyright (C) 2015-2019 DebOps <https://debops.org/>
# .. SPDX-License-Identifier: GPL-3.0-only
# .. _boxbackup__ref_defaults:
# debops.boxbackup default variables
# ==================================
# .. contents:: Sections
# :local:
#
# .. include:: ../../../../includes/global.rst
# .. envvar:: boxbackup_server [[[
#
# FQDN address of the Box Backup server to use
boxbackup_server: '{{ hostvars[groups.debops_boxbackup[0]]["ansible_fqdn"] }}'
# ]]]
# .. envvar:: boxbackup_allow [[[
#
# Set to list of IP addresses / network ranges to allow access only from these
# networks. Empty list allows access from any host / network.
boxbackup_allow: []
# ]]]
# .. envvar:: boxbackup_storage [[[
#
# Directory where boxbackup-server is storing backups
boxbackup_storage: '/var/local/boxbackup'
# ]]]
# .. envvar:: boxbackup_listenAddresses [[[
#
# boxbackup-server is listening on this IP address (all interfaces by default)
boxbackup_listenaddresses: '0.0.0.0'
# ]]]
# .. envvar:: boxbackup_verbose [[[
#
# Enable/Disable verbose logging
boxbackup_verbose: 'no'
# ]]]
# .. envvar:: boxbackup_account [[[
#
# 32-bit hexadecimal number representing the boxbackup-client account on the server
boxbackup_account: '{{ (ansible_fqdn | sha1)[:8] }}'
# ]]]
# .. envvar:: boxbackup_softlimit [[[
#
# Soft limit for storage space in megabytes, by default it's calculated as
# total disk space of a given host. When used space is bigger than this,
# boxbackup-server starts to remove old and deleted data
boxbackup_softlimit:
# ]]]
# .. envvar:: boxbackup_hardlimit [[[
#
# Hard limit for storage space in megabytes. by default it's calculated as
# soft limit * multiplier (see below). When used space reaches this limit,
# server refuses to accept new data
boxbackup_hardlimit:
# ]]]
# .. envvar:: boxbackup_softlimit_padding [[[
#
# Additional disk space added to soft limit, in megabytes. If this number is
# negative, you will subtract given amount of disk space from calculated soft
# limit
boxbackup_softlimit_padding: 1024
# ]]]
# .. envvar:: boxbackup_hardlimit_multiplier [[[
#
# Hard limit multiplier will by default set hard limit to equal
# soft limit + 50%. If you set this number lower than 1.0, you will have
# smaller hard limit than soft limit, which is not a good idea
boxbackup_hardlimit_multiplier: 1.5
# ]]]
# .. envvar:: boxbackup_email [[[
#
# Email address which will receive alerts from boxbackup. By default it's
# <backup@localhost>, which is usually aliased to root account
boxbackup_email: 'backup'
# ]]]
# .. envvar:: boxbackup_locations [[[
#
# List of directories to back up; directory is a hash key, optional
# exclude/include directives should be written as a text block. Examples can be
# found in the /etc/boxbackup/bbackupd.conf config file
boxbackup_locations:
'/etc': |
ExcludeFile = /etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw
'/home':
'/opt':
'/root':
'/srv':
'/usr/local':
'/var': |
ExcludeDir = /var/spool/postfix/dev
# ]]]
# .. envvar:: boxbackup_locations_custom [[[
#
# List of additional directories / mount points to back up, format is the same
# as a list above
boxbackup_locations_custom:
# ]]]

View file

@ -0,0 +1,14 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Restart boxbackup-server
ansible.builtin.service:
name: 'boxbackup-server'
state: 'restarted'
- name: Restart boxbackup-client
ansible.builtin.service:
name: 'boxbackup-client'
state: 'restarted'

View file

@ -0,0 +1,30 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2022 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# Ensure that custom Ansible plugins and modules included in the main DebOps
# collection are available to roles in other collections.
collections: [ 'debops.debops' ]
dependencies: []
galaxy_info:
author: 'Maciej Delmanowski'
description: 'Install and configure BoxBackup as a centralized backup service'
company: 'DebOps'
license: 'GPL-3.0-only'
min_ansible_version: '1.7.0'
platforms:
- name: 'Ubuntu'
versions: [ 'all' ]
- name: 'Debian'
versions: [ 'all' ]
galaxy_tags:
- backup
- system

View file

@ -0,0 +1,87 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Install Box Backup client package
ansible.builtin.package:
name: 'boxbackup-client'
state: 'present'
register: boxbackup__register_client_packages
until: boxbackup__register_client_packages is succeeded
- name: Set backup softlimit size for client hosts
ansible.builtin.set_fact:
boxbackup_softlimit: '{{ (ansible_mounts | sum(attribute="size_total") / 1024 / 1024
+ boxbackup_softlimit_padding) | int }}'
when: (boxbackup_softlimit is undefined or not boxbackup_softlimit)
- name: Set backup hardlimit size for client hosts
ansible.builtin.set_fact:
boxbackup_hardlimit: '{{ (boxbackup_softlimit | float * boxbackup_hardlimit_multiplier | float) | int }}'
when: (boxbackup_hardlimit is undefined or not boxbackup_hardlimit)
- name: Create accounts for client hosts
ansible.builtin.command: bbstoreaccounts create {{ boxbackup_account }} {{ boxbackup_discnum }}
{{ boxbackup_softlimit }}M {{ boxbackup_hardlimit }}M
args:
creates: '{{ boxbackup_storage }}/backup/{{ boxbackup_account }}/info.rfw'
delegate_to: '{{ boxbackup_server }}'
- name: Make sure that boxbackup client directories exists
ansible.builtin.file:
path: '{{ item }}'
state: 'directory'
owner: 'root'
group: 'root'
mode: '0700'
with_items: [ '/etc/boxbackup', '/etc/boxbackup/bbackupd', '/etc/boxbackup/servers/{{ boxbackup_server }}' ]
- name: Check if encryption key exists on Ansible Controller
ansible.builtin.stat:
path: '{{ secret + "/storage/boxbackup/clients/" + ansible_fqdn + "/" + boxbackup_account + "-FileEncKeys.raw" }}'
register: boxbackup_register_enckeys
delegate_to: 'localhost'
become: False
- name: Download BoxBackup encryption key from archive
ansible.builtin.copy:
src: '{{ secret + "/storage/boxbackup/clients/" + ansible_fqdn + "/" + boxbackup_account + "-FileEncKeys.raw" }}'
dest: '/etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw'
owner: 'root'
group: 'root'
mode: '0600'
when: boxbackup_register_enckeys.stat.exists
notify: [ 'Restart boxbackup-client' ]
- name: Create encryption key on client hosts
ansible.builtin.command: openssl rand -out /etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw
{{ boxbackup_encrypt_bits }}
args:
creates: '/etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw'
notify:
- Restart boxbackup-client
- name: Archive client encryption key
ansible.builtin.fetch:
src: '/etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw'
dest: '{{ secret }}/storage/boxbackup/clients/{{ ansible_fqdn }}/{{ boxbackup_account }}-FileEncKeys.raw'
flat: 'yes'
- name: Install notification script on client hosts
ansible.builtin.template:
src: 'etc/boxbackup/bbackupd/NotifySysadmin.sh.j2'
dest: '/etc/boxbackup/bbackupd/NotifySysadmin.sh'
owner: 'root'
group: 'root'
mode: '0700'
- name: Configure client hosts
ansible.builtin.template:
src: 'etc/boxbackup/bbackupd.conf.j2'
dest: '/etc/boxbackup/bbackupd.conf'
owner: 'root'
group: 'root'
mode: '0600'
notify:
- Restart boxbackup-client

View file

@ -0,0 +1,50 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Install Box Backup server packages
ansible.builtin.package:
name: 'boxbackup-server'
state: 'present'
register: boxbackup__register_server_packages
until: boxbackup__register_server_packages is succeeded
- name: Make sure that boxbackup server directories exists
ansible.builtin.file:
path: '{{ item }}'
state: 'directory'
owner: 'bbstored'
group: 'bbstored'
mode: '0700'
with_items: [ '/etc/boxbackup', '/etc/boxbackup/bbstored',
'{{ boxbackup_storage }}', '{{ boxbackup_storage }}/backup' ]
- name: Check block size of storage device
ansible.builtin.shell: "set -o nounset -o pipefail -o errexit &&
dumpe2fs -h $(df {{ boxbackup_storage }} | tail -n 1 \
| awk '{ print $1 }') | grep 'Block size' | awk '{ print $3 }'"
args:
executable: 'bash'
register: boxbackup_storage_blocksize
changed_when: False
- name: Make sure accounts.txt file exists
ansible.builtin.copy:
force: false
dest: /etc/boxbackup/bbstored/accounts.txt
content: ''
owner: bbstored
group: bbstored
mode: '0600'
- name: Configure boxbackup server
ansible.builtin.template:
src: '{{ item }}.j2'
dest: '/{{ item }}'
owner: 'bbstored'
group: 'bbstored'
mode: '0640'
with_items: [ 'etc/boxbackup/raidfile.conf', 'etc/boxbackup/bbstored.conf' ]
notify:
- Restart boxbackup-server

View file

@ -0,0 +1,16 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Import DebOps secret role
ansible.builtin.import_role:
name: 'secret'
- name: Configure server-side
ansible.builtin.include_tasks: configure_servers.yml
when: boxbackup_server is defined and boxbackup_server == ansible_fqdn
- name: Configure client-side
ansible.builtin.include_tasks: configure_clients.yml
when: boxbackup_server is defined and boxbackup_server != ansible_fqdn

View file

@ -0,0 +1,205 @@
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# This file is managed by Ansible, all changes will be lost
StoreHostname = {{ boxbackup_server }}
AccountNumber = 0x{{ boxbackup_account }}
KeysFile = /etc/boxbackup/bbackupd/{{ boxbackup_account }}-FileEncKeys.raw
CertificateFile = /etc/pki/boxbackup-client/default.crt
PrivateKeyFile = /etc/pki/boxbackup-client/default.key
TrustedCAsFile = /etc/pki/boxbackup-client/CA.crt
DataDirectory = /var/run
{# # This script is run whenever bbackupd changes state or encounters a
# problem which requires the system administrator to assist:
#
# 1) The store is full, and no more data can be uploaded.
# 2) Some files or directories were not readable.
# 3) A backup run starts or finishes.
#
# The default script emails the system administrator, except for backups
# starting and stopping, where it does nothing. #}
NotifyScript = /etc/boxbackup/bbackupd/NotifySysadmin.sh
{% if boxbackup_mode is defined and boxbackup_mode == 'lazy' %}
{# # The number of seconds between backup runs under normal conditions. To avoid
# cycles of load on the server, this time is randomly adjusted by a small
# percentage as the daemon runs. #}
UpdateStoreInterval = {{ (boxbackup_interval | default(60) * 60 | int) | round | int | string }}
{#
# The minimum age of a file, in seconds, that will be uploaded. Avoids
# repeated uploads of a file which is constantly being modified. #}
MinimumFileAge = {{ (boxbackup_minimumfileage | default(6) * 60 * 60 | int) | round | int | string }}
{#
# If a file is modified repeated, it won't be uploaded immediately in case
# it's modified again, due to the MinimumFileAge specified above. However, it
# should be uploaded eventually even if it is being modified repeatedly. This
# is how long we should wait, in seconds, after first noticing a change.
# (86400 seconds = 1 day) #}
MaxUploadWait = {{ (boxbackup_maxuploadwait | default(24) * 60 * 60 | int) | round | int | string }}
{#
# If the connection is idle for some time (e.g. over 10 minutes or 600
# seconds, not sure exactly how long) then the server will give up and
# disconnect the client, resulting in Connection Protocol_Timeout errors
# on the server and TLSReadFailed or TLSWriteFailed errors on the client.
# Also, some firewalls and NAT gateways will kill idle connections after
# similar lengths of time.
#
# This can happen for example when most files are backed up already and
# don't need to be sent to the store again, while scanning a large
# directory, or while calculating diffs of a large file. To avoid this,
# KeepAliveTime specifies that special keep-alive messages should be sent
# when the connection is otherwise idle for a certain length of time,
# specified here in seconds.
#
# The default is that these messages are never sent, equivalent to setting
# this option to zero, but we recommend that all users enable this. #}
KeepAliveTime = 120
{% elif boxbackup_mode is defined and boxbackup_mode == 'snapshot' %}
# This configuration file is written for snapshot mode.
# You will need to run bbackupctl to instruct the daemon to upload files.
AutomaticBackup = no
UpdateStoreInterval = 0
MinimumFileAge = 0
MaxUploadWait = 0
{% endif %}
{# # Files above this size (in bytes) are tracked, and if they are renamed they will simply be
# renamed on the server, rather than being uploaded again. (64k - 1) #}
FileTrackingSizeThreshold = {{ boxbackup_filetrackingsizethreshold | default('65535') }}
{#
# The daemon does "changes only" uploads for files above this size (in bytes).
# Files less than it are uploaded whole without this extra processing. #}
DiffingUploadSizeThreshold = {{ boxbackup_diffinguploadsizethreshold | default('8192') }}
{#
# The limit on how much time is spent diffing files, in seconds. Most files
# shouldn't take very long, but if you have really big files you can use this
# to limit the time spent diffing them.
#
# * Reduce if you are having problems with processor usage.
#
# * Increase if you have large files, and think the upload of changes is too
# large and you want bbackupd to spend more time searching for unchanged
# blocks. #}
MaximumDiffingTime = {{ boxbackup_maximumdiffingtime | default('120') }}
{# # More verbose logging #}
ExtendedLogging = {{ boxbackup_verbose | default('no') }}
{# # This specifies a program or script which is run just before each
# sync, and ideally the full path to the interpreter. It will be run as the
# same user bbackupd is running as, usually root.
#
# The script must output (print) either "now" or a number to STDOUT (and a
# terminating newline, no quotes).
#
# If the result was "now", then the sync will happen. If it's a number, then
# no backup will happen for that number of seconds (bbackupd will pause) and
# then the script will be run again.
#
# Use this to temporarily stop bbackupd from synchronising or connecting to the
# store. For example, you could use this on a laptop to only backup when on a
# specific network, or when it has a working Internet connection.
# SyncAllowScript = /path/to/interpreter/or/exe script-name parameters etc #}
{% if boxbackup_syncallowscript is defined and boxbackup_syncallowscript %}
SyncAllowScript = {{ boxbackup_syncallowscript }}
{% endif %}
{# # Where the command socket is created in the filesystem. #}
CommandSocket = /var/run/bbackupd.sock
{# # Uncomment the StoreObjectInfoFile to enable the experimental archiving
# of the daemon's state (including client store marker and configuration)
# between backup runs. This saves time and increases efficiency when
# bbackupd is frequently stopped and started, since it removes the need
# to rescan all directories on the remote server. However, it is new and
# not yet heavily tested, so use with caution.
# StoreObjectInfoFile = /var/run/bbackupd.state #}
Server
{
PidFile = /var/run/bbackupd.pid
}
{# # BackupLocations specifies which locations on disc should be backed up. Each
# directory is in the format
#
# name
# {
# Path = /path/of/directory
# (optional exclude directives)
# }
#
# 'name' is derived from the Path by the config script, but should merely be
# unique.
#
# The exclude directives are of the form
#
# [Exclude|AlwaysInclude][File|Dir][|sRegex] = regex or full pathname
#
# (The regex suffix is shown as 'sRegex' to make File or Dir plural)
#
# For example:
#
# ExcludeDir = /home/guest-user
# ExcludeFilesRegex = .(mp3|MP3)$
# AlwaysIncludeFile = /home/username/veryimportant.mp3
#
# This excludes the directory /home/guest-user from the backup along with all mp3
# files, except one MP3 file in particular.
#
# In general, Exclude excludes a file or directory, unless the directory is
# explicitly mentioned in a AlwaysInclude directive. However, Box Backup
# does NOT scan inside excluded directories and will never back up an
# AlwaysIncluded file or directory inside an excluded directory or any
# subdirectory thereof.
#
# To back up a directory inside an excluded directory, use a configuration
# like this, to ensure that each directory in the path to the important
# files is included, but none of their contents will be backed up except
# the directories further down that path to the important one.
#
# ExcludeDirsRegex = ^/home/user/bigfiles/
# ExcludeFilesRegex = ^/home/user/bigfiles/
# AlwaysIncludeDir = /home/user/bigfiles/path
# AlwaysIncludeDir = /home/user/bigfiles/path/to
# AlwaysIncludeDir = /home/user/bigfiles/path/important
# AlwaysIncludeDir = /home/user/bigfiles/path/important/files
# AlwaysIncludeDirsRegex = ^/home/user/bigfiles/path/important/files/
# AlwaysIncludeFilesRegex = ^/home/user/bigfiles/path/important/files/
#
# If a directive ends in Regex, then it is a regular expression rather than a
# explicit full pathname. See
#
# man 7 re_format
#
# for the regex syntax on your platform. #}
BackupLocations
{
{% if boxbackup_locations is defined and boxbackup_locations %}
{% for location, options in boxbackup_locations.items() %}
{{ location | replace("/","",1) | replace("/","-") | indent(8,true) }}
{
Path = {{ location }}
{% if options is defined and options %}
{{ options | indent(16,true) }}
{% endif %}
}
{% endfor %}
{% endif %}
{% if boxbackup_locations_custom is defined and boxbackup_locations_custom %}
{% for location, options in boxbackup_locations_custom.items() %}
{{ location | replace("/","",1) | replace("/","-") | indent(8,true) }}
{
Path = {{ location }}
{% if options is defined and options %}
{{ options | indent(16,true) }}
{% endif %}
}
{% endfor %}
{% endif %}
}

View file

@ -0,0 +1,74 @@
#!/bin/sh
# Copyright (C) 2003-2010 Ben Summers and contributors.
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-2.0-or-later
# This file is managed by Ansible, all changes will be lost
# This script is run whenever bbackupd changes state or encounters a
# problem which requires the system administrator to assist:
#
# 1) The store is full, and no more data can be uploaded.
# 2) Some files or directories were not readable.
# 3) A backup run starts or finishes.
#
# The default script emails the system administrator, except for backups
# starting and stopping, where it does nothing.
SUBJECT="BACKUP PROBLEM on host {{ ansible_fqdn }}"
SENDTO="{{ boxbackup_email }}"
if [ "$1" = "" ]; then
echo "Usage: $0 <store-full|read-error|backup-error|backup-start|backup-finish>" >&2
exit 2
elif [ "$1" = store-full ]; then
/usr/sbin/sendmail "$SENDTO" <<EOM
Subject: $SUBJECT (store full)
To: $SENDTO
The store account for {{ ansible_fqdn }} is full.
=============================
FILES ARE NOT BEING BACKED UP
=============================
Please adjust the limits on account {{ boxbackup_account }} on server {{ boxbackup_server }}.
EOM
elif [ "$1" = read-error ]; then
/usr/sbin/sendmail "$SENDTO" <<EOM
Subject: $SUBJECT (read errors)
To: $SENDTO
Errors occurred reading some files or directories for backup on {{ ansible_fqdn }}.
===================================
THESE FILES ARE NOT BEING BACKED UP
===================================
Check the logs on {{ ansible_fqdn }} for the files and directories which caused
these errors, and take appropriate action.
Other files are being backed up.
EOM
elif [ "$1" = backup-start ] || [ "$1" = backup-finish ] || [ "$1" = backup-ok ]; then
# do nothing by default
true
else
/usr/sbin/sendmail "$SENDTO" <<EOM
Subject: $SUBJECT (unknown)
To: $SENDTO
The backup daemon on {{ ansible_fqdn }} reported an unknown error ($1).
==========================
FILES MAY NOT BE BACKED UP
==========================
Please check the logs on {{ ansible_fqdn }}.
EOM
fi

View file

@ -0,0 +1,24 @@
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# This file is managed by Ansible, all changes will be lost
RaidFileConf = /etc/boxbackup/raidfile.conf
AccountDatabase = /etc/boxbackup/bbstored/accounts.txt
# More verbose logging
ExtendedLogging = {{ boxbackup_verbose | default('no') }}
# scan all accounts for files which need deleting every {{ boxbackup_housekeeping | default(15) }} minutes.
TimeBetweenHousekeeping = {{ (boxbackup_housekeeping | default(15) * 60 | int) | round | int | string }}
Server
{
User = bbstored
PidFile = /var/run/bbstored.pid
ListenAddresses = inet:{{ boxbackup_listenaddresses | default('0.0.0.0') }}
CertificateFile = /etc/pki/boxbackup-server/default.crt
PrivateKeyFile = /etc/pki/boxbackup-server/default.key
TrustedCAsFile = /etc/pki/boxbackup-server/CA.crt
}

View file

@ -0,0 +1,14 @@
{# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# This file is managed by Ansible, all changes will be lost
disc0
{
SetNumber = 0
BlockSize = {{ boxbackup_storage_blocksize.stdout | default('4096') }}
Dir0 = {{ boxbackup_storage }}/
Dir1 = {{ boxbackup_storage }}/
Dir2 = {{ boxbackup_storage }}/
}

View file

@ -0,0 +1,164 @@
#!/usr/bin/perl
use strict;
# Copyright (C) 2003-2010 Ben Summers and contributors.
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-2.0-or-later
# This file is managed by Ansible, all changes will be lost
# Modified script based on the "bbstored-certs" Perl script from
# boxbackup-server Debian package
# validity period for client certificates
my $sign_period = '{{ boxbackup_ssl_sign }}';
# check and get command line parameters
if($#ARGV < 0)
{
print <<__E;
sign-cert helper script
Bad command line parameters.
Usage:
sign-cert path/to/account-id-csr.pem
Signing requires confirmation that the certificate is correct and should be signed.
__E
exit(1);
}
# check for OPENSSL_CONF environment var being set
if(exists $ENV{'OPENSSL_CONF'})
{
print <<__E;
---------------------------------------
WARNING:
You have the OPENSSL_CONF environment variable set.
Use of non-standard openssl configs may cause problems.
---------------------------------------
__E
}
# check parameters
my $cert_dir = "{{ secret }}/storage/boxbackup/servers/{{ boxbackup_server }}/ca";
my @args = @ARGV;
if(!-d $cert_dir)
{
die "$cert_dir does not exist";
}
&cmd_sign;
sub cmd_sign
{
my $csr = $args[0];
if(!-f $csr)
{
die "$csr does not exist";
}
# get the common name specified in this certificate
my $common_name = get_csr_common_name($csr);
# look OK?
unless($common_name =~ m/\ABACKUP-([A-Fa-f0-9]+)\Z/)
{
die "The certificate presented does not appear to be a backup client certificate"
}
my $acc = $1;
# check against filename
if(!($csr =~ m/(\A|\/)([A-Fa-f0-9]+)-/) || $2 ne $acc)
{
die "Certificate request filename does not match name in certificate ($common_name)"
}
print <<__E;
This certificate is for backup account
$acc
Ensure this matches the account number you are expecting. The filename is
$csr
which should include this account number, and additionally, you should check
that you received it from the right person.
Signing the wrong certificate compromises the security of your backup system.
Would you like to sign this certificate? (type 'yes' to confirm)
__E
return unless get_confirmation();
# out certificate
my $out_cert = "$cert_dir/clients/$acc"."-cert.pem";
# sign it!
if(system("openssl x509 -req -in $csr -sha1 -extensions usr_crt -CAserial $cert_dir/roots/clientCA.srl -CAcreateserial -CA $cert_dir/roots/clientCA.pem -CAkey $cert_dir/keys/clientRootKey.pem -out $out_cert -days $sign_period") != 0)
{
die "Signing failed"
}
# tell user what to do next
print <<__E;
Certificate signed.
Send the files
$out_cert
$cert_dir/roots/serverCA.pem
to the client.
__E
}
sub get_csr_common_name
{
my $csr = $_[0];
open CSRTEXT,"openssl req -text -in $csr |" or die "Can't open openssl for reading";
my $subject;
while(<CSRTEXT>)
{
$subject = $1 if m/Subject:.+?CN=([-\.\w]+)/
}
close CSRTEXT;
if($subject eq '')
{
die "No subject found in CSR $csr"
}
return $subject
}
sub get_confirmation()
{
my $line = <STDIN>;
chomp $line;
if(lc $line ne 'yes')
{
print "CANCELLED\n";
return 0;
}
return 1;
}

View file

@ -0,0 +1,61 @@
---
# Copyright (C) 2014-2019 Maciej Delmanowski <drybjed@gmail.com>
# Copyright (C) 2015-2019 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# boxbackup backup mode - lazy / snapshot
# Currently only lazy mode is fully supported
boxbackup_mode: 'lazy'
# Encryption key size
boxbackup_encrypt_bits: 2048
# Housekeeping process interval in minutes
boxbackup_housekeeping: 15
# Disc set to use (currently only 0 supported)
boxbackup_discnum: 0
# The number of minutes between backup runs under normal conditions. To avoid
# cycles of load on the server, this time is randomly adjusted by a small
# percentage as the daemon runs.
boxbackup_interval: 60
# The minimum age of a file, in hours, that will be uploaded. Avoids
# repeated uploads of a file which is constantly being modified.
boxbackup_minimumfileage: 4
# If a file is modified repeated, it won't be uploaded immediately in case
# it's modified again, due to the MinimumFileAge specified above. However, it
# should be uploaded eventually even if it is being modified repeatedly. This
# is how long we should wait, in hours, after first noticing a change.
boxbackup_maxuploadwait: 24
# Files above this size (in bytes) are tracked, and if they are renamed they will simply be
# renamed on the server, rather than being uploaded again. (64k - 1)
boxbackup_filetrackingsizethreshold: 65535
# The daemon does "changes only" uploads for files above this size (in bytes).
# Files less than it are uploaded whole without this extra processing.
boxbackup_diffinguploadsizethreshold: 8192
# The limit on how much time is spent diffing files, in seconds. Most files
# shouldn't take very long, but if you have really big files you can use this
# to limit the time spent diffing them.
boxbackup_maximumdiffingtime: 120
# This specifies a program or script which is run just before each
# sync, and ideally the full path to the interpreter. It will be run as the
# same user bbackupd is running as, usually root.
#
# The script must output (print) either "now" or a number to STDOUT (and a
# terminating newline, no quotes).
#
# If the result was "now", then the sync will happen. If it's a number, then
# no backup will happen for that number of seconds (bbackupd will pause) and
# then the script will be run again.
#
# Use this to temporarily stop bbackupd from synchronising or connecting to the
# store. For example, you could use this on a laptop to only backup when on a
# specific network, or when it has a working Internet connection.
boxbackup_syncallowscript: False