Wednesday, 19 October 2011

Oddness with Windows XP Pro on a Domain functional level 2008 or above

I work as systems administrator for a small software house that produces products for a very specific sector.

We had a problem recently with our software not working on a Windows XP Professional (32-bit) machine that was in a domain with a domain functional level of 2008 R2. Our client software was producing an error about not being able to create the necessary objects when it was trying to talk to our server side software running on their DC. After several days of pulling hair it boiled down to there being a bug in Windows XP's kerberos.dll where it does not speak AES to the DC.

To see if you are getting the problem download and install wireshark on the workstation or the server and capture packets between the machines when you are getting the problem. look thru the capture to see if there is a "KRB5 - TGS-REQ" packet sent from WinXP to the server, with a "KRB Error: KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" response. Drill down into the "KRB5 - TGS-REQ" packet, TGS-REQ->KDC_REQ_BODY->Encrytion types if there is no AES encryption type then you probably have the same problem I did.

AES encryption for Kerberos comes into effect when the domain functional level is Windows 2008 or higher.

We solved the problem by applying the following hotfix (requires SP3)

I realise that this information is a bit specific as the problem only showed up when our software tried to invoke DCOM objects and that normal file sharing seemed to work without issue. Hopefully this may prevent someone else going through the pain I endured finding this fix.

Thursday, 13 October 2011

Squid authenticating against Active Directory on Debian Squeeze

Install Debian squeeze on you target (virtual) machine choosing only "Standard system utilities" during package selection.

I would normally logon and install ssh and vim to make life a little easier
# apt-get install ssh vim
we will need to install samba, winbind and kerberos client to get authentication working with Active Directory:
# apt-get install samba winbind krb5-user
If the Samba Server configuration asks you for a "Workgroup/Domain name" you can use short name that you specified for the domain when you created it but as we will replace this file shortly it doesn't actually matter what you put.

Now run re-configuration for krb5-config: 
# dpkg-reconfigure krb5-config
Default Kerberos version 5 realm: <FQDN for your AD domain in caps>
Add the kerberos server names for your domain: yes
Kerberos servers for your realm: <FQDN of your primary domain controller>
Administrative server for your kerberos realm:        <FQDN of your primary domain controller>

We can test that kerberos is working by running the kinit command, the format of the command is:
kinit <username>@<FQDN for your AD domain in caps> 
So for example, if our FQDN for the domain is test.local and we are using the administrator account we would type:
kinit administrator@TEST.LOCAL
If all is well it will ask for the password for the above account, if it accepts the password it will simply return you to the prompt, if there is something amiss it will report an error.

Move the /etc/samba/smb.conf file somewhere safe:
# mv /etc/samba/smb.conf /etc/samba/smb.old.conf
Create a new file containing the following:
netbios name = <this machine name>
workgroup = <shortname for you domain>
password server = <FQDN for your domain controller>
realm = <FQDN for your domain>
security = ads
winbind uid = 10000-20000
winbind gid = 10000-20000
winbind separator = +
winbind use default domain = yes

Restart the samba services:
/etc/init.d/samba restart ; /etc/init.d/winbind restart
Join the active directory with:
net ads join -U administrator
If you receive a "DNS update failed" error you should manually add this server to the DNS server for the domain.
Restart the samba services:
/etc/init.d/samba restart ;  /etc/init.d/winbind restart
Check the the following commands return with a success:
# wbinfo -t
Success of the above command confirms connection to the domain controller.

# wbinfo -u
Lists users (local and domain).
# wbinfo -g
Lists domain groups.

Install the squid packages:
# apt-get install squid
Copy the squid.conf somewhere safe:
# cp /etc/squid/squid.conf /etc/squid/squid.conf.old
Edit /etc/squid/squid.conf and uncomment (remove the hash from) the following line:
#http_access allow localnet
Assuming you are using a RFC1918 network range on your network this will allow you to use the proxy. Save the file and restart squid with:
/etc/init.d/squid restart
Log in to a domain joined windows box that is logged on as a domain user in the inetaccess group (or which ever group you chose earlier to add to the auth_param directives). Set the browser to use squid as it's proxy server (squid runs on port 3128) and see if you can get to the internet. If not, you will need to concentrate on getting squid working as a simple proxy before you try to add authentication into the mix.

