「OfflineIMAP」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(文字列「Tips and tricks」を「ヒントとテクニック」に置換)
(カテゴリ変更)
1行目: 1行目:
[[Category:メールクライアント]]
+
[[Category:メール取得エージェント]]
 
[[en:OfflineIMAP]]
 
[[en:OfflineIMAP]]
 
{{Related articles start}}
 
{{Related articles start}}

2019年3月1日 (金) 00:10時点における版

関連記事

OfflineIMAP は IMAP サーバーからメールを同期する Python ユーティリティです。POP3 プロトコルや mbox は使えないため、通常 Mutt などの MUA と組み合わされて使われます。

インストール

offlineimap をインストールしてください。開発版は offlineimap-gitAUR をインストールしてください。

設定

Offlineimap には2つのデフォルト設定ファイルが付属しており、どちらも /usr/share/offlineimap/ にあります。offlineimap.conf には全ての設定が含まれておりコメントが付与されています。また、offlineimap.conf.minimal にはコメントが付いておらず多少の設定しか含まれていません (参照: Minimal)。

デフォルト設定ファイルのどちらかを ~/.offlineimaprc にコピーしてください。

ノート: Writing a comment after an option/value on the same line is invalid syntax, hence take care that comments are placed on their own separate line.

Minimal

offlineimap.conf.minimal のコメントが付いたバージョンは以下になります:

~/.offlineimaprc
[general]
# List of accounts to be synced, separated by a comma.
accounts = main

[Account main]
# Identifier for the local repository; e.g. the maildir to be synced via IMAP.
localrepository = main-local
# Identifier for the remote repository; i.e. the actual IMAP, usually non-local.
remoterepository = main-remote
# Status cache. Default is plain, which eventually becomes huge and slow.
status_backend = sqlite

[Repository main-local]
# Currently, offlineimap only supports maildir and IMAP for local repositories.
type = Maildir
# Where should the mail be placed?
localfolders = ~/Maildir

[Repository main-remote]
# Remote repos can be IMAP or Gmail, the latter being a preconfigured IMAP.
type = IMAP
remotehost = host.domain.tld
remoteuser = username

フォルダの同期の選択

特定のフォルダだけを同期したい場合、~/.offlineimaprc でアカウントの remote セクションに folderfilter を使います。例えば、以下の設定では InboxSent フォルダだけが同期されます:

~/.offlineimaprc
[Repository main-remote]
# Synchronize only the folders Inbox and Sent:
folderfilter = lambda foldername: foldername in ["Inbox", "Sent"]
...

他のオプションについては、公式ドキュメント を見て下さい。

使用方法

offlineimap を実行する前に、ローカルリポジトリとして使用するペアレントディレクトリを作成してください:

$ mkdir ~/Maildir

そして、プログラムを実行してください:

$ offlineimap

メールアカウントが同期されます。何か問題が発生した場合、エラーメッセージをよく見て下さい。OfflineIMAP は基本的に問題について詳しい出力を表示します。最終的な製品からのトレースバックを取得するのに開発者が悩む必要がないようにするためです。

ヒントとテクニック

バックグラウンドで offlineimap を実行

大抵のメール転送エージェントはデフォルトで、プログラムを定期的に同期させることでデーモンとしてツールを使うのが前提になっています。offlineimap では、バックグラウンドで作業を制御する設定はあまりありません。

紛らわしいことに、バックグラウンドの設定は設定ファイルのあらゆるところに散らばっています:

~/.offlineimaprc
# In the general section
[general]
# Controls how many accounts may be synced simultaneously
maxsyncaccounts = 1

# In the account identifier
[Account main]
# Minutes between syncs
autorefresh = 0.5
# Quick-syncs do not update if the only changes were to IMAP flags.
# autorefresh=0.5 together with quick=10 yields
# 10 quick refreshes between each full refresh, with 0.5 minutes between every 
# refresh, regardless of type.
quick = 10

# In the remote repository identifier
[Repository main-remote]
# Instead of closing the connection once a sync is complete, offlineimap will
# send empty data to the server to hold the connection open. A value of 60
# attempts to hold the connection for a minute between syncs (both quick and
# autorefresh).This setting has no effect if autorefresh and holdconnectionopen
# are not both set.
keepalive = 60
# OfflineIMAP normally closes IMAP server connections between refreshes if
# the global option autorefresh is specified.  If you wish it to keep the
# connection open, set this to true. This setting has no effect if autorefresh
# is not set.
holdconnectionopen = yes

