Home
About
Contact
Monday, March 08, 2010

In the last couple of weeks we (NNUG Bergen) have remotely worked on setting up a user group event together with AltNetBeers with support from QCon London. As of today about 100 people have signed up and will show up at the Glass House on Thursday 18:30. So what have we planned? Well, the QCon speakers: Corey Haines, Udi Dahan, Dan North, Oren Eini (Ayende), Ben Hall, Roy Osherove and Jon Skeet are coming! And if that’s not interesting enough, the AltNetBeers guys are organizing an hour fish-bowl beer-fueled open-space. To get in the proper mood ThoughtWorks will buy us some beers :-) I bet you’re sorry if you’re not in London or heading for QCon now!

Btw. you don’t need to be a QCon attendee to come to this event. You can sign up here. Hope to see you there.

Monday, March 08, 2010 10:43:05 PM (W. Europe Standard Time, UTC+01:00)
Monday, February 15, 2010

In part 1 I explained why I needed a load balancer that was capable of doing smart balancing decisions using more than just IPs and why I decided to use IIS7 and Application Request Routing (ARR). In this part I will give a detailed explanation of how to setup ARR on Windows Server 2008 R2 Web Server Core.

Server Core provide the following benefits over traditional installations according to Microsoft:

  • Reduced maintenance
  • Reduced attack surface
  • Reduced management
  • Less disk space required

I concluded that the above points is quite important for a load balancer, as you don’t want it to spend its resources on anything else than load balancing.

In this guide I will walk you through the steps needed to install Windows Server 2008 Web Server Core. Secondly I will show you how to create the necessary scripts to automate about 99% of the installation and configuration of ARR.

Before we dig deep, here’s a short description of the setup I used for my ARR environment:

Two Web Servers with:

  • 3 websites running both SSL and normal HTTP
  • Each website needed its own IP
  • Each website needed its own SSL certificate

ARR Server:

  • In order to avoid the “clients NAT’ed behind one IP” problem, I needed to configure ARR Server Affinity to UseCookie.
  • As for the Load Balancing Algorithm I used Weighted Round Robin (you should look into the other alternatives that suite your needs)
  • The ARR server is responsible for distributing traffic to two web servers mentioned above

All of the above can of course be changed in the scripts that I’ll be showing later to suite your configuration needs. Below is an illustration of the infrastructure:

image

Installing Windows Server 2008 R2 Web Server Core:

  1. Install Windows Server 2008 R2 Web - Server Core
  2. Set password for admin (when prompted)
  3. Rename server:
    NETDOM renamecomputer %computername% /newname:[nameOfServer]
  4. Restart:
    shutdown /r /t 0
  5. Set static IP:
    netsh interface ipv4 set address "Local Area Connection" static [IP] [Subnet] [Gateway]
  6. Set Primary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP]
  7. Set Secondary DNS server:
    netsh interface ipv4 add dnsserver "Local Area Connection" [IP] index=2
  8. If you want the server to join a domain:
    netdom join %computername% /domain:[domainname] /userd:[username] /passwordd:*
  9. Restart:
    shutdown /r /t 0
  10. If you want to enable Remote Desktop:

    For Vista/Win7/2008 clients:
    cscript %windir%\system32\SCRegEdit.wsf /ar 0

    For earlier clients:
    cscript %windir%\system32\SCRegEdit.wsf /cs 0

    For both new and earlier clients run both of the above
  11. If you want to allow remote MMC management (e.g. to simplify managing users etc):
    netsh advfirewall firewall set rule group="Remote Administration" new enable=yes
  12. Activate Windows:
    start /w slmgr.vbs –ipk [key]
    start /w slmgr.vbs –ato

Now the server is ready for ARR installation and configuration, but since the OS is a server core, creating some scripts to automate this procedure is very helpful. Next I will show you the scripts I created and used, which hopefully will make this task easier for you than for me :-) I’ve made all the files and scripts available in this zip file.

Creating script for installing SSL certificates (do this on some client computer, not the ARR Server):

