• Performance Optimization Philosophy

    Optimizing performance is not just about making things run faster, it is about making them run appropriately fast based on perception and cost.

    Several questions may be posed at this junction:

    • Why does philosophy need to be discussed?
    • Isn't performance just about making things run faster?

    There is a common misconception that performance optimization is about making things faster.  In actuality, optimizing is actually about finding the correct balance between any number of tradeoffs.  Often and simplistically this optimization is balancing between either cost and hardware (think upgrading processor), or cost and labor (think development/test time).

    The other component is user perception.  This is often the most challenging part of the equation and is often what triggers reviews of existing infrastructure due to perceived poor performance.  It is not uncommon that the software is behaving normally and that the issue is not due to a hardware scalability issue, but the end user still feels that the software is not fast enough.  Unfortunately, in these scenarios, there is often little that can be done in the short run without waiting for hardware to catch up with the needs of the code, optimizing the code, or waiting for fundamental architectural changes (like moving from x86 to x64) to come to pass in order be able to eliminate hardware bottlenecks.  In short, the return on investment (ROI) of throwing more hardware at the code to fix user perception may not be there.

    Here are some analogies to illustrate the point:
    My grandmother is looking for a new car.  She lives on a fixed income and, since she is getting older, doesn't travel much anymore, mostly to the grocery store or bingo, which are within 3 miles of her house.  Due to her needs, the Lamborghini Murciélago is probably a little excessive though it probably performs well.  I'm sure that pretty much any car that runs will be performant enough for her needs.  Furthermore, making the investment in the Murciélago is probably not going to fix her perception that it takes too long to go the 3 miles to the supermarket.

    Stretching the analogy a little:
    Regardless of what car she gets, it is not a plane, thus it will never ever fly.  But also, there is no guarantee that if she gets a plane it will be faster than a car (the land speed record is 766 mph and a Piper Cub goes about 130 MPH).  Just like it is critical never to assume that moving from x86 to x64 will speed up the application.  It would be more analogous to moving from a car to a tractor trailer where more stuff can be stored (increased addressable memory) so fewer trips (to disk/network) need to be made.

     

  • NTLMv2 or not NTLMv2, that is the question.

    Enabling NTLMv2 is a project always fraught with challenges, mostly due to the lack of visibility into exactly which authentication protocol is being used by a client machine.  Management often is not gung-ho about the try it and see what breaks methodology of identifying systems that can not support NTLMv2.  As such, many administrators have often asked to deploy NTLMv2 to the enterprise with minimal impact to client systems.

    Up until now, sniffing network traffic was the only option available, and not a very good option.  With the release of Windows Vista and 2008, this becomes dramatically easier as both event filtering is improved AND security auditing has been dramatically improved.  And, since there is plenty of documentation on how to deploy NTLMv2, this will just tell you how to identify which systems are not using NTLMv2.

    1. On a Windows Vista or 2008 machine use the command line to enable auditing for Logon Events.
      "auditpol /set /subcategory:logon /success:enable /failure:enable"
    2. Create a custom view or filter the security log using the following syntax (copy/paste the content between the quotes):
      "<QueryList> <Query Id="0" Path="Security"> <Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4624)] and EventData[Data[@Name='LmPackageName']!='-'] and EventData[Data[@Name='LmPackageName']!='NTLM V2']]</Select> </Query> </QueryList>"

    If auditing is enabled on the DCs, all the domain accounts being used anywhere in the enterprise will be caught.

    Check out Eric Fitzgerald's blog for how to script wevtutil.  If used with the above filter you can easily automate pulling the data you want out of the security log.  Also, my thanks to Eric for the insight into the fact that we now audit the hash used during authentication
    http://blogs.msdn.com/ericfitz/archive/2008/07/16/wevtutil-scripting.aspx

     

    Here is a sample event for reference:
    Log Name:      Security
    Source:        Microsoft-Windows-Security-Auditing
    Date:          5/28/2008 9:51:11 AM
    Event ID:      4624
    Task Category: Logon
    Level:         Information
    Keywords:      Audit Success
    User:          N/A
    Computer:      computer.contoso.com
    Description:
    An account was successfully logged on.

    Subject:
     Security ID:  NULL SID
     Account Name:  -
     Account Domain:  -
     Logon ID:  0x0

    Logon Type:   3

    New Logon:
     Security ID:  ANONYMOUS LOGON
     Account Name:  ANONYMOUS LOGON
     Account Domain:  NT AUTHORITY
     Logon ID:  0x1161d3f3
     Logon GUID:  {00000000-0000-0000-0000-000000000000}

    Process Information:
     Process ID:  0x0
     Process Name:  -

    Network Information:
     Workstation Name: SOURCEMACHINE
     Source Network Address: 192.168.X.X
     Source Port:  4996

    Detailed Authentication Information:
     Logon Process:  NtLmSsp
     Authentication Package: NTLM
     Transited Services: -
     Package Name (NTLM only): NTLM V1
     Key Length:  128

    This event is generated when a logon session is created. It is generated on the computer that was accessed.

    The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe.

    The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network).

    The New Logon fields indicate the account for whom the new logon was created, i.e. the account that was logged on.

    The network fields indicate where a remote logon request originated. Workstation name is not always available and may be left blank in some cases.

    The authentication information fields provide detailed information about this specific logon request.
     - Logon GUID is a unique identifier that can be used to correlate this event with a KDC event.
     - Transited services indicate which intermediate services have participated in this logon request.
     - Package name indicates which sub-protocol was used among the NTLM protocols.
     - Key length indicates the length of the generated session key. This will be 0 if no session key was requested.
    Event Xml:
    <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
      <System>
        <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{00000000-0000-0000-0000-000000000000}" />
        <EventID>4624</EventID>
        <Version>0</Version>
        <Level>0</Level>
        <Task>12544</Task>
        <Opcode>0</Opcode>
        <Keywords>0x8020000000000000</Keywords>
        <TimeCreated SystemTime="2008-05-28T13:51:11.177Z" />
        <EventRecordID>63818</EventRecordID>
        <Correlation />
        <Execution ProcessID="656" ThreadID="752" />
        <Channel>Security</Channel>
        <Computer>computer.contoso.com</Computer>
        <Security />
      </System>
      <EventData>
        <Data Name="SubjectUserSid">S-1-0-0</Data>
        <Data Name="SubjectUserName">-</Data>
        <Data Name="SubjectDomainName">-</Data>
        <Data Name="SubjectLogonId">0x0</Data>
        <Data Name="TargetUserSid">S-1-5-7</Data>
        <Data Name="TargetUserName">ANONYMOUS LOGON</Data>
        <Data Name="TargetDomainName">NT AUTHORITY</Data>
        <Data Name="TargetLogonId">0x1161d3f3</Data>
        <Data Name="LogonType">3</Data>
        <Data Name="LogonProcessName">NtLmSsp </Data>
        <Data Name="AuthenticationPackageName">NTLM</Data>
        <Data Name="WorkstationName">SOURCEMACHINE</Data>
        <Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
        <Data Name="TransmittedServices">-</Data>
        <Data Name="LmPackageName">NTLM V1</Data>
        <Data Name="KeyLength">128</Data>
        <Data Name="ProcessId">0x0</Data>
        <Data Name="ProcessName">-</Data>
        <Data Name="IpAddress">192.168.X.X</Data>
        <Data Name="IpPort">4996</Data>
      </EventData>
    </Event>