S-nail

提供: ArchWiki
2017年6月28日 (水) 22:48時点におけるKusakata (トーク | 投稿記録)による版 (翻訳)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

S-nail (heirloom-mailx のフォーク) は ed と同じようなコマンド構文が使えるメール処理システムです。ed における行がメッセージになります。POSIX の mailx コマンドの機能を実現し行編集や IDNA, MIME, S/MIME, SMTP, POP3 (IMAP) などの拡張を提供します。メールバッチ言語として使うことが可能です。

S-nail は Unix のメールシステムのユーザーサイドを担うものであり、システムサイドは伝統的に sendmail が使われていました。

Arch Linux では S-nail は SMTP によるメールの直接配達に対応しているため、外部の SMTP サーバーに直接メッセージを送信することができます。その場合、ローカルのメール転送エージェント (MTA) はシステムサイドには不要です。ただし、S-nail にはメールキュー機構が存在しません。SMTP で直接かつ即座にメッセージを送るだけです。

インストール

s-nail パッケージは Arch Linux の base グループに含まれているため、最初からインストールされています。

システム全体の設定ファイル (/etc/mail.rc) には最初から有用な設定が含まれており、以下のように sendmailpostfix などのローカルメール転送エージェント (MTA) でメールを送信できます:

# echo 'Message body' | mailx -d -s 'A subject' -a an_attachment.txt foo1@bar.example 'Foo2 <foo2@bar.example>'

-d フラグを付けることでドライランとなり実際にはメールは送信されません (saverecord 設定も無視されます)。sendmail 変数を設定することで MTA として使用するプログラムを調整できます (sendmail-arguments, sendmail-no-default-arguments, sendmail-progname など詳しくはマニュアルの "Sending mail" を参照):

# < /etc/passwd mailx -Ssendmail=/usr/bin/sendmail -Ssendwait -s 'My password file content!' public-foo@bar.example
# echo Message was passed successfully: $?

デフォルトではメールの配達は非同期となっており、メッセージが配達システム (MTA など) に渡されると S-nail はすぐに終了します。メッセージの準備ができたかどうかだけ出力します。sendwait オプションを設定した場合、S-nail は起動した MTA インスタンスが終了するまで待機し、MTA の終了ステータスを確認してメールの配達が成功したか失敗したか判断します。

expandaddr オプションを設定した場合、ファイルやコマンドにメッセージを送信することができます:

# echo bla | mailx -Sexpandaddr -s test ./mbox.mbox
# echo bla | mailx -Sexpandaddr -s test '|cat >> ./mbox.mbox'

To avoid that members of the program environment and settings of configuration files modify program behaviour, scripts can (and should) detach from configuration files and use the -S and -X command line flags to create their own setup and run necessary commands, respectively.

expandaddr can be given a value and be used for address verification. For example, the following only allows network addressees. The -. command line option will terminate option processing and turn on message send mode. Together these form active barriers to prevent misinterpretation of address arguments as command line options and other injection attacks. The following example can be used as is, except for {ic|-d}}, provided that you have a somefile.pdf somewhere; it sets the record variable to the pathname of the folder used to record all outgoing mail, so that we then can look into the generated message:

# echo Body |
#   LC_ALL=C MAILRC=/dev/null \
#   mailx -d -n -Sv15-compat -Ssendwait \
#     -Sexpandaddr=fail,-all,+addr \
#     -Snosave -Srecord=/tmp/out.mbox \
#     -Smimetypes-load-control \
#     -X'mimetype "application/pdf pdf"' \
#     -Sfrom='Me <me@home>' \
#     -a somefile.pdf -s Subject \
#      -. '(foo2bar) <foo2@bar.example>' bob@hey.example
# mailx -Rf /tmp/out.mbox

The sections "A starter", "Sending mail" and "Reading mail" of the manual page should be worth a glance when looking for more "quick shots".

In cases when in the following USER and PASS are specified as part of an URL (and only then), they must become URL-percent-encoded; S-nail offers the urlcodec command which does this for you:

# printf 'urlcodec encode USER PASS\nx\n' | mailx -#

printf as well as S-nail / mailx are subject to your locale settings:

# # In UTF-8:
# printf 'urlcodec encode SPAß\nx\n' | mailx -#
  in: <SPAß> (5 bytes)
  out: <SPA%C3%9F> (9 bytes)
# # In ISO-8859-1:
# printf 'urlc enc SPAß\nx\n' | mailx -#
  in: <SPAß> (4 bytes)
  out: <SPA%DF> (6 bytes)

設定

設定ファイルは各ユーザー個別の $HOME/.mailrc と全ユーザー共通の /etc/mail.rc があり、後者のファイルは Arch Linux でアップデートしたときに変わる可能性があるため、変更や追加は前者のファイルに行ってください。

ヒント: By using the -n command line option or by setting the NAIL_NO_SYSTEM_RC reading /etc/mail.rc upon startup can be inhibited. And by setting the MAILRC environment variable to /dev/null in addition it is ensured that no configuration file is loaded, so that a reproducable environment for running scripts is created, as shown by the script example above.

基本的なセキュリティや送信モードを設定する設定例:

# All the examples require v15-compat!
set v15-compat

# ArchLinux-specific locations of certificates.
# Since these are subject to the ArchLinux update mechanism,
# use only those, don't try to load OpenSSL builtin ones.
# And use the TLS specific set: see "man 8 update-ca-trust"
#set ssl-ca-dir=/etc/ssl/certs
set ssl-ca-file=/etc/ssl/certs/ca-certificates.crt
set ssl-no-default-ca

# Don't use protocols older than TLS v1.2.
# Change this only when the remote server doesn't support it:
# maybe use ssl-protocol-HOST (or -USER@HOST) syntax to define
# such explicit exceptions, then, e.g.
#     ssl-protocol-USER@archlinux.org="-ALL,+TLSv1.2"
set ssl-protocol="-ALL,+TLSv1.2"

# Explicitly define the list of ciphers, which may improve security,
# especially with protocols older than TLS v1.2.  See ciphers(1).
# Hint: it is important to include "@STRENGTH": only with it the
# final list will be sorted by algorithm strength.
# This is an example: in reality it is possibly best to only use
# ssl-cipher-list-HOST (or -USER@HOST), as necessary, again..
set ssl-cipher-list="ALL:!aNULL:!eNULL:!MEDIUM:!LOW:!MD5:!RC4:!EXPORT:@STRENGTH"

# Request strict transport security checks
set ssl-verify=strict

# Essential setting: select allowed character sets
# (Have a look at the "CHARACTER SETS" manual section)
set sendcharsets=utf-8,iso-8859-1

# A very kind option: when replying to a message, first try to
# use the same encoding that the original poster used herself!
set reply-in-same-charset

# When replying to or forwarding a message the comment and name
# parts of email addresses are removed unless this variable is set
set fullnames

# When sending messages, wait until the Mail-Transfer-Agent finishs.
# Only like this you'll be able to see errors reported through the exit
# status of the MTA (including the builtin SMTP one)!
set sendwait

# Only use builtin MIME types, no mime.types(5) files.
# That set is often sufficient, but look at the output of the
# mimetype command to ensure this is true for you, too
set mimetypes-load-control

# Default directory where we act in (relative to $HOME if not absolute)
set folder=mail
# A leading "+" (often) means: under folder
# record is used to save copies of sent messages, DEAD is error storage
# inbox: system mailbox, by default /var/mail/$USER: file %
# MBOX: secondary mailbox: file &
set MBOX=+mbox.mbox record=+sent.mbox DEAD=+dead.mbox
set inbox=+system.mbox

# Define some shortcuts; now one may say, e.g., file mymbo
shortcut mymbo %:+mbox.mbox \
         myrec +sent.mbox

# This is optional, but you should get the big picture
# by reading the manual before you leave that off
set from="Your Name <youremail@domain>" 