systemd サービス

バックグラウンドジョブを実行するように設定したら、以下の systemd サービスで offlineimap を管理することができます:

/etc/systemd/system/offlineimap@.service
[Unit]
Description=Start offlineimap as a daemon
Requires=network-online.target
After=network.target

[Service]
User=%i
ExecStart=/usr/bin/offlineimap
KillSignal=SIGUSR2
Restart=always

[Install]
WantedBy=multi-user.target

サービスを作成したら offlineimap@user.service有効化してください。

ノート: D-Bus の操作を含む設定をした場合 (例: #Gnome Keyring)、上記の systemd サービスは直接使うのではなく systemd/ユーザー に書かれているように systemd のユーザーインスタンスとして使う必要があります。DBUS_SESSION_BUS_ADDRESS 変数を適切に設定してください。

mutt 用に自動的にメールボックスを作成

Mutt cannot be simply pointed to an IMAP or maildir directory and be expected to guess which subdirectories happen to be the mailboxes, yet offlineimap can generate a muttrc fragment containing the mailboxes that it syncs.

~/.offlineimaprc
[mbnames]
enabled = yes
filename = ~/.mutt/mailboxes
header = "mailboxes "
peritem = "+%(accountname)s/%(foldername)s"
sep = " "
footer = "\n"

Then add the following lines to ~/.mutt/muttrc.

~/.mutt/muttrc
# IMAP: offlineimap
set folder = "~/Mail"
source ~/.mutt/mailboxes
set spoolfile = "+account/INBOX"
set record = "+account/Sent\ Items"
set postponed = "+account/Drafts"

account is the name you have given to your IMAP account in ~/.offlineimaprc.

Gmail の設定

This remote repository is configured specifically for Gmail support, substituting folder names in uppercase for lowercase, among other small additions. Keep in mind that this configuration does not sync the All Mail folder, since it is usually unnecessary and skipping it prevents bandwidth costs:

~/.offlineimaprc
[Repository gmail-remote]
type = Gmail
remoteuser = user@gmail.com
remotepass = password
nametrans = lambda foldername: re.sub ('^\[gmail\]', 'bak',
                               re.sub ('sent_mail', 'sent',
                               re.sub ('starred', 'flagged',
                               re.sub (' ', '_', foldername.lower()))))
folderfilter = lambda foldername: foldername not in ['[Gmail]/All Mail']
# Necessary as of OfflineIMAP 6.5.4
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
ノート:
  • If you have Gmail set to another language, the folder names may appear translated too, e.g. "verzonden_berichten" instead of "sent_mail".
  • After version 6.3.5, offlineimap also creates remote folders to match your local ones. Thus you may need a nametrans rule for your local repository too that reverses the effects of this nametrans rule. If you don't want to make a reverse nametrans rule, you can disable remote folder creation by putting this in your remote configuration: createfolders = False
  • 2012年10月1日現在、gmail の SSL 証明書のフィンガープリントはいつも同じだとは限りません。このため cert_fingerprint を使うよりも sslcacertfile を使って SSL の確認をするほうが良いでしょう (#SSL フィンガープリントが一致しないを参照)。

パスワードの管理

.netrc

以下の行を ~/.netrc に追加してください:

machine hostname.tld
    login [your username]
    password [your password]

Do not forget to give the file appropriate rights like 600 or 700:

$ chmod 600 ~/.netrc

GPG を使う

GNU Privacy Guard を使うことで暗号化ファイルにパスワードを保存することができます。このセクションの設定を行う前にまず GnuPG をセットアップしてください。パスワードを入力しなくても GPG の秘密鍵をいつでも使えるようにしておく必要があります。

まずプレーンテキストファイルにメールアカウントのパスワードを入力してください。暗号化されていないパスワードがディスクに書き込まれないように、ファイルの作成は tmpfs 上の 700 パーミッションの安全なディレクトリで行なって下さい。それから、公開鍵でファイルを暗号化します:

$ gpg --default-recipient-self -e /path/to/plain/password

必要なくなったプレーンテキストファイルは削除してください。暗号化したファイルは最終的に必要な場所 (例: ~/.offlineimappass.gpg) に移動してください。

次にパスワードを復号化する python 関数を作成します:

~/.offlineimap.py
#! /usr/bin/env python2
from subprocess import check_output

def get_pass():
    return check_output("gpg -dq ~/.offlineimappass.gpg", shell=True).strip("\n")

上記のファイルを ~/.offlineimaprc からロードして、定義した関数を指定してください:

~/.offlineimaprc
[general]
# Path to file with arbitrary Python code to be loaded
pythonfile = ~/.offlineimap.py
...

[Repository example]
# Decrypt and read the encrypted password
remotepasseval = get_pass()
...

pass を使う

pass は GPG ベースのシンプルなコマンドラインのパスワードマネージャです。

最初にメールアカウントのパスワードを作成:

$ pass insert Mail/account

次にパスワードを復号化する python 関数を作成:

~/.offlineimap.py
#! /usr/bin/env python2
from subprocess import check_output

def get_pass(account):
    return check_output("pass Mail/" + account, shell=True).splitlines()[0]

上記はマルチアカウントセットアップの例です。前述の pass の引数はカスタマイズできます。

~/.offlineimaprc からファイルをロードして、定義した関数を指定:

~/.offlineimaprc
[general]
# Path to file with arbitrary Python code to be loaded
pythonfile = ~/.offlineimap.py
...

[Repository Gmail]
# Decrypt and read the encrypted password
remotepasseval = get_pass("Gmail")
...

Gnome Keyring

In configuration for remote repositories the remoteusereval/remotepasseval fields can be set to custom python code that evaluates to the username/password. The code can be a call to a function defined in a Python script pointed to by 'pythonfile' config field. Create ~/.offlineimap.py according to either of the two options below and use it in the configuration:

[general]
pythonfile = ~/.offlineimap.py

[Repository examplerepo]
type = IMAP
remotehost = mail.example.com
remoteusereval = get_username("examplerepo")
remotepasseval = get_password("examplerepo")
方法 1: gnomekeyring の Python モジュールを使う

python2-gnomekeyring をインストールしてください。

~/.offlineimap.py
#! /usr/bin/env python2

import gnomekeyring as gkey

def set_credentials(repo, user, pw):
    KEYRING_NAME = "offlineimap"
    attrs = { "repo": repo, "user": user }
    keyring = gkey.get_default_keyring_sync()
    gkey.item_create_sync(keyring, gkey.ITEM_NETWORK_PASSWORD,
        KEYRING_NAME, attrs, pw, True)

def get_credentials(repo):
    keyring = gkey.get_default_keyring_sync()
    attrs = {"repo": repo}
    items = gkey.find_items_sync(gkey.ITEM_NETWORK_PASSWORD, attrs)
    return (items[0].attributes["user"], items[0].secret)

def get_username(repo):
    return get_credentials(repo)[0]
def get_password(repo):
    return get_credentials(repo)[1]

if __name__ == "__main__":
    import sys
    import os
    import getpass
    if len(sys.argv) != 3:
        print "Usage: %s <repository> <username>" \
            % (os.path.basename(sys.argv[0]))
        sys.exit(0)
    repo, username = sys.argv[1:]
    password = getpass.getpass("Enter password for user '%s': " % username)
    password_confirmation = getpass.getpass("Confirm password: ")
    if password != password_confirmation:
        print "Error: password confirmation does not match"
        sys.exit(1)
    set_credentials(repo, username, password)

証明書を設定するために、シェルから上記のスクリプトを実行してください。

方法 2: gnome-keyring-queryAUR ツールを使う
~/.offlineimap.py
#! /usr/bin/env python2
# executes gnome-keyring-query get passwd
# and returns the output

import locale
from subprocess import Popen, PIPE

encoding = locale.getdefaultlocale()[1]

def get_password(p):
    (out, err) = Popen(["gnome-keyring-query", "get", p], stdout=PIPE).communicate()
    return out.decode(encoding).strip()

python2-keyring

There is a general solution that should work for any keyring. Install python2-keyring from AUR, then change your ~/.offlineimaprc to say something like:

[general]
pythonfile = /home/user/offlineimap.py
...
[Repository RemoteEmail]
remoteuser = username@host.net
remotepasseval = keyring.get_password("offlineimap","username@host.net")
...

and somewhere in ~/offlineimap.py add import keyring. Now all you have to do is set your password, like so:

$ python2 
>>> import keyring
>>> keyring.set_password("offlineimap","username@host.net", "MYPASSWORD")

and it will grab the password from your (kwallet/gnome-) keyring instead of having to keep it in plaintext or enter it each time.

Emacs EasyPG

http://www.emacswiki.org/emacs/OfflineIMAP#toc2 を見てください。

KeePass / KeePassX

AUR から python2-keepass-gitAUR をインストールして、offlineimap.py ファイルに以下を追加してください:

#! /usr/bin/env python2
import os, getpass
from keepass import kpdb
 
def get_keepass_pw(dbpath, title="", username=""):
    if os.path.isfile(dbpath):
        db = kpdb.Database(dbpath, getpass.getpass("Master password for '" + dbpath +    "': "))
        for entry in db.entries:
            if (entry.title == title) and (entry.username == username):
                return entry.password
    else:
        print "Error: '" + dbpath + "' does not exist."
        return

(Credit to aki--aki: https://gist.github.com/aki--aki/5180359)

Next, edit your ~/.offlineimaprc:

[general]
# VVV Set this path correctly VVV
pythonfile = /home/user/offlineimap.py
...
[Repository RemoteEmail]
remoteuser = username@host.net
# Set the DB path as well as the title and username of the specific entry you'd like to use.
# This will prompt you on STDIN at runtime for the kdb master password.
remotepasseval = get_keepass_pw("/path/to/database.kdb", title="<entry title>", username="<entry username>")
...

Note that as-is, this does not support KDBs with keyfiles, only KDBs with password-only auth.

Kerberos 認証

Install python2-kerberosAUR from AUR and do not specify remotepass in your .offlineimaprc. OfflineImap figure out the reset all if have a valid Kerberos TGT. If you have 'maxconnections', it will fail for some connection. Comment 'maxconnections' out will solve this problem.

トラブルシューティング

UI の上書きと自動更新の設定

For the sake of troubleshooting, it is sometimes convenient to launch offlineimap with a more verbose UI, no background syncs and perhaps even a debug level:

$ offlineimap [ -o ] [ -d <debug_type> ] [ -u <ui> ]
-o
Disable autorefresh, keepalive, etc.
-d <debug_type>
Where <debug_type> is one of imap, maildir or thread. Debugging imap and maildir are, by far, the most useful.
-u <ui>
Where <ui> is one of CURSES.BLINKENLIGHTS, TTY.TTYUI, NONINTERACTIVE.BASIC, NONINTERACTIVE.QUIET or MACHINE.MACHINEUI. TTY.TTYUI is sufficient for debugging purposes.
ノート: More recent versions use the following for <ui>: blinkenlights, ttyui, basic, quiet or machineui.

フォルダが作成できない

In version 6.5.3, offlineimap gained the ability to create folders in the remote repository, as described here.

This can lead to errors of the following form when using nametrans on the remote repository:

ERROR: Creating folder bar on repository foo-remote
  Folder 'bar'[foo-remote] could not be created. Server responded: ('NO', ['[ALREADYEXISTS] Duplicate folder name bar (Failure)'])

The solution is to provide an inverse nametrans lambda for the local repository, e.g.

~/.offlineimaprc
[Repository foo-local]
nametrans = lambda foldername: foldername.replace('bar', 'BAR')

[Repository foo-remote]
nametrans = lambda foldername: foldername.replace('BAR', 'bar')
  • For working out the correct inverse mapping. the output of offlineimap --info should help.
  • After updating the mapping, it may be necessary to remove all of the folders under $HOME/.offlineimap/ for the affected accounts.

SSL フィンガープリントが一致しない

ERROR: Server SSL fingerprint 'keykeykey' for hostname 'example.com' does not match configured fingerprint. Please verify and set 'cert_fingerprint' accordingly if not set yet.

To solve this, add to ~/.offlineimaprc (in the same section as ssl = yes) one of the following:

  • either add cert_fingerprint, with the certificate fingerprint of the remote server. This checks whether the remote server certificate matches the given fingerprint.
cert_fingerprint = keykeykey
  • or add sslcacertfile with the path to the system CA certificates file. Needs ca-certificates installed. This validates the remote ssl certificate chain against the Certification Authorities in that file.
sslcacertfile = /etc/ssl/certs/ca-certificates.crt

Copying message, connection closed

ERROR: Copying message -2 [acc: email] connection closed
Folder sent [acc: email]: ERROR: while syncing sent [account email] connection closed

上記の問題はローカルとサーバーで同じメッセージが作成されていることが原因です。メールのプロバイダが自動的にローカルクライアントと同じフォルダに送信したメールを保存した場合に発生します。この問題が起こったときはローカルクライアントで送信済みメッセージの保存を無効化してください。

参照