doc: Update forget security considerations and thread model

This commit is contained in:
Leo R. Lundgren 2022-02-19 22:47:35 +01:00
parent 9c1d49e312
commit 676d5d498c
5 changed files with 96 additions and 88 deletions

View file

@ -16,10 +16,9 @@ var cmdForget = &cobra.Command{
Long: ` Long: `
The "forget" command removes snapshots according to a policy. Please note that The "forget" command removes snapshots according to a policy. Please note that
this command really only deletes the snapshot object in the repository, which this command really only deletes the snapshot object in the repository, which
is a reference to data stored there. In order to remove this (now unreferenced) is a reference to data stored there. In order to remove the unreferenced data
data after 'forget' was run successfully, see the 'prune' command. after "forget" was run successfully, see the "prune" command. Please also read
When using this command on special append-only repositories, please see the the documentation for "forget" to learn about important security considerations.
documentation for security considerations.
EXIT STATUS EXIT STATUS
=========== ===========

View file

@ -657,9 +657,8 @@ credentials) is encrypted/decrypted locally, then sent/received via
A more advanced version of this setup forbids specific hosts from removing A more advanced version of this setup forbids specific hosts from removing
files in a repository. See the `blog post by Simon Ruderich files in a repository. See the `blog post by Simon Ruderich
<https://ruderich.org/simon/notes/append-only-backups-with-restic-and-rclone>`_ <https://ruderich.org/simon/notes/append-only-backups-with-restic-and-rclone>`_
for details. When using ``restic forget`` on such a repository, additional for details and the documentation for the ``forget`` command to learn about
security considerations apply: please review the documentation on removing important security considerations.
backup snapshots.
The rclone command may also be hard-coded in the SSH configuration or the The rclone command may also be hard-coded in the SSH configuration or the
user's public key, in this case it may be sufficient to just start the SSH user's public key, in this case it may be sufficient to just start the SSH

View file

