Intro

With OpenVPN it is quite common to use Easy-RSA to create a Public Key Infrastructure (PKI) so that client certificates may be distributed. For my use case I much prefer to use LDAP authentication with OpenVPN. I use OpenLDAP but any LDAP server should be fine. I am also using an Arch PKGBUILD file to build the actual plugin that makes OpenVPN work with LDAP auth.

LDAP Prerequisite

Before anything can work we need to have an OpenVPN LDAP schema loaded into our environment. While this LDAP schema offers many attributes, for my use case I only care about having authorized VPN users connect. Once openvpn-ldap.schema is loaded, an LDAP record can contain a new VPN objectClass and attributes.

...
objectClass: openVPNUser
openvpnEnabled: TRUE
openvpnClientx509CN: mydomain.net
...

The nice thing about this is we can easily modify a People record to enable or disable VPN user access.

LDAP OpenVPN Config

There are only a few fairly simple things to do once our environment is ready for OpenVPN.

  1. Build and install the openvpn-auth-ldap plugin. On Arch Linux you can easily build and install the plugin from AUR.
  2. Add the following to your OpenVPN server configuration:
    plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/auth/auth-ldap.conf

    Adjust the paths for openvpn-auth-ldap.so and auth-ldap.conf as needed.

  3. It is a good idea to keep a default copy of auth-ldap.conf. An example configuration can be found on GitHub. Since I like to be organized I keep my LDAP config inside /etc/openvpn/auth.
  4. Restart OpenVPN after modifying auth-ldap.conf accordingly. With systemd one can execute systemctl restart openvpn-server@server, respectively.

INFO

Upon restarting, openvpn.log should show a plugin initialization entry similar to

PLUGIN_INIT: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so '[/usr/lib/openvpn/plugins/openvpn-auth-ldap.so] [/etc/openvpn/auth/auth-ldap.conf]' intercepted=PLUGIN_AUTH_USER_PASS_VERIFY|PLUGIN_CLIENT_CONNECT|PLUGIN_CLIENT_DISCONNECT

At this point we can now have our VPN client authenticate with a username and password using our LDAP auth backend. We can see successful LDAP connections in openvpn.log when a new client connects.

127.0.0.1:60923 TLS: Initial packet from [AF_INET]127.0.0.1:60923, sid=42bec808 6635b5f5
127.0.0.1:60923 peer info: IV_VER=2.4.3
127.0.0.1:60923 peer info: IV_PLAT=mac
127.0.0.1:60923 peer info: IV_PROTO=2
127.0.0.1:60923 peer info: IV_NCP=2
127.0.0.1:60923 peer info: IV_LZ4=1
127.0.0.1:60923 peer info: IV_LZ4v2=1
127.0.0.1:60923 peer info: IV_LZO=1
127.0.0.1:60923 peer info: IV_COMP_STUB=1
127.0.0.1:60923 peer info: IV_COMP_STUBv2=1
127.0.0.1:60923 peer info: IV_TCPNL=1
127.0.0.1:60923 PLUGIN_CALL: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so/PLUGIN_AUTH_USER_PASS_VERIFY status=0
127.0.0.1:60923 TLS: Username/Password authentication succeeded for username 'tony'
127.0.0.1:60923 Control Channel: TLSv1.2, cipher TLSv1.2 DHE-RSA-AES256-GCM-SHA384
127.0.0.1:60923 [] Peer Connection Initiated with [AF_INET]127.0.0.1:60923
127.0.0.1:60923 MULTI_sva: pool returned IPv4=10.8.0.6, IPv6=(Not enabled)
127.0.0.1:60923 PLUGIN_CALL: POST /usr/lib/openvpn/plugins/openvpn-auth-ldap.so/PLUGIN_CLIENT_CONNECT status=0
127.0.0.1:60923 OPTIONS IMPORT: reading client specific options from: /tmp/openvpn_cc_0e9bde0ccb231123af86cd70e8a6f37c.tmp
127.0.0.1:60923 MULTI: Learn: 10.8.0.6 -> 127.0.0.1:60923
127.0.0.1:60923 MULTI: primary virtual IP for 127.0.0.1:60923: 10.8.0.6
127.0.0.1:60923 PUSH: Received control message: 'PUSH_REQUEST'
127.0.0.1:60923 SENT CONTROL [UNDEF]: 'PUSH_REPLY,route 192.168.128.0 255.255.128.0,route 10.8.0.0 255.255.255.0,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 208.67.222.222,dhcp-option DNS 208.67.220.220,route 10.8.0.0 255.255.255.0,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 1,cipher AES-256-GCM' (status=1)
127.0.0.1:60923 Data Channel: using negotiated cipher 'AES-256-GCM'
127.0.0.1:60923 Data Channel Encrypt: Cipher 'AES-256-GCM' initialized with 256 bit key
127.0.0.1:60923 Data Channel Decrypt: Cipher 'AES-256-GCM' initialized with 256 bit key

Intro

