Solving dnsmasq/vpn resolv.conf contention with openresolv

One middleman to control them all

dnsmasq is a great DNS cacher to speed up queries to previously visited sites, and also serve as DHCP server is need be. Since it runs locally, you generally end up adding an entry of nameserver 192.168.1.1 to /etc/resolv.conf. If you happen to use a vpn connection occasionally via something like vpnc, it will overwrite your resolv.conf with your vpn providers nameservers, essentially bypassing dnsmasq. While there is no big harm here, if you would still like to use dnsmasq in your vpn connections without manually overriding the nameservers, openresolv is the tool for you.

Actually getting dnsmasq, vpn & openresolv to work together is fairly straight forward. The rest of this entry assumes you have openresolv installed (which is pretty straight forward and provided by most distros).

This is what a regular dnsmasq setup looks like. Since the actual resolv.conf is almost always auto generated nowadays, you add the entry for dnsmasq to resolv.conf head file

$ cat /etc/resolv.conf.head
 nameserver 127.0.0.1

What we’re going to do is setup openresolv to provide nameservers and configuration to dnsmasq from a pre-specified location and have dnsmasq configured to pick them up from said location. Thus the actual resolv.conf is generated by openresolv, with dnsmasq as the middle man, with openresolv feeding dnsmasq the fallback servers and search domains as well. Clear out any resolv.head files you may have modified (though this is optional really). The first configuration we setup is openresolv, as show below. You can change the file names (except for /etc/resolv.conf obviously) if you like.

$ cat /etc/resolvconf.conf
  resolv_conf=/etc/resolv.conf
  # If you run a local name server, you should uncomment the below line
  # and configure your subscribers configuration files below.
  name_servers=127.0.0.1
  dnsmasq_conf=/etc/dnsmasq-resolvconf.conf
  dnsmasq_resolv=/etc/dnsmasq-resolv.conf

Next you change the following entries in dnsmasq configuration in /etc/dnsmasq.conf

resolv-file=/etc/dnsmasq-resolv.conf
conf-file=/etc/dnsmasq-resolvconf.conf

conf-file is optional, and used for any custom configuration that you would normally do in resolv.conf. Make sure the file names match with the configuration in openresolv.conf. /etc/dnsmasq-resolv.conf will always contain the actual nameserver configuration that dnsmasq will fallback on for entries not found in cache. That’s pretty much all the configuration required to make openresolv, dnsmasq & vpn work together.

LDAP integration with phabricator

Where RTFM is no good

This post tells you how to use connect phabricator to your LDAP server for auth credentials

When it comes to code review Gerrit is pretty much unbeatable. Sadly, since it’s git only, and our internal codebase is hosted on Mercurial, this was of no use to us.

Enter phabricator. While the setup is pretty easy (even the manual installation on RHEL 5), the configuration is not as straightforward as I would like, with using LDAP integration for authentication not quite working as expected. Specifically our LDAP server did not support anonymous searches. While there are a few examples floating around the web, I couldn’t really find one that worked. ldapsearch actually proved to be quite helpful here. An easy way to try this out is to run the following command :

ldapsearch -h bar.foodomain.com -p 389 -x -b "CN=Users,dc=foodomain,dc=com" -D "foodomain\user" -W | less

Where bar.foodomain.com is your ldap server, and user is your ldap login name. The -x indicates use simple authentication, and -W prompts for the password for ‘user’. If this command worked for you, then the following configuration should work for LDAP in phabricator

* Hostname: bar.foodomain.com
* Port: 389
* Base DN:  dc=foodomain,dc=com
* Search Attribute: sAMAccountName
* Always Search : No
* Username Attributes: sAMAccountName
* Real Name attributes: displayName
* LDAP Version: 3
* Referrals: No
* Use TLS: No
* Active Directory Domain:  foodomain

A sample return for ldapsearch looks something similar to this (abbreviated for brevity) :

dn: CN=Bob Bobberson,CN=Users,DC=foodomain,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Bob Bobberson
sn: Bobberson
description: Burger Wrangler
telephoneNumber: 311-555-2368
givenName: Bob
distinguishedName: CN=Bob Bobberson,CN=Users,DC=foodomain,DC=com
displayName: Bob Bobberson
mailNickname: burgerguy
name: Bob Bobberson
sAMAccountName: burgerguy
sAMAccountType: 705403368
userPrincipalName: burgerguy@foodomain.com
objectCategory: CN=Person,CN=Schema,CN=Config,DC=foodomain,DC=com
mail: burgerguy@fodomain.com

Username Attributes & Real name attributes were based on this sample return. The phabricator config actually recommends using sn instead of sAMAccount, this did not work for me. These values are not case sensitive. You can replace displayName with givenName,sn or pretty much any combination of returned attributes.

Note : a lot of places seem to recommend specifying Real Name attributes as ["givenName","sn"] instead of givenName,sn but only the format without the brackets & quotes worked for me. You can also use the auth test utility shipped with phabricator to test ldap via phabricator/bin/auth ldap. It uses ldap settings set in phabricator > auth > ldap.

Simple LDAP configuration only allows you to login via ldap, you still need to import ldap users into phabricator for it to work correctly. To do this go to phabricator > people > import from ldap. Enter any useable username/password combo, and an ldap query to search for users to import. Based on the sample return above, a useable query would be (objectClass=person). Note: if the root user uses an email address found in ldap search, you won’t be able to add that particular user to phabricator, as phabricator will detect a duplicate entry of the email address.

Replying to a thread on lkml via git send-email

