AWS Elastic Beanstalk ebextensions: Update the IIS App Pool using commands to another App Pool Identity

So I had a .Net application that needed to leverage the Network Service application identity instead of the OOB ApplicationPoolIdentity that comes with a default shipped EBS windows server with IIS. The solution? An ebextenion of course!

0) We’re going to have a step 0 assuming you already have a development AWS account with credits to push servers to Elastic Beanstalk. If you have not do this part then do some reading here: https://aws.amazon.com/elasticbeanstalk/

1) Once you have an account and have configured your Visual Studio environment to your account appropriately then proceed to open your VS solution.

2) Create a folder in your solution called .ebextensions

3) Create your config file (if you don’t have an editor Notepad++ will do) within that folder and edit it in YAML format

The following example below will update the DefaultAppPool app identity to Network Service leveraging powershell and the commands/command features:

files:
  "C:\\Robo\\Update_App_Pool.ps1":
    content: |
      Write-Verbose 'Update the application pool'
      Set-Location C:\\Robo
      import-module WebAdministration
      Set-ItemProperty IIS:\AppPools\DefaultAppPool -name processModel.identityType -value 2
  
commands:
  update_app_pool: 
    command: powershell.exe -ExecutionPolicy Bypass -File "C:\\Robo\\Update_App_Pool.ps1"
    ignoreErrors: False
    waitAfterCompletion: 0	

4) Save the Deploy this with your application into EBS you should see the updated app pool identity as the application is deployed.

Hope this helps. Questions are welcome!

If you want to venture deeper into this then start here: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers.html

Validate here: http://www.yamllint.com/

Dealing with SSLv3 Padding Oracle On Downgraded Legacy Encryption Vulnerability (POODLE)

A lot of you may be getting emails from your sys admins telling you about needing to protect yourself from the POODLE vulnerability. I wanted to post my response back to what I did to bring my servers into compliance.

I used a tool called IISCrypto to place the server in best practice template from the command line. You can do it to be in PCI, PCI31 or FIPS140 compliance as well.

Here’s what I ran for what got fixed:

ss1

They also offer a GUI that you can run to see exactly what’s being used. Here’s the box after I applied the command ran above to confirm the removal of PCT 1.0 & SSL 2.0/3.0:ss2

My recommendation would be to deploy the command line version of the tool and execute the best practice template, let it apply the best practice template and restart the box.

However, if you don’t prefer a 3rd party tool then you can follow the Microsoft suggested actions to update the registry entries and build a .reg script to run.

Hope this helps.

Need To Clean Your IIS Log Files (Older Than x Number of Days) For All Sites? Here’s a Script

You may have the classic issue of needing logs cleared but you do not have time to log onto each server and delete files for space. Here’s a script that will do it for all IIS sites and will let you select how many days back you wish to keep. For this example this script is wrote for 30 days and would be run on a task scheduler monthly.

  • Open notepad and create a file called IISLogMonthlyCleanup.vbs
  • Put in the following snippet and adjust your settings to apply to what you need:
sLogFolder = "c:\inetpub\logs\LogFiles"
iMaxAge = 30 ' # of days
Set objFSO = CreateObject("Scripting.FileSystemObject")
set colFolder = objFSO.GetFolder(sLogFolder)
For Each colSubfolder in colFolder.SubFolders
 Set objFolder = objFSO.GetFolder(colSubfolder.Path)
 Set colFiles = objFolder.Files
 For Each objFile in colFiles
 iFileAge = now-objFile.DateCreated
 if iFileAge > (iMaxAge+1) then
 objFSO.deletefile objFile, True
 end if
 Next
Next

Save and run. *Poof* the old logs are gone. Set it up in a task scheduler and move on to more important things.

TIP: You can run the scheduled task as SYSTEM since it has privileges to run whether logged on or not. It also has access to the file system.

Hope this helps.

Resolving CRM XRMServices System.ServiceModel.ServiceActivationException Issues With Multiple IIS Site Bindings

So if you ever attempt to go from http to https (or vice versa) on your CRM environment be aware that you may face the following issue with your XRM Services if you have multiple bindings set in IIS:

WebHost failed to process a request.
 Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/12547953
 Exception: System.ServiceModel.ServiceActivationException: The service '/Dev/XRMServices/2011/Organization.svc' cannot be activated due to an exception during compilation. The exception message is: The value could not be added to the collection, as the collection already contains an item of the same type: 'System.ServiceModel.Description.UseRequestHeadersForMetadataAddressBehavior'. This collection only supports one instance of each type.
Parameter name: item. ---> System.ArgumentException: The value could not be added to the collection, as the collection already contains an item of the same type: 'System.ServiceModel.Description.UseRequestHeadersForMetadataAddressBehavior'. This collection only supports one instance of each type.
Parameter name: item
 at System.Collections.Generic.KeyedByTypeCollection`1.InsertItem(Int32 index, TItem item)
 at Microsoft.Crm.Extensibility.SdkServiceEndpointBuilder.AddDefaultPorts(ServiceHost serviceHost, PortSchemeDictionary portSchemes)
 at Microsoft.Crm.Extensibility.SdkServiceEndpointBuilder.AddDefaultEndpoint(ServiceHost serviceHost, Type implementedContract)
 at Microsoft.Crm.Extensibility.SdkServiceEndpointBuilder.BuildEndpoints(ServiceHost serviceHost, Type implementedContract, Func`1 messageInspectorFactory)
 at Microsoft.Crm.Extensibility.SdkServiceHost.InitializeRuntime()
 at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity)
 at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)
 --- End of inner exception stack trace ---
 at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)
 at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath, EventTraceActivity eventTraceActivity)
 Process Name: w3wp
 Process ID: 8388

Why you ask?! This is due to the fact that CRM is quite finicky about only wanting one particular binding for the CRM instance. Having the multiple bindings without properly setting it up will cause some conflicts (starting with the one above). So the solution here is to ensure you only have one binding in IIS. Once you have your bindings set up properly be sure to perform an IISRESET on the web server. This should resolve the error and make the XRMServices play nice. If it does not check to make sure you do not have any hard-coded values of URLs or ports anywhere. Hope this helps.

Redirect All HTTP Requests To HTTPS With IIS URL Rewrite

Make sure you obtain the appropriate version of URL Rewrite for your version of IIS.

Once you have the URL Rewrite module installed then create a new blank inbound rule and give it a name (mine is Redirect to HTTPS).

Once you have the rule created select to match the pattern with regular expressions using .* as the pattern:

Capture1

For your conditions, add a condition with the input as {HTTPS} matching the pattern of OFF:

Capture2

For the action select Redirect and set your Redirect URL to https://{HTTP_HOST}/{R:0}. Select to append query string and indicate the Redirect type is a Permanent (301):

Capture3

Once this is completed (and assuming you have configured your sites for SSL) then you can test it by browsing any page or directory on your site with HTTP and watch it change to HTTPS. Easy enough, right? Hope this helps.