Workaround for “Windows AD domain is the same as my company’s primary DNS domain name,” Part 2

Previously I wrote about a Workaround for “Windows AD domain is the same as my company’s primary DNS domain name.” It involved installing a tiny web server on each domain controller. Today I'm going to write about an alternative way...

Let’s say my organization is “sojourners.me” and I use that for my internal Active Directory domain name (yes, not recommended) as well as the public face of my organization. It’s bad because people inside the network don’t resolve “sojourners.me” to the public webserver--they resolve it to the internal domain controllers (which is required for DFS to function properly).

Here’s a workaround... proxy autoconfiguration magic.

function FindProxyForURL(url, host) {
  if (shExpMatch(host, "sojourners.me"))
    return "PROXY proxy.sojourners.me:3128; DIRECT";
  else
    return "DIRECT";
}

If you’re interested in more info on FindProxyForURL, there are good references here and here.

You may say, “We don’t use a proxy server at my company. Our users don’t have proxy settings in their browsers.” For Windows AD-joined machines, a proxy autoconfiguration script can be easily rolled out via Group Policy Object. You can use your favorite search engine to search for “proxy auto configuration script gpo” or words to that effect. In the past, doing this on Firefox was more of a pain, but in the last few years they made the default proxy option to use the system proxy settings. As an alternative to GPO, you can play with DHCP and/or WPAD settings or get creative.

What should that auto configuration script point at? Using Squid, Apache proxy module, NetsScaler (like we have), or another proxy server of your choice, you can easily run a proxy service that won’t have to do much. In fact, with the script above, the only proxy requests it will have to handle are the ones to send it to the public web server, which should then send a HTTP 301 or 302  redirect to “www.sojourners.me.”

Keep Six months worth of data

I often have things that back themselves up often, or syslogs that roll over daily. Sometimes I want to keep six months worth of data. Here are two scripts to accomplish that.. one for Windows and one for bash:

In bash, I define my glob (wildcard list of files) that I want to only save 180 days worth of stuff. In this case, the FortiAuthenticator backup files, which the device pushes to the backup server via sftp every day. You could customize it for anything though, just by changing the “glob” environment variable.

#!/bin/bash

files_to_save=180
glob=FortiAuthenticator*

num_of_files=`ls -1 $glob | wc -l`

if [ $num_of_files -le $files_to_save ]; then
 exit
else
 count=$(($num_of_files-$files_to_save))
 for i in `ls -1t $glob | tail -$count`; do
  rm -f $i
 done
fi

It's a little trickier in Windows, because you don't have the tail command that UNIX derivatives supply, so you have to be creative with the best command available for batch files: the for command. I usually cheat and use the GNU UNIX tools (like head, tail, grep, awk, sed, etc), but I can’t count on having those on somebody else’s computer. Someday I’ll sit down and learn PowerShell, but until then, I have to lean on my batch-file crutch...
@echo off

set files_to_save=180
for /f "tokens=1,2 delims=:" %%a in ('dir/a-d/b/o-d ^| findstr /n ".*"') do if %%a GTR %files_to_save% del "%%b"
 

In a DNS Bind

Recently a friend, who also works in IT, asked me, “What DNS server do you guys run?” I had to think for a second, because I wondered where to begin. It’s not a quick, easy answer.

Note that I use the term “domain” and “zone” more-or-less interchangeably in this post.


Internal

We run Windows Server 2012r2 DNS on our domain controllers, as many organizations with Active Directory infrastructure do: DNS is critical to its operation. We also make extensive use of dynamic DNS with DHCP integration. We don’t use external caching servers or anything like that for our internal network. Every workstation and IoT device is pointed at two of our domain controllers. You can get away with that when you work at a company with less than 5,000 devices. We did a Cisco Umbrella (formerly OpenDNS) pilot recently, but besides their on-premises server that augments the DNS a bit, it’s more-or-less Microsoft AD DNS as the star player.

“Semi-Private”