Pwgen is a password generator for creating easily memorable passwords. I stumbled across this tool and found it to be one of the best for Linux and macOS.

Installation

Arch Linux

$ pacman -S pwgen

Most Linux distributions should have a package management system with pwgen in their own repositories.

macOS

$ brew install pwgen

Pwgen is also available in MacPorts.

Usage

$ pwgen -h

Usage: pwgen [ OPTIONS ] [ pw_length ] [ num_pw ]

Options supported by pwgen:
  -c or --capitalize
        Include at least one capital letter in the password
  -A or --no-capitalize
        Don't include capital letters in the password
  -n or --numerals
        Include at least one number in the password
  -0 or --no-numerals
        Don't include numbers in the password
  -y or --symbols
        Include at least one special symbol in the password
  -s or --secure
        Generate completely random passwords
  -B or --ambiguous
        Don't include ambiguous characters in the password
  -h or --help
        Print a help message
  -H or --sha1=path/to/file[#seed]
        Use sha1 hash of given file as a (not so) random generator
  -C
        Print the generated passwords in columns
  -1
        Don't print the generated passwords in columns
  -v or --no-vowels
        Do not use any vowels so as to avoid accidental nasty words

Examples

Generate one single password.

$ pwgen -c -n -y 100 1
9S3UKhXUmoFMl7Nfm2E093EFTWVyX2d711AEKuOnCqWnkAQIJyPjgd3pgITmvove9wx0MbqLAnl8t8EsgMARigM5rSHFLDeopEuD

This password uses

  • at least 1 capital letter
  • at least 1 number
  • at least 1 symbol
  • 100 characters
  • 1 total password

Tell Pwgen to give 10 passwords.

$ pwgen -c -n -y -s 100 10
8Jjnm7RDTmMbMVs1gJotHo0esHR0GAJPaDErSjqyWZmdMJxh4xe5uiScHu4LfK8AbCj5lH5Iyu7P9Ia9nJyNZENJqmqruzQVIcO9
QatpFsxT7uHCWdEO5d0x7oKX1SKzv9w1gJkrYd8lXcaJyoZr1BCMe2xuaWbyy7Zidf9ueCZOv3oAFO0aWhTRT0T44o9OLdtPOWR3
9Zm70DICfcvfHPTsyz83VuLJ1MyUSHJE9kkuXDltGorouwaXsHuRfdvJDXg40XmPSOTC6K4omfinqGefU6oQ7pj4sOCnplhiMxAD
bi8DOCfMmDmTQ3EL8RXDgInEUqV0mTk0ZeUXDstiEm2pj3PQ6kjSRcVawQw0jIuuaq4ZQGsyNzIBnNJJVkT42hgPLtJD9WaxIICE
DfdQiPEwPytSHBD5vDqgqxxbBuqlNFbADRvljtfTUAf2eCheuGLsLBUJGvs4YZ3MUglrY3ebKLQBQ20aEJu0RAeC0M1mjdNNJp3z
ZnL0oJSh45a2yAVvaS4HM2GTuUWgitX5pGRjF2LjXnmsp2kRvQYrxkQxo2yqWmJ6Lqh6uaDmckQhlcujoJvZgRruSbUZxZniLjNi
UaeFRz4rcMfVtarft7J5Lspu2tamL9i9fu9J394exCfRDj2k6UN5HsCi7shWy8bD2IB1ISAGyIb8qIpXvygQuzQJaZ9V5dYaCRaj
NLRZSsmtDCA2sVtjIse8brhMM0GWskJffOvarAYBZEagz179AdwtgnmpaRz2sZo3Yw36RO15Nls9QbJrvWQbKek0ULq4dNMaNK1N
1TOvS5zuKB1LC9PaewvOO8jEn8lij1KYJyvvfLIgbLP8zlo4vzf2uOcJmkXa9ukpXxxcTuoYRNpscwbfx8HiSDWLJQ4jNjxUICz6
AwmHShhV8WQGjvOwyM8mTIjex6APatAVEGHcACCji53ClfnPKsiO7cacdQK5zTSxdLIqe4bwqWImlQJYMY0P4Uj6PckdfMWRptWX

I think anyone should get the idea right away. In short, you can easily fine tune Pwgen to give as complex of passwords as needed.

Intro

Mozilla Thunderbird is a free, open source, cross-platform email, news, and chat client developed by the Mozilla Foundation.

Mozilla Thunderbird is arguably the best Mail User Agent for the desktop. Being an avid user of Email I thought I would list some of the extensions I find makes Thunderbird even better in no specific order.

Adblock Plus

First on the list is Adblock Plus. I really think it's ridiculous to serve ads in Emails, so this works really well for anyone looking to block all those annoying ads. This extension is probably not needed if Emails are read in plain text.

Display Quota

This is a nice extension to display your mail quota. I use quotas on my mail servers and like how this extension will tell you how many messages are in each folder. You can also have it give you a warning when you reach a certain percentage and modify it's appearance.

Enigmail

This is a must have extension all Thunderbird users should have. It does a great job at what it was intended to do - sign & encrypt Email messages. From my experience it has been quite stable.

ImportExportTools

This extension is great for those looking to import or export folders and messages. There are plenty of available options.

Manually sort folders

I'm not sure why Thunderbird does not have native support for manually sorting folders, but this extension really does deliver. You can sort manually or automatically and re-order accounts in the folder pane. Definitely worth having.

Markdown Here

I really enjoy using markdown and just so happen to write my blog using markdown, so thought why not extend support to other apps like Thunderbird. This extension works really well for writing Email messages using markdown syntax.

Send Later

I needed to send an Email at a specific time and found Send Later to exist. I'm glad I came across this extension because it definitely excels at what it does. The caveat is that Thunderbird must be open for it to work, but the support page suggests some solutions.

I originally thought about writing a small script to do this, so decided to write something up that I could easily use on Linux and macOS systems.

#!/usr/bin/env bash

## use the 'at' command to send an outgoing email at a specific time
MAILTO=''
MAILFROM=''
SUBJECT=''
Cc=''
Bcc=''
AT="at 9:00 AM Today" # 'at' expressions: http://www.computerhope.com/unix/uat.htm

MESSAGE=''

# Begin script
$AT <<EMAIL
mail -s "$SUBJECT" -c "$Cc" -b "$Bcc" -r "$MAILFROM" "$MAILTO"
$MESSAGE
EMAIL

# EOF

Sieve

I use pigeonhole with Dovecot for Sieve support on my Linux server. I'm really glad this Thunderbird extension exists. It easily implements the ManageSieve protocol to securely manage Sieve Script on a remote IMAP server. For example, we can set a vacation notice.

require ["body","fileinto","vacation"];
# rule:[Vacation]
if true
{
    vacation :days 2 :addresses "hello@tnyc.me" :subject "Out of Office" "Thanks for your message. I am on vacation and will respond to emails when I return.";
}

I want to also point out you can grab the latest Thunderbird Sieve extension on GitHub. I had to use a Development Build because the extension available from the official Mozilla page would hang and never make the initial connection.

So there you have all the extensions worth mentioning that I find make Thunderbird even better. Leave a comment if you have any other useful Thunderbird extensions!

Intro

LDAP makes it a breeze to add multiple domain names you wish to serve email accounts with. Although I am describing how I configured multiple domains in my own environment using OpenLDAP - this should also work for other LDAP implementations.

Domains Organizational Unit

dn: ou=Domains,dc=domain1,dc=net
objectClass: organizationalUnit
objectClass: top
ou: Domains
description: Domains used for Postfix as its list of locally hosted domains

This LDIF will define our Domains Organizational Unit (OU). Add the LDIF with ldapadd so our domains have a container to live in.

Adding Domains

dn: dc=domain1.net,ou=Domains,dc=domain1,dc=net
dc: domain1.net
objectClass: dNSDomain
objectClass: top

dn: dc=domain2.me,ou=Domains,dc=domain1,dc=net
dc: domain2.me
objectClass: dNSDomain
objectClass: top

After importing our domains from an LDIF we can now verify our 2 domains in LDAP get returned with the postmap command.

$ postmap -q domain1.net ldap:/etc/postfix/ldap/ldap-virtual-domains.cf

domain1.net

$ postmap -q domain2.me ldap:/etc/postfix/ldap/ldap-virtual-domains.cf

domain2.me

Intro

This post will touch on what objectClass and attributes I used specifically for OpenLDAP mail user records. I like the idea of keeping things well organized and with this simple structure I'm keeping the People and Mail containers separate. As a result, user records in the Mail organizational unit will have mail specific attributes not found in People user records.

For the attributes to work I needed to have postfix-book.schema loaded into LDAP.

Import Mail Account

dn: uid=jdoe,ou=Mail,dc=domain1,dc=net
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: PostfixBookMailAccount
uid: jdoe
cn: John Doe
sn: Doe
mailEnabled: TRUE
mailAlias: alias1@domain1.net
mailAlias: alias2@domain2.me
mailAlias: alias3@domain1.net
mailAlias: alias4@domain2.me
mailUidNumber: 5000
mailGidNumber: 5000
mail: johndoe@domain1.net
description: John Doe's mail account
userPassword: {SSHA}lFXu8SajJaj+vEk99SvsBa+sRLmLfiRV
mailHomeDirectory: /home/vmail/domain1.net/johndoe@domain1.net
mailStorageDirectory: maildir:/home/vmail/domain1.net/johndoe@domain1.net/Maildir

Once this mail record is imported into LDAP, the primary mail account including additional mail aliases defined by the mailAlias attribute can be verified using the postmap command.

$ postmap -q johndoe@domain1.net ldap:/etc/postfix/ldap/ldap-vmailbox.cf

johndoe@domain1.net

$ postmap -q alias4@domain2.me ldap:/etc/postfix/ldap/ldap-aliases.cf

johndoe@domain1.net

We know LDAP can find our alias because the primary mail account that owns the alias was returned.