You will need to choose or create a security group within your Active Directory domain that we will use for deciding which users can authenticate with squid. I have chosen the group named inetaccess (a single word for the name of the group so we don't have to deal with spaces in the group name) and added as members all the users I want to give internet access to this group.

Edit squid.conf with the following changes:

Add the following auth_param section:
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp --require-membership-of=<short name of the domain>+inetaccess
auth_param ntlm children 5
If you want basic (very insecure, but handy for fallback) authentication then you will also need the following auth_param section.
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic --require-membership-of=<short name of the domain>+inetaccess
auth_param basic children 3
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 5 hours
To stop the leaking of your client IP addresses out of the proxy, set forwarded_for to off
forwarded_for off
Add the following after the existing acl entries:

acl users proxy_auth REQUIRED
Comment out (add a hash to the front of) the line we uncommented before:

http_access allow localnet

Add the following after the http_access, but BEFORE http_access deny all
http_access allow users
Restart squid 
/etc/init.d/squid restart
Using the same domain joined windows box that is logged on as a domain user that you confirmed things were working from earlier see if you still have access.

Trouble shooting
If you are not sure why squid is not letting you through, try changing the debug in the squid.conf to:
debug_options ALL,1 33,8
Try the proxy again and then look though the log file /var/log/squid/cache.log for clues as to what is going on.


Windows machines running on the Vista or Windows 7 code base (so this includes Windows server 2008 & 2008 R2) by default have a local policy setting that prevents you from authenticating with squid using the older version of NTLM. If you go into the local security policy management console then "local Policies"->"Security Options"->"Network security: LAN Manager authentication level" and set it to "Send LM & NTLM - Use NTLMv2 session security if negotiated" then reboot.
You can set this by group policy if you have a lot of machines to change, also if you find that this setting is not taking effect then maybe group policy is changing it back.

Wednesday, 5 October 2011

Debian Squeeze samba domain member fileserver

I struggled to find information on how to set up a samba domain member server on Debian Squeeze. This is how I got it working.

Firstly we install and configure an NTP client. This is needed to keep Kerberos happy, if the time is out by more than 5 mins Kerberos refuses to work.
apt-get install ntp
If you machine can access internet time servers, then this is all you need to do, ntp will happily start connecting  to the Debian time server pool and sync your time.

I have my own time server set up so in /etc/ntp.conf I commented out the server directives for the Debian time server pools and added my own server with the following:
Restart the ntp daemon with :
/etc/init.d/ntp restart
You can check what ntp gets up to with:
tail -f /var/log/syslog
You will hopefully see something like the following:

Oct  1 10:34:12 myserver ntpd[3757]: ntpd 4.2.4p4@1.1520-o Sun Nov 22 16:14:34 UTC 2009 (1)
Oct  1 10:34:12 myserver ntpd[3758]: precision = 1.000 usec
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #0 wildcard, Disabled
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #1 wildcard, ::#123 Disabled
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #2 lo, ::1#123 Enabled
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #3 eth0, fe80::250:56ff:fe84:1#123 Enabled
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #4 lo, Enabled
Oct  1 10:34:12 myserver ntpd[3758]: Listening on interface #5 eth0, Enabled
Oct  1 10:34:12 myserver ntpd[3758]: kernel time sync status 0040
Oct  1 10:34:12 myserver ntpd[3758]: frequency initialized 0.000 PPM from /var/lib/ntp/ntp.drift
Oct  1 10:43:28 myserver ntpd[3758]: synchronized to, stratum 3
Oct  1 10:43:28 myserver ntpd[3758]: time reset +298.707500 s
Oct  1 10:43:28 myserver ntpd[3758]: kernel time sync status change 0001

Install the kerberos client
apt-get install krb5-user
Default Kerberos version 5 realm: <FQDN for your domain>
Kerberos servers for your realm: <FQDN for you dc>
Administrative Server for your Kerberos realm:  <FQDN for you dc>

Test that kerberos is working correctly by running the following command (caps are important):
kinit administrator@MYCOMPANY.COM
This will ask you for the password for the above account, which needs to exist on your Active Directory. If you input the password correctly you should be returned to the command prompt, otherwise you will see something like:
kinit(v5): Preauthentication failed while getting initial credentials
In which case you will need to check the contents of your krb5.conf file.

Install samba and winbind with:
apt-get install samba winbind
Don't worry what we put for the config of samba as we will replace the file anyway

Move the samba config file out of the way with:
mv /etc/samba/smb.conf /etc/samba/smb.conf.orig 
Create /etc/samba/smb.conf with the following contents, change the workgroup and realm to what your AD is set to.

        netbios name = sambafileserver
        workgroup = MYCOMPANY
        realm = MYCOMPANY.COM
        server string = Samba Domain Member
        smb ports = 445
        security = ADS
        encrypt passwords = yes
        winbind enum users = yes
        winbind enum groups = yes
        winbind use default domain = yes
        winbind nested groups = yes
        winbind separator = +
        idmap uid = 10000-20000
        idmap gid = 10000-20000

        client use spnego = yes
        client ntlmv2 auth = yes

        comment = file store
        path = /store
        read only = no
        valid users = MYCOMPANY+administrator

There are a couple of things to note about the smb.conf file, workgroup = the short name for your domain (like the domain part of a username when used like so: DOMAIN\username), realm is the FQDN of the domain (the part after the @ when you are using the username format like so: username@DOMAIN.LOCAL)

Create the /store path so that samba can access it to share it out:
mkdir /store 
chmod 777 /store
Edit /etc/nsswitch.conf and ensure that the passwd line looks like this:
passwd:         compat winbind
Restart the samba and winbind services:
/etc/init.d/samba restart ; /etc/init.d/winbind restart
We now need to join the computer to the active directory with:
net ads join -U administrator
As long as the join reports as successful you should be able to ignore any other failures.

Test that winbind can communicate with the domain:
wbinfo -t
If all is well the above command should return:
checking the trust secret for domain NA via RPC calls succeeded
Now jump onto a domain connected windows PC and see if you can create files in the share as the user mentioned in the "valid users" directive of the smb.conf.