We have business partners that have trust relationships with our Active Directory. However, we don’t give them direct access to our internal Active Directory servers. They configure their DNS to perform “Conditional Forwarders” to us. What they actually hit are two Unbound DNS servers running on Windows Server 2012r2. Unbound is very flexible caching name server software. We use it because we want them to see “parts” of our internal network, but also “parts”of our public DNS... basically we use Unbound to override parts of our public space with private resolution, then whatever we don’t override gets sent on to our public DNS servers. We also do extensive NAT’ing, so we need to override the internal IP addresses as well.

Public

We used to use the free GoDaddy DNS service that came with domain ownership purchased through them. However, after the DDOS attacks on Dyn on October 16, 2016, we decided that we should diversify DNS providers. In addition, we had just purchased a new /24 IPv4 range as well as wanting to take control of the reverse lookups for the two /27 subnets we lease from one of our ISPs. We upgraded to GoDaddy’s Premium DNS and employed DNS Made Easy as our second provider. While they are providing secondary services for our main three zones, they are providing primary services for the PTR records for our two /27 subnets, our /24, as well as our IPv6 subnet’s ip6.arpa zone.

Notify Me!

We quickly discovered that there were some problems with this arrangement... namely in the way that our providers handle NOTIFY messages. In case you’re not aware, NOTIFY messages are an important component of keeping DNS servers in sync. If I change a record on my primary DNS server and NOTIFY is not functioning properly, it will take up to the refresh interval specified in the zone’s SOA record to replicate to the secondary. Actually, without NOTIFY, it’s the responsibility of the secondary server to “reach out” to the primary when it’s refresh interval is reached. If NOTIFY is working properly, the primary server reaches out to its secondaries to tap them on the shoulder and say, “Hey, I have some new information, ask me what it is,” at which point the secondary will issue an IXFR or AXFR transfer request.

Problems

The problem we found is that GoDaddy will only send NOTIFY messages to DNS servers defined as NS records for a particular domain. However, DNS Made Easy will not listen for notify messages on its authoritative servers--they have their own set of servers that listen for NOTIFY messages. GoDaddy offers no way to add those servers to an “also-notify” list. I sent trouble tickets to both companies, and (eventually) they both agreed that it was a problem. They also both said that this was a low priority thing as nobody else besides me seemed to care, and basically said they’ll get to it some day (insha’Allah, as our Arab friends would say).

BIND to the Rescue

ISC’s BIND software is insanely flexible. We ended up setting up a virtual private server with Linode whose $5/month role was primarily to act as a broker between two grumpy DNS providers who didn’t want to share nicely. It’s like the referee at the beginning of the boxing match that forces the boxers to shake hands. The BIND set up is pretty simple: in our options section, we have defined a max-refresh-time 120 that tells it to check the serial number on the primary server every two minutes. Then in our relevant configurations, we have also-notify { dnsmadeeasy-slaves; }; with the dnsmadeeasy-slaves defined in the masters section. In addition, we have notify-explicit; which ensures that the BIND server notifies the secondary (slave) servers upon discovery of a change. GoDaddy has a place to define an access-list that allows the BIND server to initiate a zone transfer. The BIND server also allows the DNS Made Easy servers to transfer the zones from BIND.

Final Answer

To answer my friend’s original question (which at this point he probably wished he hadn’t asked), I guess we’re running five different interfaces (Windows, Unbound, GoDaddy, DNS Made Easy, and BIND). I’m not sure which DNS software the providers are running, since the cute little BIND trick has been overridden (try nslookup -type=txt -class=chaos version.bind. 208.80.126.2). It’s amazing how much more complicated something can turn out to be beyond what you had originally intended.

The Point

Besides simply explaining what our crazy DNS set up is, my point is that if you know the technology well enough, you can leverage the right tool to get the job done. If you have to learn a new configuration file format, that’s not a big deal if you have an idea of what’s supposed to happen. One of the things I also tell my colleagues is that the software is supposed to serve you, you are not supposed to serve the software.

Time zones, abbreviations, and becoming grumpy with age

