Managing deployment of encrypted connection string (IIS) - security

I have ran in my computer
aspnet_regiis -pe "connectionStrings" -app "/MyApp" -site "MySite"
And it created an encripted < connectionStrings > xml element in web config
Now every time that I delpoy my app to a new environment
web.config is being "web transformed" into a new web.config and then deployed.
I understand that the encryption is unique per machine.
I tried to copy the encrypted value and it didnt work.
Do I need to run "aspnet_regiis -pe... " command evey time I deploy and on every machine?
Is there a better practice?
what/where is the unique key in my computer that my machine uses in the encription?
Do I need to guard it for potential attacks?
thanks.

1) Yes, I would recommend deploying the unencrypted web.config file to the new server, then running your encryption command as part of the "deployment process".
2) The OS and Framework should be guarding the default encryption key for you already. You can learn more about the internals of all this at the following link:
http://msdn.microsoft.com/en-us/library/dtkwfdky%28v=vs.100%29.aspx
"This walkthrough uses the default RsaProtectedConfigurationProvider provider that is specified in the Machine.config file and named "RsaProtectedConfigurationProvider". The RSA key container that is used by the default RsaProtectedConfigurationProvider provider is named "NetFrameworkConfigurationKey"."
Keep in mind that the key that is used to encrypt/decrypt the web.config file is not the machine key (it is separate). However if you're deploying to a web farm you'll want to also ensure that the machine keys are consistent or you'll see strange errors arise.

Related

IIS Manager hangs when enabling shared configuration

When I go to enable Shared Configuration in IIS 10 on Server 2022 and point it to my configuration folder and enter the encryption key the interface just hangs. There are no entries in event viewer to give any indication what happened. I have to kill off the IIS Mgr process. The server I used to "export" the config is also IIS 10 but on server 2019, in case that matters.
As a test I tried exporting the config on the Server 2022 host and pointing Shared Configuration to that and it worked fine. So there must be something about the config export from the other server it doesn't like. I've ensured that all the same IIS features are installed on both servers. Same SSL certificates are available and the same wwwroot is available.
Any ideas what might be going on? Thanks.
OK I figured this out and wanted to report back in case anyone else has this issue down the road. Through more troubleshooting I traced the issue down to the configEncKeyAes.key file that's generated when you export your IIS config using the tool in the IIS Shared Configuration window.
I found that if I exported the config on the destination server and just used the key file generated and retained the configuration files from the source server the Shared Configuration would finally apply without freezing. All sites came over as expected. The only issue is any credentials saved in the config (e.g. custom AppPool credentials) could not be decrypted and had to be reset. This made sense since I was using a different key file than the one generated with the original export on the source server.
This led me to the site below that talked about the need to export the IIS WAS and Configuration Keys from the source server and import them on any other IIS nodes at play. Doing so immediately fixed the issue and the shared configuration applied without issue and the embedded credentials I had on a couple sites carried over as well.
https://byronpate.com/2014/08/troubleshooting-iis-shared-configuration/
I've read several articles about deploying Shared Configuration and none of them mention this seemingly necessary step. But I'm finding that documentation and support around this feature leaves much to be desired.

IIS - AddDataProtection PersistKeysToFileSystem not creating

I've developing an asp.net core application to tun on a web far, and I'm using "AddDataProtection" to protect for key encryption at rest like, the documentation recommends, but when I deploy my application and run directly from IIS with AppPool identity, the key is never created and I get errors on the DpapiNG windows logs.
My code is the following:
services.AddDataProtection(opt => opt.ApplicationDiscriminator = ApplicationConfig.dataProtectionApplicationDiscriminator)
.PersistKeysToFileSystem(new DirectoryInfo(encKeyPath))
.ProtectKeysWithDpapiNG(string.Format("CERTIFICATE=HashId:{0}", ApplicationConfig.dataProtectionCertThumbprint),
flags: DpapiNGProtectionDescriptorFlags.None);
Debugging from visual studio, everything runs fine, but I'm running VS under administrator rights, so permission is not an issue here.
I've tried adding permissions to the AppPool App user to the private key it self directly from MMC, but it did not worked, and even gave permission on the full path to the location were the keys should be created like stated here https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview (check first comment) but also it did not worked.
I was only able to make it work by setting the AppPool to run with the identity of an Administrator, but clearly this is a no go, I just wanted to make sure this was a permission issue somewhere.
Is anybody facing the same issue that is able to help?
Regards,
André
Most likely your issue is you are trying to store your keys somewhere in a folder path that you are cobbling together (or even by using the default path that AddDataProtection provides) that uses an environment path such as %LOCALAPPDATA%. Example: "%LOCALAPPDATA%\ASP.NET\DataProtection-Keys".
Usually, by default IIS DOES NOT set up your app pool accounts with environment path variables such as %LOCALAPPDATA%. The value ends up being blank and your app then tries to write keys to the wrong folder (such as \ASP.NET\DataProtection-Keys instead of %LOCALAPPDATA%\ASP.NET\DataProtection-Keys).
Fix: Within %WINDIR%\System32\inetsrv\config\applicationHost.config set setProfileEnvironment=true. I think you have to restart IIS as well.

Using EFS with IIS. How enshure recovery

