Immediately send Postfix messages to HOLD

For a project, I needed to find some way to purposefully and immediately throw sent messages into the Postfix HOLD queue so they could be released programmatically.

On Debian, you’ll need the postfix-pcre package, and then:

In /etc/postfix/
header_checks = pcre:/etc/postfix/header_checks

And then in /etc/postfix/header_checks:
/^X-My-Custom-Header: .*YES/ HOLD

In your application, for applicable messages you can set X-My-Custom-Header: YES and the messages will immediately go into HOLD.

An example config: CORS + PHP + NGINX

Using this guide from I was able to cobble together an example wide-open CORS config for php files. This may not be everything your particular setup needs, and there may be a better way to do it, but it’s a place to start.

    location ~* CORSTest.php {
        root           /webs/;
        fastcgi_pass   unix:/var/run/php5-fpm-edm.sock;
        include        fastcgi_params;
        #fastcgi_intercept_errors on;
        fastcgi_param  SCRIPT_FILENAME /webs/$fastcgi_script_name;

     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';

Let’s Encrypt and nginx

With the distrust of StartCom by Google and Mozilla, the Let’s Encrypt movement is gaining steam rapidly.

You can use CertBot to get instructions on how to use Let’s Encrypt automatically. Here’s my implementation:

1.) enable jessie-backports and make sure your domain is pointing at your webserver. Then:
2.) # apt-get install certbot -t jessie-backports
3.) # certbot certonly --standalone -d -d --pre-hook "service nginx stop" --post-hook "service nginx start"
4.) You should now have the necessary files in /etc/letsencrypt/live/ in a folder named after your domain. Add them to the appropriate nginx config thus:

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;

(note: I don’t cover dhparams or cipher order in this post.)

Let’s Encrypt certificates are valid for 90 days, so the last step is to automate renewals. In root’s crontab I use the following for quiet monthly renewal attempts, noting that if nothing is due for renewal, no action is taken:

@monthly certbot renew -q --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"

There are other ways to do this; while certbot has a renewal cron in /etc/cron.d/certbot, Certbot’s own advanced setup documentation illustrates how to use the ‘webroot’ plugin which will work with any webserver you like, but since I don’t mind stopping my webserver once a month for this quick check, I simply use the ‘standalone’ plugin instead.

Extending macOS DNS resolution for fun and utility

In macOS, it is possible to extend DNS resolution for specific n-level domains using specially named files in /etc/resolver/ to use nameservers (and the associated options) without changing your default nameservers. In this post I’m going to outline what I’m using it for and how to accomplish it, and some other things you can do, should you be inclined.

I recently became aware of the OpenNIC Project which provides a variety of services like public DNS servers, dynamic DNS, and a couple top-level domains – and it’s that last item I found interesting and wanted to play with it. I could just change my DNS nameservers to any one of many nameservers run by members of the OpenNIC project, but I’m not ready to commit to moving away from Google DNS just yet.

In Linux, I could probably accomplish this by running a nameserver on localhost and slurping in all the OpenNIC TLD data, but in MacOS I wasn’t sure if there was a better solution.

Enter /etc/resolver/. If you create /etc/resolver on your mac, you can then place files there for whatever n-level domains you want. Here is the beginnings of a script I created; it:

– creates the directory /etc/resolver/ if it does not exist,
– creates the file _opennic and supplies a few v4 and v6 nameservers for the OpenNIC project,
– creates symlinks to _opennic for each of the OpenNIC TLD’s I’m interested in resolving.

## - add other resolvers to /etc/resolver 
## (see 'man 5 resolver' for more info)
## 03192017 jkl 

# if /etc/resolver doesn't exist make it 
[ -d /etc/resolver ] || mkdir /etc/resolver; 

# provide for the OpenNIC Project ( and a few TLD's:
tee <<EOF /etc/resolver/_opennic >/dev/null
nameserver 2a05:dfc7:5::53
nameserver 2a05:dfc7:5::5353
nameserver 2a0b:1904:0:53::

ln -fs _opennic /etc/resolver/o
ln -fs _opennic /etc/resolver/dyn
ln -fs _opennic /etc/resolver/oss
ln -fs _opennic /etc/resolver/bbs
ln -fs _opennic /etc/resolver/free
ln -fs _opennic /etc/resolver/geek

