joeware - never stop exploring... :)

Information about joeware mixed with wild and crazy opinions...

So very close… Reasonable Effort Platform Agnostic Perl Script That Implements the Active Directory DC Locator Process…

by @ 12:09 am on 3/22/2019. Filed under perl, tech

Getting very close to being ready to release the reasonable effort platform agnostic version perl script that will run through the DC Locator process.

Note that I intend for this to be a fairly robust script. It finds server (domain controller) site, client site, and next closest site. It polls the DCs validating them to make sure they are responding (so not behind a firewall or otherwise not responding) and have other specific items right (obviously you could tweak the validation rules as you need[1]). Once it has a list and validates the DCs on the list it then rates them based on response time performance and DNS Priority. If using multiple DCs to load balance multiple requests to multiple domain controllers (highly recommended for performance and stability for reads) you can easily see how to add in weighting logic.

The code is extremely long winded (nearly 2000 lines) with lots of comments and whitespace to make it mostly readable so people can take it and use any parts of it that are desired and convert to whatever languages are needed. The actual hardcore parts of it could be easily reduced down and in fact yanked out and put into other code. In fact that is the whole intent. In part of the code I actually have comments of:

#
# Function AnonLDAPPing
#  Requires the Net::LDAP module
#   This is where the totally cool stuff starts!!!
#   No seriously, I don’t think I have ever seen
#   this in simple basic open code anywhere before. It
#   uses the same dynamic underlying processes to
#   determine the site the client is in that is used
#   by Windows.
#  
#
sub AnonLDAPPing

Oh and that AnonLDAPPing function… It works over TCP, it doesn’t use UDP like everyone else I have seen. That is so if you have a network that likes to chop down UDP packets you don’t have to care about it. Also I think using TCP to perform the ping and get the response timings is more realistic anyway. You can change it to UDP if you like… I don’t care. Depending on the language you use it could be more or less painful.

I spent a little time the last couple of nights building a new CentOS 7 server and spending time trying to get reacquainted with CentOS and upgrading perl to 5.26. I need to do the same with FreeBSD12.0 next. Once I get done with FreeBSD12.0 then I will wrap up the specifics needed for each (use/requires/modules that need to be loaded[2]) so I can put it all in a single script. This has taken longer than expected as my real job has been excessively involved the last few months and even more so the last few weeks. I have to say writing my “for fun” code keeps me sane though. Who knows how long ago my brain would have melted down from nearly 25 years working in the Enterprise Class Fortune X company space. My first Enterprise job was at Ford when it was in the Fortune and Global 5 category, I have been in the Fortune/Global 30 or bigger since. Now I am back up in the Fortune/Global 5 again.  

I will expand more about support of the script when I finally release it but short and simple… this will be unsupported code. If you have questions you will be able to send them, I might respond; if you dump a bunch of money into my tip jar, I might be more likely to respond. The times people have done that I don’t think they have been disappointed, though “a bunch” is my definition. Smile  Anyway, my previous forays into shared source code went horribly with people making changes and compiling and then expecting me to figure out what was wrong while not telling me they changed something. I have learned a lot since then and released the perl script rdp_sec_check which was a modification of another security teams tool that made it more useful for me and I didn’t have any issues with that but just the same I still have a bad taste in my mouth about that initial code sharing… I do have to admit though that sharing this code could be VERY USEFUL for people who still need to find domain controllers since the free stuff out there, and quite frankly a lot of the expensive stuff, either can’t do this work or can’t do it well (or absolutely in a pretty shitty half ass dip the toe in the water to say they did it manner).

Good day and may the good news be yours. Just kidding

    joe

[1] …say you are pretending to be a Windows Hello for Business Client in Hybrid Key Mode and can only use Windows Server 2016 domain controllers because earlier stuff can’t process the WH4B commands properly and the later stuff (Windows Server 2019) has a code regression bug that doesn’t allow it to work either (allegedly)…

[2] There is currently, and literally, one single “use” line commented out of nearly 2000 lines of script in the CentOS7 version compared to the Windows version and I intend to get that handled so there is no difference.

Windows 10 Pro 1809

[Thu 03/21/2019 23:01:19.71]
E:\DEV\perl\jwDCLocator>perl jwDCLocator.pl /domain:k16tst.test.loc

jwDCLocator V01.01.00pl  Joe Richards (support@joeware.net)  March 2018

Initializing Logging to logfile 20190321-2301-jwDCLocator.log…
Reading configuration file jwDCLocator.config…
Processing configuration file…
Configuration file does not exist, skipping…
Determining bootstrap domain controllers via DNS for k16tst.test.loc…
  BootStrap Hosts: k16tst-scdc1.k16tst.test.loc k16tst-dc2.k16tst.test.loc k16tst-dc1.k16tst.test.loc
Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Site2
  AutoDetected Client Site             : joenetlogontestsite
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site joenetlogontestsite…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Default-First-Site-Name…
Validating DCs for joenetlogontestsite…(Order=0)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
           Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.011377
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.010118
Validating DCs for Default-First-Site-Name…(Order=1)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.008036
      Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.008876
Checking Validation List for PDC domain controllers
Ordering DCs by Site | Priority | Avg Elapsed Response Time…
Sorted Validated Domain Controller List
k16tst-dc1.k16tst.test.loc
k16tst-dc1.k16tst.test.loc

The command completed.

CentOS Linux release 7.6.1810 (Core)

[joe@centos7-1 AD]$

[joe@centos7-1 AD]$ perl jwDCLocator_linux.pl /domain:k16tst.test.loc

jwDCLocator V01.02.00pl  Joe Richards (support@joeware.net)  March 2018

Initializing Logging to logfile 20190321-2329-jwDCLocator.log…
Reading configuration file jwDCLocator.config…
Processing configuration file…
Configuration file does not exist, skipping…
Determining bootstrap domain controllers via DNS for k16tst.test.loc…
  BootStrap Hosts: k16tst-dc1.k16tst.test.loc k16tst-scdc1.k16tst.test.loc k16tst-dc2.k16tst.test.loc
Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Default-First-Site-Name
  AutoDetected Client Site             : Site2
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Site2…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Default-First-Site-Name…
Validating DCs for Site2…(Order=0)
       k16tst-dc2.k16tst.test.loc…
        TCP LDAP PING…
           Sending LDAP Ping to LDAP://k16tst-dc2.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.00778
     Retrieving RootDSE…
          Synchronized = TRUE     
          ElapsedTime  = 0.031609
      k16tst-scdc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.00709
     Retrieving RootDSE…     
          Synchronized = TRUE
          ElapsedTime  = 0.042098
Validating DCs for Default-First-Site-Name…(Order=1)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.008532
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.007037
Checking Validation List for PDC domain controllers
Ordering DCs by Site | Priority | Avg Elapsed Response Time…
Sorted Validated Domain Controller List
k16tst-scdc1.k16tst.test.loc
k16tst-dc2.k16tst.test.loc
k16tst-dc1.k16tst.test.loc

The command completed.
[joe@centos7-1 AD]$

Rating 4.33 out of 5

2 Responses to “So very close… Reasonable Effort Platform Agnostic Perl Script That Implements the Active Directory DC Locator Process…”

  1. David Loder says:

    No need to publish this. Your header says March 2018. It’s been 2019 for several months now. 🙂

    • joe says:

      LOL! Thanks for giving me a giggle Dave. Good thing it wasn’t released yet! 🙂

      joe

[joeware – never stop exploring… :) is proudly powered by WordPress.]