How to Setup Kerberos SPNs for SharePoint


This is a fairly short post about how to setup kerberos for SharePoint 2007 and 2010 written because it is a subject that frequently continues to baffle SharePoint consultants.

Why

Kerberos authentication has been available since SharePoint 2003 yet most people are still using NTLM authentication. Why? NTLM is ancient and we all know that it works out of the box where Kerberos comes with a huge number of knowledge base articles and instruction to create Service Principal Names (SPNs) in your AD.

The reason for making the effort is that it enables you to solve the old double hop issue.

Ehh? When you are authenticated on a SharePoint server the server side code runs in “your name” with the privileges of your account. If however that server side code calls a second system, e.g. a web service, that second (the double hop) call is not authenticated and run with anonymous privileges. This is a limitation (or a security feature in your AD).

Now there are a number of ways around this problem, hardcoding some credentials in the server side, escalating privileges in the code, messing with the host file, etc. but the only good way is to use Kerberos.

Now when does this apply to SharePoint, where does it benefit from Kerberos? Then non-complete list is (additional suggestions welcome in the comments)

  • RSS viewer webpart
  • Page viewer webpart
  • Mail, calendar and task webparts (often used in MySites)
  • Excel services
  • Forms services
  • (and your custom code)

How to setup Kerberos

Now this is very far from a complete guide on Kerberos as it’s by far too long and too complicated for most people to read it. I’ll describe the simple bits needed to make SharePoint spin with Kerberos.

SharePoint setup

When you create a new web application you get the choice of using NTLM or Kerberos authentication. After creation you can always go into the authentication provider settings within the Central Administration and change it. Note: That a faulty Kerberos setup is virtually the same as bare NTLM 😉

SPN setup

The hardest part is to setup Service Principal Names in your AD to enable SharePoint to use Kerberos properly. Basically a SPN is an entry into the AD allowing a specific service account for a service (e.g. HTTP) to re-authenticate a user.

The trick is of course what exactly should go into these SPNs and how many you need. The answer is:

  • One for each URL you are serving
  • One for each combination of server and app pool service account (if you are like me you’ll have multiple)

You use the “SetSPN.exe” program to do this and you need very high privileges to do so. Domain Admin or equivalent is sufficient 😉 though it could have been delegated to lower ranks. Note that this can be executed on any server in your domain not only the SharePoint servers.

The major point of this post is that I’ve created a small PowerShell script to generate a bat file that will create the SPNs required.

Given a config file (CreateSPNBatFile_config.xml) like this:

 <?xml version="1.0" ?> <Config> <Servers> <Server name="moss1" domain="internal.contoso.com" /> <Server name="moss2" domain="internal.contoso.com" /> <Server name="moss3" domain="internal.contoso.com" /> </Servers> <Urls> <Url hostheader="intranet" serviceaccount="contoso\sa_intranet" /> <Url hostheader="extranet.contoso.com" serviceaccount="contoso\sa_extranet" /> </Urls> </Config> 

The script (CreateSPNBatFile.ps1) (download here if quotes and stuff are messed up):

# Create a bat file for SPN creation based on config file # # 2010 Søren L. Nielsen function CreateSPNBatFile( $configFile, $outputFile ){ $config = [xml] (Get-Content $configFile) $output = "" #Gather all the service accounts $serviceAccounts = @{} foreach( $url in $config.Config.Urls.Url ){ $output += "Setspn.exe -A HTTP/" + $url.hostheader + " " + $url.serviceaccount + "`r`n" $serviceAccounts[ $url.serviceaccount.ToLower() ] = 1 } foreach( $server in $config.Config.Servers.Server ){ foreach( $serviceAccount in $serviceAccounts.Keys ){ #every combination of server and service account $output += "Setspn.exe -A HTTP/" + $server.name + "." + $server.domain + " " + $serviceAccount + "`r`n" } } $output += "pause`r`n" Set-Content -LiteralPath $outputFile -Value $output Write "Batch file $outputFile created" } CreateSPNBatFile "./CreateSPNBatFile_config.xml" "./CreateSPN.bat" 