Hi Im working on a system where the user can store important information on a website.
Using Ws2012, and IIS8
Im using EFS to encrypt the data in normal files.
It need to be secure from the Admin on the server. (at least make it difficult to get the information)
The files need to be en/decryptet in-flight.
It's actually working fine. Just by setting the folder as EFS and then the files saved by IIS are encryptet and the Admin cant get the content.
So far so good.
Problem: But if the IIS is reinstalled, or the server needs to be rebuild/reinstalled then the files are not avalible for the "new" IIS, as the certificate is different.
Normally I can login as a user and backup the EFS certificte, but how do i do this with IIS.
The idea is to have only one Admin (super trusted) to export the certificate and keep it safe. So all the "normal" admins cant get to it.
So after a rebuild of the server the certificate can be reinstalled and the new IIS can access the files Again.
I have looked at several ways to get the certificate, but all explanations / examples uses a local logged in user, and not a "service" user like the IIS uses.
There could be 2 ways:
One is when creating the site, a certificate would be installed for the IIS to use. This way export is not nessesery, and all sites uses the same certificate. But How?
Second way is to export the certificate the IIS uses, but How?
Hopefully this is a simple task, i just can't find it.
Regards
Jesper

Where to store external credentials in JBoss?

When using WAS we use the j2c credentials store to hold external system's users & passwords.
WAS provides some proprietary apis to get this information.
The benefit of using this instead of a local file that:
- the WAS admin can add/modify credentials having no knowledge of the application structure.
- it is managed in a central way for the whole cluster
- WAS stores it among other own credentials in a folder that is supposed to be secure (at SO level)
- Devs do not need to know about production passwords
Now we are coding for JBOSS and we wonder if there is any similar API in JBoss to get users/passwords by code.
Thank you!!
We have found the solution. JBoss has a "vault" that is explained in the security guide.
Basically it lets you cypher everything you want in the server configuration file (i.e. standadlone.xml). Then it decyphers it when starting the server.
We simple added a JNDI String to the server xml config file with the cyphered credentials. When we get that JNDI value from our code, credentials are already in plain text.
Quite an elegant solution from JBoss dev team.

VS2012 Web Deploy Package to create application pool

I have a web application project in VS2012 which I'm publishing using a "Web Deploy Package". I want this package to include app-pool settings, specifically creating an IIS app-pool and assigning the newly created application to it.
I'm familiar with the option "Include application pool settings used by this Web project" available when the project is configured to use an IIS instance (not IIS Express), but IIS configuration is not part of the project file, and thus not source controlled. What happens when somebody builds a deployment package on a machine that hasn't had IIS meticulously configured? Not ideal.
How else then, can I go about getting AppPool settings into my web deploy package? I understand that the appPoolConfig provider is IIS7+ only, I'm fine with that limitation. I've banged my head against this issue in the past and never found a solution. 18 months later, we've got a new VisualStudio version, and a new web-publishing-pipeline, are there new options to address this? Or maybe something I missed when I first tackled this problem?
Edit
OK, I'm seeing the following as options:
Configure my project to sync settings from an IIS instance. As mentioned, I'm not a fan of this given that it puts settings outside of the project, meaning the environment has to be meticulously configured to build + publish. Plus it drags along other IIS settings I don't want included.
Inject something into the web-publishing-pipeline (WPP) to modify the archive.xml. I've toyed with this in the past and had limited success. One problem is the pipeline isn't exactly co-operative with working directly on the archive.xml file, another problem is some of the more cryptic attributes involved, like MSDeploy.MSDeployProviderOptions which appears to have some Base64 encoded binary? No idea what to put in there.
Find an existing "provider" that can do what I want. I might be out of luck here, the appPoolConfig provider only seems to want to read / write IIS, not, say, an XML file of settings. Does anybody know otherwise?
Write my own "provider" to produce manifest output entries. I'm not sure, is it possible to write a custom provider that writes to a manifest using the name of an existing provider? As in, MyCustomPoolProvider writes appPoolConfig sections into a manifest? This sounds like a potentially painful exercise that may or may not work. Would I still need to figure out the encoding of whatever is going into MSDeploy.MSDeployProviderOptions?
I get the feeling that the fundamental obstacle with Web Deploy for what I'm trying to accomplish, is how strictly it leans on "providers". The pre-existing providers are largely designed for IIS synchronisation, not primary development and publication. It so happens that some of these providers can be relatively easily hooked into via MSBuild, but the majority insist on pulling data from IIS, and that's that.
You are correct in your understanding of the appPoolConfig provider, in that it can only sync between App Pools and can't be provided with the configuration directly. What you could potentially do is keep a copy of the appPool in question in package form (ie. msdeploy -verb:sync -source:appPoolConfig=PoolName -dest:package=apppool.zip) and attempt to hijack the pipeline so that the MSDeploy call adds the application content into the package, leaving the existing content there.
Alternatively, you could always keep the packages separate and deploy them with different calls to MSDeploy.
FYI, MSDeploy.MSDeployProviderOptions is simply an encoded version of the parameters supplied to the provider when it was packaged. For example, -source:dirPath=c:\,ignoreErrors=0x10293847 -dest:package=package.zip would package the ignoreErrors value.

Resources