I'm 40 years old now, and I can feel my list of annoyances growing as I age. If I'm not careful, by the time I'm 80, I'll be one of those people Meg Ryan's character described in French Kiss.

The way people abbreviate time zones is often wrong. I live in the Central Time zone in the United States. Depending on the time of year, you abbreviate it in one of two ways.
  • CST: Central Standard Time
  • CDT: Central Daylight Time
In the United States, we have Daylight savings time between early/mid March and early November (see chart), and Standard time the rest of the year. Can you tell what's wrong with this sentence?
The meeting will be held at 14:00 CST on July 8.
Answer: There is no CST on July 8, there is only CDT. Perhaps I have an unfair advantage over the general public, because as a computer network engineer, I have to manage devices where you specify CDT verses CST as far as how you name the time zones.

Anyway, the dirty secret is that the very things that drive me nuts about other people, I sometimes do myself! Once in a while, I fall victim to not catching my own grammer or spellling mistakes [intentionally ironic]. I guess when Jesus said...
“Do not judge, or you too will be judged. For in the same way you judge others, you will be judged, and with the measure you use, it will be measured to you” (Matthew 7:1-2).
... he wasn't just teaching a good truth, he was (and is) trying to protect us from opening up judgement on ourselves (i.e., looking stupid)!

Batch down-sampling lots of MP3 files

I had to convert about 1,100 mp3 files from 44.1 kHz to 22.05 kHz so I could get them from a total of 6 gigabytes to 3 gigabytes. I just thought I would share my process.

First I had to decide what software to use. There are two that came to mind: FFmpeg and LAME. I primarily use Windows 10, but I also administer several Linux systems. I try to pick whichever one will be most efficient. For tasks I do on my own computer, I sometimes do it “natively” in Windows, and sometimes I use the Windows Subsystem for Linux, which is a full-blown Debian installation.

This time, however, I just did it in Windows. Here is the batch file I wrote to do it. I will include comments afterward. The thing to know is that the folders with the audio all have the format NN-LLL (N=number; L=letter).

  1. @echo off

  2. for /d %%I in (??-???) do (
  3.  for %%J in (%%I\*.mp3) do (
  4.   if not exist _22kHz\%%~nxJ (
  5.    ffmpeg -i %%J -ac 1 -ab 64000 -ar 22050 _22kHz\%%~nxJ
  6.   )
  7.  )
  8. )

I put it in a numbered list so I can refer to the line numbers.

Line 3 says to get a list of all directories that have the format XX-XXX and put them in a variable called ‘I.’ I often pick ‘I’ because that's what the examples at the end of “for /?” in command prompt use, so it's a no-brainer. The ‘/d’ is necessary because the ‘for’ command will ignore directories by default.

Line 4 looks in the directory stored in variable ‘I’ and gets a list of all the mp3 files and stores them (with pathname) in the variable ‘J.’

Line 5 indicates that my output folder is called ‘_22kHz.’ I had manually created this folder (an important step!). So it says that if the file doesn't already exist in that folder, go ahead and run line 6. The ~nx is important because it basically strips the full path name of the file and gives you just the file name, so we can accurately check for it.

Line 6 is the actual FFmpeg command to convert to 64k bit rate at 22.05 kHz sampling. It reads the file in the ‘J’ variable and outputs it to the new ‘_22kHz’ folder.

Workaround for “Windows AD domain is the same as my company’s primary DNS domain name”

