Adding email accounts from command line

A script /usr/local/directadmin/scripts/add_email.sh can be used to add email accounts from the command line.

Usage:
   ./add_email.sh <user> <domain> '<cryptedpass>' <plaintext> <quota>

Where the cryptedpass can either be an MD5/DES password
If plaintext is set to 1, then it can be a raw password
Else, set plaintext to 0 to use the provided crypted pass.
quota, in bytes. Use 0 for unlimited

The domain must already exist under a DA account
1
2
3
4
5
6
7
8
9

Try adding single account to ensure it works:

./add_email.sh user domain.tld supersecurepass 1 20971520
1

Check the DirectAdmin user panel and confirm that the email account was added and that the login credentials work as expected.

Mass-adding email accounts

Let's use the same /usr/local/directadmin/scripts/add_email.sh script for that job.

This guide will describe how to read in a CSV file formatted like this:

user1@domain.com,password1,500
fred@domain.com,password2,500
bob@domain.com,password3,500
joe@domain.com,password4,500
carl@domain.com,password5,500
gary@domain.com,password6,500
1
2
3
4
5
6

And have it automatically added to the /etc/virtual/domain.com/passwd file. Note, it's assumed the numbers on the right (500) are in Megabytes, and passwords are plain-text (passwords can alternatively be crypted). It's important that passwords do not contain any commas, since CSV requires that commas be used as the separators. Also, the DA User and domain should already be set up.

Add a test email account first to ensure all paths are set correctly.

  1. Test adding an email account from command line using the above guide with the ./add_email.sh script.
  2. Create a script that will transform your .csv file into understandable format and call the add_email.sh script:
cd /root
nano csv.sh
1
2

And fill it with the following code:

#!/bin/sh
#sample line:
#user@domain.com,password,500

FILE=mailboxes.csv

#the quotas are stored in bytes. so the # in meg, x 1024 x 1024 gives us bytes.(1024x1024=1048576)
QUOTAMULTIPLIER=1048576

if [ ! -s $FILE ]; then
   echo "Ensure ${FILE} exists";
   exit 1
fi

for line in `cat $FILE`; do
{
   EMAIL=`echo "$line" | cut -d, -f1`
   PASS=` echo "$line" | cut -d, -f2`
   QUOTA=`echo "$line" | cut -d, -f3`

   QUOTA=`perl -e "print $QUOTA * $QUOTAMULTIPLIER"`

   USER=`echo "$EMAIL" | cut -d@ -f1`
   DOMAIN=`echo "$EMAIL" | cut -d@ -f2`

   /usr/local/directadmin/scripts/add_email.sh $USER $DOMAIN "$PASS" 1 $QUOTA
};
done;

exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  1. Add your data into the file /root/mailboxes.csv, set the csv.sh script to 755, then run it:
chmod 755 csv.sh
./csv.sh
1
2
  1. Confirm that the data has been added correctly by viewing the accounts in DirectAdmin via:
    User Level -> Email Accounts

Also, test the login credentials with your preferred webmail client.

Adding specific forwarders by default

If you wish for specific default forwarders be present for new domains, for example "postmaster", "webmaster", and "abuse", you can create the script /usr/local/directadmin/scripts/custom/domain_create_post.sh and add the code:

#!/bin/sh

#modify the TO value as desired
TO=${username}

ALIASES=/etc/virtual/${domain}/aliases
TEMP_ALIASES=${ALIASES}.temp

addalias()
{
   COUNT=`grep -c -e "^${1}:" ${ALIASES}`
   if [ "${COUNT}" -eq 0 ]; then
       echo "${1}: ${TO}" >> ${TEMP_ALIASES}
       cat ${ALIASES} >> ${TEMP_ALIASES}
       mv -f ${TEMP_ALIASES} ${ALIASES}
       chown mail:mail ${ALIASES}
   fi
}

addalias postmaster
addalias webmaster
addalias abuse

exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

You can add more lines (in addition to the postmaster, webmaster, and abuse entries noted in the script above) in order to add more default aliases to newly created accounts. Alternatively, you can remove lines if you prefer not to have any of the aforementioned email accounts created by default.