# that's all for now

You don’t have to do it this way. You could simply echo 'nameserver' > /etc/resolver/dyn and it would do the same thing; I’m doing it this way because it’s less work if I have to make a major change that effects multiple things on the same location.

Similarly, if you want to affect a single second-level domain and all of the hosts under it, you could for example do echo 'nameserver' > /etc/resolver/' and it would cause lookups for and * to go through You could specify a third-level domain in much the same way as /etc/resolver/ for example, and so on.

(This also means you could make up any TLD you want for local use if you did, say, run dnsmasq locally, and echo 'nameserver' > /etc/resolver/jkl, but I digress. 😉 )

The last thing to remember is that certain tools like dig and nslookup are not going to provide accurate results if you use them on a hostname you have configured in this way. To confirm it is working, use the dns-sd command, thus:

$ dns-sd -G v4 reg.dyn
DATE: ---Mon 20 Mar 2017---
6:22:20.420 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
6:22:20.421 Add 2 0 reg.dyn. 377

megaraid on debian

A while back I was presented with a Dell server of uncertain providence and asked to make it go. Everything went okay until I was looking for RAID management tools. The PERC 5/i RAID controller wants to be used with megaraid; the original company involved with the RAID card in the system had changed hands a couple times, so with a half hour of research that consisted of a quick google search, scouring a few resulting websites, and letting out a small amount of profanity owed to poorly designed downloads pages I turned up an URL.

You can get megaraid from ; then use apt-get to install the alien package to convert the .rpm to .deb like so: alien MegaCli-8.07.14-1.noarch.rpm

Then I took a quick look at the resulting .deb (mostly out of curiosity, I’d never had a reason to use alien until now)…

# dpkg-deb -c megacli_8.07.14-2_all.deb
drwxr-xr-x root/root 0 2015-09-18 03:03 ./
drwxr-xr-x root/root 0 2015-09-18 03:03 ./usr/
drwxr-xr-x root/root 0 2015-09-18 03:03 ./usr/share/
drwxr-xr-x root/root 0 2015-09-18 03:03 ./usr/share/doc/
drwxr-xr-x root/root 0 2015-09-18 03:03 ./usr/share/doc/megacli/
-rw-r--r-- root/root 772 2015-09-18 03:03 ./usr/share/doc/megacli/copyright
-rw-r--r-- root/root 163 2015-09-18 03:03 ./usr/share/doc/megacli/changelog.Debian.gz
drwxr-xr-x root/root 0 2015-09-18 03:03 ./opt/
drwxr-xr-x root/root 0 2015-09-18 03:03 ./opt/MegaRAID/
drwxr-xr-x root/root 0 2015-09-18 03:03 ./opt/MegaRAID/MegaCli/
-rwxr-xr-x root/root 2469692 2013-12-16 05:43 ./opt/MegaRAID/MegaCli/MegaCli
-rwxr-xr-x root/root 2720320 2013-12-16 05:43 ./opt/MegaRAID/MegaCli/MegaCli64
-rwx------ root/root 540512 2013-12-16 05:43 ./opt/MegaRAID/MegaCli/

… before installing it with dpkg -i.

I then checked to make sure that it was actually there and that any shared libs it might want were present:

# file MegaCli64
MegaCli64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped
# ldd MegaCli64 => (0x00007fffdebfe000) => /lib/x86_64-linux-gnu/ (0x00007f49684a6000) => /lib/x86_64-linux-gnu/ (0x00007f4968283000) => /lib/x86_64-linux-gnu/ (0x00007f496807e000) => /usr/lib/x86_64-linux-gnu/ (0x00007f4967d7a000) => /lib/x86_64-linux-gnu/ (0x00007f4967a74000) => /lib/x86_64-linux-gnu/ (0x00007f496785d000) => /lib/x86_64-linux-gnu/ (0x00007f4967498000)
/lib64/ (0x00007f49686cd000) => /lib/x86_64-linux-gnu/ (0x00007f496726f000)

The last step is to make a quick addition to /root/.profile:

if [ -d "/opt/MegaRAID/MegaCli" ] ; then

One quick source ~/.profile to get it into the running session and everything is ready to rumble!

making iptables more useful