I have seen many companies over the years who have their internal domain set as the same domain that their corporation uses publicly. For example, if my company is Example, Inc, my primary web and e-mail presence might be example.com. When my Windows NT 3.5 domain was set up in 1997, we called it EXAMPLE, as it seemed logical. When Windows 2000 came out and we upgraded to Active Directory, it became logical to create example.com as the AD DNS Name. The recommendation is to NOT do that, but for many it was done before the recommendations were widely published (or they didn't think to look), and they simply have to live with it.

Years ago, most non-technical users (in my estimation) believed there was something magical about the “www” portion of a web address. For example, “www.example.com” was any given company’s web site. However, more and more people are dropping the “www” and just going to “example.com”. It’s the responsibility of the IT people (DNS and web administrators) to make sure the DNS A record for @ (domain root) points to the web server address, and the web admin must make sure the site answers for www.example.com and example.com and presents the same content to both (or redirects one to the other).

Here comes the problem in the first paragraph. For one thing, it requires split DNS: there is a public “version” of all the example.com records, and a private version. Within an Active Directory infrastructure, the private version of example.com (with no host name specified) should resolve to the IP address of all the domain controllers. For example, if I have three domain controllers, nslookup example.com should return 10.1.1.5, 10.1.2.5, and 10.1.3.5, assuming those are the addresses of my DCs. Most likely, the domain controllers are also not hosting the public web site (and they sure shouldn’t be!). This means that if I’m inside the network, pointing to internal DNS servers and I type example.com into my web browser, I won’t get anywhere.

The simplest solution I found in that case is to redirect the request to www.example.com, which can point to the public address of the public web server--what people expect to hit when they type in example.com internally. To do this, we could install IIS on every domain controller and set up a HTTP 301 or 302 redirection to www.example.com. But installing IIS on every domain controller adds overhead, etc, to the box, as well as lots of new DLLs and other things to introduce security problems (anyone remember Code Red?).

Another solution is to use ncat and NSSM (the Non-Sucking Service Manager). ncat can sit in memory with the help of NSSM and simply redirect http queries to the box to www.example.com. All that is needed is two exe files and one batch file to be copied to each server. Here’s how it could be done.

redir.cmd
@echo off
echo HTTP/1.1 302 Found >%temp%\redir.txt
echo Location: http://www.example.com/ >>%temp%\redir.txt
c:\redir\ncat -l 80 < %temp%\redir.txt


Put all three files (ncat.exe, nssm.exe, redir.cmd) in c:\redir. Then install the service using nssm with the following command (run as administrator):

nssm install "Web Redirector" c:\redir\redir.cmd

You could even deploy it to all your DCs remotely. You could do it your way, or using something like this:

deploywebredir.cmd
@echo off

setlocal ENABLEDELAYEDEXPANSION
set DCLIST=\\

for /f "delims=. " %%a in ('nltest /dclist:%USERDNSDOMAIN% ^|findstr /c:"[DS]"') do (
 md \\%%a\c$\redir
 for %%b in (ncat.exe nssm.exe redir.cmd) do copy /y %%b \\%%a\c$\redir
 set DCLIST=!DCLIST!%%a,
)

set DCLIST=%DCLIST:~0,-1%

psexec %DCLIST% -e c:\redir\nssm install "Web Redirector" c:\redir\redir.cmd


If you’re not familiar with psexec or nltest, you should get up to speed! Just search for them in your favorite search engine.

If you want to make this more secure, define a user with no particular privileges (besides Log on as a Service) and set the service to run as that user. Even if someone buffer overruns ncat.exe, they will only have basic user access.

Kindle URI Format

As many people, I am an avid user of Amazon Kindle. My family of three has two Kindles (2.0 and Paperwhite), my wife and I each have the app on our smart phones, and we each have Kindle for Windows on our laptops.

I was writing a document in Word and I wanted to be able to refer to particular sections of a Kindle book. I had a heck of a time figuring out the URI format, but I eventually put enough pieces together to give me what I wanted.

Here it is:

     kindle://book?action=open&asin=B003G4W49C&location=1178

There are more options than this, but this gets you to a particular location... it is made up of three components:
  1. action = open ... open the book
  2. asin = book identifier; you can find this in any number of ways. The easiest I've found is this:
    1. Go to your Kindle Content directory. Mine is C:\Users\Matt\Documents\My Kindle Content
    2. Then run findstr /m "Ender's Game" *.azw where in this case you would replace "Ender's Game" with your book's title.
  3. location = xxxxx ... whatever location you want to go to

Just thought I'd share...

Previous working directory in Windows Command Prompt

Using bash in *nix has a handy feature: If you are in one directory and you switch to another one, you can use   cd -  to go back to the pr...