Note: You can skip this section (except step 1 and 2) if you’re not using SSL.

  1. Create a folder called ARRInstall
  2. In the ARRInstall folder, create a new folder called Utils
  3. Download capicom_dc_sdk.msi and place MSI in the Utils folder
  4. Download winhttpcertcfg.msi and install with default options on a client computer
  5. Browse to C:\Program Files (x86)\Windows Resource Kits\Tools\ and copy winhttpcertcfg.exe into your Utils folder
  6. Create a folder called Certificates in your ARRInstall folder
  7. The above folder must contain all your certificates (both with and without private keys). For my setup this looks like this:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
  8. Copy the script below, read comments in script and modify accordingly. Then save the script as _SetupCertificates.cmd in the ARRInstall folder:
    @echo off
    
    echo Installing CAPICOM...
    
    echo.
    
    msiexec /qn /i "%~dp0Utils\capicom_dc_sdk.msi"
    
    echo Removing existing certificate from store...
    
    REM Example:
    
    REM certutil -delstore Root "blog.torresdal.net"
    
    certutil -delstore Root "[certificate name]"
    
    echo Removing SSL certificate from IIS...
    
    netsh http delete sslcert ipport=0.0.0.0:443
    
    echo Installing certificates...
    
    echo.
    
    REM Example:
    
    REM certutil -f -addstore Root "%~dp0Certificates\blog.torresdal.net.cer"
    
    certutil -f -addstore Root "%~dp0Certificates\[certificate name].cer"
    
    IF EXIST "%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\system32\cscript.exe
    
    )
    
    IF EXIST "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK" (
    
        SET capicompath="%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Samples\vbs\cstore.vbs"
    
        SET cscript=%windir%\syswow64\cscript.exe
    
        ECHO Setting up CAPICOM for 64 bits environment...
    
        copy /y "%PROGRAMFILES(x86)%\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll" %windir%\syswow64
    
        %windir%\syswow64\regsvr32.exe /s %windir%\syswow64\capicom.dll
    
    )
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% delete -l LM -subject "blog.torresdal.net" -noprompt
    
    %cscript% /nologo %capicompath% delete -l LM -subject "[certificate name]" -noprompt
    
    REM Example:
    
    REM %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\blog.torresdal.net.pfx" "somePassword"
    
    %cscript% /nologo %capicompath% import -l LM "%~dp0Certificates\[certificate name].pfx" "[password]"
    
    REM Example:
    
    REM "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s blog.torresdal.net -a "IIS_IUSRS"
    
    "%~dp0Utils\winhttpcertcfg.exe" -g -c LOCAL_MACHINE\My -s [certificate name] -a "IIS_IUSRS"
    
    echo.
    
    echo ============================
    
    echo Certificates Setup finished!
    
    echo ============================
    
    REM pause
    
    :end
  9. Your folder structure should now look like this:
    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |-- Utils
            |-- capicom_dc_sdk.msi
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd

Create script for installing and configuring ARR:

  1. Download the x64 installer for ARR from the ARR website: http://www.iis.net/expand/ApplicationRequestRouting
  2. Copy the downloaded file (ARRv2_setup_x64.EXE) into the Utils folder
  3. Download IIS7Util.exe which I’ve made available for you on my site. (The source code can be found at the foaf-ssl-dotnet project. Just browse code and search for “iis7util”, to make it clear where I got it from :-))
  4. Copy the IIS7Util.exe into the Utils folder
  5. Copy the script below, read comments in script and modify accordingly. Then save the script as InstallARR.cmd in the ARRInstall folder. You should then have this file structure:

    ARRInstall 
      |-- Certificates 
            |-- site1.torresdal.net.cer 
            |-- site1.torresdal.net.pfx 
            |-- site2.torresdal.net.cer 
            |-- site2.torresdal.net.pfx 
            |-- site3.torresdal.net.cer 
            |-- site3.torresdal.net.pfx
      |—Utils
            |-- ARRv2_setup_x64.EXE
            |-- capicom_dc_sdk.msi
            |-- IIS7Util.exe
            |-- winhttpcertcfg.exe
      |-- _SetupCertificates.cmd
      |-- InstallARR.cmd

    Note: If you’re not using SSL, comment out this line in your script:
    call %~dp0_SetupCertificates.cmd

    @echo off
    
    REM =====================
    
    REM 	CONFIGURATION
    
    REM =====================
    
    REM =============================================
    
    REM IP's for the different sites on the LB Server
    
    REM =============================================
    
    SET Site1IPNLB=10.0.0.51
    
    SET Site2IPNLB=10.0.0.52
    
    SET Site3IPNLB=10.0.0.53
    
    REM =============================
    
    REM IP's for back end web servers
    
    REM =============================
    
    SET Site1IPWeb01=10.137.13.61
    
    SET Site2IPWeb01=10.137.13.62
    
    SET Site3IPWeb01=10.137.13.63
    
    SET Site1IPWeb02=10.137.13.71
    
    SET Site2IPWeb02=10.137.13.72
    
    SET Site3IPWeb02=10.137.13.73
    
    REM ==============================
    
    REM Host names for different sites
    
    REM ==============================
    
    SET Site1HostName=site1.torresdal.net
    
    SET Site2HostName=site2.torresdal.net
    
    SET Site3HostName=site3.torresdal.net
    
    REM ==================================
    
    REM Name of Server Farms for each site
    
    REM ==================================
    
    SET ARRServerFarm1=Site1
    
    SET ARRServerFarm2=Site2
    
    SET ARRServerFarm3=Site3
    
    REM ============================
    
    REM File locations for web sites
    
    REM ============================
    
    SET Site1FileLoc=C:\%ARRServerFarm1%
    
    SET Site2FileLoc=C:\%ARRServerFarm2%
    
    SET Site3FileLoc=C:\%ARRServerFarm3%
    
    REM ==========
    
    REM AppCmd.exe
    
    REM ==========
    
    SET AppCMD=%windir%\system32\inetsrv\appcmd.exe
    
    REM =========================
    
    REM	INSTALLATION
    
    REM =========================
    
    Echo Installing IIS...
    
    start /w pkgmgr /l:log.etw /iu:IIS-WebServerRole;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI;NetFx2-ServerCore;NetFx2-ServerCore-WOW64;IIS-ManagementService
    
    Echo Enabling remote management of IIS...
    
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WebManagement\Server /v EnableRemoteManagement /t REG_DWORD /d 1 /f
    
    sc config WMSVC start= auto
    
    Echo Installing Application Request Routing (ARR)...
    
    net stop was /y
    
    net stop wmsvc /y
    
    "%~dp0utils\ARRv2_setup_x64.EXE" /Q
    
    net start was
    
    net start wmsvc
    
    Echo Disable Idle Timeout on Application Pool...
    
    %AppCMD% set apppool "DefaultAppPool" -processModel.idleTimeout:"00:00:00" /commit:apphost
    
    %AppCMD% set config -section:system.applicationHost/applicationPools /[name='DefaultAppPool'].recycling.periodicRestart.time:"00:00:00" /commit:apphost
    
    Echo Installing certificates...
    
    call %~dp0_SetupCertificates.cmd
    
    Echo Adding aditional IPs for web sites...
    
    netsh interface ipv4 add address "Local Area Connection" %Site1IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site2IPNLB% 255.255.255.0
    
    netsh interface ipv4 add address "Local Area Connection" %Site3IPNLB% 255.255.255.0
    
    Echo Creating folders for web sites...
    
    md %Site1FileLoc%
    
    md %Site2FileLoc%
    
    md %Site3FileLoc%
    
    Echo Creating web sites in IIS...
    
    %AppCMD% add site /name:%site1HostName% /bindings:"http/%Site1IPNLB%:80:,https/%Site1IPNLB%:443:" /physicalPath:"%Site1FileLoc%"
    
    %AppCMD% add site /name:%site2HostName% /bindings:"http/%Site2IPNLB%:80:,https/%Site2IPNLB%:443:" /physicalPath:"%Site2FileLoc%"
    
    %AppCMD% add site /name:%site3HostName% /bindings:"http/%Site3IPNLB%:80:,https/%Site3IPNLB%:443:" /physicalPath:"%Site3FileLoc%"
    
    Echo Adding farms and servers to ARR...
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm1%'].[address='%Site1IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm2%'].[address='%Site2IPWeb02%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb01%']" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /+"[name='%ARRServerFarm3%'].[address='%Site3IPWeb02%']" /commit:apphost
    
    REM ==============================================================================
    
    REM ALERT!: REMEMBER THAT SSL RULES FOR EACH SITE MUST BE BEFORE THE HTTP RULES!!!
    
    REM 	    E.g. 1) Rules for Site1 SSL
    
    REM              2) Rules for Site1 HTTP
    
    REM		 3) Rules for Site2 SSL
    
    REM		 4) Rules for Site2 HTTP
    
    REM		 5) etc.
    
    REM
    
    REM	    If we had switched 1 and 2, it would match on HTTP first, and would
    
    REM	    have redirected to a non SSL site, resulting in SSL offloading.
    
    REM
    
    REM	    If SSL offloading is the wanted behaviour, only the HTTP rule is 
    
    REM	    nessesary.
    
    REM ==============================================================================
    
    echo Adding rewriting rules to ARR...
    
    %AppCMD% clear config -section:system.webServer/rewrite/globalRules
    
    REM Site1 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site1 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site1HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm1%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm1%/{R:0}" /commit:apphost
    
    REM Site2 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site2 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site2HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm2%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm2%/{R:0}" /commit:apphost
    
    REM Site3 SSL
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTPS}',pattern='on']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%_SSL',patternSyntax='Wildcard',stopProcessing='True'].action.url:"https://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM Site3 HTTP
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%', patternSyntax='Wildcard',stopProcessing='True']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].match.url:"*"  /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /+"[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].conditions.[input='{HTTP_HOST}',pattern='*%Site3HostName%*']" /commit:apphost
    
    %AppCMD% set config  -section:system.webServer/rewrite/globalRules /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.type:"Rewrite" /[name='%ARRServerFarm3%',patternSyntax='Wildcard',stopProcessing='True'].action.url:"http://%ARRServerFarm3%/{R:0}" /commit:apphost
    
    REM ===============
    
    REM Server Affinity
    
    REM ===============
    
    Echo Adding Server Affinity...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.affinity.useCookie:"True"  /commit:apphost
    
    REM ========================
    
    REM Load Balancing Algorithm
    
    REM ========================
    
    Echo Adding Load Balancing Algorithm...
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm1%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm2%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost
    
    %AppCMD% set config  -section:webFarms /[name='%ARRServerFarm3%'].applicationRequestRouting.loadBalancing.algorithm:"WeightedRoundRobin" /commit:apphost