@ -14,14 +14,13 @@
Removing backup snapshots Removing backup snapshots
######################### #########################
All backup space is finite, so restic allows removing old snapshots. All backup space is finite, so restic allows removing old snapshots. This can
This can be done either manually (by specifying a snapshot ID to remove) be done either manually (by specifying a snapshot ID to remove) or by using a
or by using a policy that describes which snapshots to forget. For all policy that describes which snapshots to forget. For all remove operations, two
remove operations, two commands need to be called in sequence: commands need to be called in sequence: ``forget`` to remove snapshots, and
``forget`` to remove a snapshot and ``prune`` to remove the remaining ``prune`` to remove the remaining data that was referenced only by the removed
data that was only referenced by this snapshot from the repository. This can snapshots. The latter can be automated with the ``--prune`` option of ``forget``,
be automated with the ``--prune`` option of the ``forget`` command, which runs ``prune`` automatically if any snapshots were actually removed.
which runs ``prune`` automatically if snapshots have been removed.
Pruning snapshots can be a time-consuming process, depending on the Pruning snapshots can be a time-consuming process, depending on the
number of snapshots and data to process. During a prune operation, the number of snapshots and data to process. During a prune operation, the
@ -164,8 +163,8 @@ The most important command-line parameter here is ``--dry-run`` which
instructs restic to not remove anything but print which snapshots would instructs restic to not remove anything but print which snapshots would
be removed. be removed.
.. note:: If you use append-only backups, some best practices apply. .. note:: If you use an append-only repository, some best practices apply.
Please refer to the security considerations below. Please refer to the security considerations below for more information.
When ``forget`` is run with a policy, restic loads the list of all When ``forget`` is run with a policy, restic loads the list of all
snapshots, then groups these by host name and list of directories. The grouping snapshots, then groups these by host name and list of directories. The grouping
@ -175,27 +174,27 @@ snapshots separately. This is a safety feature.
The ``forget`` command accepts the following parameters: The ``forget`` command accepts the following parameters:
- ``--keep-last n`` never delete the ``n`` last (most recent) snapshots - ``--keep-last n`` keep the ``n`` last (most recent) snapshots.
- ``--keep-hourly n`` for the last ``n`` hours in which a snapshot was - ``--keep-hourly n`` for the last ``n`` hours which have one or more
made, keep only the last snapshot for each hour. snapshots, keep only the most recent one for each hour.
- ``--keep-daily n`` for the last ``n`` days which have one or more - ``--keep-daily n`` for the last ``n`` days which have one or more
snapshots, only keep the last one for that day. snapshots, keep only the most recent one for that day.
- ``--keep-weekly n`` for the last ``n`` weeks which have one or more - ``--keep-weekly n`` for the last ``n`` weeks which have one or more
snapshots, only keep the last one for that week. snapshots, keep only the most recent one for that week.
- ``--keep-monthly n`` for the last ``n`` months which have one or more - ``--keep-monthly n`` for the last ``n`` months which have one or more
snapshots, only keep the last one for that month. snapshots, keep only the most recent one for that month.
- ``--keep-yearly n`` for the last ``n`` years which have one or more - ``--keep-yearly n`` for the last ``n`` years which have one or more
snapshots, only keep the last one for that year. snapshots, keep only the most recent one for that year.
- ``--keep-tag`` keep all snapshots which have all tags specified by - ``--keep-tag`` keep all snapshots which have all tags specified by
this option (can be specified multiple times). this option (can be specified multiple times).
- ``--keep-within duration`` keep all snapshots which have been made within - ``--keep-within duration`` keep all snapshots having a timestamp within
the duration of the latest snapshot. ``duration`` needs to be a number of the specified duration of the latest snapshot, where ``duration`` is a
years, months, days, and hours, e.g. ``2y5m7d3h`` will keep all snapshots number of years, months, days, and hours. E.g. ``2y5m7d3h`` will keep all
made in the two years, five months, seven days, and three hours before the snapshots made in the two years, five months, seven days, and three hours
latest snapshot. before the latest (most recent) snapshot.
- ``--keep-within-hourly duration`` keep all hourly snapshots made within - ``--keep-within-hourly duration`` keep all hourly snapshots made within
specified duration of the latest snapshot. The duration is specified in the specified duration of the latest snapshot. The ``duration`` is specified
the same way as for ``--keep-within`` and the method for determining in the same way as for ``--keep-within`` and the method for determining
hourly snapshots is the same as for ``--keep-hourly``. hourly snapshots is the same as for ``--keep-hourly``.
- ``--keep-within-daily duration`` keep all daily snapshots made within - ``--keep-within-daily duration`` keep all daily snapshots made within
specified duration of the latest snapshot. specified duration of the latest snapshot.
@ -206,11 +205,13 @@ The ``forget`` command accepts the following parameters:
- ``--keep-within-yearly duration`` keep all yearly snapshots made within - ``--keep-within-yearly duration`` keep all yearly snapshots made within
specified duration of the latest snapshot. specified duration of the latest snapshot.
.. note:: All calendar related ``--keep-*`` options work on the natural time .. note:: All calendar related options (``--keep-*``) work on the natural time
boundaries and not relative to when you run the ``forget`` command. Weeks boundaries and not relative to when you run the ``forget`` command. Weeks
are Monday 00:00 -> Sunday 23:59, days 00:00 to 23:59, hours :00 to :59, etc. are Monday 00:00 to Sunday 23:59, days 00:00 to 23:59, hours :00 to :59, etc.
Snapshots seemingly made in the future (relative to when you run the
``forget`` command) will be ignored and never removed. .. note:: All duration related options (``--keep-within`` and ``--keep-within-*``)
ignore snapshots with a timestamp in the future (relative to when the
``forget`` command is run) and these snapshots will hence not be removed.
.. note:: Specifying ``--keep-tag ''`` will match untagged snapshots only. .. note:: Specifying ``--keep-tag ''`` will match untagged snapshots only.
@ -317,12 +318,12 @@ four Sundays, but remove the rest:
--------------------------------------------------------------- ---------------------------------------------------------------
8 snapshots 8 snapshots
The result of the ``forget --keep-daily`` operation only partially depends on when it The result of the ``forget --keep-daily`` operation only partially depends on
is run: it will only count the days for which a snapshot exists, although when it is run; it will only count the days for which a snapshot exists,
with a `time` lying in the future are ignored and never removed. This is a although snapshots with a `time` lying in the future are ignored and never
safety feature: it prevents restic from removing snapshots when no new ones are removed. This is a safety feature: it prevents restic from removing snapshots
created. Otherwise, running ``forget --keep-daily 4`` on a Friday (without any when no new ones are created. Otherwise, running ``forget --keep-daily 4`` on
snapshot Monday to Thursday) would remove all snapshots! a Friday (without any snapshot Monday to Thursday) would remove all snapshots!
Another example: Suppose you make daily backups for 100 years. Then Another example: Suppose you make daily backups for 100 years. Then
``forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75`` ``forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75``
@ -345,34 +346,46 @@ could specify:
Security considerations in append-only mode Security considerations in append-only mode
=========================================== ===========================================
To prevent data from being deleted by a compromised backup client (for example To prevent a compromised backup client from deleting its backups (for example
due to a ransomware infection), a so-called append-only mode can be used. This due to a ransomware infection), a repository service/backend can serve the
requires the server to deny delete and overwrite operations, which is not repository in a so-called append-only mode. This means that the repository can
possible on many standard back-ends. Software such as `rest-server`_ or only be written to and read from, while delete and overwrite operations are
`rclone`_ can be used instead or in addition. denied. Restic's `rest-server`_ features the append-only mode, but few other
standard backends do. To support append-only with such a backend, one can use
`rclone`_ as a complement in between the backup client and the backend service.
.. _rest-server: https://github.com/restic/rest-server/ .. _rest-server: https://github.com/restic/rest-server/
.. _rclone: https://rclone.org/ .. _rclone: https://rclone.org/commands/rclone_serve_restic/
To recover disk space from obsolete snapshots, ``forget`` and ``prune`` must be To remove snapshots and recover the corresponding disk space, the ``forget``
run on a repository with full read-write access. If an attacker can do this, and ``prune`` commands must have full read, write and delete access to the
the protection offered by append-only mode is void. However, even if only the repository. If an attacker has this, the protection offered by append-only
trusted client runs the ``forget`` command, it can be possible for the attacker mode is naturally void.
to add snapshots in such a pattern that all legitimate snapshots are removed.
If the ``forget`` policy is to keep three weekly snapshots, the attacker can However, even with append-only mode active, an attacker who is able to add
add an empty backup for each of the last three weeks with a `time` slightly additional and empty or otherwise useless snapshots to the repository can
newer than the existing snapshots (but still within the target week). The next potentially cause a situation where a trusted client running ``forget`` with
time the repository administrator (or cron job) runs the ``forget`` policy, the certain ``--keep-*`` options might unknowingly remove legitimate snapshots,
legitimate snapshots will be removed. Even without pruning, recovering data leaving only the attackers useless snapshots.
would be messy and some metadata will be lost.
To avoid this, policies applied to append-only repositories should use the For example, if the ``forget`` policy is to keep three weekly snapshots, and
``--keep-within`` option. If the system time is set correctly when ``forget`` the attacker adds an empty snapshot for each of the last three weeks, all with
runs, this will allow you to notice problems with the backup or the compromised a timestamp (see the ``backup`` command's ``-`time`` option) slightly more
host. This is, of course, limited to the specified duration: if recent than the existing snapshots (but still within the target week), then the
``restic forget --keep-within 7d`` is run 8 days after the last good snapshot, next time the repository administrator (or scheduled job) runs the ``forget``
then the attacker can still use that opportunity to remove all good snapshots. command with this policy, the legitimate snapshots will be removed (since the
policy will use the most recent snapshot within each week). Even without
running ``prune``, recovering data would be messy and some metadata lost.
To avoid this, ``forget`` policies applied to append-only repositories should
use the ``--keep-within`` option, as this will keep not only the attacker's
snapshots but also the legitimate ones. Assuming the system time is correctly
set when ``forget`` runs, this will allow the administrator to notice problems
with the backup or the compromised host (e.g. by seeing more snapshots than
usual or snapshots with suspicious timestamps). This is, of course, limited to
the specified duration: if ``forget --keep-within 7d`` is run 8 days after the
last good snapshot, then the attacker can still use that opportunity to remove
all legitimate snapshots.
Customize pruning Customize pruning
***************** *****************

View file

@ -35,7 +35,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = 'restic' project = 'restic'
copyright = '2021, restic authors' copyright = '2018, restic authors'
author = 'fd0' author = 'fd0'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for

View file

@ -607,7 +607,7 @@ examples of things an adversary could achieve in various circumstances.
An adversary with read access to your backup storage location could: An adversary with read access to your backup storage location could:
- Attempt a brute force password guessing attack against a copy of the - Attempt a brute force password guessing attack against a copy of the
repository (use strong passwords with sufficient entropy). repository (please use strong passwords with sufficient entropy).
- Infer which packs probably contain trees via file access patterns. - Infer which packs probably contain trees via file access patterns.
- Infer the size of backups by using creation timestamps of repository objects. - Infer the size of backups by using creation timestamps of repository objects.
@ -618,7 +618,7 @@ An adversary with network access could:
- Determine from where you create your backups (i.e., the location where the - Determine from where you create your backups (i.e., the location where the
requests originate). requests originate).
- Determine where you store your backups (i.e., which provider/target system). - Determine where you store your backups (i.e., which provider/target system).
- Infer the size of backups by using creation timestamps of repository objects. - Infer the size of backups by observing network traffic.
The following are examples of the implications associated with violating some The following are examples of the implications associated with violating some
of the aforementioned assumptions. of the aforementioned assumptions.
@ -629,11 +629,11 @@ system making backups could:
- Render the entire backup process untrustworthy (e.g., intercept password, - Render the entire backup process untrustworthy (e.g., intercept password,
copy files, manipulate data). copy files, manipulate data).
- Create snapshots (containing garbage data) which cover all modified files - Create snapshots (containing garbage data) which cover all modified files
and wait until a trusted host has used forget often enough to forget all and wait until a trusted host has used ``forget`` often enough to remove all
correct snapshots. correct snapshots.
- Create a garbage snapshot for every existing snapshot with a slightly different - Create a garbage snapshot for every existing snapshot with a slightly
timestamp and wait until forget has run, thereby removing all correct different timestamp and wait until certain ``forget`` configurations has been
snapshots at once. run, thereby removing all correct snapshots at once.
An adversary with write access to your files at the storage location could: An adversary with write access to your files at the storage location could:
@ -645,29 +645,26 @@ An adversary with write access to your files at the storage location could:
the snapshot cannot be restored completely. Restic is not designed to detect the snapshot cannot be restored completely. Restic is not designed to detect
this attack. this attack.
An adversary who compromises a host system with append-only access to the An adversary who compromises a host system with append-only (read+write allowed,
backup repository could: delete+overwrite denied) access to the backup repository could:
- Capture the password and decrypt backups from the past and in the future. - Capture the password and decrypt backups from the past and in the future
See the "leaked key" circumstance below. (see the "leaked key" example below for related information).
- Render new backups untrustworthy *after* the host has been compromised - Render new backups untrustworthy *after* the host has been compromised
(due to having complete control over new backups). An attacker cannot delete (due to having complete control over new backups). An attacker cannot delete
or manipulate old backups. As such, restoring old snapshots created *before* or manipulate old backups. As such, restoring old snapshots created *before*
a host compromise remains possible. a host compromise remains possible.
- Potentially manipulate the ``restic forget`` command into deleting all - Potentially manipulate the use of the ``forget`` command into deleting all
legitimate snapshots, keeping only bogus snapshots added by the attacker. legitimate snapshots, keeping only bogus snapshots added by the attacker.
Ransomware might try this in order to leave only one option to get your data Ransomware might try this in order to leave only one option to get your data
back: paying the ransom. For safe use of ``restic forget``, see the back: paying the ransom. For safe use of ``forget``, please see the
documentation on removing backup snapshots. corresponding documentation on removing backup snapshots and append-only mode.
An adversary who has a leaked key for a repository could: An adversary who has a leaked (decrypted) key for a repository could:
- Decrypt existing and future backup data. If multiple hosts backup into the same
repository, an attacker will get access to the backup data of every host.
Since the local encryption key gives access to the master key, a password
change will not prevent this. Changing the master key can currently be done
using ``restic copy`` which moves the data into a new repository with a new
master key, or by making a completely new repository and new backup.
Re-encrypting all data without creating a new repository is tracked in
:issue:`1602`.
- Decrypt existing and future backup data. If multiple hosts backup into the
same repository, an attacker will get access to the backup data of every host.
Note that since the local encryption key gives access to the master key, a
password change will not prevent this. Changing the master key can currently
be done using the ``copy`` command, which moves the data into a new repository
with a new master key, or by making a completely new repository and new backup.