Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

  1. Nolan feat. Amber Jolene – Everyday & Everynight (KANT Remix)
  2. Todd Terje – Inspector Norse
  3. Kyodai Feat. Stee Downes – Music Rises Up (Claptone Remix)
  4. Miami Horror – Ultraviolet
  5. Miami Horror – Illuminated
Audioscrobbler/Last.fm

ClustrMap

General Considerations For Securing Windows Servers On The Internet (And Anywhere Else)

Posted in IIS | Networking | PowerShell | Security | SQL Server | Windows at Friday, February 08, 2008 5:04 PM W. Europe Standard Time

By now there are a couple of Windows Servers that I actively manage, or, in the case of projects, I touched while moving the project forward. Most of these servers have an Internet connection. Since I've been asked how to make servers more secure and manageable, here are a couple of management rules I applied. Consider it a checklist.

  • Use a firewall and configure it accordingly.
  • Enable automatic Windows Updates and upgrade to Microsoft Update to receive updates of other Microsoft products like SQL Server.

Okay, the two above should have been obvious.

  • Keep the machine clean.
    Don't install any unnecessary software and don't leave any temporary files on the server. I've seen certificate requests lingering on drive C: and "test" folder remnants. A clean system might reveal hacker activity early in case they leave unfamiliar files behind.
  • Leverage the principle of least privilege.
    All users and service accounts should only have the minimum rights they need. Configure the file system such that system services can only access the files and folders they are in charge of. Typical example: Use a dedicated service account for SQL Server. (Setting this up on SQL 2005 is even more simple.)
  • Rename the Administrator account.
    Rename the Administrator account and make it match your preferred user naming scheme (i. e. agross). You might apply this to your whole organization if you use Active Directory. This is another hurdle to guess the Administrator account from a list of user accounts and works good with account lockout enabled (see below).
  • Create a new "Administrator" account
    and give it a very strong throw-away password. I typically use two or three concatenated GUIDs that I immediately forget. Disallow this user to change his password, remove all group memberships and disable the account.
  • Audit the hell out of the machine.
    Windows uses the Security event log to record security-related events. Configure auditing using secpol.msc and enable success and failure logging at least for
    • Account logon events,
    • Logon events and
    • Policy change.
    The last option is for tracking changes to the policy you just set.
  • Enable complexity criteria for passwords and account lockout.
    To be found in the same MMC snap-in as above. For account lockout I often go with the default values of 5 attempts and 30 minutes of threshold and duration.
  • Deactivate file sharing/Microsoft Networking on the WAN connection.
    Because it's most likely unneeded.
  • Secure RDP sessions using a certificate.
    Torsten has a nice write-up on how to leverage SSL to secure the RDP handshaking/authentication phase to overcome man-in-the-middle and ARP spoofing attacks. His article is available in German only so here's two-sentence recap: On the server's RDP security tab, enable SSL and choose the same certificate you use for HTTPS encryption. On the client side, enable server authentication.
  • Extra: Allow RDP sessions only from white-listed workstations.
    For a server that was hacked a while ago using an ARP spoofing attack (see bullet above) I wrote a Powershell script forces RDP session to originate from a list of known workstations. Each RDP user can have multiple allowed workstations. If a logon attempt occurs from another machine that RDP session is killed immediately.
    #
    # Alert.ps1
    #
    # Logon script for users with known RDP client names.
    #
    
    # Array of users with known workstations.
    $userWorkstations = @{
    	"user1" = @("VALIDCOMPUTERNAME1", "VALIDCOMPUTERNAME2")
    	"user2" = @("VALIDCOMPUTERNAME3")
    	}
    
    # Logoff executable.
    $logoffCommand = $Env:SystemRoot + "\system32\logoff.exe"
    
    # Trim the user name.
    $currentUser = $Env:UserName.Trim()
    
    # Cancel if a user that's not contained in $userWorkstations logs on.
    if ($userWorkstations.Keys -inotcontains $currentUser)
    {
    	return
    }
    
    # Send alert e-mail and log off if the user logs on from an unknown workstation.
    if ($userWorkstations[$currentUser] -inotcontains $Env:ClientName.Trim())
    {
    	$subject = $("Unknown RDP client '{0}' for user '{1}'" -f $Env:ClientName.Trim(), $currentUser)
    
    	$message = New-Object System.Net.Mail.MailMessage
    	$message.From = "alerts@example.com"
    	$message.To.Add("admin1@example.com")
    	$message.To.Add("admin2@example.com")
    
    	$message.IsBodyHtml = $false
    	$message.Priority = [System.Net.Mail.MailPriority]::High
    	$message.Subject = $subject
    	$message.Body = $subject
    
    	$smtp = New-Object System.Net.Mail.SmtpClient
    	$smtp.Host = "localhost"
    	$smtp.Send($message)
    
    	# Force logoff.
    	&$logoffCommand
    }
    Set the script as a logon script for your users using the Alert.cmd helper script below.
    rem Alert.cmd - runs the Alert.ps1 Powershell script.
    @powershell.exe -noprofile -command .\Alert.ps1
  • Enable SQL Server integrated authentication.
    I don't see a need for SQL Server Authentication in most scenarios, especially if you're running/hosting .NET applications. However, in some projects I've worked on there seems to be a tendency towards SQL Server Authentication for no special reason.
  • Configure IIS log detail and directories.
    I tend to enable full IIS logs, that is, all information regarding a request should be logged. Also, I like my logs residing in "speaking" folders, so instead of %windir%\system32\LogFiles\W3SVC<Some number> they should be placed in %windir%\system32\LogFiles\IIS <Site name>\W3SVC<Some number>. This makes it easy to find the logs you're interested in.
  • Use SSH to connect remotely.
    There's a little free SSH server out there that should fit most user's needs. Besides a secure shell environment freeSSHd offers SFTP and port tunneling capabilities to tunnel insecure protocols. Authentication works natively against Windows accounts.
  • Deploy a server monitoring tool.
    I like to use the free MRTG tool, of course any other tool allowing you quickly view any uncommon activity to will do.
  • Use a dedicated management network interface, if possible.
    You should configure strict firewall rules for that interface. Allow access only from a known management subnet.

