Clearing old Print Jobs

When using Windows Server as a print server over time the queues eventually begin to fill up. Print jobs are sent one day when a printer is offline and days later after the printer is turned back on sometimes dozens of print jobs start coming from the printer. The other issue that arises is caused by this backup of print jobs, slowly the print server will use disk space until in space cases it just runs out. Here is a simple PowerShell script to clear up the stale print jobs.

$TooOld = (Get-Date).AddDays(-2)
Get-WmiObject Win32_PrintJob | Where-Object { $_.ConvertToDateTime($_.TimeSubmitted) -lt $TooOld } | Foreach-Object { $_.Delete() }

This can be setup as an easy scheduled task to take of ever needing to worry about this issue in the future.

Runaway process checking

Recently I ran into an issue with PHP exhaustion on a Windows Server running IIS. In this scenario the PHP-CGI.exe process would continue to spawn additional instances as load on the server would increase but over time the application pool would struggle and begin to slow to a crawl. In the past I have seen other applications during various iterations of development run into the same issue where if you run into more than “x” instances of an application it is unhealthy or less than “y” instances it is not running properly.

 

$myprocess = "php-cgi"
$myserver = "WebServer"
$mydomain = "liquidobject.com"
$mail_server = "mail.liquidobject.com"
$mail_recipient = "my_support_team@liquidobject.com"
$toomany = 40
$waytoomany = 80

$mail_sender = "$myserver@$mydomain"
$mailreport_subject = "Script: $myserver $myprocess count"
$body = " "

function SendEmailReport
{
    $body = [string]::join([environment]::NewLine, ($body)) 
    $msg = New-Object System.Net.Mail.MailMessage $mail_sender, $mail_recipient, $mailreport_subject, $body
    $client = New-Object System.Net.Mail.SmtpClient $mail_server
    $client.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
    $client.Send($msg)
}


$mycount =  (Get-Process -Name $myprocess).count

if($toomany -lt $mycount)
{
	$body = "We have $mycount $myprocess processes, something is unusual."
	if($waytoomany -lt $mycount)
        {
             IISRESET /STOP
             IISRESET /START
             $body = "We have $mycount $myprocess processes, IIS has been reset."
        }
        SendEmailReport
}

In this case we are sending an email notification to the fictional “support team” when more than 40 instances of the php-cgi process are running and in the event no one responds by the time 80 instances are hit the site is automatically bounced to ensure it’s availability.

The simple method for checking is the use of Task Scheduler and call up the script every 5 minutes, pretty simple yet effective.

Disabling DNS Recursion on Windows Server 2008 R2 and mitigation of DNS Amplification Attacks

