What makes a email MIME part an attachment?

If you want to know what types of files your users are gettingin email , it's likely that an importantprerequisite is being able to recognize attachments in the firstplace. In a sane and sensible world, this would be easy; it wouldjust be any MIME part with a Content-Disposition header of attachment .

I regret to tell you that this is not a sane world . There are mail clients thatgive every MIME part an inline Content-Disposition, so naturallythis means that most mail clients can


Modern DNS servers (especially resolvers) should have query logging

Since OpenBSD has shifted to using Unbound as their resolving DNSserver, we've been in the process of making this shift ourselvesas we upgrade, for example, our local OpenBSD-based resolver machines.One of the things this caused me to look into again is what Unboundoffers for logging, and this has made me just a little bit grumpy.

So here is my opinion:

Given the modern Internet environment, every DNS server should becapable of doing compact query logging.

By compact query logging, I mean


Today's lesson on the value of commenting your configuration settings

We have a relatively long-standing Django web application that was first written for Django 1.2 andhadn't been substantially revised since. Earlier this year I did amajor rework in order to fully update it for Django 1.9; not justto be compatible, but to be (re)structured into the way that Djangonow wants apps to be set up.

Part of Django's app structure is a settings.py file that contains,well, all sorts of configuration settings for your system


If you send email, don't expect people to help you with abuse handling

I'll start with the tweets:

@thatcks :I see these spammers used @MailChannels to hit us once before, inApril. I reported them then, but I have no time for this shit anymore.

Back in April, a persistent long-term spammer of one of our addressesattempted to send it spam via MailChannels, a commercial emailsending outfit. I complained to MC's abuse contacts at the time,because I'm an optimist, and someone at MC got back to me to


How not to maintain your DNS (part 22)

Much as the previous installment , this exampleof bad DNS setup is sufficiently complicated that it's best illustratedin text instead of trying to show DNS output.

We start with the domain zshine.com. At the moment its WHOISregistration says that it has the DNS servers ns1.gofreeserve.comand ns2.gofreeserve.com. If you query the nameservers for .com,they will agree with this and give you an IP for each nameserver,192.196.15


What Python 3 versions Django supports, and when this changes

I was idly skimming the in-progress release notes for Django 1.10 when one ofthe small sections that I usually ignore jumped out at me instead:

Like Django 1.9, Django 1.10 requires Python 2.7, 3.4, or 3.5.[...]

Since I've recently been thinking about running Django onPython 3 , the supported Python 3 versionscaught my eye. More exactly, that it was a short list. This mademe wonder


Our new plan for creating our periodic long term backups

Our ordinary backups are done on the usualstraightforward rolling basis, where we aim to have about 60 daysworth of backups. We also try to make an additional set of longterm backups every so often, currently roughly three times a year,and keep these for as long as possible. Every so often this makespeople very happy because we can restore something they deleted sixmonths ago without noticing.

Our long term backups are done with the same basic system as our regular disk-based backups. We have some


Moving from Python 2 to Python 3 calls for a code inventory

I was all set to write a blog entry breaking down what sort ofPython code we had, how much it was exposed to security issues andother threats, and how much work it would probably be to migrateit to or towards Python 3. I even thought it was going to be arelatively short and simple entry. Then, as I was writing thingsdown, I kept remembering more and more bits of Python code we'reusing in different contexts, and I'm pretty sure I'm still


I need to cultivate some new coding habits for Python 3 ready code

We have a Django application , and becauseof various aspects of Django (such as Django handling much of theheavy lifting), I expect that it's our most Python 3 ready chunkof code. Since I was working on it today anyways, I took a brief runat seeing if it would at least print help messages if I ran it underPython 3. As it turns out, making the attempt shows me that I need tocultivate some new coding habits in order to routinely write code thatwill be


A tiny systemd convenience: it can reboot the system from RAM alone

One of the things I do a fair bit of is building and testingfrom-scratch system installs. Not being crazy, I do this in virtualmachines (it's much faster that way). When you do this sort of work,you live in a constant cycle of installing a machine from scratch,testing it, and then damaging the install enough so that when youreboot, your VM will repeat the 'install from scratch' part. Mostof the time, the most convenient way to damage the