Installing Application Request Routing:

  1. From the ARR server connect to your client containing the script files:
    net use [some drive letter]: \\clientComputerName\[drive on client]$ /user:domain\user
    Example:
    net use r: \\myClient\c$ /user:torresdal\jon
  2. Make a directory on the server to copy the files to:
    E.g.: md c:\temp\arr
  3. Copy the ARRInstall folder from your client to C:\temp\arr on your server
  4. Run InstallARR.bat, watch for errors and wait for it to finish
  5. Install Remote IIS Manger on a PC that will administrate IIS and connect to the ARR server: http://www.iis.net/expand/IISManager
  6. In Internet Information Services Manager connected to ARR do:
    1. Select Sites->Site1
    2. Click Bindings (upper right corner)
    3. Click https –> Edit
    4. Select proper certificate
    5. Repeat for all other sites
  7. Under Sites:
    1. For each site that require SSL:
      1. Click SSL Settings
      2. Check Require SSL
  8. Start IIS on ARR server:
    iisreset /start
  9. Using Internet Information Services Manager:
    Stop “Default Web Site”
  10. You’re done!

I hope this helped in making the installation and configuration of the ARR server easier, and that my scenario is applicable to others except me :-) Let me know if I can help with questions or if you find any errors.

Next time I will talk about how to avoid the ARR server being the Single Point of Failure.

Monday, February 15, 2010 8:00:00 AM (W. Europe Standard Time, UTC+01:00)
Wednesday, February 10, 2010

image A few weeks back I had to solve a performance problem at work. For some of our applications most of our users are NAT’ed behind the same IP, making the default load balancer (NLB) in Windows direct the majority of all traffic to one server. NLB in Windows work on layer 3 (network layer) in the OSI model (that thing you learned at uni), meaning we can only take advantage of IP stuff. So usually you use what’s often called Sticky Sessions (Single Affinity) to keep track of which IP’s got redirected to which server, and keep doing that from that point on for that IP. This was the setup we had.

You can work around that problem by disabling Sticky Sessions, but it might influence performance and could give you unwanted consequences. As an example, if you use ASP.NET Web Forms you will probably run into an issue with ViewState and possibly session issues. For SSL however (which was the case for us), Sticky Session is not recommended.

Other “smarter” load balancers work on layer 7 (application layer), providing us with a much bigger toolbox to inspect traffic and make smarter choices for where to redirect traffic. So I started to look for a load balancer on layer 7. The obvious first choice was hardware LB. This is often the quickest solution, but also the most expensive. I looked at Cisco’s Application Control Engine Module (ACE) and F5 BigIP, but the price was and issue as well as the lack of people with know-how inside our organization of how to configure them.

My next option was setting up a Linux server running Apache and LB, but then I came across a Microsoft module on IIS7: Application Request Routing (ARR). I found some really good documentation and it looked quite easy to set up. Since I (and others in my organization) are used to working with IIS, this seamed to be worth investigating.

