Adding machineKey to web.config on web-farm sites - asp.net

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

Overriding web config file at the time of deployment in ASP.NET and IIS

We are using ASP.NET for our web application which is hosted in IIS 8.5. ASP.NET uses a web.config file to store all application and IIS related configurations. Whenever we deploy a new version of code for the web application, we also deploy the web.config file.
Recently the operation team has raised a concern to this deployment process. They say, if someone change some settings in IIS and for that web.config has been updated for that, there is no way for the developers to know that change so that they can update the web.config in codebase (version control system). So eventually at the time of next deployment the web.config changes will be overridden by the old web.config.
There are two possible solutions can be taken:
Merge the web.config with server and codebase before deploy the code everytime.
Decouple the application configuration and IIS configuration in different configuration files.
My question is, what is the best practice to solve these kinds of problems in ASP.NET?
IIS 7+ introduced its distributed configuration which allowed for IIS as well as .NET configuration to live inside of Site/App/Directory web.config files. One of the primary reasons for this is as follows: In IIS 6, whenever an application team needed to deploy their application and make changes to settings like Default Document, they needed the IIS team involved because "Default Document" was an IIS configuration setting. You could argue that Default Document settings for a particular application is not IIS configuration, but instead is Application configuration. As result, the Application Team should own that configuration setting and deploy it as part of the application.
A bit more about IIS7+ configuration system: Administrators are able to configure what settings are allowed to be set inside Web.config files. For example, by default, "Default Document" is able to be set inside Web.config files, and Authentication settings like Windows Authentication are not. The implementation can actually get complex, but if you'd like to read about it, you can see it here: https://learn.microsoft.com/en-us/iis/get-started/planning-for-security/how-to-use-locking-in-iis-configuration.
Ultimately the best practice is for IIS Administrators to configuration the settings they want Application teams to manage (by delegating those settings to Web.config) and then not touch them. In other words, if Default Document needs to be updated, then it is the Application Team's responsibility and they publish a new web.config file. If the IIS team decides they want to manage Default Document, then they need to lock down the IIS configuration system to prohibit Default Document from being managed in the web.config files.

Load site specific config as well as application web.config

I have a asp.net mvc application which comes with web.config. I deploy it to my Windows server 2012 with IIS 8.
I have to make some changes to the web.config because of the unique settings on the server, for instance, disable a URL rewrite rule, to name a few.
I treat my application as a open source project which shouldn't include settings specific to my server. But if I don't put the unique settings in web.config, every time I deploy the site, I have to manually edit it again.
Are there ways to resolve the problem? Is it possible for IIS to load two web.config, one from the repository, the other somewhere on the server?
I know <appsetting> has file attribute that include additional app settings, but my changes are not only app setting.

When is it necessary or beneficial to specify a custom Machine Key in web.config? (ASP.NET)

I've come across a couple of open source applications which recommend or require that a custom machine key is specified in web.config.
Why would this be necessary?
What is the reason, or advantage in specifying a custom machine key in web.config?
The first place a website search for configuration is Machine.config. Then Web.config overrides it.
Here are few reasons.
When you do Encryption and Decryption for example you can specify the keys in Machine key. Read this and this
And, if you need to share a value between multiple websites hosted on the same server.

IIS7 Application Configuration

I have a custom ASP.NET application that I utilize for several clients that I host. Each client has a separate domain and the application is normally a child application under the root domain (http://domain.com/customapp). The application files are the same (aspx, ascx, style sheets, images, etc.). The only thing different is the web.config file for each client. As development of the application continues to evolve, I have to update the application for each directory and this obviously becoming tedious. I am trying to come up with a method keep the application up to date. My first though is placing the application into a single physical path and creating multiple applications pointing to that path (the problem with this method is I can't have different web.config files). I am curious as to what solution others are using in this scenario...
If you want to handle this entirely in Visual Studio, VS2010 offers web.config transforms which could solve your problem.
In a nutshell, create a build configuration (In VS, select Build|Configuration Manager...) for each site. Add a web.config transform for each client, which only specifies the differences required for each application.
I use this for differentiating between development, staging and release configurations - each transform adjusts the connection string, app settings, etc - and it works quite well both within Visual Studio and when deploying via MSBuild.
Also, note that web.config settings are inherited by IIS applications. So, if you have a root site
/root
and client apps
/root/client1
/root/client2
...
you could place the client-specific config settings in a web.config in each client-specific folder, and global settings a web.config in the root folder.
Can you just move your web.config content to a database and load it conditionally based on the domain that was referenced?
Select Case Request.Url.Host.ToLowerInvariant()
Case "xyz.com", "www.xyz.com"
'Load XYZ stuff'
Case "abc.com", "www.abc.com"
'Load ABC stuff'
Case Else
'Throw an error probably'
End Select
Even better, store your domains in the database as keys so that you don't ever have to touch the code.

Share information beetween ASP.NET applications on the same IIS

I have a solution with more than one ASP.NET web-application. Every application has its own virtual directory on the same IIS. One application is calling aspx pages in the other applications.
How can I share some information (e.g. user/password) between these applications. Is the only way using querystrings (in this case, I must encrypt the information). Or are there other possibilities / techniques ?
Maybe this will help, I asked and answered this question myself
Using one Asp.net Membership database with multiple applications
I had two asp.net applications on one IIS server. It was my goal to make it so when user logged onto app1 their user credentials would be available in app2. Configuring the asp.net membership provider is only one step of what I was looking for. Even if both apps were using the same back end database and provider I still wouldn't be authenticated when I hit app2. What I was looking for was a Single Sign On solution.
Once you have both apps pointing at your asp_membership database by placing the following in the system.web section of your web config
make sure both have the same applicationname property set.
I was using IIS 6 so I configured it to autogenerate a machine key for both applications. Because both of these applications live on the same machine the key would be identical, this is the critical part to making the SSO work. After setting up IIS the following was added to my web.config
<machineKey decryptionKey="AutoGenerate" validation="SHA1" validationKey="AutoGenerate" />
That was all there was to it. Once that was done I could log into app1 and then browse to app2 and keep my security credentials.
Thanks for the push in the right direction.

Resources