/imap-backup

Backup GMail (or other IMAP) accounts to disk

Primary LanguageRubyMIT LicenseMIT

Build Status Source Analysis Test Coverage

imap-backup

Backup GMail (or other IMAP) accounts to disk

Version 2

With versions above 2.x, this gems stores IMAP metadata in a backwardly-incompatible way. When upgrading, all old backups will be gradually deleted to allow for the new file format to be introduced.

Installation

$ gem install 'imap-backup'

Setup

In order to do backups, you need to add accounts via a menu-driven command line program:

Run:

$ imap-backup setup

Folders

By default, all folders are backed-up. You can override this by choosing specific folders.

Configuration file

setup creates the file ~/.imap-backup/config.json

E.g.:

{
  "accounts": [
    {
      "username": "my.user@gmail.com",
      "password": "secret",
      "local_path": "/path/to/backup/root",
      "folders":
        [
          {"name": "[Gmail]/All Mail"},
          {"name": "my_folder"}
        ]
    }
  ]
}

It connects to GMail by default, but you can also specify a server:

{
  "accounts": [
    {
      "username": "my.user@gmail.com",
      "password": "secret",
      "server": "my.imap.example.com",
      "local_path": "/path/to/backup/root",
      "folders":
        [
          {"name": "[Gmail]/All Mail"},
          {"name": "my_folder"}
        ]
    }
  ]
}

Connection options

You can override the parameters passed to Net::IMAP with connection_options.

Specifically, if you are using a self-signed certificate and get SSL errors, e.g. certificate verify failed, you can choose to not verify the TLS connection:

{
  "accounts": [
    {
      "username": "my.user@gmail.com",
      "password": "secret",
      "server": "my.imap.example.com",
      "local_path": "/path/to/backup/root",
      "folders": [
        {"name": "[Gmail]/All Mail"},
        {"name": "my_folder"}
      ],
      "connection_options": {
        "ssl": {"verify_mode": 0},
        "port": 993
      }
    }
  ]
}

GMail

  • Enable IMAP access to your account via the GMail interface (Settings/Forwarding and POP/IMAP),
  • Under 'Sign-in & security', 'Signing in to Google', 'App passwords', generate a password for imap-backup,
  • In imap-backup setup, set the server to imap.gmail.com

Security

Note that email usernames and passwords are held in plain text in the configuration file.

The directory ~/.imap-backup, the configuration file and all backup directories have their access permissions set to only allow access by your user.

Run Backup

Manually, from the command line:

$ imap-backup

Alternatively, add it to your crontab.

Result

Each folder is saved to an mbox file. Alongside each mbox is a file with extension '.imap', which lists the source IMAP UIDs to allow a full restore.

Troubleshooting

If you have problems:

  1. ensure that you have the latest release,
  2. turn on debugging output:
{
  "accounts":
  [
    ...
  ],
  "debug": true
}

Restore

All missing messages are pushed to the IMAP server. Existing messages are left unchanged.

This functionality requires that the IMAP server supports the UIDPLUS extension to IMAP4.

Other Usage

List IMAP folders:

$ imap-backup folders

Get statistics of emails to download per folder:

$ imap-backup status

Design Goals

  • Secure - use a local file protected by permissions
  • Restartable - calculate start point based on already downloaded messages
  • Standalone - do not rely on an email client or MTA

Similar Software

Testing

Integration Tests

Integration tests (feature specs) are run against a Docker image (antespi/docker-imap-devel:latest).

In one shell, run the Docker image:

docker run \
  --env MAIL_ADDRESS=address@example.org \
  --env MAIL_PASS=pass \
  --env MAILNAME=example.org \
  --publish 8993:993 \
  antespi/docker-imap-devel:latest

Currently, the integration tests with Docker are excluded from the CI run.

To run just the Docker-based tests:

rspec -t docker

To run all specs, including the integration tests, do the following:

rspec -O .rspec-all

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request