Now, make the script executable:

chmod 755 /usr/local/directadmin/scripts/custom/domain_create_post.sh
1

There is no need to execute the script manually as this script is ran via post hooks (which are scripts hooked to certain actions to be executed before or after that particular event occurs), so this script will be ran automatically after (post) domain creation.


If you wish to apply this to existing domains, you can create the script /root/fix.sh and add the code:

#!/bin/sh
for u in `ls /usr/local/directadmin/data/users`; do
{
   for d in `cat /usr/local/directadmin/data/users/${u}/domains.list`; do
   {
       domain=$d username=$u /usr/local/directadmin/scripts/custom/domain_create_post.sh
   };
   done;
};
done;
exit 0;
1
2
3
4
5
6
7
8
9
10
11

Make it executable, then run:

cd /root
chmod 755 fix.sh
./fix.sh
1
2
3

Automatically purge inbox and other IMAP folders

The only automated purge tool DA has is for the Spam box and Trash data.

Admin Level -> Admin Settings -> Automatically Purge Spambox/Trash data

The inbox and other folders (inbox + other) won't be touched by DA as it would be considered live data that the User may want.

If you needed to purge that data anyway, you'd likely need to create a script that uses the "find" command with the -mtime option. The following will print all emails that will be subsequently deleted using the command that follows:

find /home/*/imap/*/*/Maildir -mtime +30 -type f | grep -E '/cur/|/new/'
1

Double check the output before using it to ensure the syntax is what you need.
The command above finds files in the new/ and cur/ directories that are older than 30 days (+30).

Once satisfied it's generating the files you want, try the following command to remove those files older than 30 days:

rm -f `find /home/*/imap/*/*/Maildir -mtime +30 -type f | grep -E '/cur/|/new/'`
1

Just be very careful and double check all of the syntax, else it might delete files you don't want deleted.

Listing all E-Mail accounts on a system

If you need to get a full list of all created end-User email accounts, you can use a script to do so:

#!/bin/sh
cd /etc/virtual
for i in `cat domains`; do
{
   if [ ! -s $i/passwd ]; then
       continue
   fi

   for u in `cat $i/passwd | cut -d: -f1`; do
   {
       echo "$u@$i"
   };
   done

};
done
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Which will show you all email accounts that were created by Users on the system. This does not include system accounts.

The same idea, with a few changes, can be used to break it down on a per-Reseller basis:

#!/bin/sh
USERS=/usr/local/directadmin/data/users
VIRTUAL=/etc/virtual
for ul in `ls ${USERS}/*/users.list`; do
{
   r=`echo $ul | cut -d/ -f7`
   echo ""
   echo "Email Accounts for Reseller $r"

   for u in `cat $ul; echo $r`; do
   {
        for d in `cat ${USERS}/$u/domains.list`; do
        {
             if [ ! -s ${VIRTUAL}/$d/passwd ]; then
                  continue
             fi
             
             for e in `cat ${VIRTUAL}/$d/passwd | cut -d: -f1`; do
             {
                  echo "$e@$d"
             };
             done
        };
        done
   };
   done
};
done
exit 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

Don't forget to chmod the script to 755.

Controlling email accounts of a Domain Pointer

Domain Pointers are designed to be exact duplicates of the domain they're created under. As such, you cannot edit many aspects of them.

However, if you wish to have the same website data as , and be able to control email accounts, you can do it by creating the as another full domain name, and then use symbolic links to link the website data to that of the main domain.

  1. If the Domain Pointer exists, delete it.

  2. Create the Domain Pointer as a full domain:

  • User Level -> Domain Setup -> Add Another Domain -> domain=domainpointer.com
  1. Apply either a OR b below:
  • a) Change the DocumentRoot of the domainpointer.com to point it to maindomain.com :
    Admin level >> Custom Httpd Config >> domainpointer.com
    Add CUSTOM token code:
|*if SSL_TEMPLATE="1"|
|?DOCROOT=`HOME`/domains/maindomain.com/private_html|
|*else|
|?DOCROOT=`HOME`/domains/maindomain.com/public_html|
|*endif|
1
2
3
4
5