In my next post I’ll go trough all the details of setting up ARR on Windows 2008 R2 Server Core. Everything from installing and configuring the OS to automate installation of ARR by scripts.

Wednesday, February 10, 2010 7:00:00 AM (W. Europe Standard Time, UTC+01:00)
Tuesday, February 09, 2010

image I’m happy to say I was invited by Microsoft to join their MSDN Live tour in Norway this spring. I’ll be talking about Windows Identity Foundation (WIF) (used to be Geneva) which I find to be at great help simplifying authentication and authorization in small shops as well as in the enterprise.

I’ll be showing how you can take advantage of Claims (link is a PDF) in your applications today and why that is a good idea, how to easily integrate with Active Directory using Active Directory Federation Services (ADFS), how to create a custom Security Token Service (STS) and cover parts of the tiny topic of: how to do Federation in the enterprise :-)

Remember that the concepts around WIF, like Claims and STS, is nothing new and is not something that Microsoft has invented. It’s been around for many years and are supported on many platforms as well as programming languages.

Personally I’m quite excited about this new framework, cause it particularly helps us at Frende solve some pain points we’ve had to tackle around authentication with a lot of different sign-on methods and applications, and ease the use of SSO. We can now delete a lot of code, since WIF takes care of a lot of the plumbing we previously had to do ourselves. Less code to maintain is always good!

For more information about the agenda, have a look at Rune Grothaug’s blog: http://blogs.msdn.com/grothaug/pages/msdn-live-april-2010-en-fest-for-utviklere.aspx

I expect the official MSDN Live and TechNet site to be updated with the spring agenda very soon: http://www.microsoft.no/live/

The cities and dates are:

Stavanger: 16th of April
Trondheim: 20th of April
Bergen: 23rd of April
Oslo: 26th of April

Tuesday, February 09, 2010 10:02:26 AM (W. Europe Standard Time, UTC+01:00)
Tuesday, January 19, 2010

I finally got a setup at work which I’m really satisfied with. The short version:

  • 3 24-inch monitors (HP LA2405wg with two Display Ports)
  • Desktop computer (HP Z600) 2.26gHz with 6 GB RAM running Windows 7 x64 - using 2 of 3 screens
  • Laptop (nothing exciting - HP Compaq 6910p with Win 7 x64 – for mobility) – using the 3rd screen
  • Synergy to share a single mouse and keyboard between desktop computer and laptop

3MonitorySetup
(the two screens on the left is the desktop computer, the one on the right is the laptop. Couldn’t take a picture further away because I have a wall just behind me :-) )

What’s really nice about this setup is that I don’t really notice I have two computers running, because of the way Synergy “abstract” the other computer away.

Setting up Synergy (the long version)

  1. Install Synergy on both computers
  2. Setup the computer that’s connected to the mouse/keyboard as “server”
    1. Select “Share this computer’s keyboard and mouse (server)”
    2. Click Configure…
    3. Under Screens click + to add a new screen (actually it’s a computer you’re adding and not a screen)
    4. Set the Screen Name to the name of your computer (yes, it has to be the hostname of your computer in order for Synergy to communicate with other clients) and click OK
    5. Do the same for the other computers (the clients)
    6. Under links you set how the screens are in relation to each other (based on my screen setup above):
      1. Highlight your “server” under Screens
      2. Under Links ([New Link]) enter:
        0 to 100 % of the left of YOUR_CLIENT goes to 0 to 100 % of YOUR_SERVER
      3. Click +
      4. 0 to 100 % of the right of YOUR_SERVER goes to 0 to 100 % of YOUR_CLIENT
      5. Note: Synergy does not implicitly understand that if server is left of client, the client is right of server, so you need to define that explicitly, hence #4
      6. Click OK
      7. Click Start (consider setting up AutoStart)

        On my server it looks like this: 
        image
  3. Setup the client
    1. On the client computer select “Use another computer’s shared keyboard and mouse (client)
    2. Enter the name of YOUR_SERVER
    3. Click Start (consider setting up AutoStart)
  4. That’s it. Test by moving your mouse from the left most monitor to the right most monitor! Cool!
Tools | Work
Tuesday, January 19, 2010 9:54:57 PM (W. Europe Standard Time, UTC+01:00)

It so happens that I’m from Norway. Codinghorror (Jeff Atwood) just tweeted a great video quite accurately describing Norwegians (hilarious):

Tuesday, January 19, 2010 12:08:51 AM (W. Europe Standard Time, UTC+01:00)
Monday, January 18, 2010