I don’t remember where I got it, but there’s a script called xt_geoip_dl that facilitates downloading IP Geolocation data for use with iptables. I didn’t like some of the things the script did, so I made some modifications, namely to make it more friendly to cron updates.

To set up iptables for Debian Jessie you need to install the following:
apt-get install linux-headers-`uname -r` libtext-csv-xs-perl xtables-addons-common iptables-dev

This should create a /usr/lib/xtables-addions/xt_geoip_dl – back up that file and then replace it with my version:


rm -f /root/geo/Geo*
wget -P /root/geo \ \;
gzip -d /root/geo/GeoIPv6.csv.gz;
unzip /root/geo/;


After that, all that’s left is to add two lines to your crontab to make sure you always have the up-to-date IP list:

@monthly /usr/lib/xtables-addons/xt_geoip_dl
@monthly /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip /root/geo/*.csv

Then you can issue iptables commands like

iptables -A INPUT -p tcp -m geoip --src-cc XX -j DROP

where ‘XX’ is a country code you want to drop traffic from.

Nagios 4 and NGiNX

I decided to write this post after a weekend of wanting to set up Nagios using NGiNX on my Debian system. There are one or two guides out there which document how this is done but I had to go a little farther than either of them to get it working, and thought I’d make my own blog post to fill in the missing pieces. I’m retracing my steps from memory; I don’t think I missed anything, but if I did let me know. 🙂

Continue reading

Solarized Dark for SecureCRT

Here’s a set of solarized dark colors for SecureCRT.

With SecureCRT closed, edit your Global.ini which lives by default in %appdata%\VanDyke\Config\Global.ini, find the three lines the start with B:”ANSI Color RGB” and replace it and the two lines of hex below it with:

B:”ANSI Color RGB”=00000040
00 2b 38 00 dc 32 2f 00 85 99 00 00 b5 89 00 00 26 8b d2 00 d3 36 82 00 2a a1 98 00 ee e8 d5 00
07 36 42 00 cb 4b 16 00 58 6e 75 00 65 7b 83 00 83 94 96 00 6c 71 c4 00 93 a1 a1 00 fd f6 e3 00

This version is different than the version I put on pastebin a couple years ago- it has a darker background color (still using solarized colors!) than the pastebin version.

one time when file extensions matter

I needed Java JDK on a Debian system as a prerequisite for some other software and wanted to create a .deb for it.   In contrib there is a package to do this called make-jpkg.

So let’s install it and try to use it:

╭─jkl@dev ~ 
╰─$ fakeroot make-jpkg jdk-7u45-linux-x64.gz 
Creating temporary directory: /tmp/make-jpkg.pWb1sEAQde
Loading plugins: /usr/share/java-package/ /usr/share/java-package/ /usr/
share/java-package/ /usr/share/java-package/ /usr/share/java-package
/ /usr/share/java-package/ /usr/share/java-package/oracle-j2sdk-doc
.sh /usr/share/java-package/

Detected Debian build architecture: amd64
Detected Debian GNU type: x86_64-linux-gnu

No matching plugin was found.
Removing temporary directory: done

Hm. Why is this failing? A quick read of the man page provided the answer:

Download a supported Java RE or SDK or API tar.gz or self-extracting archive from and execute make-jpkg file with the downloaded file.

“Wait,” says I. “don’t I already have one of those?”

╭─jkl@dev ~ 
╰─$ file jdk-7u45-linux-x64.gz
jdk-7u45-linux-x64.gz: gzip compressed data, from Unix, last modified: Tue Oct 8 09:03:05 2013

I renamed the file to .tar.gz  and lo and behold:

╭─jkl@dev ~/tmp 
╰─$ fakeroot make-jpkg jdk-7u45-linux-x64.tar.gz 
Creating temporary directory: /tmp/make-jpkg.sKqSkUnRVf
Loading plugins: /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/ /usr/share/java-package/

Detected Debian build architecture: amd64
Detected Debian GNU type: x86_64-linux-gnu

Detected product:
 Java(TM) Development Kit (JDK)
 Standard Edition, Version 1.7.0+update45
 Oracle(TM), Inc.
Is this correct [Y/n]:

So the whole entire reason this is failing is because make-jpkg is expecting a file ending in .tar.gz. Oops!