Will generate the following bat file (CreateSPN.bat):

Setspn.exe -A HTTP/intranet contoso\sa_intranet Setspn.exe -A HTTP/extranet.contoso.com contoso\sa_extranet Setspn.exe -A HTTP/moss1.internal.contoso.com contoso\sa_extranet Setspn.exe -A HTTP/moss1.internal.contoso.com contoso\sa_intranet Setspn.exe -A HTTP/moss2.internal.contoso.com contoso\sa_extranet Setspn.exe -A HTTP/moss2.internal.contoso.com contoso\sa_intranet Setspn.exe -A HTTP/moss3.internal.contoso.com contoso\sa_extranet Setspn.exe -A HTTP/moss3.internal.contoso.com contoso\sa_intranet pause 

Ready to ship off to your domain administrator.

Trust for Delegation (Updated)

You need to configure the servers to be trusted for delegation in the AD (sorry I don’t know the command line). The procedure is:

  1. On any computer in the domain start Active Directory Users and Computers (“dsa.msc”)
  2. In the left pane, click Computers.
  3. In the right pane, right-click the name of your SharePoint server, and then click Properties.
  4. Click the Delegation tab (or General for WinSrv2000), click to select the Trust computer for delegation check box.
  5. Repeat step 3 and 4 for every SharePoint server in your farm including the SQL server

And you also need to configure the service accounts the same way (provided that they are domain accounts):

  1. On any computer in the domain start Active Directory Users and Computers (“dsa.msc”)
  2. Locate your service account in your AD (I generally prefer to search for the samAccountName)
  3. click Properties on the service account
  4. Click the Delegation tab (or General for WinSrv2000), click to select the Trust this user/computer for delegation to any service (Kerberos)  check box.
  5. Repeat step 3 and 4 for every service account in your farm including SQL account

Firewall

Kerberos uses port 88 to communicate with the AD server therefore that port need to be open between the AD and your servers. There likely are a bunch of additional ports – ask google not me.

Test

There are of course a number of ways to test this – look at the list above.

I generally start by enabling fiddler and check that the authentication part looks like a Kerberos ticket – fiddler will tell you this on the “Auth” tab.

The easiest test is to go to a list and get the RSS feed url. Then add a RSS viewer webpart to a page with that URL. If Kerberos works (for that site! You need to test all) you should see the list feed with the same elements as you would browsing directly to the RSS url.

If it does not work you’ll see the RSS feed as an anonymous user (note: Pick a list without anonymous access).

There are a large number of potential problems that would make this fail. Kerberos is very hard to debug – I can’t help you all but do try some of Microsofts tools.

I hope this help some of you with Kerberos. I had to hunt down a surprising number of post, documents and trial runs to compile this. Sorry for not sharing them all I simply don’t recall all of them as I did the installation over a year ago.

Note: If some users cannot authenticate but others get a “400 bad request” have a look here.

What Local Admin Privilege Really Mean


This is a small post to explain common misunderstandings regarding local administrators rights that I encounter so often that I find I need somewhere to point for an explanation.

