Email reader programs such as Thunderbird or Evolution are great, but sometimes they can feel bloated. If you found yourself working mainly from CLI, you may find useful to learn how to install and configure Mutt, a command line email client: that’s what we will do in this tutorial.
In this tutorial you will learn:
- How to install Mutt
- How to configure Mutt to be used with a gmail account
- How to store sensitive information in an encrypted file and source it from the main Mutt configuration
- How to setup some macros to easily switch between mailbox directories
Software requirements and conventions used
|Category||Requirements, Conventions or Software Version Used|
|Software||Mutt, gpg to encrypt sensitive information|
|Other||It is assumed you have a working gpg setup with personal keypairs|
|Conventions||# - linux-commands to be executed with root privileges either directly as a root user or by use of |
$ - linux-commands to be executed as a regular non-privileged user
Mutt is available by default in the official repository of all the major Linux distributions, therefore we can easily install it using our favorite package manager. On the Fedora family of distributions, we can use dnf:
$ sudo dnf install mutt
On Debian and derivatives we can use apt:
$ sudo apt install mutt
Mutt is also available in the Archlinux extra repository. To install it we can use pacman:
$ sudo pacman -S mutt
Once installed we can proceed and configure the application. In this tutorial we will tune it to work with a gmail account.
We can choose among many paths to create the Mutt configuration file, however the most common ones are
~/.config/mutt/muttrc; in this tutorial we will use the former. Here are some of the directives we may want to use inside of it:
set ssl_force_tls = yes set abort_nosubject = no set mail_check = 60 set timeout = 10 set sort = "reverse-date-received" set signature = "~/.mutt/signature" set copy = no
Let’s take some time to explain what is the meaning of the variables we set above, and how they alter the behavior of Mutt.
Force tls connection
The version of Mutt we installed should be compiled with support for tls: this is needed to enable encrypted communication with remote servers. To verify it, we can launch the following command:
$ mutt -v | grep tls
As the result of the above command, we should see
--with-gnutls among the configuration options highlighted as a match. If mutt is configured with this option we can use set
ssl_force_tls to “yes” to make Mutt require all connections with remote servers to be encrypted. Mutt will try to use encryption even when communicating with those server which not officially support it, and will abort the connection if it doesn’t succeed.
Abort if a message contains no subject
abort_nosubject we can setup how Mutt will behave when a message is composed but no subject is given at the subject prompt. The default for this option is
ask-yes, meaning that will be asked to confirm if we really want to send the message anyway, with the “yes” option used as default. In this case we used
no as value, so messages without a subject will be sent without the need for a confirmation.
Check for new emails
Mutt updates the status of all directories every time an input is received from the keyboard. We normally want to be notified of new emails even on idle, without the need to press a key. The variable which governs this behavior is
timeout. It takes a value in seconds which is the maximum time to wait for an input from the user. If no user input is received during the amount of time specified, the update operation takes place anyway. The default value for the variable is
600 seconds, so if no input is given, we would receive updates every 10 minutes. The default value is too high, we use
As we said, each time a user input is received mutt looks for updates; on a high keyboard activity this would cause too many access operations, therefore we want to limit this frequency anyway. To accomplish the task we can use the
mail_check variable. As happens for
timeout this variable accepts a numerical value, which is interpreted as the minimum time in seconds between two scans. The default value for the variable is
5 so mutt will search for new mails every
5 second even if keys are pressed very often. We want to increase the value of this variable, especially if using multiple mailboxes, to avoid possible slowdowns:
60 should be a reasonable value.
Set the email sort order in the index page
By default emails, in the “index” menu (where the list of messages is displayed) are sorted by date in ascending order, so newer emails will be displayed at the bottom. To change the way email are sorted, we can use and set the value of the
sort_order variable. In this case we used
reverse-data-received in order for newer emails to appear at the top of the list. Other parameters can be used as sorting factors, as for example subject and size.
Appending a signature to outgoing emails
If we want to append a specific signature to our outgoing emails, we can set and use the
signature variable. With this variable we specify the path of a file containing the signature. If the filename ends with a
| (pipe) it is interpreted as the shell command the output of which should be used as a signature. In this case we just used the path of an existing file:
Save copy of outgoing messages
By default, in Mutt, the
copy variable is set to ‘yes’, so copies of outgoing messages are saved for later references in the file specified via the
record variable, which, by default, is
~/sent. Since we are configuring Mutt to work with gmail, which has this functionality built in (outgoing email are stored in the remote “[Gmail]/Sent Mail” folder), we want to set
copy to false, otherwise sent emails would be also saved locally, in the location we saw above (
Configuring Mutt to work with gmail
Until now we saw and set few basic and important options. Now we will see how we can configure Mutt to work with a gmail account.
Generating an app-specific-password for Mutt
If we are using google two-factor authentication, to be able to access our gmail account from Mutt, we need to generate an app-specific-password, since google requires it for the applications that don’t use Oauth2 as authentication method. To generate an app-specific-password, just navigate to this address, authenticate yourself, and follow the instructions to generate the password: we will use it in the configuration.
Gmail account configuration
The options we want to set in order to use Mutt with gmail are the following (we use a dummy address):
set from = "firstname.lastname@example.org" set realname = "Foo Bar" # Imap settings set imap_user = "email@example.com" set imap_pass = "<mutt-app-specific-password>" # Smtp settings set smtp_url = "smtps://firstname.lastname@example.org" set smtp_pass = "<mutt-app-specific-password>" # Remote gmail folders set folder = "imaps://imap.gmail.com/" set spoolfile = "+INBOX" set postponed = "+[Gmail]/Drafts" set record = "+[Gmail]/Sent Mail" set trash = "+[Gmail]/Trash"
Let’s take a look at the variables we defined above. First of all, we have
realname: with them we specify, respectively, the value of the “From:” header parameter and the “real name” (your first and last name) that will be used in the emails we will send.
The next thing we did above was to specify the
imap_pass variables. The former is practically your address, the same we used for
from; the value we assign to the latter is the app-specific-password we generated earlier for our account.
We then proceeded to set the value to use for
smtp_pass. The first one defines the url where to send messages for delivery, in the case of gmail it is
smtp://<yourusername>@smtp.gmail.com. The value of the
smtp_pass variable, must be, again, the generated app-specific-password.
As the last thing we defined some gmail folders:
folder: the location of our mailbox, in the case of gmail is
spoolfile: the folder, inside the mailbox, where emails arrive;
postponed: the folder to use to store postponed messages (drafts);
record: the directory where gmail stores sent messages;
trash: the directory where to store delete emails, instead of purging them directly.
As we said before, gmail stores sent mails in the dedicated folder automatically; here we assigned the value of the
record directory (
+[Gmail]/Sent Mail) just to be able to reference it later in macros without hard-coding the path (gmail is not the only mailbox provider). We also defined
trash: it is the directory where mails marked for deletion will be moved when closing Mutt or synchronizing its state, instead of being purged directly: this gives us the chance to retrieve accidentally deleted messages. This functionality is included by default in recent versions of Mutt; to obtain it in older versions, the so called “trash patch” should be applied, even though it could be achieved also via macros.
Securing sensitive account information
At this point a question should raise in you: isn’t it dangerous to put sensitive information like the app-specific-password we generated for Mutt in a plain configuration file? Of course it is! This is something that should never be done! On the other hand, having to provide a password each time we want to connect to our mailbox would be really, really tedious. The solution to this problem is to store our gmail account information in a separate file we will encrypt using gpg; the file will be then sourced and decrypted in memory from the main mutt configuration file.
Here is an example of how to do it. Move all the gmail information we setup in the previous section in a file called
~/.mutt/gmail and encrypt it using gpg, running the command:
$ gpg --recipient <recipientname> --encrypt ~/.mutt/gmail
The above command would generate a new encrypted file,
~/.mutt/gmail.gpg. You can now delete the original, plain text one. To source the encrypted file from the main Mutt configuration, all we have to do is to place this line at the beginning of the
~/.muttrc configuration file:
# Source default account configuration source "gpg2 -dq ~/.mutt/gmail.gpg |"
Notice the traling pipe: this is important to let Mutt use the output of the command. If you are using the “pass” password manager, you don’t need to encrypt the file manually, but create an entry for it that will be stored in the password-store. Want to know more? We talked about pass in How to organize your passwords using pass password manager article.
Mutt let us define some “Macros” we can use for various purposes, as for example to establish shortcuts to switch between folders. Here are some useful ones we can place in our
~/.muttrc file. Their purpose is self-explanatory:
macro index gd "<change-folder>$postponed<enter>" "go to drafts" macro index gs "<change-folder>$record<enter>" "go to sent" macro index gi "<change-folder>$spoolfile<Enter>" "go to inbox" macro index gt "<change-folder>$trash<enter>" "go to trash""
In this article we learned how to install and configure Mutt, a command line mail client, on some of the major Linux distributions. We learned how to set some of the most important options, how to configure Mutt in order to use it with a gmail account, and how to store sensitive information in a separate, encrypted file with gpg, which is sourced from the main Mutt configuration file. We also created some macros in order to quickly switch directories. Now you can enjoy reading your emails from your terminal!