Monday, December 28, 2009

Secure file system access for Windows 2008 Servers

With VPS technology becoming main stream quite a few companies are switching from shared hosting solutions to (cheap) VPS server solutions, mostly Windows based.

Security
As a web developer I need secure access to these systems. FTP is about as insecure as an unencrypted USB stick left behind in public transport. FTP is not an option.

WebDAV
I’ve given WebDAV (over SSL) a try. It works but I’m not quite happy with it. WebDAV on IIS is subject to the same rules as all other IIS applications. Meaning that it won’t allow me to update the Views folder of an MVC application because there is a web.config there that won’t give me access to that folder.
The alternative would be to install Apache for WebDAV. I’ve configured this for a customer that uses WebDAV to access shared subversion repositories. Once this is up and running it is very solid.
Installing apache however just to get secure filesystem access seems like overkill to me.
The nice thing about WebDAV is that Windows can connect to a WebDAV server directly and allows me to drag&drop files directly in explorer.

SSH
Ideally, I’d like to use SSH which I also use to access Unix based servers. I’ve looked into this a couple of years ago and found only half-baked or very expansive solutions. Recently I’ve come across freeSSHd.

It’s a near perfect solution. The only issue is that the configuration tool tries to interact with the service which is not allowed by default on Windows 2008. The work around is to stop the service, do the configuration and restart the service.

To connect to the SSH server I use WinSCP which allows me to drag & drop files onto the server.

FreeSSH installation on Windows 2008

  • Download and run the installer
  • During installation, make sure you select freeSSH to run as a service
  • Open up the computer management console and stop the freeSSH service.
  • Open the freeSSH admin console through the start menu. After starting it adds an icon to the system tray. Click that to open up the console.
  • On the Authentication tab:
    - Require password login
    - I don’t use public key login so disable public key
  • On the SFTP tab:
    Set the base folder to your web root
  • On the Users tab:
    Add users. I prefer to use Windows accounts and grant only SFTP access.
  • On the Host restrictions tab:
    Enable only administrative IP’s but you really should have a firewall policy that takes care of this.
  • On the Logging tab:
    Enable logging
  • Finally, make sure your firewall allows access to the SSH port (22 by default). As mentioned earlier it’s best to only allow access to this port for your own IP addresses.
submit to reddit

Tuesday, December 22, 2009

Git tips : Zipping all changed files

I’ve been using git (and msysgit on my dev system) for the most part of this year. So far it’s worked great, allowing me to work on multiple branches and on multiple locations. The command-line stuff is a bit annoying though. I just can’t be bothered to remember all those pesky commands and options so I’m just going to blog about all the powerful tricks I come across.

Tip 1: Zipping all changed files
To export changes between commits in Git the following command is very handy:

git diff -–name-only commit1 commit2 | zip ../Changes.zip –@

Commit1 and commit2 can be anything like a branch name, a commit id or a tag.

Using UnxTools or Cygwin this will even work on windows.

For more info check StackOverflow or this post, which gave me the original idea.

submit to reddit

Sunday, December 20, 2009

Castle: PerWebRequestLifeStyle revisited

In my previous post I talked about a problem using Castle project’s Inversion of Control container (MicroKernel and/or Windsor) during application initialization.

Today I’ve finally had a chance to dive into this subject and see if I can come up with a solution.

A workaround
Testing has shown that moving all initialization to the Application’s Init method seems to resolve this issue at runtime. I’ve tried this on my development system and on an Windows 2008/IIS7 server.

UPDATE: This workaround may cause problems because the HttpApplication.Init method is invoked when ever a new application instance is created. 
Since there can be more than one instance of the HttpApplication within an AppDomain the Init method may be invoked more than once and from multiple threads concurrently causing all kinds of nasty problems.

In contrast Application_Start is invoked once for the entire lifetime of the AppDomain in which the application runs so that is the place to do application configuration without worrying about multi-threading issues.

Components using PerWebRequestLifeStyle (PWR for short) will never work from Application_Start because at that point in the ASP.NET application lifecycle modules are not initialized yet. I’ve tried to figure out a way to make the module used by PWR work, but as far as I can tell there isn’t any. Not without breaking compatibility with Medium-trust anyway.