Over the past year DNS Amplification attacks have been worse, even to the point that the US-CERT (http://www.us-cert.gov/ncas/alerts/TA13-088A) issued a warning last month. With Linux and Unix BIND DNS Server installs a simple config change can take care of this issue however, in Microsoft’s implementation of the DNS server there is a lack of this basic functionality.

This problem is two fold on Windows if you are also using the recursive DNS servers internally for your DNS forwarders. If you are then the first step is standing up a couple of basic forwarding DNS servers. For an additional level of security I would also suggest deployment with conditional forwarders for domains which you are the root DNS server for to reduce the possibility spoofing (if not using DNSSEC), enhance internal DNS performance, and allow for internal DNS resolution to work in the event your WAN link goes down.

The second step is the actual removal of recursion on your existing DNS servers which the below step by step instructions will take of.

Load up DNS Management, right click on your DNS server and select properties.
DNS-1

Select the “Advanced” tab and check the box to “Disable recursion (also disables forwarders)”

DNS-3

Select “Apply”, then “OK”, and finally close out of the DNS management utility.

At this point we need to stop the DNS server service temporary via “net stop dns”

Now pull up Windows Explorer and navigate to %systemroot%\system32\dns, in this folder you’ll find something called “cache.dns”. This file contains the list of root-forwarders which are always active even though recursion is disabled…. anyway, rename this file to something like cache.dns.bak
DNS-4

Lastly start the DNS server back up “net start dns”

At this point validate recursion is really disabled via nslookup.

On a client system pull up a command line and perform the following

nslookup
server my_non_recursive_dns_server_ip
www.google.com
www.mydomain.org

The resolution for www.google.com should not return an IP address (unless your Google) and the address for www.mydomain.org should return an IP assuming the DNS entry is located within the zone file on the server.

With the above completed, you will no longer be a potential node in a DNS amplification attack.

Large exchange distribution automation

Exchange distribution groups are a very useful method for delivering email to a large number of clients, however every design has it’s limits. I needed to use a distribution list for a rotating number of users with a total count of close to 20,000 members. When looking at distribution groups with more than a few thousand entries causes scalability limits. Naturally I’d rather not have to manually load lists every night.

if(Get-Module -Name ActiveDirectory){}
else{Import-Module ActiveDirectory}

Write-Host "Loading employees"
$myusers = Get-ADUser -filter "*" -SearchBase "OU=Employees,DC=liquidobject,DC=com" -properties description | Select-Object samaccountname
Write-Host "Successfully loaded" $myusers.count "employee accounts."

$alpha = "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"
foreach($i in $alpha)
{
    $mygroup = "EmployeeSub_$i"
    $myoldgroupmembers = Get-AdGroupMember -identity $mygroup | Select-Object SamAccountName
    Write-Host "Group:" $mygroup "has" $myoldgroupmembers.count "members"
    $mycurrentusers = $myusers | where {$_.samaccountname -like "$i*"}
    Write-Host "We currently have" $mycurrentusers.count "which should be in this group"
    
    $mydiff =  Compare-Object -ReferenceObject $myoldgroupmembers -DifferenceObject $mycurrentusers -property samaccountname
    $mydiff
    foreach($i in $mydiff)
    {
        if($i.SideIndicator -eq "=>"){Add-AdGroupMember -identity $mygroup -members $i.samaccountname}
        else {Remove-AdGroupMember -identity $mygroup -members $i.samaccountname -confirm:$False}
    }
}

The above provides a differential solution by splitting the single very large group into a series of 26 smaller, more manageable groups. Then we can wrap the 26 groups with a query-based distribution group for simplified delivery to clients using

new-DynamicDistributionGroup All_Employees -OrganizationalUnit "OU=My OU,DC=liquidobject,DC=com" -RecipientFilter {RecipientContainer -eq "OU=EmployeeGroups,My OU,DC=liquidobject,DC=com"}

FreeNAS and renaming ZFS datasets

While not a feature of FreeNAS at least as of version 8.3 you can actually rename your ZFS datasets. The rename command is feature of ZFS and can be accomplished through the shell.

First, use: zfs list

[root@NAS-1] /mnt/RaidZ# zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
RaidZ                 306G  2.36T  53.3K  /mnt/RaidZ
RaidZ/Backups        8.19G  91.8G  8.19G  /mnt/RaidZ/Backups
RaidZ/Test_gzip6  17.4G  32.6G  17.4G  /mnt/RaidZ/Test_gzip6
RaidZ/Photos            5G  20.0G  40.0K  /mnt/RaidZ/Photos
RaidZ/Transfer       3.70G  46.3G  3.70G  /mnt/RaidZ/Transfer

 

The first column generated will give you the actual name of your dataset. In my case I wanted to rename “Test_gzip6” to “Test1”

zfs rename RaidZ/Test_gzip6 RaidZ/Test1

Which results in:

[root@NAS-1] /mnt/RaidZ# zfs list
NAME                  USED  AVAIL  REFER  MOUNTPOINT
RaidZ                 306G  2.36T  53.3K  /mnt/RaidZ
RaidZ/Backups        8.19G  91.8G  8.19G  /mnt/RaidZ/Backups
RaidZ/Test1  17.4G  32.6G  17.4G  /mnt/RaidZ/Test1
RaidZ/Photos            5G  20.0G  40.0K  /mnt/RaidZ/Photos
RaidZ/Transfer       3.70G  46.3G  3.70G  /mnt/RaidZ/Transfer

Pretty straight forward, the syntaxing is the only hangup because it’s not looking for the true path in this case which was /mnt/RaidZ/Test_gzip6 but just the full dataset name.

FreeNAS 8.3 and VMware ESXi’s VMXNet3 adapter

The built-in networking support under FreeNAS 8.3 is only the e1000 adapter and while it does “work” it really lacks performance in a virtual environment. To get around this limitation we need to install VMware Tools to support more modern networking adapters. While this question is ask time and time again in the FreeNAS forums and around I never see a straight forward solution for adding the VMXNet3 adapter. So here we go.

We’ll assume you already have your VM deployed with one e1000 and one vmxnet3 adapter and we are just loading in the drivers.

 

Add Perl

Pull up the shell or connect via SSH to your FreeNAS VM

mount -urw /
cd /tmp
pkg_add -r perl -K
tar -xjf perl.tbz
cp lib/perl5/5.12.14/mach/CORE/libperl.so  /lib

(the build number will change as time goes on)

Add compat6x

pkg_add -r compat6x-amd64

Install VMware Tools

It is assumed you are installing with the default options.

Install VMware tools as normal via the "Install/Upgrade VMware tools" menu option
mkdir /mnt/cdrom
mount -t cd9660 "/dev/iso9660/VMware Tools" /mnt/cdrom
cd /tmp
tar zxpf /mnt/cdrom/vmware-freebsd-tools.tar.gz
umount /mnt/cdrom
cd vmware-tools-distrib
./vmware-install.pl
/usr/local/bin/vmware-config-tools.pl

Ignore the failed notice for the memory manager. At this point VMware Tools is installed but still needs some tweaking.

VMware tools tweaking

vi /usr/local/etc/rc.d/vmware-tools.sh
Look for: if [ "$vmdb_answer_VMHGFS_CONFED" = 'yes' ]; then    and change yes to xyes
Look for: if [ "$vmdb_answer_VMMEMCTL_CONFED" = 'yes' ]; then    and change yes to xyes
Look for: if [ "$?" -eq 0 -a "$vmdb_answer_VMXNET_CONFED" = 'yes' ]; then    and change yes to xyes
save and close vi (escape wq enter)
rm /etc/vmware-tools/not_configured
reboot

Now within the FreeNAS WUI (Web User Interface) add an additional network adapter, you’ll see vmxnet3 adapter called “vmx3f0”.

 

I’m seeing the following differences when sequential data (4GB iso) to and from a test system via SSD and Gigabit infrastructure.

e1000 Adapter

  • Read: 50 MB/sec to 59MB/sec (for first 2GB then 73 MB/sec)
  • Write: 33.0 MB/sec to 35 MB/sec

VMXNet3 Adapter

  • Read: 93MB/sec to 95MB/sec
  • Write: 29.5 MB/sec to 42.1 MB/sec

My VM configuration

  • vCPU: 3
  • Ram: 6GB
  • Drives: 4GB vmdk, 3×1.5TB virtual RDM
  • Raidz
  • NIC: e1000(management),VMXNET3(data)
  • VM Hardware Version: VMX-09

My host config

  • CPU: Dual Xeon e5320’s
  • Ram: 24GB ECC DDR2
  • Controllers: IBM M1015 (IT firmware), LSI 8308ELP
  • Drives: 2x500GB(hardware mirror), 3×1.5TB(7200.11)(FreeNAS virtual RDM’s)
  • NIC: Onboard Intel 1000pro
  • OS: ESXi 5.1 Update 1

Sorry, no VT-d on this host to pass through the M1015 which may be giving me a small amount of overhead running the virtual RDM’s.