What rules do you apply to make your servers more secure and manageable?

Now Playing [?]: MorcheebaDive DeepEnjoy the ride (feat. Judy Tzuke)

Reconfiguring Team Foundation Server URLs

Posted in Visual Studio at Wednesday, February 06, 2008 8:15 PM W. Europe Standard Time

Microsoft's solution to integrated software project management, the Team Foundation Server product, offers a lot of services. Beyond Source Control they have a work item tracking, build services and reporting in stock (I suspect there is even more functionality under the hood). You might be tempted to think that such an "all-in-one" solution can become complex to manage pretty soon. Let me tell you, it does! A couple of months ago I set up a Team Foundation Server (beta 2) for a project some friends of mine do for Microsoft (you will hear of it, I promise).

The server was initially installed as a virtual machine on our pretty decent server connected to the DSL line at home. The installation alone took me a week to complete since there was a bug in some XML file that made Visual Studio 2005 misinterpret the file's contents. (I don't remember exactly the source of the problem.) It was quite a hassle to get my first TFS project created.

The project hosted on that server went well, but it became pretty soon obvious that the team needed more resources in respect to bandwidth and virtual machines for testing the application they build. That's something we could not handle with our 640 kbit/s upload bandwidth and 1,5 GBs of RAM in the server. We moved the TFS virtual machine to another physical machine (more RAM) and hooked it up to the University network (lots of free bandwidth).

After moving the server we found that new projects could not be created due to one misconfigured Team System service URL, i. e. that service could be accessed on the home network (think http://tfs/) but not over the Internet. Specifically it was the URL to the SharePoint Central Administration Web Site, but that doesn't actually matter. I checked TFS' Registration Service to see if the corrected URL has been applied. The Registration Service URL looks like this:

http://<TFS Server>:<Port>/Services/v1.0/Registration.asmx

Registration Service

The WssAdminService has a publicy known URL. Good to go! I tried creating a new project, but received that same error as before.

Project Creation Failed

The error message above is a bit misleading because the Team Foundation Client did not try to connect to tfs.therightstuff.de, but rather to the (old) tfs server, as Fiddler revealed.

Team Foundation Client Connects To The Wrong URL

Looking through the other HTTP requests originating from Visual Studio's Team Foundation Client I found that the Registration Service has never been queried to get the updated service URLs. On Buck Hodges' blog I found a hint:

When a client app, such as tf.exe, VS, or your own custom application, needs to use version control, the TF client code must request the service definition from registration service on the server.  To avoid constantly requesting service registration information that rarely changes, the client-side registration code maintains a cache and only makes the server call when the cache is out of date.

Whatever it means that the client re-requests that piece of information when it's out of date. On my machine the Team Foundation cache mentioned above is located at the folder

C:\Users\<User name>\AppData\Local\Microsoft\Team Foundation\2.0\Cache\

I wiped the cache folder and, just to make sure, I also deleted the TFS server registration in Visual Studio.

After re-adding the TFS server in Visual Studio I can now create new Team Foundation projects. Wow!

Now Playing [?]: The Cinematic OrchestraHorizonOregon