Note that it’s perfectly ok to create the container and register services with it from Application_Start, just don’t try and resolve any components that use the PWR life style.

Also note that this is no solution for testing an application outside of ASP.NET. For that the hybrid solution I’ve described in my previous post is still a valid solution.

submit to reddit

Sunday, July 5, 2009

Castle: PerWebRequestLifeStyle won’t work from Application_Start

Update: Please read the follow up post on this topic.

I’m using the Castle project to implement dependency injection and inversion of control in my web applications.
Castle supports creating objects on a per-request basis which is a big help in keeping the number of objects created per request to a minimum.

I ran into a problem with this however. The PerWebRequestLifeStyle is implemented using an HttpModule to make sure objects are evicted at the end of a request. This works well except when using Castle from the Application_Start method (or the Init method for that matter).

The Application_Start method is invoked before any modules are initialized for the application and therefore any objects registered with Castle to use the PerWebRequestLifestyle cannot be used in Application_Start.

The problem manifests itself by reporting the module is probably not configured:

Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
Add '<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.MicroKernel" />' to the <httpModules> section on your web.config.

Similar problems occur when performing tests outside the web environment because, well, there is no web request obviously.

Workaround
I’ve implemented a workaround by customizing the implementation of the lifestyle manager. This work-around falls back to the TransientLifeStyleManager in case the web context is not available. T
his enables both testing and application startup to use objects managed per web request.

[Serializable] 
public class PerWebRequestLifestyleManager : Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleManager 
{ 
  public PerWebRequestLifestyleManager() 
  { 
    _fallback = new TransientLifestyleManager(); 
  }

  public override object Resolve( CreationContext context ) 
  { 
    HttpContext current = HttpContext.Current;
    if ( null == current || current.ApplicationInstance == null )    
    {
      // fall back to transient behaviour if not in web context 
      return _fallback.Resolve( context ); 
    } 
    else 
    { 
      return base.Resolve( context ); 
    } 
  }

  public override void Dispose() 
  { 
    _fallback.Dispose(); 
    base.Dispose(); 
  }   
  
  public override void Init( IComponentActivator componentActivator, IKernel kernel, Castle.Core.ComponentModel model ) 
  { 
    base.Init( componentActivator, kernel, model ); 
    _fallback.Init( componentActivator, kernel, model ); 
  }   
  
  private TransientLifestyleManager _fallback; 
}

To make sure Castle uses this custom implementation I’m using a custom AttributeFacility:

internal class AttributeFacility : AbstractFacility
{
   protected override void Init()
   {
      Kernel.ComponentModelCreated += kernel_ComponentModelCreated;
   }

   void kernel_ComponentModelCreated( ComponentModel model )
   {
      var attributes = model.Implementation.GetCustomAttributes( typeof( Castle.Core.LifestyleAttribute ), false );
      if ( attributes.Length > 0 )
      {
         var attr = attributes[ 0 ] as LifestyleAttribute;
         if ( null != attr )
         {
            switch ( attr.Lifestyle )
            {
               case LifestyleType.PerWebRequest:
                  model.CustomLifestyle = typeof( Alanta.Services.PerWebRequestLifestyleManager );
                  model.LifestyleType = LifestyleType.Custom;
                  break;
               default:
                  break;
            }
         }
      }
   }    
}

I usually hook up the facility from code, like this:

var container = new WindsorContainer();
container.AddFacility<AttributeFacility>();

Update : this solution does not work on IIS7 in integrated pipeline mode. In this mode both HttpContext.Current and HttpContext.Current.ApplicationInstance are set so the detection method in the code above does not work.
I haven’t found a clean solution for this yet; I’ve had to resort to setting a flag in Application_Start that controls the behavior of the PerWebRequestLifestyleManager. Check out the demo code to see how this works.

Update : There is a discussion on this subject at the Castle Project Users group.

Update : Download the source code for this solution. The zip contains an ASP.NET MVC 1 demo application (VS 2008). The code in this

submit to reddit