Playing around with eBPF
Here is a wonderful github repository for playing around with BPF https://github.com/iovisor/bcc
Here is a wonderful github repository for playing around with BPF https://github.com/iovisor/bcc
Recently I needed to fetch IP ranges from SPF records. After looking at different python/ruby/perl modules I came to the conclusion that a fancy module (sometimes with wonky dependencies) was overkill just to parse a simple SPF record. So I threw together a simple bash script that is mainly just fetching the SPF record with dig and grep:
1 | dig txt "${fqdn}"|grep -oE 'v=spf[0-9] [^"]+' |
It iterates through the options (it currently recognizes a, mx, ip4, ip6, include, and redirect), and then sorts the output by ipv4, then ipv6.
1 2 3 4 5 6 | fetch_spf.sh ryanschulze.net 138.201.86.179 138.201.86.184 192.249.58.230 2a01:4f8:172:2270:1::102 2604:180::ef4b:4638 |
Download URL: fetch_spf.sh
This is a little function I use to compare package version strings. Sometimes they can get complex with multiple different delimiters or strings in them. I cheated a bit by using sort –version-sort for the actual comparison. If you are looking for a pure bash version to compare simpler strings (e.g. compare 1.2.4 with 1.10.2), I’d suggest this stackoverflow posting.
The function takes three parameters (the version strings and the comparison you want to apply) and uses the return code to signal if the result was valid or not. This gives the function a somewhat natural feel, for example compare_version 3.2.0-113.155 “<” 3.2.0-130.145 would return true. Aside from < and > you can also use a few words like bigger/smaller, older/newer or higher/lower for comparing the strings.
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 | compare_version() { local versionOne="${1}" local comparision="${2}" local versionTwo="${3}" local result= local sortOpt= local returncode=1 if [[ "${versionOne}" == "${versionTwo}" ]] ; then return 3 fi case ${comparision} in lower|smaller|older|lt|"<" ) sortOpt= ;; higher|bigger|newer|bt|">" ) sortOpt='r' ;; * ) return 2 ;; esac result=($(printf "%s\n" "${versionOne}" "${versionTwo}" | sort -${sortOpt}V )) if [[ "${versionOne}" == "${result[0]}" ]] ; then returncode=0 fi return ${returncode} } # end of function compare_version |
List of return codes and meanings:
1 2 3 4 | 0: Comparison is true 1: Comparison is false 2: Did not recognize the comparison 3: Both version strings are identical |
A recent update broke my WordPress theme. I’ve used the same theme for almost 10 years and it was starting to be a pain to keep updated and working with newer WordPress versions. So I decided to put up this simple theme until I get a new theme picked out and up and running.
Update November 2018:
A reader contacted me and pointed out that removing the {} around DKIM_DOMAIN solves the errors in the original example I found and had problems using. I’ve updated the code below (line 8) to reflect those changes in case anyone ends up here via google.
He also shared a nifty way to make selector rollovers easier by adding them to the filename:
1 2 3 4 5 6 7 8 | DKIM_SELECTOR = whatever DKIM_FILE =/etc/exim4/dkim/DKIM_DOMAIN.pem.DKIM_SELECTOR DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}} With the format of the key files being .... /etc/exim4/dkim/example.org.pem.previousselector /etc/exim4/dkim/example.org.pem.whatever |
And last but not least an elegant way to populate the DKIM_DOMAIN variable: https://bugs.exim.org/show_bug.cgi?id=1019
Original Posting:
I was recently setting up SPF, DKIM and DMARC for multiple domains and was having trouble getting Exim to sign emails for the different domains. I found an article here explaining the steps. But I kept getting the following error in my exim logs:
failed to expand dkim_private_key: missing or misplaced { or }
The suggested configuration was the following:
1 2 3 4 5 6 7 8 9 10 11 | DKIM_CANON = relaxed DKIM_SELECTOR = 20150726 # Get the domain from the outgoing mail. DKIM_DOMAIN = ${sg{${lc:${domain:$h_from:}}}{^www\.}{}} # The file is based on the outgoing domain-name in the from-header. DKIM_FILE = /etc/exim4/dkim/DKIM_DOMAIN.pem # If key exists then use it, if not don't. DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}} |
I’m not quite sure why, but Exim was having trouble using the macros in the following macros, so I ended up changing it to the following snippet instead. If you don’t use DKIM_FILE you can omit it. Also you might want to set DKIM_STRICT to true if you published a DMARC policy that will reject or quarantine email failing the DKIM tests (unset, or “false” tells Exim to send the message unsigned if it ran into problems signing the email). The default setting for DKIM_CANON is “relaxed“, so it also can be omitted.
1 2 3 4 5 6 | DKIM_CANON = relaxed DKIM_STRICT = false DKIM_SELECTOR = 20160724 DKIM_DOMAIN = ${lc:${domain:$h_from:}} DKIM_FILE = /etc/exim4/dkim/${lc:${domain:$h_from:}}.pem DKIM_PRIVATE_KEY = ${if exists {/etc/exim4/dkim/${lc:${domain:$h_from:}}.pem} {/etc/exim4/dkim/${lc:${domain:$h_from:}}.pem}} |
Other than that, just make sure the exim process has permissions to access the dkim directory and certificate files and everything should work nicely.