Iis – Add Machine Key to machine.config in Load Balancing environment to multiple versions of .net framework

iisload balancingnetwindows-server-2008-r2

I have two web servers behind a F5 load balancer. Each web server has identical applications to the other. There was no issue until the config of the load balancer changed from source address persistence to least connections.

Now in some applications I receieve this error

Server Error in '/' Application.

Validation of viewstate MAC failed. If this application is hosted by a
Web Farm or cluster, ensure that configuration specifies
the same validationKey and validation algorithm. AutoGenerate cannot
be used in a cluster. Description: An unhandled exception occurred
during the execution of the current web request. Please review the
stack trace for more information about the error and where it
originated in the code.

Exception Details: System.Web.HttpException: Validation of viewstate
MAC failed. If this application is hosted by a Web Farm or cluster,
ensure that configuration specifies the same
validationKey and validation algorithm. AutoGenerate cannot be used in
a cluster.

Source Error:

The source code that generated this unhandled exception can only be
shown when compiled in debug mode. To enable this, please follow one
of the below steps, then request the URL:

  1. Add a "Debug=true" directive at the top of the file that generated the error. Example:

or:

2) Add the following section to the configuration file of your
application:

Note that this second technique will cause all files within a given
application to be compiled in debug mode. The first technique will
cause only that particular file to be compiled in debug mode.

Important: Running applications in debug mode does incur a
memory/performance overhead. You should make sure that an application
has debugging disabled before deploying into production scenario.

How do I add a machine key to the machine.config file? Do I do it at server level in IIS or at website/application level for each site? Does the validation and decryption keys have to be the same across both web servers or are they different? Should they be different for each machine.config version of .net?

I cannot find any documentation of this scenario.

Best Answer

If you only need it for your web site, you can add it to your web site's web.config. If there are multiple sites/applications that need to use the same machineKey for encrypting/decrypting, that is when you would use a machine-scoped configuration file.

And yes, they should be the same across all servers in the farm, and you should do this for each .NET folder's machine.config (.NET 2.0 + 4.0, and x86 + x64, so you may be updating four files).

Here is some sample code you may use to generate your keys:

/// <summary>
/// http://msdn.microsoft.com/en-us/library/w8h3skw9.aspx
/// </summary>
public static string CreateMachineKey(int characterLength)
{
    /*
     * decryptionKey:
     * DES: 64 bits (16 hexadecimal characters)
     * 3DES:192 bits (48 hexadecimal characters)
     * AES: 128 bits (32 characters), 192 bits (48 characters), or 256 bits (64 characters)
     * 
       validationKey:
        AES requires a 256-bit key (64 hexadecimal characters).
        MD5 requires a 128-bit key (32 hexadecimal characters).
        SHA1 requires a 160-bit key (40 hexadecimal characters).
        3DES requires a 192-bit key (48 hexadecimal characters).
        HMACSHA256 requires a 256-bit key (64 hexadecimal characters).
        HMACSHA384 requires a 384-bit key (96 hexadecimal characters).
        HMACSHA512 requires a 512-bit key (128 hexadecimal characters).

    */
    byte[] byteArray = new byte[characterLength / 2];
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(byteArray);
    StringBuilder sb = new StringBuilder(characterLength);
    for (int i = 0; i < byteArray.Length; i++)
    {
        sb.Append(string.Format("{0:X2}", byteArray[i]));
    }
    Debug.WriteLine(sb);
    return sb.ToString();
}

Here is an example of a machine.config:

<system.web>
    <machineKey 
    decryption="AES" 
    decryptionKey="D416EFCFEC011CC3A8F0F72A15E7EF725AA39FDBCE3CA361"
    validation="HMACSHA256" 
    validationKey="EF4BFB4B2E1A9AB427430897A13528E4530A231112014E070B246DCA7383EB7F4163D685F590E9B54005F5215AD3BA7CE4EA7D404FE310C543D100D09CC00AE2"/>
</system.web>

Files:

%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework64\v4.0.30319\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.5727\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework64\v2.0.5727\CONFIG\machine.config

Related Topic