Synchronizing machine keys in ASP.NET web application [duplicate] - c#

We (our IT partner really) recently changed some DNS for a web farmed site we have, so that the two production server have round-robin DNS switching between them. Prior to this switch we didn't really have problems with WebResource.axd files. Since the switch, when we hit the live public URL, we get an error:
CryptographicException
Padding is invalid and cannot be removed.
When we hit the specific servers themselves, they load fine. I've researched the issue and it seems since they're sharing assets between two servers, we need to have a consistent machineKey in the web.config for each server so they can encrypt and decrypt consistently between the two. My questions are:
Can I generate a machineKey via a tool on the server, or do I need to write code to do this?
Do I just need to add the machineKey to the web.config on each server or do you think I'll need to do anything else to make the two server work together? (Both web.config's currently do not have a machineKey)

This should answer:
How To: Configure MachineKey in ASP.NET 2.0 - Web Farm Deployment Considerations
Web Farm Deployment Considerations
If you deploy your application in a Web farm, you must ensure that the
configuration files on each server share the same value for
validationKey and decryptionKey, which are used for hashing and
decryption respectively. This is required because you cannot guarantee
which server will handle successive requests.
With manually generated key values, the settings should
be similar to the following example.
<machineKey
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7
AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1"
decryption="AES"
/>
If you want to isolate your application from other applications on the
same server, place the in the Web.config file for each
application on each server in the farm. Ensure that you use separate
key values for each application, but duplicate each application's keys
across all servers in the farm.
In short, to set up the machine key refer the following link:
Setting Up a Machine Key - Orchard Documentation.
Setting Up the Machine Key Using IIS Manager
If you have access to the IIS management console for the server where
Orchard is installed, it is the easiest way to set-up a machine key.
Start the management console and then select the web site. Open the
machine key configuration:
The machine key control panel has the following settings:
Uncheck "Automatically generate at runtime" for both the validation
key and the decryption key.
Click "Generate Keys" under "Actions" on the right side of the panel.
Click "Apply".
and add the following line to the web.config file in all the webservers under system.web tag if it does not exist.
<machineKey
validationKey="21F0SAMPLEKEY9C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7
AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"
decryptionKey="ABAASAMPLEKEY56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1"
decryption="AES"
/>
Please make sure that you have a permanent backup of the machine keys and web.config file

If you are using IIS 7.5 or later you can generate the machine key from IIS and save it directly to your web.config, within the web farm you then just copy the new web.config to each server.
Open IIS manager.
If you need to generate and save the MachineKey for all your applications select the server name in the left pane, in that case you will be modifying the root web.config file (which is placed in the .NET framework folder). If your intention is to create MachineKey for a specific web site/application then select the web site / application from the left pane. In that case you will be modifying the web.config file of your application.
Double-click the Machine Key icon in ASP.NET settings in the middle pane:
MachineKey section will be read from your configuration file and be shown in the UI. If you did not configure a specific MachineKey and it is generated automatically you will see the following options:
Now you can click Generate Keys on the right pane to generate random MachineKeys. When you click Apply, all settings will be saved in the web.config file.
Full Details can be seen # Easiest way to generate MachineKey – Tips and tricks: ASP.NET, IIS and .NET development…

Make sure to learn from the padding oracle asp.net vulnerability that just happened (you applied the patch, right? ...) and use protected sections to encrypt the machine key and any other sensitive configuration.
An alternative option is to set it in the machine level web.config, so its not even in the web site folder.
To generate it do it just like the linked article in David's answer.

Related

Using in memory repo for data protection when running in IIS

I'm running a production server (Windows Server 2012) with an AspNet Mvc Core RC1 website.
I'm seeing the following in the logs:
Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
After inspecting the source code for DataProtection, I tracked the problem to the following method call:
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
This is probably returning null on the server for some reason. I don't have any special custom configuration in place and I've read the docs so I thought the default would work.
I think the problem is with the IIS website not running in a certain user's context but I have no idea how to confirm or fix this. My website is configured with its own pool.
As an aside: the result of running an in memory repository for storing keys causes them to recycle whenever the application exits which is very annoying and not even intended for use in production environments.
User profile should be loaded in IIS configuration.
Open IIS, right click on Application Pools then Advanced Settings. And set "Load user profile" to true. Restart your app and it should work perfectly.
Data Protection keys used by ASP.NET applications are stored in registry hives external to the applications. When running your application as an AppPool Identity you have to create a registry hive for every AppPool used with an ASP.NET Core application.
For standalone IIS installations, you may use the Data Protection PowerShell script for each application pool used with an ASP.NET Core application. The keys will be persisted in the registry.
Like clearly stated in the logs since the registry hive that Data Protection looks for does not exist, keys will not be persisted to disk. Instead, they will be ephemeral and live in-memory only.
In web farm scenarios, an application can be configured to use a UNC path to store its data protection key ring. By default, the data protection keys are not encrypted. You can deploy an x509 certificate to each machine to encrypt the key ring.
See the official ASP.NET Core doc about data-protection for more information
Those who are on the hosted environment where the access rights are very limited can use PersistKeysToFileSystem instead.
Adding the following listing into the Startup.cs will resolve your issue:
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(#"\\server\share\directory\"));
}
You can change the path string acording to your needs.
Please also check ProtectKeysWith if you want to configure the system to protect keys at rest by calling any of the ProtectKeysWith* configuration APIs.
Take a look at this from the DataProtection Git repository
In short, there is a bug in IIS that may never be corrected that prevent the correct registry setup for DataProtection keys. There is a powershell script to setup manually the registry correctly so that it works for AspNet Core. After you run the script for each application pool you use for AspNet Core applications, those applications will then work as intended.

