mirror of
https://github.com/octoleo/restic.git
synced 2024-12-22 10:58:55 +00:00
Document "forget" security considerations and add references
Removing data based on a policy when the attacker had the opportunity to add data to your repository comes with some considerations. This is added to the 060_forget.rst documentation. That document is also updated to reflect that restic now considers the current system time while running "forget". References to the security considerations section are added: - In `restic forget --help` - In the threat model (design.rst) - In the (030) setup section where an append-only setup is referenced A reference is also to be added to the `rest-server` readme's append-only paragraph (see my fork). This commit also resolves a typo (amount->number for countable noun), changes a password length recommendation into the metric that actually matters when creating passwords (entropy) since I was editing these doc files anyway, and updates the outdated copyright year in `conf.py`. Some wording in 060_forget (line 21..22) was changed to clarify what "forget" and "prune" do, to try and avoid the apparent misconception that "forget" does not remove any data.
This commit is contained in:
parent
ca1e2316cf
commit
9c1d49e312
@ -18,6 +18,8 @@ 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 this (now unreferenced)
|
||||||
data after 'forget' was run successfully, see the 'prune' command.
|
data after 'forget' was run successfully, see the 'prune' command.
|
||||||
|
When using this command on special append-only repositories, please see the
|
||||||
|
documentation for security considerations.
|
||||||
|
|
||||||
EXIT STATUS
|
EXIT STATUS
|
||||||
===========
|
===========
|
||||||
|
@ -657,7 +657,9 @@ 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.
|
for details. When using ``restic forget`` on such a repository, additional
|
||||||
|
security considerations apply: please review the documentation on removing
|
||||||
|
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
|
||||||
|
@ -18,13 +18,13 @@ All backup space is finite, so restic allows removing old snapshots.
|
|||||||
This can be done either manually (by specifying a snapshot ID to remove)
|
This can be done either manually (by specifying a snapshot ID to remove)
|
||||||
or by using a policy that describes which snapshots to forget. For all
|
or by using a policy that describes which snapshots to forget. For all
|
||||||
remove operations, two commands need to be called in sequence:
|
remove operations, two commands need to be called in sequence:
|
||||||
``forget`` to remove a snapshot and ``prune`` to actually remove the
|
``forget`` to remove a snapshot and ``prune`` to remove the remaining
|
||||||
data that was referenced by the snapshot from the repository. This can
|
data that was only referenced by this snapshot from the repository. This can
|
||||||
be automated with the ``--prune`` option of the ``forget`` command,
|
be automated with the ``--prune`` option of the ``forget`` command,
|
||||||
which runs ``prune`` automatically if snapshots have been 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
|
||||||
amount of snapshots and data to process. During a prune operation, the
|
number of snapshots and data to process. During a prune operation, the
|
||||||
repository is locked and backups cannot be completed. Please plan your
|
repository is locked and backups cannot be completed. Please plan your
|
||||||
pruning so that there's time to complete it and it doesn't interfere with
|
pruning so that there's time to complete it and it doesn't interfere with
|
||||||
regular backup runs.
|
regular backup runs.
|
||||||
@ -164,6 +164,9 @@ 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.
|
||||||
|
Please refer to the security considerations below.
|
||||||
|
|
||||||
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
|
||||||
options can be set with ``--group-by``, to only group snapshots by paths and
|
options can be set with ``--group-by``, to only group snapshots by paths and
|
||||||
@ -206,6 +209,8 @@ The ``forget`` command accepts the following parameters:
|
|||||||
.. note:: All calendar related ``--keep-*`` options work on the natural time
|
.. note:: All calendar related ``--keep-*`` options 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 -> 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:: Specifying ``--keep-tag ''`` will match untagged snapshots only.
|
.. note:: Specifying ``--keep-tag ''`` will match untagged snapshots only.
|
||||||
|
|
||||||
@ -312,8 +317,9 @@ four Sundays, but remove the rest:
|
|||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
8 snapshots
|
8 snapshots
|
||||||
|
|
||||||
The result of the ``forget --keep-daily`` operation does not depend on when it
|
The result of the ``forget --keep-daily`` operation only partially depends on when it
|
||||||
is run, it will only count the days for which a snapshot exists. This is a
|
is run: it will only count the days for which a snapshot exists, although
|
||||||
|
with a `time` lying in the future are ignored and never removed. This is a
|
||||||
safety feature: it prevents restic from removing snapshots when no new ones are
|
safety feature: it prevents restic from removing snapshots when no new ones are
|
||||||
created. Otherwise, running ``forget --keep-daily 4`` on a Friday (without any
|
created. Otherwise, running ``forget --keep-daily 4`` on a Friday (without any
|
||||||
snapshot Monday to Thursday) would remove all snapshots!
|
snapshot Monday to Thursday) would remove all snapshots!
|
||||||
@ -336,6 +342,38 @@ could specify:
|
|||||||
(Note that `1w` is not a recognized duration, so you will have to specify
|
(Note that `1w` is not a recognized duration, so you will have to specify
|
||||||
`7d` instead)
|
`7d` instead)
|
||||||
|
|
||||||
|
Security considerations in append-only mode
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
To prevent data from being deleted by a compromised backup client (for example
|
||||||
|
due to a ransomware infection), a so-called append-only mode can be used. This
|
||||||
|
requires the server to deny delete and overwrite operations, which is not
|
||||||
|
possible on many standard back-ends. Software such as `rest-server`_ or
|
||||||
|
`rclone`_ can be used instead or in addition.
|
||||||
|
|
||||||
|
.. _rest-server: https://github.com/restic/rest-server/
|
||||||
|
.. _rclone: https://rclone.org/
|
||||||
|
|
||||||
|
To recover disk space from obsolete snapshots, ``forget`` and ``prune`` must be
|
||||||
|
run on a repository with full read-write access. If an attacker can do this,
|
||||||
|
the protection offered by append-only mode is void. However, even if only the
|
||||||
|
trusted client runs the ``forget`` command, it can be possible for the attacker
|
||||||
|
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
|
||||||
|
add an empty backup for each of the last three weeks with a `time` slightly
|
||||||
|
newer than the existing snapshots (but still within the target week). The next
|
||||||
|
time the repository administrator (or cron job) runs the ``forget`` policy, the
|
||||||
|
legitimate snapshots will be removed. Even without pruning, recovering data
|
||||||
|
would be messy and some metadata will be lost.
|
||||||
|
|
||||||
|
To avoid this, policies applied to append-only repositories should use the
|
||||||
|
``--keep-within`` option. If the system time is set correctly when ``forget``
|
||||||
|
runs, this will allow you to notice problems with the backup or the compromised
|
||||||
|
host. This is, of course, limited to the specified duration: if
|
||||||
|
``restic forget --keep-within 7d`` is run 8 days after the last good snapshot,
|
||||||
|
then the attacker can still use that opportunity to remove all good snapshots.
|
||||||
|
|
||||||
Customize pruning
|
Customize pruning
|
||||||
*****************
|
*****************
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'restic'
|
project = 'restic'
|
||||||
copyright = '2018, restic authors'
|
copyright = '2021, 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
|
||||||
|
@ -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 (even more reason to use long, 30+ character passwords).
|
repository (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.
|
||||||
|
|
||||||
@ -648,18 +648,26 @@ An adversary with write access to your files at the storage location could:
|
|||||||
An adversary who compromises a host system with append-only access to the
|
An adversary who compromises a host system with append-only access to the
|
||||||
backup repository could:
|
backup repository could:
|
||||||
|
|
||||||
|
- Capture the password and decrypt backups from the past and in the future.
|
||||||
|
See the "leaked key" circumstance below.
|
||||||
- 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.
|
||||||
*Note: It is **not** recommended to ever run forget automatically for an
|
- Potentially manipulate the ``restic forget`` command into deleting all
|
||||||
append-only backup to which a potentially compromised host has access
|
legitimate snapshots, keeping only bogus snapshots added by the attacker.
|
||||||
because an attacker using fake snapshots could cause forget to remove
|
Ransomware might try this in order to leave only one option to get your data
|
||||||
correct snapshots.*
|
back: paying the ransom. For safe use of ``restic forget``, see the
|
||||||
|
documentation on removing backup snapshots.
|
||||||
|
|
||||||
An adversary who has a leaked key for a repository which has not been re-encrypted
|
An adversary who has a leaked key for a repository could:
|
||||||
could:
|
|
||||||
|
|
||||||
- Decrypt existing and future backup data. If multiple hosts backup into the same
|
- 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.
|
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`.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user