So what you can do with local admin rights is almost everything specifically:

  • You can modify almost any file, except those with (very) special security set
    • But you do have the right to change that security
  • Similarly you can modify almost all parts of the registry
    • And grant yourself access to remaining parts
  • But you are not exempt from Group Policies set by the domain administrators for either the computer or your account. You may find that you cannot
    • Use the command line (but perhaps bat files?)
    • Not start registry editor (but the command line REG command works)
    • Not start any MMC snapin’s (sometimes it’s only authoring that is disabled)
    • Type addresses in the windows explorer bar
    • Etc..

    When in doubt you can run “GPResults.exe” (part of win xp) to get the list of policies applied.

    What can you do about it? You can remove the computer from the domain but that’s likely not an option. You do not have the option of removing the GPO’s but you probably have (or is able to grant) sufficient access to the registry to disable them temporarily. Each one will need to be disabled in different manners, e.g. to enable command prompt again run “REG add HKCU\Software\Policies\Microsoft\Windows\System /v DisableCMD /t REG_DWORD /d 0 /f”. Needless to say it is very awkward and time consuming – your changes will be overwritten by next GPO update – so you probably have to live with this.

  • If your server host MOSS/WSS you can do pretty much everything as long as you are sure you are browsing that server. Known by most people this is a very useful little “backdoor” (by design) security feature

And there are so many details better left out here…

Heads-up: Your MOSS Web Services are not Secured


This is a little heads-up (and fix) of a security issue in MOSS web services for anonymous accessible sites.

I’ve tested a number of public MOSS sites and I only found one where I couldn’t access “…/_vti_bin/SiteData.asmx” (none mentioned none called out). Try it on your favorite MOSS site and you’ll most likely get the list of web method exposed by this webservice.

You can access all the other MOSS webservices as well.

This is not as big a security hole as you might think because the MOSS webservices will still respect the SharePoint permissions, so the anonymous evil internet hacker can probably not do anything that anonymous users are not allowed to. But he can probably access a whole lot more information than is available on your main site and are you really sure you secured it all properly? Do you really want people to access your webservices?

Specifically the SiteData.asmx webservice is bad story here. It’s used by the crawler to list all pages on the SharePoint site that have changed since last time it crawled. In other words it lists every page in your farm. It also lists secured and/or unpublished pages. You definitely do not want this. What about the title (not the actual content!) of your next stock announcement being available to the outside, before it’s published?

How to fix

I’ve messed a bit with the web.config file that is associated with the web services to disallow anonymous access by default. It’s just a few lines and then all web service calls requires authentication 🙂

The default web.config file lists 3 web services that are always allowed anonymous access; I suggest that you leave those unchanged.

If you have any additional web services that require anonymous access you can just add it to the list (after my additions).

So; change the web.config file in “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI” on all your frontend servers to this:

[..]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
    <system.web>
        <webServices>
            <protocols>
                <remove name="HttpGet" />
                <remove name="HttpPost" />
                <remove name="HttpPostLocalhost" />
                <add name="Documentation" />
            </protocols>
        </webServices>
        <customErrors mode="On"/>

	<!-- Søren Nielsen: 23-02-2009 disable anonymous access to webservices -->
        <authorization>
            <deny users="?"/>
        </authorization>
    </system.web>

    <location path="authentication.asmx">
        <system.web>
            <authorization>
                <allow users="*"/>
            </authorization>
        </system.web>
    </location>
    <location path="wsdisco.aspx">
        <system.web>
            <authorization>
                <allow users="*"/>
            </authorization>
        </system.web>
    </location>
    <location path="wswsdl.aspx">
        <system.web>
            <authorization>
                <allow users="*"/>
            </authorization>
        </system.web>
    </location>
</configuration>

[..]

Notes

  • This is a farm wide setting so all your sites will be affected. Non anonymous sites are unchanged as this is similar to their default behaviour.
  • You could copy this web.config file to all your servers (not just frontend) if you like. I don’t see any problems with this, however I’ve not tested it thoroughly enough to say for sure.
  • If you add another frontend server be sure to deploy it there too.
  • You could add this web.config file to a wsp file and deploy it through SharePoint, but in that case be careful when you retract it because SharePoint will then remove the file and no webservices will work across the entire farm.
  • I suggest that you verify that the web.config file is still in place every time you apply a major upgrade/service pack

Lock Down Security: My Best Practices (and restoring usability)


I’m sure many of you are need to establish and implement a security matrix on your SharePoint sites. What do you need to do to ensure that your users can actually do the stuff they need to do? After all they are the business they are bringing the actual money home.