# Mailing-list specifics (manual: "Mailing lists"):
set followup-to followup-to-honour=ask-yes reply-to-honour=ask-yes
# And teach some non-subscribed / some subscribed lists, too
mlist @xyz-editor.xyz$ @xyzf.xyz$
mlsubscribe ^xfans@xfans.xyz$

The above combination of SSL/TLS configuration results in the most secure end-to-end TLS transport that is possible.

Tips and tricks

外部 SMTP サーバーでメールを送信

To send messages via the built-in SMTP (Simple Mail Transfer Protocol) client to an external SMTP server, several options have to be set or adjusted. Add the following as appropriate to the configuration as above, changing bold strings. Reading the manual section "On URL syntax and credential lookup" is worthwhile.

# It can be as easy as
# (Remember USER and PASS must be URL percent encoded)
set smtp=smtp://USER:PASS@HOST \
    smtp-use-starttls

# It may be necessary to set hostname and/or smtp-hostname
# if the "SERVER" of smtp and "domain" of from don't match.
# Reading the "ON URL SYNTAX.." and smtp manual entries may be worthwhile
set smtp=(smtp[s]/submission)://[USER[:PASS]@]SERVER[:PORT] \
    smtp-auth=login[/plain]... \
    smtp-use-starttls

# E.g. here is a real life example of a very huge free mail provider
# (Activate this account via mailx -AXooglX from the command line,
# or use the ? acc[ount] XooglX command in interactive mode)
account XooglX {
   # Localize options, forget them when changing the account
   localopts yes
   # (The plain smtp:// proto is optional)
   set smtp=USER:PASS@smtp.gmXil.com smtp-use-starttls
   set from="Your Name <youremail@domain>"
}

# And here is a pretty large one which does not allow sending mails
# if there is a domain name mismatch on the SMTP protocol level,
# which would bite us if the value of from does not match, e.g.,
# for people who have a sXXXXeforge project and want to speak
# with the mailing list under their project account (in from),
# still sending the message through their normal mail provider
account XandeX {
   localopts yes
   set smtp=smtps://USER:PASS@smtp.yaXXex.ru:465 \
       hostname=yaXXex.com smtp-hostname=
   set from="Your Name <youremail@domain>"
}
ヒント: If you have enabled two-step authentication in Gmail, and you have added an application specific password for S-nail, you will want to use that password rather than your regular Gmail password, which may work without enabling the otherwise necessary "less secure apps".

Note that, when storing passwords in $HOME/.mailrc, you should set appropriate permissions with chmod 0600. You can also set the netrc-lookup option and store user credentials in $HOME/.netrc (or $NETRC) instead; e.g., here is a real life example that sets up SMTP, POP3 as well as IMAP, storing all user credentials in there:

account XandeX {
   localopts yes
   set from="Your Name <youremail@domain>"
   set netrc-lookup
   #set agent-shell-lookup="gpg -d .pass.gpg"
   set smtp=smtps://smtp.yXXXXx.ru:465 \
       smtp-hostname= hostname=yXXXXx.com
   set pop3-keepalive=240
   shortcut pop pop3s://pop.yXXXXx.ru
   # Type xp to login to the POP3 account
   ghost xp 'fi pop'
   set imap-keepalive=240
   shortcut imap imaps://imap.yXXXXx.ru
   # Type xi to login to the IMAP account
   ghost xi 'fi imap'
 }

and, in $HOME/.netrc:

machine *.yXXXXx.ru login USER password PASS

In this case USER and PASS are clear text, not URL encoded. You can further diversify things and use encrypted password storage, since ArchLinux compiles in password agent support. To adjust the example, simply do not specify the password PASS token in $HOME/.netrc but instead uncomment the agent-shell-lookup line in the example account above. The encrypted password storage .pass.gpg can be created like this:

# echo PASS > .pass
# gpg -e .pass
# eval `gpg-agent --daemon --pinentry-program=/usr/bin/pinentry-curses --max-cache-ttl 99999 --default-cache-ttl 99999`