Though I don’t use WiX anymore, I do still follow the project. You may ask yourself why I don’t use it anymore since I created a series of WiX articles and apparently spent a lot of time with it? The answer is simple: I switched jobs about a year ago and MSI’s are overkill for deploying our current solutions (all web) to the web servers.

Back to the topic though. A few days ago Scott Hanselman published an interview with Rob Mensching (creator of WiX) that should be interesting to you if you’re using or planning to use MSI’s. One thing that was new to me though is that Rob actually created Orca as an intern at MS in 98! If you don’t know/use Orca you should really check it out (even though Rob says nobody uses it anymore :-)). It’s a great small tool that lets you peek inside and change the internal MSI database. Really helpful to find out what’s going on inside an MSI.

WiX
Monday, January 18, 2010 11:26:15 PM (W. Europe Standard Time, UTC+01:00)
Thursday, January 14, 2010

logo_qcon Going to QCon London? I am and a bunch of my friends are too! Just a heads up that the early bird is about to expire this Friday.

If you haven’t been to QCon before, I can really recommend it. What I find especially attractive by this conference is its various tracks that should satisfy the most demanding devs and architects, and of course not to mention the speaker list (which is still growing). Here’s a few selected speakers from my point of view:

  • Dan North
  • Floyd Marinescu
  • Jim O. Coplien
  • Joe Armstrong
  • Jon Skeet
  • Kevlin Henney
  • Michael T. Nygard
  • Ola Bini
  • Ayende (Oren Eini)
  • Rod Johnsen
  • Ryan Slobojan
  • Stefan Tilkov
  • Steve Freeman
  • Udi Dahan
  • Ulf Wiger

And here’s the tracks:

  • Architectures You've Always Wondered About
  • Dev and Ops: A single team
  • Functional programming
  • Non-Relational DBs & Web Oriented Data
  • Software Craftsmanship
  • Solution Track: Wednesday
  • 2015 Software Development
  • Agile Evolution
  • AlphaGeeks on .NET
  • Cloud Solutions
  • Irresponsible Architectures and Unusual Architects
  • Solutions Track: Performance and ScalabilityBrowser as a Platform
  • Cool Stuff with Java
  • How do you test that?
  • SOA 2010
  • The Concurrency Challenge

Hope to see you in London March 10-12 (March 8-9 for tutorials).

Thursday, January 14, 2010 8:13:05 PM (W. Europe Standard Time, UTC+01:00)
Wednesday, December 09, 2009

I just published an interview with Jeffrey Palermo, Ben Scheirman and Jimmi Bogard about their ASP.NET MVC in Action book. You’ll find chapter three (the controller) and the interview over at InfoQ: http://www.infoq.com/articles/aspnet-mvc-in-action

Also, you’ll find a 35% discount code in there for the book.

Wednesday, December 09, 2009 2:51:10 PM (W. Europe Standard Time, UTC+01:00)
RSS RSS - Comments Twitter LinkedIn
         
SEARCH
 
 
         
TOP POSTS
   
         
NAVIGATION
   
         
CATEGORIES
  .Net (57) Agile (29) Ajax (5) Architecture (17) Articles (1) ASP.NET (3) ASP.NET-MVC (1) Blogging (12) Books (2) BPEL (1) CleanCode (1) CloudComputing (7) Community (2) CSharp (11) DasBlog (5) Database (2) DDD (5) Deployment (14) DSL (1) Events (37) ExtremeProgramming (6) Fun (6) Gadgets (4) IIS (8) InfoQ (4) Java (2) Lean (2) Linq (2) MemoryLeaks (5) Microsoft (37) MVC (1) NDC (2) NNUG (35) Other (10) Patterns (9) Performance (3) Scrum (17) Security (3) Silverlight (4) Software (19) TeamManagement (11) TechEd (7) Testing (4) Tools (23) TvGuide (1) Vista (15) VisualStudio (16) WCF (7) Web (15) Windows (10) WiX (9) Work (16) Workflow (3)  
         
ARCHIVE
   
         
BLOGROLL
   
         
ON THIS PAGE...
 
NNUG Bergen and AltNetBeers User Group Event at QCon London
Using IIS7 And Application Request Routing as Load Balancer – Part 2
Using IIS7 And Application Request Routing as Load Balancer – Part 1
Presenting Windows Identity Foundation At MSDN Live In April
3 Monitor Setup With Two Computers And One Keyboard
Norway
Interview With WiX Guru Rob Mensching
QCon London Early Bird About To Expire
ASP.NET MVC in Action