This is my first of probably many blog articles about SharePoint security. It is a rather complex and annoying issue that most of us don’t really want to think about too much. Generally most people solve it in one of three ways:

  1. Grant everybody some standard permissions and forget about it
  2. Grant (too) many administrative rights and trust them not to mess it up
  3. Lock down security and accept the loss of usability as many features stop working

I tend to go with either 1 or 3. For my more advanced setup the standard groups (option 1) doesn’t quite cut it and I’m stuck with option 3. That being said I do take pains to ensure that as much functionality as possible continue to work – the very purpose of this article.

I usually think of (and use) SharePoint Groups as roles and permission levels as role definitions. Note that the security setup has changed substantially since WSS 2.0, so you might need to read up on it (see bottom).

Designing the Security Matrix

When you need to implement security you quickly discover that there really is no way to import/export the security definitions and you are stuck with manual configuration. Sorry. It’s on my to-do list of tools that I would like (someone) to build. I know of only one way to “copy” the security setup from one environment to the next and that is a stsadm backup/restore of the site collection. It can be useable once or twice if you plan it right.

So what you need to do is to document and plan it thoroughly before you start. Nobody likes to do the same work 5 times over which you will otherwise end up doing. And sadly you’ll need to involve your client/customer/user and get them to buy in on whatever security you end up implementing. If you are like me you’ll want them to be able to maintain it after the project is delivered and then you need them to understand what you are doing, why and how they should use it in the future.

I prefer to use excel with a simple sheet with the site hierarchy as the first column and subsequent user groups/roles on the next columns. In the cells you simply write something the places where you’ll break the security inheritance and invent some labels that describe what that particular group should be able to do at that particular site. Don’t be too creative and don’t use a 20 letter encoding of the SharePoint permission levels. Use a label and map that to a custom permission level later (client probably don’t care about that).

It almost goes without saying that you should plan for as much inheritance as possible so the spreadsheet should be fairly sparse. If it contains lists or individual list items you should consider other options as that will certainly go awry in a very short time.

Deciding on AD or SharePoint Groups

So should you use SharePoint groups or should you use AD security groups (I’ll skip the discussion of AD group scope here – domain local, universal etc.)? You’ll probably end up with both as there are benefits and tradeoffs with both:

AD Security Group SharePoint Group
Contains both users and other AD security groups Contains both users and other AD security groups, but not other
SharePoint groups
Must be maintained in the AD, usually by IT department and/or IT administrators Permission to maintain groups can be assigned within SharePoint
Can be used (directly) within SharePoint for permissions Can be used for permission assignment (obviously)

And there are many more that I didn’t consider important here. Sharp readers will notice that I omitted server local groups here. Don’t ever use them. They are simply confusing, impossible to maintain and they don’t go well with a multi-server farm.

I usually prefer to have the AD deliver as much as possible, e.g. at least domain membership, probably department membership. I then assign those groups to a number of SharePoint groups that I use as roles and don’t worry too much about those. E.g. if you want to assign every user in the domain reader rights and a few (10%) some additional rights, then 90% of the users will be correctly assigned after adding “Domain Users” to your reader SharePoint group.

One word of warning: If your organization has been very creative in their domain setup and use excessively deep nesting in AD it might not work within SharePoint. It has been seen to happen. If you can assign that group properly to file share on the SharePoint server you should be quite certain that it also works in SharePoint.

The most important missing feature of the SharePoint groups is that they cannot be nested. It is a shame and the consequence is that you might need to add a given user to, say, 4 different SharePoint groups to make everything work. If it requires somebody to grant permissions on individual basis somewhere on the portal chances are that you should rethink your design.

Be sure to write down what is needed to grant a new user access to your portal that can be used as a reference for the SharePoint business owners at a later stage.

Managing Membership