Test the configuration (use the -d command line option for a dry-run):

# echo test-body | mailx -vv -A XandeX -s test-subject some@where

インタラクティブな使用方法

Arch Linux の S-nail にはコマンドラインエディタが組み込まれており、履歴機能や正規表現、メッセージのカラー表示が使えます。S-nail は POSIX 標準に準拠しているためインタラクティブに使う前に設定を変更する必要があります。全ての設定に手を入れる必要はありませんがマニュアルは必ず読んでください。最低でも設定の一番上に以下を追加してください:

# (The global configuration /etc/mail.rc provides some commented basics;
# in particular it shows all options that POSIX mandates as defaults.)

# Start into interactive mode even if the system mailbox is empty or
# doesn't exist.  S-nail would exit immediately without that one
set emptystart

# When composing a message, let period `.' on a line by itself finalize
# composition, before start directly into $EDITOR
set dot 
set editalong

# Start $PAGER when a message is longer than VALUE lines;
# without VALUE: screen $LINES
set crt=

# Colourize headers when displaying messages (note that $PAGER may
# require special flags, e.g., less(1) needs the -R option; S-nail will
# however set the $LESS environment variable accordingly, but only if
# that was not set before..)
set colour-pager

# A nicer prompt for a modern terminal
set prompt="\033[31m?\?[\$ \@]\& \033[0m"

# Add more entries to the history, and make that persistent
set history-gabby NAIL_HISTFILE=+.s-nailhist NAIL_HISTSIZE=-1

# When printing messages, show only these headers
# (Easier to retain what you want than to ignore
# what you don't; use Print to see all headers and Show
# to see the raw message content)
retain date from to cc subject

# Try to get around weird MIME attachment specifications
# (This option can take a value, see the manual for more)
set mime-counter-evidence

# Display HTML parts inline, nicer than what the builtin viewer can achieve
#set pipe-text/html="lynx -stdin -dump -force_html"
# Learn another mimetype
mimetype 'model/vrml wrl vrml'

# Create some new commands so that, e.g., `ls /tmp' will..
ghost ls !ls -latro
ghost ps !ps axu

Once you're in it use list to print all available builtin commands. ArchLinux compiles in the "DOCSTRINGS" feature, so that typing `?X' tries to expand "X" and print a help string; since S-nail will allow abbreviations of all commands this is sometimes handy; try, e.g., ?h, ?he and ?hel ... The command help will print a short summary of the most frequent used commands.

コマンド

When starting into interactive mode a summary of the content of the initially opened mailbox is printed, as via the headers command. In the header display messages are given numbers (starting at 1) which uniquely identify messages. Messages can be printed with the print command, or short: p. Whereas p honours retained (or ignored) list of headers to be displayed, the Print command will not and display all headers; the Show command will print raw message content.

By default the current message (dot) is printed, but just like with many other commands it is possible to specify lists of messages, as is documented in the manual section "Specifying messages"; e.g., p:u will display all unread messages, p. will print the dot, p 1 5 will print the messages 1 and 5 and p- and p+ will print the last and the next message, respectively. Note that simply typing RETURN in an empty line acts like next (n), and thus prints the next message.

The command from (f) is nice for an overview, e.g., f '@<@arch linux' will print the header summary of all messages that contain the string "arch linux" in some message header, whereas f '@arch linux' will only match those with "arch linux" in their subject; finally, the regular expression f @^A[^[:space:]]+ finds... that is, be aware that quoting may be necessary when there is whitespace in search expressions etc.

  • file and File open a new mailbox, the latter in readonly mode (which can be handy to avoid flag updates etc.)
  • newmail (dependent on the mailbox, checks for new mail and) prints a listing of new messages
  • he (headers) reprints the message list
  • z-, z+, z0, z$ scroll through the header display (dependent on the terminal you are using the Home/End/PageUp/PageDown keys will be working aliases)
  • folders shows a listing of mailboxes under the currently set folder
  • r replies to all addressees of the given message(s)
  • R replies to the sender of the given message(s)
  • Lreply "mailing-list" reply to the given message(s)
  • move or mv moves (a) message(s)
  • (un)flag marks (a) message(s) as (un)flagged
  • new marks (a) message(s) unread
  • seen marks (a) message(s) read
  • P prints (a) message(s) with all headers
  • p prints (a) message(s) and all non-ignored headers.
  • show prints the raw message of content of (a) message(s)