Windows Authentication and web.config renaimg

We are facing a strange issue with ASP.net Application using Windows Authentication and required some expert advice for resolution. Below is the detail scenario
1- Application-1: deployed on IIS on its own App.pool, Call the default page and provided the User ID and Password on IIS windows login screen. It successfully logged in=>No Issues.
2- Application-2: Create a new virtual directory on Same IIS and copy the web content of Application-1. Call default page and provided the User ID and Password on IIS windows login screen, It fails and Keep prompting Login screen
3- Rename the web.config in Application 2 to anything. e.g web123.config.
4- Call the Default Page of Application 2. It shows error which is obvious as IIS unable to find the web.config.
5- Reverse the name of web config from web123.config to web.config in Application 2.
6- Now call the application 2 again as per step 4, and it works.
It seems the IIS is overwriting some thing once we call the application with no web config as in step-4. But What and why it is not working at Step 2, where as technically we did not change any thing in web.config.
I'm not sure why renaming the web.config makes this work for you, but I have had this issue with duplicate websites on the same server having conflicting cookies. Without renaming the web.config can you do this and change the cookie name and see if anything changes?

ASP.NET FormsAuthentication: have to log in again when restarting application

I have an ASP.NET application using FormsAuthentication. Whenever I restart the application or web server, my authentication token is invalid and I have to log in again. What's going wrong?
By default, FormsAuthentication validates authentication data on every request by having the client store an encrypted copy of the data. The encryption key is stored in Machine.config. The specific key to use is in <machineKey decryptionKey="YOUR KEY HERE">.
If you do not provide a decryption key, one is automatically generated on application startup. Since it is randomly generated, it will be different each time you restart the application. On the validation phase, FormsAuthentication attempts to decrypt the authentication data and fails. Then the user is no longer logged in.
There are two ways of resolving this problem.
Providing a machineKey in Machine.config will give FormsAuthentication a consistent key to use, so validation will succeed with the encrypted cookie from previous application runs.
Using <forms protection="None" ... /> in Web.config will disable authentication data encryption and validation. This is insecure and only appropriate for development, since it will be trivial for users to impersonate each other.
The default session state mode in asp.net is in-proc (cached in-memory) unless you specify otherwise. When the application shuts down, memory is cleared and the in-proc session cache is therefore lost.
#dhasenan The machinekey config will only be an issue if the application is deployed across a web farm or the cloud. The idea of overriding the machine-level config of the Machinekey element is to ensure that multiple machines are using the exact same keys.
Therefore, the machine key shouldn't be an issue because if one is not provided at the application level, the machine key in the machine.config will be used instead, which is persisted and static, so it will not be regenerated between sessions.

C# Elmah - how to fix when it is working in one website but not another on the same server

I have two copies of the same website on my IIS7.5 windows 2008 server:
Default Website/my_app
Beta/my_app
The code base for the two are identical, and they both have identical web.config files.
On the default website, ELMAH works and logs messages (to file), but on the Beta website it does not log anything. What can I check to see why it is not working?
I have compared the ACLs for both physical folders and they are the same.
All it need is a write permission for apppool identity.
We are using very simple webdeploy package for automagic managing ACLs.
You should check ACLs for appPools
I'm sure your site use different identities.

Uses for MachineKey in ASP.NET

What different ways are Machine Keys useful in asp.net?
I think the following are correct but thought there may be more.
Multiple applications can use the same cookie
Multiple servers can work with the same viewstate
MachineKey is used for:
ViewState encryption and validation
Forms Authentication (or Federated Authentication) uses this key for signing the authentication ticket
Having a Web App installed on multiple servers requires same Machine Key configured on all of them in order for Load Balancing to work.
To see all details, please refer to: MSDN How To: Configure MachineKey in ASP.NET 2.0
Machine key is also used to encrypt/decrypt the webresources.axd parameters.
Even on a single server the machine key should be configured, because any recycle of the app domain will generate a new key when it is set to auto. This causes the next postback just for pages rendered before the recycle, to cause a viewstate validation error, and also issues with the resources during that time.
Encryption - very common.

Categories