OR

  • b) Link the data directory that of the main domain for user (requires ssh):
cd "/home/username/domains/domainpointer.com/"
mv public_html public_html.old
ln -s "../maindomain.com/public_html" "./public_html"
mv private_html private_html.old
ln -s "../maindomain.com/private_html" "./private_html"
chown -h "username":"username" public_html private_html
1
2
3
4
5
6

If everything works, and there is no important data in the public_html.old and private_html.old, then you can delete those 2 unused directories.

You can now create email accounts for domainpointer.com, independently from the main domain.

A side-effect of this change is that you can control the SSL certificates for each pointer independently.

How to store e-mail data on a different partition

By default, the Maildir data for system and virtual accounts live here:

/home/fred/imap/domain.com/user/Maildir

/home/fred/Maildir

where fred is the system account name.

There can be advantages for storing email data on a different partition:

  • Can use a smaller/faster disk with better I/O performance, needed by E-Mail's higher iops
  • Frees up space on website disk, also increasing website read performance
  • Prevents Users from accidentally deleting their email data

For this, we can make use of DirectAdmin's Custom Mail Partition option, which lets you specify some other partition or path, like /email, where data will be stored (instead of /home, e.g., /email/fred/Maildir).

Here's how:

  1. We'll assume you've already got your new E-Mail partition mounted with quotas in /etc/fstab and ready to go.

Tell DirectAdmin about it:

cd /usr/local/directadmin
./directadmin set mail_partition /email
service directadmin restart
1
2
3
  1. (OPTIONAL): Run a conversion simulation to see what DA would be running, if you've got questions:
cd /usr/local/directadmin
echo 'action=convert&value=mail_partition&simulate=yes' > data/task.queue.cb; ./dataskq d200 --custombuild
1
2

Like how it looks? go to the next step.

  1. Convert:
cd /usr/local/directadmin
echo 'action=convert&value=mail_partition' > data/task.queue.cb; ./dataskq d200 --custombuild
1
2
  1. If you had any issues and need to run it again, but only want to check and run it for things that have not already been copied (only a basic directory existence check), you can add the quick=yes option to the conversion:
cd /usr/local/directadmin
echo 'action=convert&value=mail_partition&quick=yes' > data/task.queue.cb; ./dataskq d200 --custombuild
1
2