One very helpful tip in managing the memberships of the SharePoint groups is that each group is assigned a owner that can adjust the memberships (by default), but it will also work if you assign a SharePoint group that role.

Go to the edit group page to modify it and set your custom SharePoint administrator group as owner of the group. From that point on your membership handling can be delegated to somebody without excessive rights e.g. farm administrators.

Implementing the Security Matrix

One thing that I’ll always recommend: Don’t use the standard SharePoint permission levels. They are well designed and therefore you should take a copy of them and assign the copy to your groups where you need it. That will enable you to later modify the permission levels in one place (as opposed to going through everywhere you assigned permission to that group) without compromising the integrity of the standard permission levels. Nothing is worse than a Contributor permission that actually grants administrative rights…

Ensure that the right people can administrate various group memberships by making sure who the owner of the SharePoint groups is.

When you implement (click through it) your matrix make extensive use of the “View Group Permission” feature (from settings menu when viewing group memberships, people.aspx). Another thing for my to-do list is to extend this feature to handle users as well – it’s not as hard as it sounds.

In the following I’ll cover some specific quirks that you might need to remember to ensure that your users can still use the site after you did your work (oh, they will resent you for it…)

Making the Galleries Work (Again)

The web part, list and site template galleries might need special permissions (if you try to limit access to the site collection root), to continue to work. To go to the permission setup, go to the actual galleries through Site settings, then gallery settings and finally the permissions.

  • Web Part Template Gallery: You should assign read permissions to this gallery to everybody (their group!) that should be able to add webparts somewhere. Otherwise the Add Web Part popup will be rather empty
  • List Template Gallery: Users that need to create lists from saved list templates obviously needs read access and the people creating the list templates should have contribute/write permissions.
  • Site Template Gallery: Users that need to create sites from the templates require read access. Users creating the site templates need contribute permissions on the gallery as well as the Site permission “Manage Permissions” (available on the permission level settings) on the target site that they want to save

Reuseable content

On a publishing web site, i.e. publishing or collaboration site, there is a list in the site collection root named “Reuseable content”.

If you want the functionality to work on any subsites you need to assign all editors contributor right to the list and all other users read permissions. If some users lack the permissions they simply won’t see that particular item of content on your publishing page. There will be no sign that they do not see the complete page, which tend to be pretty confusing to end users.

Content Types

Sadly there is no list or permission level that governs the customization of content types. You can’t prevent this through permissions if you also require some users to be able to manage your site permissions, i.e. add users.

You will want to prevent “people” (administrators) from changing all the content types that you defined in xml through feature deployment as that will disconnect your content type (see my two posts on that, 1 and 2) from the underlying xml source.

You can mark your content type as either read only or sealed with following tradeoffs

  • Read only: Will prevent accidental changes and allow inherited content types to delete/hide inherited columns. Administrators can actually override this setting if they really want to (but then they are not “in good faith”)
  • Sealed: Will prevent all changes through the GUI, but will also lock child content types so they can only hide inherited columns, not delete them

Both cases will not affect your ability to update the underlying xml files, i.e. it is actually not supported to change them after initial deployment. You can do it, but then you’ll need to update all inherited content types to preserve or restore their “inheritance” (see post). (A proper fix for this is another item on my to-do list)

Master Pages, Page Layouts and Styles

Just maintain the default “Style Readers” group and you should have no problems with these lists. If you do change the style readers group too much you need to ensure that

  • all users can read from the master pages catalog (“/_catalogs/”), otherwise they are completely blocked from your pages
  • all users can read from “/Style Library”

Final Words

I hope that these guidelines will help you a little bit. They helped me, but don’t for a minute consider them to be complete.

There are a number of features that require some special permission here and there if you tighten security on something else. It’s bound to happen and it is tedious and hard to test thoroughly.

Additional Resources

You can find some general information from Microsoft that defines all the basics and provides some guidelines here.

As usual Joel Oleson has something worthwhile to read on the subject.