Where cli proves to be the best mail client

This post tells you how to use git send-email’s in-reply-to function to create a threaded reply

I recently had to reply to a thread on the linux kernel mailing list that happened to be posted when I was not subscribed to it. While clients like Thunderbird/Outlook or even Gmail may be smart enough to string conversations together via the subject line or some variation thereof (eg, foo & Re: foo), mailing lists rely on message headers, specifically Message-Id & In-Reply-to.

What this basically means is that if you are sending message B as a reply to message A (thus creating a thread), the value of In-Reply-To field in the message headers of B should be the same as the Message-Id in the message headers of A. Similarly, message C will include the Message-Id of B in the In-Reply-To field when sent as a reply to B. Take a look here for an example of a threaded view.

Now lkml has a fairly strict set of guidelines about how to format email sent to lkml, but it basically boils down no html, text only, no word wrapping and inline patches. If these do not apply to your mailing list, you might want to directly try configuring Thunderbird to support In-Reply-To and skip the rest of this. Note: this did not seem to work on Thunderbird 24. Pretty much none of the email clients I tried (mutt, realpine) seemed to have an easy way to support in-reply-to

If you’re still here stranger, time to get excited about cli !

To get past all these mailing constraints, and because Linus basically wrote Git, git supports the ability to directly send out email that passes all these requirements. Note, git send-email needs perl-MIME-Base64 and perl-Authen-SASL installed. There is also a bug in git send-email(v2.0.0.) that forces encryption even if your smtp server does not require it. Please (temporarily) apply the following patch if your outgoing/relay server does not use encryption

--- /usr/lib/git-core/git-send-email.orig       2014-06-06 12:26:00.982762503 -0700
+++ /usr/lib/git-core/git-send-email    2014-06-02 18:36:12.857747720 -0700
@@ -1056,7 +1056,7 @@ sub smtp_host_string {
 # (smtp_user was not specified), and 0 otherwise.

 sub smtp_auth_maybe {
-       if (!defined $smtp_authuser || $auth) {
+       if (defined $smtp_authuser || $auth) {
                return 1;
        }

Now, lets takes a sample message to reply to. Let’s presume we want to reply to Linus Torvalds (Please do not actually email Linus for testing purposes). First thing we want to do is fetch the headers for that message, which we can see by clicking [headers]. Specifically, we only need one line

Message-Id	<CA+55aFzNDTm_O8rGYdNw1S99P06u6EeSdttXBvtURJocQT2O0g@mail.gmail.com>

The value inside <…> is the Message-Id we need to reply to create a thread around this message. Next, we create a text file, let’s say msg1 that git can parse as an email draft. You can type out your email here if you like but you really need to have only two lines in there, message body goes below these two lines

From: Bob Bobberson <bob@bobberson.com>
Subject: Re: Bob Bobbersons Burgers is now open

Change your email address & subject as required, the ‘Re: ‘ before the subject line is recommended to indicate a reply. Next, run git send-email as follows

git send-email --smtp-server smtp.bobberson.com --smtp-user bob --to torvalds@linux-foundation.org --cc linux-kernel@vger.kernel.org  --in-reply-to CA+55aFzNDTm_O8rGYdNw1S99P06u6EeSdttXBvtURJocQT2O0g@mail.gmail.com --annotate <path_to_msg1>

To set encryption, use –smtp-encryption ssl or tls. Using any other value disables encryption (but take note of previously mentioned bug). Using the –annotate flag lets you edit the email before it is sent out, simply type out your message below the subject line. If you skip –annotate, git will proceed to send email (but asks for confirmation).

Note, there are some caveats here. Some places like the Indiana University Kernel Mailing List Archives group messages into chunks of 15 days, you won’t be able to see a threaded view unless you reply before that 15 day window expires, but you will still see your reply threaded at places without this restriction, for eg the actual lkml archives

Using IEEE-DCBx with open-lldp

A short guide

This post assumes that you already have open-lldp installed, and are using a network driver that supports IEEE-DCBx (cxgb4, ixgbe or mlx4). Please note that at the time of writing bnx2x & qlcnic only seemed to support DCBx CEE.

I recommend resetting the lldpad configuration before you enable IEEE. Skip down to the dcbtool step if you wish to skip this. First, stop the lldpad service via
# service stop lldpad
or # /etc/init.d/lldpad stop
Next, clear out the old configuration by deleting or backing up
/var/lib/lldpad/lldpad.conf
Then, restart lldpad via
# service stop start or # /etc/init.d/lldpad start
Enable DCBx on the interface of your choice, replacing ethX with the applicable interface name

# dcbtool sc ethX dcb on

Enable PFC, ETS & APP TLVs as follows

# lldptool -T -i ethX -V ETS-CFG -c enableTX=yes

# lldptool -T -i ethX -V ETS-REC -c enableTX=yes

# lldptool -T -i ethX -V PFC -c enableTX=yes

# lldptool -T -i ethX -V APP -c enableTX=yes

# lldptool -T -i ethX -V IEEE-DCBX mode=reset

# lldptool -t -i ethX -V IEEE-DCBX -c mode

If you did not get any errors, you should see the last command return mode=auto. This basically indicates that lldpad will try and negotiate IEEE-DCBx first, falling back to CEE DCBx.
Finally, restart lldpad to store this configuration via
# service lldpad restart
or # /etc/init.d/lldpad restart.

You can verify negotiation by running lldpad in the foreground and making it print debug messages using # lldpad -V 10. Actual configuration is explained in further detail on the dcbtool and lldptool man pages.