There’s some irony in a customer coming into the bank to execute line of credit transfers from his business account… while wearing a Sons of Anarchy sweatshirt (Missouri chapter, for what it's worth).
Yearly Archives: 2011
Da plane! Da plane!!
It’s now a lot quicker (if also a lot more expensive) for the parents to come visit us. This is their Comanche on the ground at home base, and then Mom and Dad getting ready to head back to home base from New Century Air Service… a mere four minutes from our front door.
Straight Pool & Equal Offense Scoresheet/Spreadsheet Update
I’ve made some updates to the score sheets.
I’ve uploaded all of them now to GoogleDocs for one. That’s the big change.
Other small changes, currently exclusive to the GoogleDocs versions, are minor formatting changes, formulaic changes to rid the sheets of #DIV/0 errors, and the removal of some extraneous columns to help with formula drag filling.
Furthermore, I’ve shared all the GoogleDocs versions so they’re public for the finding, though I’ve retained exclusive editing rights.
As always, suggestions and tweaks, especially those that stem from trial-by-fire experience, are always welcome.
Update to Malware Protecting Script
In an attempt to be a little more friendly in terms of bandwidth to the strapped folk over at Malware Domains, I’ve retooled the script I wrote about in the post To Be Protecting Against the Malware.
I’ve added some lines to take advantage of remote zipped files (.zip), which will help them by reducing the number of bits we’re pulling from them.
I’ve added some lines to copy the downloaded malware zones file to other servers behind my firewall, which will help them by not making individual connections from each server to pull the files. I just set up a cron job on each internal “slave” server to bounce named every morning timed for after this process is complete.
Here’s the updated code. It is, as is my wont, rather verbose. It is considerably more verbose than other examples out there that take care of this same problem, but as I said, such is my wont.
The URLS array is filled with fake hosts right now b/c the zipped format is still in testing. When the folk at malwaredomains.com think it’s ready for public consumption, I’ll put the real hosts back in.
Also, it’s relatively untested, and I expect to be tweaking it. Use at your own risk.
On the “master” server, I’m using this…
#!/usr/local/bin/bash
# To know where script is running
HOSTNAME=$( hostname )
# To put file where named can see it
BLACKHOLEDIR=/var/named/etc/namedb/blackhole
# To name file so we know what named seeing
TMPZONEFILE=tmp.malwaredomains.zones
ZONEFILE=malwaredomains.zones
ZONEFILEBACKUP=malwaredomains.zones.bak
# To get updated file from remote server
URLGRABBER=/usr/local/bin/curl
USERAGENT="Malware Domain Grabber ( ${HOSTNAME}; unix; BASH )/0.1"
# To keep quiet while am getting file
URLGRABBEROPTS="-s -f"
# To know where file is hosted
URLS=( host1 host2 host3 host4 )
TIMESTAMPFILE=timestamp
# To know how to decompress the file
UNZIPCMD=/usr/local/bin/unzip
UNZIPOPTS="-o -qq"
# To copy files to other servers so that we are only
# pulling the files once, though we have multiple
# DNS servers in house
HOSTS=( host1 host2 host3 host4 )
# MOUNTCMD: The mount command
MOUNTCMD=/sbin/mount
UMOUNTCMD=/sbin/umount
# FSTYPE: The filesystem type of the mounted partition
FSTYPE=nfs
# MOUNTDIR: The directory that the dumps will be written to
MOUNTDIR=/mnt
# To control bind
NAMEDCMD="/usr/sbin/rndc reload"
#==============================================================
# Get start time so we can know how long this thing runs
START=$( date +%s )
# Make our working directory the location of the blackhole files
cd ${BLACKHOLEDIR}
# Copy the current timestamp file to ${TIMESTAMPFILE}.old so we can
# make a comparison between what we have and what's out there now.
if [ -f ${BLACKHOLEDIR}/${TIMESTAMPFILE} ]; then
cp ${BLACKHOLEDIR}/${TIMESTAMPFILE} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.old
fi
# Attempt to download the timestamp file and zone file from each mirror.
# Break out of the loop at the first successful download of a zone file,
# otherwise, try each one in turn
# Assume there are no updates available
NEW=0
for URL in "${URLS[@]}"; do
echo "Attempting to download from ${URL}"
echo " Checking timestamps..."
${URLGRABBER} ${URLGRABBEROPTS} -A '${USERAGENT}' -o ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip ${URL}/${TIMESTAMPFILE}.zip
if [ $? -ne 0 ]; then
echo " ... timestamp download from ${URL} failed! Code: $?"
# Move on to next URL so we keep the timestamp/zonefile pair intact
continue
else
if [ -f ${BLACKHOLEDIR}/${TIMESTAMPFILE} ]; then
# Unzip the new timestamp file over the old old one
${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
# Do a little cleanup
rm -f ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
OLDTIMESTAMP=$( cat ${BLACKHOLEDIR}/${TIMESTAMPFILE}.old )
NEWTIMESTAMP=$( cat ${BLACKHOLEDIR}/${TIMESTAMPFILE} )
if [ ${OLDTIMESTAMP} -ge ${NEWTIMESTAMP} ]; then
echo " ... no new updates."
# No new updates on this server... but how well are the various mirrors
# kept in sync? Let's try the others. This is a tiny transfer, and it's
# only once a day, so it's pretty cheap.
continue
fi
else
# Timestamp file does not exist. Create it.
${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
rm ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
fi
fi
# Backup and copy file to final location for named to find
# (via "include" directory in named.conf)
echo "Backing up zone file"
cp ${BLACKHOLEDIR}/${ZONEFILE} ${BLACKHOLEDIR}/${ZONEFILEBACKUP}
echo "Retrieving new zone file from ${URL}..."
${URLGRABBER} ${URLGRABBEROPTS} -o ${BLACKHOLEDIR}/${ZONEFILE}.zip ${URL}/${ZONEFILE}.zip
if [ $? -ne 0 ]; then
echo " ... zonefile download from ${URL} failed! Code: $?"
# Oops. Try the next server. If this is the last, then ${NEW} is still
# set to 0, and we'll be done. Better luck tomorrow...
continue
else
# We have a new timestamp, and were able to download the zone file from
# the same server we downloaded the timestamp from. Set ${NEW} to 1 and
# get out of the loop. No need to check further.
echo "Unzipping new zone file..."
if [ -f ${ZONEFILE}.zip ]; then
${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${ZONEFILE}.zip
rm ${ZONEFILE}.zip
# Rename the zone file temporarily to allow sed to work on it later, and
# and in that process, rename it back to the name that named knows.
mv ${ZONEFILE} ${TMPZONEFILE}
else
echo "No new zone file..."
exit
fi
NEW=1
break
fi
done
# If ${NEW} hasn't been set, then we either error'd out of all servers, or there are no
# new files. Either way, we're done.
if [ ${NEW} == 0 ]; then
exit 1
else
# Disable name checking for only those domains with underscores,
# so we don't have to turn off name checking globally.
SEARCH='_'
FIND='blockeddomain.hosts";};'
REPLACE='blockeddomain.hosts"; check-names ignore;};'
# Get a count of the zones from the last update
OLDZONECOUNT=$( cat ${BLACKHOLEDIR}/${ZONEFILEBACKUP}|grep "^zone"|wc -l )
echo "Disabling checking on domains with underscores"
sed "/${SEARCH}/ s/${FIND}/${REPLACE}/g" ${BLACKHOLEDIR}/${TMPZONEFILE} > ${BLACKHOLEDIR}/${ZONEFILE}
rm -f ${BLACKHOLEDIR}/${TMPZONEFILE}
# Get a count of the zones from the current update
NEWZONECOUNT=$( cat ${BLACKHOLEDIR}/${ZONEFILE}|grep "^zone"|wc -l )
echo "${OLDZONECOUNT} Previous Zones"
echo "${NEWZONECOUNT} Current Zones"
echo "Reloading named"
${NAMEDCMD}
if [ $? -ne 0 ]; then
echo " ... failed! Restoring zone file"
cp ${BLACKHOLEDIR}/${ZONEFILEBACKUP} ${BLACKHOLEDIR}/${ZONEFILE}
echo "Reloading old zones in named"
${NAMEDCMD}
if [ $? -ne 0 ]; then
echo " ... failed again!! You'll want to see to that."
fi
fi
echo "Copying files to other internal network servers..."
for HOST in "${HOSTS[@]}"; do
DUMPDEVICE=${HOST}:${BLACKHOLEDIR}
MOUNTRESULTS=$( ${MOUNTCMD} | grep "${DUMPDEVICE} on ${MOUNTDIR}" )
if [ "${MOUNTRESULTS}" == "" ]; then
echo ""
echo "Mounting ${DUMPDEVICE} on ${MOUNTDIR}"
${MOUNTCMD} -t ${FSTYPE} ${DUMPDEVICE} ${MOUNTDIR}
if [ $? = 1 ]; then
echo " ... failed. Files will not be copied."
continue
else
echo " ... succeeded"
fi
else
echo "${HOSTNAME}:${DUMPDEVICE} already mounted on ${MOUNTDIR}"
fi
# Copy the files to ${MOUNTDIR} as a temporary file. On the remote server,
# we'll manage bouncing named if necessary.
echo ""
echo "Copying ${BLACKHOLEDIR}/${ZONEFILE} to ${TMPZONEFILE}"
cp ${BLACKHOLEDIR}/${ZONEFILE} ${MOUNTDIR}/${TMPZONEFILE}
if [ $? = 1 ]; then
echo "... Failed to copy ${ZONEFILE}! You might want to see to that."
fi
# Umount the backup filesystem
echo ""
echo "Unmounting ${MOUNTDIR}"
${UMOUNTCMD} ${MOUNTDIR}
if [ $? = 1 ]; then
echo " ... failed. You might want to see to that."
else
echo " ... succeeded"
fi
done
END=$( date +%s )
RUNTIME=$(( ${END} - ${START} ))
H=$(( ${RUNTIME}/3600 ))
M=$(( ( ${RUNTIME}/60 ) % 60 ))
S=$(( ${RUNTIME} % 60 ))
echo "Malware zonefile download on ${HOSTNAME} complete in"
echo "${H} hrs, ${M} mins and ${S} secs (${RUNTIME} secs)"
exit
fi
On the “slave” servers, I’m using this…
#!/usr/local/bin/bash
# To put file where named can see it
BLACKHOLEDIR=/var/named/etc/namedb/blackhole
ZONEFILE=malwaredomains.zones
TMPZONEFILE=tmp.malwaredomains.zones
# To control bind
NAMEDCMD="/usr/sbin/rndc reload"
if [ -f ${BLACKHOLEDIR}/${TMPZONEFILE} ]; then
echo "New zone file exists..."
# Rename the zone file to back it up
echo "Backing up current zone file."
mv ${BLACKHOLEDIR}/${ZONEFILE} ${BLACKHOLEDIR}/${ZONEFILEBACKUP}
# Rename the tmp file to the name the daemon can find
echo "Replacing it with the new zone file and removing the temp file."
mv ${BLACKHOLEDIR}/${TMPZONEFILE} ${BLACKHOLEDIR}/${ZONEFILE}
# Reload named.
${NAMEDCMD}
if [ $? -ne 0 ]; then
echo " ... failed! Restoring zone file"
cp ${BLACKHOLEDIR}/${ZONEFILEBACKUP} ${BLACKHOLEDIR}/${ZONEFILE}
echo "Reloading old zones in named"
${NAMEDCMD}
if [ $? -ne 0 ]; then
echo " ... failed again!! You'll want to see to that."
fi
fi
else
echo "No update. Quitting..."
fi
Moving the Home Network
Part of the packing, cleaning and moving marathon of the last week, which is to continue through the coming weekend, was the move of the family computers and servers. This meant the following very simple steps:
- the set up of the internet connection at the new place,
- changing DNS upstream to point to the new IP,
- shutting down and physically moving the servers,
- physically reconnecting them,
- connecting the wireless router to the new cable router,
- configuring the new cable router to account for the wireless router,
- configuring the external IP on the wireless router,
- firing up the servers,
- enjoy fun website availability and internal DNS goodness.
Every step went well and easy, all the way up until that last step.
Though all the laptops in the house connected just fine to the Comcast cable modem/router, the two FreeBSD servers simply would not. From a logical network topology standpoint, nothing had changed. None of the IP addresses, including the gateway and the subnet, had changed. As far as the server interfaces were concerned, they’d just been turned off and turned back on. Let me emphasize that – from a logical network topology standpoint, nothing had changed.
I had it set up like so:
Net -> Comcast Router -> Servers & Laptops.
But they weren’t working. One worked briefly, but then quit. The other never would work.
If the cat5 cable (any cat5 cable) was plugged in, a ping to the (same as before) gateway would result in “sendto: Host is down”. If the cable wasn’t plugged in, I’d get a “sendto: No route to host”. Clearly there was some awareness going on, and the NIC was functioning at some level, because pinging the assigned IP, localhost, or 127.0.0.1 would all return successful. I couldn’t get any response from the gateway, however, and no other working machines could get responses from the servers. It was weird.
So, I got on the phone with Comcast to ask them about any incompatibilities with the router and FreeBSD. I got some good information about my usable external public IP (unrelated to the problem at hand), and some completely bogus information about having to use static IPs within the DHCP scope on their router (yeah but… what?!). The first level tech support wanted to help, but he just didn’t have the expertise, and so he escalated me to the next level (who is well past their 48 hour self-imposed deadline at the time of this writing). I decided to change things up a bit.
I went to this setup:
Net-> Comcast Router -> Wireless Router -> Servers & Laptops.
Note that this is exactly the same as I had at my old house, with the substitution of the Comcast Router for the Surewest cable modem. Everything from the wireless router on back is identical.
You know what? The laptops all worked (I love knowing even rudimentary networking), but the servers still didn’t work. Having eliminated the router, cables and network configs, the fact that it doesn’t work anymore with the exact same setup as was at the other house tells me it’s a another type of hardware problem.
So I yanked the gigabit NICs right out of the servers and went back to the on-board 100baseTX ports and… get this – it worked just fine.
What I’m concluding is that the D-Link GigaExpress DGE-530T card doesn’t work well with the BIOSTAR N68S3+ and the Diablotek EL Series PSEL400 400W ATX PSU. I base that conclusion in part b/c, in addition to flat out not working anymore, there are times when the machines won’t power on when the DGE-530T is installed without some creative combinations of the case power button and the PSU switch. When those cards aren’t installed, there are no issues. What, I didn’t mention that before? My bad.
Given that when I put these servers together, I did so with as little cash outlay as possible. I’m thinking I’ve been bit by the “get what you pay for” principle. In time, I’ll beef them up a bit with better components. But for now, I’m just happy to be back online enjoying fun website availability and internal DNS goodness.
New Homes are Heavy
The wife and I have been very busy lately. It’s not yet over, but this past weekend was perhaps the busiest, not to mention heaviest, part of the process. That process is moving.
The whole thing started last spring, when we put our two houses on the market. This past spring, a year later almost to the day, her house finally sold and we had the wherewithal to purchase a new house. We packed her house into two POD units and moved them into storage until we had a place to put them. At the same time, we took mine off the market because it hadn’t sold yet, and we didn’t want to take the chance of it selling and us having no place to go. Turns out it wasn’t a concern, because we found the house we wanted to buy within days.
We made an offer, they countered, we met in the middle, and two long months later, we took possession. When that day finally arrived, we couldn’t move in immediately because we had too many other family obligations (Jami’s sister graduated with her doctorate! We couldn’t miss that graduation day…). So, exactly one week after we took possession, I had the two full-to-the-roof POD units filled with more boxes and heavy furniture than any one person has any business owning, delivered for unloading at the new house. With the help of some very friendly neighbors, we started unloading them that night. We continued unloading the next night, and did so until we dropped. We spent our first night in our new home that night. Fortunately, the bed was easily accessible in the POD unit, so we didn’t have to sleep on the floor. By the time we were done, though, it wouldn’t have mattered where we slept… we were too tired to care. Finally, on Saturday, some friends came over to help unload the rest.
By Saturday night, we were absolutely beat. Unfortunately, our work was not yet done. We spent Sunday at the old house, packing up, mowing the yard, and cleaning. Then we devoted that evening at the new home unpacking, straightening up and getting all the computers back online.
Being Memorial Day weekend, we had an extra day which was spent back at the old house for more packing (about 500lbs worth of books – plus lots of this and that) and lots of cleaning. Monday night was given to more unpacking, more cleaning, and more organizing. We did give ourselves a bit of a break for a glass of wine on the front porch before getting back to it.
At the end of the weekend, between the two of us and some very helpful friends and neighbors, we have a pretty good start on a new home.
But our work is not yet done. The POD units were still in the driveway as of Wednesday, to be picked up on Thursday and Friday. Saturday we’ll get a truck to move the rest of the heavy stuff out of my house. Until then, we’ll spend a lot of time at the old house getting as much packed and moved as possible so that the friends who are helping on Saturday only have to help us with the heavy items we can’t move by ourselves. From there, it’s a matter of final cleaning and finishing up a few little details here and thereto get it in tip-top shape to put back on the market. We’re hoping to sell it within the next 2 and a half months. We’ll see…
Back to the Gate
So, I started playing Baldur’s Gate recently. I never finished it back in the day (though I got close), and barely took advantage of the Tales of the Sword Coast expansion. For some reason, with everything going on in our lives right now, and in spite of the fact that I’m arguably busier now than I’ve been since Finals Week in college, I just couldn’t help running through 5 CDs worth of installation and launching some relatively old school gaming (I consider Atari 2600 and the Age of Darkness and the Age of Enlightenment truly Old School – and even that’s too new for some).
It runs a little fast on my m9700, but not too fast to play. The dialog runs together now and again when there is a lengthy challenge/response conversation playing out, but other than that, I’ve noticed no ill effects of the slightly accelerated rate.
I tried using the G3: Widescreen Mod in order to enjoy larger resolutions, but found that I had issues with mouse scrolling around the area at 16:9 resolutions that were less than the native resolution of my monitor (1920 x 1080). Because of the time consuming way the mod is applied, I didn’t try too many resolution options. I also noticed some frame rate issues at the native resolution in spite of the age of the engine (or perhaps, because of it). So I decided to stick with playing it the way it was originally released and patched. I’m not playing for the graphics, after all, but the experience.
I’ve heard rumors that it’s possible to convert BGI to the BGII engine, though. I might look into that. Graphics aren’t everything, but the BGII engine is so much nicer…
I probably won’t have much time in the next couple of months to do more than tinker with it here and there, but after we’re settled in to the new house, and some of my other responsibilities are managed (not the least of which is a FreeBSD build that’s proving difficult due to a troublesome inability to detect the hard drives once in sysinstall), I’ll be able to devote a little more time to it. I may even dive back into Baldur’s Gate II, and the Icewind Dale series.
I wonder how it’ll run on the X79 LGA2011 based machine I plan on building towards the end of the year. If it runs fast on a 6 year old laptop…
DiscoverCard.com & Password Length Restrictions
With all the major breaches in the news lately (RSA, Gawker, PSN, Lastpass, MySQL, Texas Comptroller, etc. – hit the googles with you!), I finally got angry enough to ask a question of DiscoverCard that has been sitting on the back burner for too long. It’s about what I consider to be absurd password length restrictions on their site, and what that might say about how they’re storing those passwords on the back end.
Let’s clear one thing up: On principle, I believe I should be able to use whatever password I want. If I want to use “abc123″, or “puppy1″, or “;a3Wfzu0J|rqVHj%l]x6PZdQHqhpK39vx5?|fSb9NmFdq”, I should be able to. I should have the right to be as smart, stupid, paranoid or legitimately cautious as I want (here’s the thing) so long as my choice doesn’t affect others using the same system. I’m not the only one to think along those lines.
Principles aside, I don’t have a practical problem with complexity enforcement. I understand that repositories of critical and/or sensitive data and services have a need to shore things up a bit with more complex passwords. That doesn’t stop me from thinking there are design issues at hand if my weak web password can compromise someone else’s data. I also can’t help but think the whole mess is, at least in part, driven by a disgusting, ludicrously naive and juvenile expectation that “everything will always be ok, and I’m entitled to it. It’s my right! So there!” and all the litigation that goes along with that childish attitude.
That all said, it’s one thing to require password complexity, it’s another entirely to not allow it past X characters. It raises some questions…
So I asked DiscoverCard about it: (May 05, 02011 09:41 AM)
Can you please explain to me the exact method by which discovercard.com website logon passwords are stored? The length limit greatly concerns me. With the major breaches of late (PSN, Sony, Lastpass, MySQL, Gawker, etc.) it is critical that passwords be stored securely, with adequate encryption, or at the very least, salted hashing. Thank you.
Admittedly not the best in terms of wording and stated concerns. But there you have it. I can’t help but believe DiscoverCard, of all places, is using top-notch methods for storing passwords, but you just never know, do you?
DiscoverCard’s first reply: (May 05, 02011 10:46 AM)
Thank you for your recent message. I understand your concern about online security, and I will be happy to assist you today!
Our emphasis on privacy provisions and improved Internet security has made using our website safer than ever. We use the Secure Socket Layer (SSL) protocol for encrypting communications with our Cardmembers. SSL uses public-key cryptography to scramble the information sent between senders and receivers. In the unlikely event that third parties try to eavesdrop or intercept this message, SSL encryption prevents them from viewing its contents.
We also have Superior Fraud Protection, which means that when you use your Discover Card to shop anywhere on the Internet, you will not be liable for any unauthorized transactions. For more information about our security, please see the following page:
http://www.discovercard.com/customer-service/safety/site-security.html
I appreciate your business and the opportunity to be of service. Thank you for choosing to use Discover Card.
[signature and legalese removed]
Awesome, but no, that’s not what I asked. So, I completed a survey indicating as much and replied… (May 05, 2011 11:06 AM)
Thank you for the prompt reply. I appreciate the information on SSL, however, that doesn’t answer the question I asked. I asked about password storage (at-rest), not information on the wire (in-transit). My question is restated here for your convenience…
“Can you please explain to me the exact method by which discovercard.com website logon passwords are stored? The length limit greatly concerns me. With the major breaches of late (PSN, Sony, Lastpass, MySQL, Gawker, etc.), it is critical that passwords be stored securely, with adequate encryption, or at the very least, salted hashing. Thank you.”
To which they replied… (05/05/2011 12:06 PM)
Thank you for your recent inquiry. In an effort to provide you the best service possible, I have escalated this issue to the appropriate parties in our company for further assistance. We will respond as soon as we have any additional information concerning this matter. Thank you for your patience.
I appreciate your business and the opportunity to be of service. Thank you for choosing to use Discover Card.
[signature and legalese removed]
I don’t expect another reply anytime soon… but I’ll let you know if I do get one, either in the comments, or as a new post depending on the reply.
To Be Protecting Against The Malware
Last night, my wife called me into the office with an alarming “It says it’s infected with malware!” Needless to say (and yet I’m going to say it anyway) I hurried into the room to see what the hullabaloo was all about.
Sure enough, there was a window exclaiming the existence of not one or two, but quite a few malware infections.
It fooled her, and damn if that stupid pop-up didn’t nearly fool me too! Truth be told, it did, if only for a second. Those malware serving fake malware pop-up warnings are clever.
It got me to thinking.
Then Osama bin Laden was shot in the head, and malware peddlers started leveraging our insatiable appetite for news about it (the sick bastards).
That got me thinking more.
It reminded me of the malware peddlers that took advantage of the quake in Japan recently. Now those are some seriously sick bastards.
Those events all in quick succession and all that thinking led me to this.
A little ditty that downloads the bind formatted zone file from MalwareDomains.com, moves it to where Named can see it, and reloads Named zone files if the download is complete. I’d verify the file if they provided an md5 of the zones file. But they don’t. Not that I could find, anyway.
I don’t even begin to hope to eliminate the risk of malware infected sites, but I think this is a positive step towards cutting off malware source domains which might, in turn, help against sites on legitimate domains that happen to be infected. As of today, May 3rd, 2011, there are nearly 10,000 domains in the latest file. That has to be nearly all of them.
Right?
I’ll try it out for a while and see what happens.
BTW, this only works if you’re running your own DNS. If not, you’re at the mercy of your ISP or whatever DNS you choose to use. There are plenty of options out there, and they’re not all horrible.
First, the script, which pulls down the latest malware domains zones file from malwaredomains.com, fixes some problems with underscores in the subdomains, copies the fixed zones file to the named chroot, and reloads the named configs.
#!/usr/local/bin/bash
# To know where script is running
HOSTNAME=$( hostname )
# To put file where named can see it
NAMEDDIR=/var/named/etc/namedb
# To name file so we know what named seeing
ZONEFILE=malwaredomains.zones
# To have a file for sed to work on
TMPZONEFILE=tmp.malwaredomains.zones
# To get updated file from remote server
URLGRABBER=/usr/local/bin/curl
# To keep quiet while am getting file
URLGRABBEROPTS="-s -S"
# To know where file is hosted
#URL=http://www.malwaredomains.com/files/spywaredomains.zones
URL=http://mirror1.malwaredomains.com/files/malwaredomains.zones
# To control bind
NAMEDCMD="/usr/sbin/rndc reload"
#==============================================================
# Get start time so we can know how long
START=$( date +%s )
# Get directory we're running from
SCRIPTDIR=$( dirname $0 )
cd ${SCRIPTDIR}
if [ $? -ne 0 ]; then
echo "ERROR: Unable to cd to ${SCRIPTDIR}! AbOrTinG!!"
exit 1
fi
# If we were executed like "./whatever.sh" - set SCRIPTDIR to the pwd
if [ "${SCRIPTDIR}" == "." ]; then
SCRIPTDIR=$( pwd )
fi
echo "Script is running from ${SCRIPTDIR}"
# Download the zones file in bind format to a temporary location.
# We don't want to overwrite what we already have until we're sure
# the download worked
echo "Downloading file from ${URL}"
${URLGRABBER} ${URLGRABBEROPTS} -o ${SCRIPTDIR}/${ZONEFILE} ${URL}
# Check for errors. If the file downloaded, then move on, but if not
# we don't want to reload named without the previously updated
# malware domain list
if [ $? -ne 0 ]; then
echo " ... download failed! Error: $?"
exit 1
else
# Disable name checking for only those domains with underscores,
# so we don't have to turn off name checking globally.
SEARCH='_'
FIND=';};'
REPLACE='; check-names ignore;};'
echo "Disabling checking on domains with underscores"
sed "/${SEARCH}/ s/${FIND}/${REPLACE}/g" ${SCRIPTDIR}/${TMPZONEFILE} > ${SCRIPTDIR}/${ZONEFILE}
# Get a count of the zones from the last update
OLDZONECOUNT=$( cat ${NAMEDDIR}/${ZONEFILE}|grep "^zone"|wc -l )
# Copy file to final location for named to find
#(via "include" directory in named.conf)
echo "Copying file from ${SCRIPTDIR} to ${NAMEDDIR}"
cp ${SCRIPTDIR}/${ZONEFILE} ${NAMEDDIR}
if [ $? -ne 0 ]; then
echo " ... failed! AbOrTinG!!"
exit 1
fi
echo "Reloading zones in named"
${NAMEDCMD}
if [$? -ne 0]; then
echo " ... failed! You'll want to see to that."
fi
# Get a count of the zones from the current update
NEWZONECOUNT=$( cat ${NAMEDDIR}/${ZONEFILE}|grep "^zone"|wc -l )
echo "${OLDZONECOUNT} Previous Zones"
echo "${NEWZONECOUNT} Current Zones"
fi
END=$( date +%s )
RUNTIME=$(( ${END} - ${START} ))
H=$(( ${RUNTIME}/3600 ))
M=$(( ( ${RUNTIME}/60 ) % 60 ))
S=$(( ${RUNTIME} % 60 ))
echo "Malware zonefile download on ${HOSTNAME} complete in"
echo "${H} hrs, ${M} mins and ${S} secs (${RUNTIME} secs)"
exit 0
Then, the cron job to update the list on a daily basis:
35 0 * * * /root/bin/malwaredomains/malwaredomains.sh 2>&1 | mail -E -s "Malware Domain Named Update" me@here.com
Then, the blackhole host file that all those zones in the malwaredomains.com download refer to. Careful with this one, and you’ll want to replace the domains with something a little more relevant:
$TTL 86400 ;one day
@ IN SOA ns0.example.net. hostmaster.example.net. (
2011050100 ; serial number YYYYMMDDNN
28800 ; refresh 8 hours
7200 ; retry 2 hours
864000 ; expire 10 days
86400 ; min ttl 1 day
)
NS ns0.example.net.
NS ns1.example.net.
A 127.0.0.1
* IN A 127.0.0.1
Finally, the line in the named.conf file (in my case, in the internal view) to call on the recently downloaded zones file:
include /etc/namedb/malwaredomains.zone
That should do it!
This is what I receive in my inbox after every update (daily for me):
Script is running from /root/bin/malwaredomains Downloading file from http://mirror1.malwaredomains.com/files/malwaredomains.zones Disabling checking on domains with underscores Copying file from /root/bin/malwaredomains to /var/named/etc/namedb Reloading zones in named server reload successful 10116 Previous Zones 10116 Current Zones Malware zonefile download on [hostname] complete in 0 hrs, 0 mins and 2 secs (2 secs)
Gas Mileage TinyApp
If this keeps up, I’m going to have to put together a dedicated page for web projects. I hope it does keep up. I really love doing it…
My latest project following the FreeBSD backup script (bash), a host of system admin scripts too small to bear mentioning (bash, tcsh, perl), and the twice-built RAID crash victimized wine database (PHP, Smarty & MySQL) (in addition to the many projects no longer online), is a gas mileage tracker. It’s also written in PHP, delivered through Smarty, and backed by MySQL, but now with delicious pChart.
I originally used GoogleDocs and a GoogleForm to record the data, and I have data going back a few years. That worked well enough and did most of what I wanted it to do, but it didn’t do everything. Now that I have my own server(s) up and running again, I have the luxury of being dissatisfied.
What it Didn’t Do
- Provide meaningful feedback after submitting the form. I want to know what was submitted immediately on the “Form Submission Successful” screen, and if applicable, how it relates to information previously submitted. That’s just good UI feedback that it’s missing.
- Allow me to maintain and build upon my scripting/database chops. Working with GoogleDocs is easy, fairly extensible, and has the benefit of having a preexisting world class infrastructure (and all that entails) and environment in which to work. However, I’m a bit of a maverick in these things, and for my own projects I want things set up the way I want them. Their infrastructure and environment doesn’t allow me to build on the skills I want to build on. I have my own environment. I want to take advantage of it.
- Allow me to maintain and build upon my UI design chops. I’ve always loved the UI design aspect of building web apps. There’s a few things you can do with Google, but I felt too constrained by their system, and wanted, again, things the way I wanted them.
It wasn’t all bad, though. Setting it up in GoogleDocs did effectively (if not intentionally) serve as a sort of rough draft for rebuilding it on my own server.
What it Did Do
- Gave me a firm sense of what I wanted, and what I didn’t want, if not a solid workflow to follow.
- Gave me a good sense of the basic information I wanted to collect, which was then easy to translate to MySQL tables.
- The visualizations in the form of charts and graphs were good enough that I decided I couldn’t do without them, which gave me the desire to research PHP graphing/charting libraries. I settled on pChart.
Now, I have a small web app that lets me…
- Track the gas mileage I’m getting for my car and how many miles I’m getting per tank.
- Track how the price of gas is changing. Always up, but still…
- Track how much I’m spending per mile on gas.
- Track how often I fill the tank.
- Keep tabs on how often I’ve changed the oil (I change it myself… a pox on paying someone else to do it), and how long until I need to change it again.
Soon, it will let me…
- Track how many miles I drive over time, per week, month, year, etc.
- Track how long between major service visits I don’t care to do (tires, brakes, etc.)
- Implement multiple vehicles in the hopes that I can get my wife on board and using it.
- Authenticate access so I don’t have to worry about the data being mangled by miscreants and malcontents. Obfuscation and low-profile domains will only work for so long (stay away, Noah! :) )…
- Better UI flow… it’s good enough for me, but it’s rough. It’s fine on the desktop, but I need to clean it up so it works on the mobile platforms better.
Here are the charts I’m generating. I know, the gas mileage isn’t that hot. But the payments are $0, so there’s that.