Note that the action=convert&value=mail_partition task.queue request also support the use of &user=fred, in case you're only looking to run it for one account.

  1. Now that the data is correctly set, you should be able to login with your email accounts, the same way you did before. Existing data still there (there is a race during the copy, where it's possible for new messages to not be copied over).

  2. QUOTAS: With the E-Mail data being on a completely separate disk, you'll want DA to include it in the User's usage. Inform DA of the new partition by adding it to the Extra Quota Partitionsopen in new window option:

/usr/local/directadmin/directadmin set ext_quota_partitions /email
service directadmin restart
1
2

Note, If you have multiple other partitions, say /home2, they'll be comma separated, eg:

./directadmin set ext_quota_partitions '/home2,/email'
1

and then have DA set all quotas:

cd /usr/local/directadmin
echo 'action=rewrite&value=quota' > data/task.queue.cb; ./dataskq d2000 --custombuild
1
2

Remote E-Mail

If you wish to use a remote mailserver, a few changes will need to be made.

  1. Go to User Panel -> domain.com -> MX Records

There should be an option for "Local Mail Server". Uncheck that option.

  1. You'll need to change the MX dns record to point to the external mailserver. Remove the "mail" MX record and add "other.domain.com." as the new MX record where "other.domain.com." resolves to the remote mailserver. Notice the ending period in the record as it is important.

Disable "Local Mail Server"

If all new domains are going to have their mail hosted remotely and you wish to have this option set by default, you can do so with the domain_create_post.sh script.

Create: /usr/local/directadmin/scripts/custom/domain_create_post.sh

In it, add the following code so that newly created domains will not exist in /etc/virtual/domains (the file that specifies the domains to use the local mailserver):

#!/bin/sh
FILE=/etc/virtual/domains
cp -f $FILE $FILE.backup
grep -v -e "^$domain\quot; $FILE > $FILE.tmp
mv -f $FILE.tmp $FILE
chmod 644 $FILE
chown mail:mail $FILE
exit 0
1
2
3
4
5
6
7
8

Make the script executable:

chmod 755 /usr/local/directadmin/scripts/custom/domain_create_post.sh
1

Now the script will be automatically ran after a domain is created so that any newly created domains after this point should not be included in the /etc/virtual/domains file.

Don't forget to copy /usr/local/directadmin/data/templates/dns_mx.conf to the custom folder and then edit the custom/dns_mx.conf for the correct default values (i.e., the default remote MX record you want domains to use in lieu of the local 'mail' MX record).

How to activate SNI for dovecot and exim

Requirements

  1. OpenSSL and exim supporting SNI, usually CentOS 6 and higher.

  2. Recent dovecot and dovecot_conf, for support of /etc/dovecot/conf.d/95-sni.conf and /etc/dovecot/conf/sni/*.

  3. CustomBuild 2 to install the exim and dovecot configs.

  4. secure_access_group=access should be enabled in the directadmin.conf, so that the certificates are chmod to 640 with group "access", so that "mail" (within the access group) can read them.

Installation

All steps are done via CustomBuild 2:

cd /usr/local/directadmin
./directadmin set mail_sni 1
service directadmin restart
cd custombuild
./build update
./build set eximconf yes
./build set eximconf_release 4.5
./build set dovecot_conf yes
./build exim_conf
./build dovecot_conf
1
2
3
4
5
6
7
8
9
10

How it works

Any certificate that is saved, either by pasting it through the SSL page, or created/renewed via LetsEncrypt, will trigger a write.

The logic is that DA will read the contents of the new certificate, and place all values in the /etc/virtual/snidomains file.

If a wildcard is found for the current domain, the values from:

letsencrypt_list=www:mail:ftp:pop:smtp
1

will be used to replace the *.domain.com value.

Note: A certificate with multiple wildcards, e.g., *.domain.com and *.otherdomain.com is not supported.

The per-domain option can be used to override domains that should not have it enabled by setting mail_sni=OFF in the domain.com.conf.

When a signed cert and cacert are found, the domain.com.cert.combined file is created (similar to with Nginx), and then all records in the cert are added to:

  • /etc/virtual/snidomains - for exim to use as a lookup. If a subdomain exists in some other domain, but is also in this cert, the last one added has priority (would be a newer, valid cert anyway).
  • /etc/dovecot/conf/sni/domain.com.conf - with each record in there, pointing to the correct cert.

Important

DirectAdmin will only accept valid signed certificates. If you use a self-signed certificate or your own domain does not exist in the certificate, then DA will refuse to accept it and won't add the values to /etc/virtual/snidomains nor create the dovecot sni file at /etc/dovecot/conf/sni/domain.com.conf.

If you rename your domain to domain2.com, for example, the old values are removed from snidomains and conf/sni/domain.com and are only re-added if the above checks are still true.

Currently, a certificate is only considered signed using the quick check where the Issuer and Subject values in the certificate must be different.

If you have a signed certificate which DA isn't accepting, please let us know, and include the certificate and CA bundle/chain so that we can check it out.

Task queue

If you want to issue dovecot config rewrites for all live SSL domains, type;

echo "action=rewrite&value=mail_sni" >> /usr/local/directadmin/data/task.queue
1

This will recreate the sni/domain.com.conf for each SSL domain, plus one for the system hostname.

It will use the /etc/virtual/domainowners file to go through each domain, each cert, and remove any existing *:user:domain.com entries from snidomains, and re-add whatever is present.

To issue a rewrite for a single domain, use the following, but replace 'domain.com' in the command below with the actual domain you want the config rewritten for:

echo "action=rewrite&value=mail_sni&domain=domain.com" >> /usr/local/directadmin/data/task.queue
1
Last Updated: 6/23/2021, 9:36:08 PM