メッセージの作成

Composition is started by typing mail user@host or by replying to a message. When you return from $EDITOR (assuming editalong is set) you'll find yourself in the native editor, where many operations can be performed using tilde escapes (short help available via ~?). Of particular interest is ~@, which either allows interactive editing of the attachment list, or, when given arguments, to add a(n) (comma-separated list of) additional attachment(s).

To send the mail, signal EOT with Ctrl+d or type "." on its own line (the latter requires the dot option).

S/MIME を使う

The manual contains a step-by-step example of how to create your certificates etc. ("Signed and encrypted messages with S/MIME"). Assuming you have your private key and signed certificate already, just create the paired file we need

# cat private-key.pem signed-certificate.pem > ~/pair.pem

and setup S-nail via

set smime-sign-cert=~/pair.pem \
    smime-sign-message-digest=SHA256 \
    smime-sign

From now any message that is sent will be signed. The default message digest would be SHA1, as mandated by RFC 5751. Note that S/MIME always works relative to the setting of the variable from, so it seems best to instead place the above settings in an account. The verify command verifies S/MIME messages, but note that S/MIME decryption and verification is solely based upon OpenSSL for now, which only supports messages with a simplicistic MIME structure. Sorry. By the way, if you miss hyperlinks and a table-of-content to get yourself going, the manual on the projects' website offers this; and the manual that ships with ArchLinux does, too, but needs the mdocmx(7) extension to be visible.

OpenPGP のサポート

S-nail は OpenPGP をサポートしていませんが、マクロを使うことで自動的に --clearsign されたメッセージを検証することができます。リソースファイルで以下を使うことで V を押すだけでメッセージを検証することが可能です:

 define V {
   localopts yes
   set pipe-text/plain="set -C;\
     : > \"${TMPDIR}/${NAIL_FILENAME_GENERATED}\";\
     trap \"rm -f \\\"${TMPDIR}/${NAIL_FILENAME_GENERATED}\\\"\" EXIT;\
     trap \"exit 75\" INT QUIT TERM;\
     set +C;\
     cat > \"${TMPDIR}/${NAIL_FILENAME_GENERATED}\";\
     < \"${TMPDIR}/${NAIL_FILENAME_GENERATED}\" awk \
         -v TMPFILE=\"${TMPDIR}/${NAIL_FILENAME_GENERATED}\" '\
       BEGIN {done=0}\
       /^-----BEGIN PGP SIGNED MESSAGE-----/,/^$/ {\
         if (done++ != 0)\
           next;\
         print \"--- GPG --verify ---\";\
         system(\"gpg --verify \" TMPFILE \" 2>&1\");\
         print \"--- GPG --verify ---\";\
         print \"\";\
         next;\
       }\
       /^-----BEGIN PGP SIGNATURE-----/,/^-----END PGP SIGNATURE-----/ {\
         next;\
       }\
       {print}\
       '"
   print
 }
 define RK {
   !printf 'Key IDs to gpg --recv-keys: ';\
     read keyids;\
     gpg --recv-keys ${keyids};
 }
 ghost V call V
 ghost RK call RK

IMAP メールボックスを使う

The following is only a quick hint, it is also possible to define folder and inbox to point to IMAP server folders, for example. Internationalised names are supported.

set v15-compat

# or many servers will expire the session
set imap-keepalive=240
set imap-cache=~/.imap_cache

# You may want to define shortcuts to folders, for example:
shortcut myimap "imaps://USER:PASS@server:port"
set inbox=myimap