Wednesday 28 May 2014

Configure Fedora 19 to authenticate with Samba4 AD using kerberos

Introduction
The data used in this tutorial:
  • Samba4 Active Directory Domain: example.com
  • Samba4 Active Directory host: host.example.com
  • Realm/workgroup: EXAMPLE.COM
  • Samba4 Active Directory, DNS & NTP IP Address: 192.168.1.2
  • Fedora19 Client machine hostname : FEDCLIENT1

Overview
A summary of the steps we are going to do:
  • Install Packages
  • Configure NTP & DNS
  • Configure Kerberos
  • Configure nsswitch
  • Configure Samba
  • Join the Domain
  • Test the setup
 Need to have a privileged account to join the Active Directory Domain.

Install Packages
Install the following packages on a freshly install Fedora 19 machine
#yum install krb5-workstation krb5-libs samba-winbind samba-winbind-clients samba samba-client samba-libs samba-winbind-krb5-locator samba-common ntp

Configure NTP & DNS
Inorder to synchronize active directory and the client's time for kerberos
#/etc/ntp.conf
server 192.168.1.2

For DNS
#/etc/resolv.conf
domain example.com
search example.com
nameserver 192.168.1.6


Configure Kerberos
What is Kerberos?
Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography. It has the following characteristics:
  • It is secure: it never sends a password unless it is encrypted.  
  • Only a single login is required per session. Credentials defined at login are then passed between resources without the need for additional logins.
  • The concept depends on a trusted party – a Key Distribution Center (KDC). The KDC is aware of all systems in the network and is trusted by all of them.
  • It performs mutual authentication, where a client proves its identity to a server and a server proves its identity to the client.
Edit the /etc/krb5.conf file, remove everything and place the following in it, changing the EXAMPLE.COM domain to your own Active Directory Domain:

[libdefaults]
  ticket_lifetime = 24h
  default_realm = EXAMPLE.COM
  forwardable = true

[realms]
  EXAMPLE.COM = {
  kdc = EXAMPLE.COM
  default_domain = EXAMPLE.COM
  admin_server = 192.168.1.2
  kdc = host.example.com
  }

[domain_realm]
  .example.com = EXAMPLE.COM
  example.com = EXAMPLE.COM

[appdefaults]
  pam = {
  debug = false
  ticket_lifetime = 36000
  renew_lifetime = 36000
  forwardable = true
  krb4_convert = false
  }

[logging]
  kdc = FILE:/var/log/krb5kdc.log
  admin_server = FILE:/var/log/kadmin.log
  default = FILE:/var/log/krb5lib.log

Test Kerberos by getting a ticket for the Active Directory Administrator User.
#kinit Administrator
Password for Administrator@EXAMPLE.COM:

The following command should list a valid ticket for kinit.
#klist
Ticket cache: DIR::/run/user/0/krb5cc/tktgdYTR
Default principal: administrator@EXAMPLE.COM

Valid starting       Expires              Service principal
05/28/2014 16:43:40  05/29/2014 02:43:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 05/29/2014 16:43:35

If youo get error, check your Kerberos and DNS and NTP (time) settings and try again.

Configure nsswitch 
nsswitch is used to tell the system that the Active Directory users are also valid users. We are going to configure it to also accept winbind users, which is what Samba uses after it has bound to the domain.

Edit the /etc/nsswitch.conf
passwd:     files ldap winbind
group:        files ldap winbind
shadow:     files ldap winbind

Configure Samba
Now we need to set up Samba to also support the domain.
Edit /etc/samba/smb.conf


[global]
      workgroup = EXAMPLE
      realm = EXAMPLE.COM
      password server = host.example.com
      security = ads
      domain master = no
      local master = no
      preferred master = no
      idmap config * : backend = rid
      idmap config * : range = 2000-50000000
      template homedir = /home/%U
      template shell = /bin/bash
      winbind use default domain = yes
      winbind offline logon = yes
      winbind enum users = yes
      winbind enum groups = yes
      winbind nested groups = yes
      winbind refresh tickets = yes
      wins support = yes
     dns proxy = yes
     wins proxy = yes

Save the file and restart all the daemons:
#service smb restart
#service nmb restart
#service ntp restart
#service winbind restart

Join the domain

Make sure you still have a valid Kerberos ticket. If not, do a new kinit Administrator. Then execute the following command:

#net ads join -U Administrator
Enter Administrator's password:
Using short domain name -- EXAMPLE
Joined FEDCLIENT1 to realm 'example.org'
DNS Update for fedclient1.example.org failed: ERROR_DNS_GSS_ERROR
DNS update failed!

The DNS error can be ignored, make sure you create an A record and a PTR record manually.

Restart all the daemons:
#service smb restart
#service nmb restart

#service winbind restart

Update pam:
#authconfig --enableshadow --enablewinbind --update

check if winbind and nsswitch are correctly working and displays the list of all active directory users and group:
#getent passwd
#getent group



Sunday 18 May 2014

Squid with Kerberos and LDAP authentication in Samba4 Active Directory

Making users to authenticate on squid proxy using:
1.  Kerberos (single sign-on)
2.  Fall back to ldap authentication if kerberos fails.

Prerequisites:
  • Working samba4 domain with dns server and ntp server and squid server.
  • Client Windows Computers need to have "Enable Integrated Windows Authentication" ticked in Internet Options ⇒ Advanced settings. 
Environment:
Network
Domain = xyz.com
Subnet = 192.168.1.0/24

Proxy Server
IP = 192.168.1.1
Hostname = proxysrv.xyz.com
Kerberos computer name = PROXYSRV-HTTP

Samba4 AD
IP: 192.168.1.2
Hostname = domain.xyz.com

Configure ntp
Kerberos needs to have the time syncronised with samba domain for kerberos authentication
vi /etc/ntp.conf
Enter the ntp server name to obtain time from
server domain.xyz.com

Restart ntp
service ntp restart

Test NTP
ntpq -p
You should see output that refers to the Domain Controllers and other NTP Servers which are processed in the order that they appear in the conf file.

Check that the proxysrv is using the Domain's internal DNS Server for name resolution and update /etc/resolv.conf accordingly.
vi /etc/resolv.conf
nameserver 192.168.1.2
search domain.xyz.com xyz.com

Install and Configure Kerberos

apt-get install krb5-user libkrb53
vi /etc/krb5.conf
[libdefaults]
    default_realm = XYZ.COM
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log

    dns_lookup_kdc = no
    dns_lookup_realm = no
    ticket_lifetime = 24h
    default_keytab_name = /etc/squid3/PROXY.keytab
    default_tgs_enctypes = RC4-HMAC DES-CBC-MD5 DES-CBC-CRC
    default_tkt_enctypes = RC4-HMAC DES-CBC-MD5 DES-CBC-CRC
    preferred_enctypes = RC4-HMAC DES-CBC-MD5 DES-CBC-CRC

[realms]
    XYZ.COM = {
        kdc = domain.xyz.com
        admin_server = domain.xyz.com
        default_domain = xyz.com
    }

Install Samba and Winbind 

apt-get install samba winbind samba-common-bin
Edit /etc/samba/smb.conf
[global]
      workgroup = XYZ
      password server = domain.evolvus.com
      realm = XYZ.COM
      security = ads
      dns_lookup_realm = true
      dns_lookup_kdc = true
      idmap config * : backend = rid
      idmap config * : range = 2000-50000000

      template homedir = /home/%U
      template shell = /bin/bash
      winbind use default domain = true
      winbind offline logon = true

Restart samba & winbind
Initiate a kerberos session to the server with administrator permissions to add objects to AD
kinit administrator
Password for administrator@XYZ.COM: ******

It should return without errors. You can see if you succeSsfully obtained a ticket with:
klist

Now join the proxysrv to the domain.
net ads join -U Administrator
Enter Administrator's password:
Using short domain name -- XYZ
Joined 'PROXYSRV' to realm 'xyz.com'

Restart samba and winbind and test acces to the domain  

wbinfo -t
checking the trust secret for domain XYZ via RPC calls succeeded
In DNS Server, ensure new A record entry for the proxysrv server's hostname and ensure a corresponding PTR entry is also created and works.
Ping a internal and external hostname to ensure DNS is operating.
ping domain.xyz.com -c 4 && ping google.com -c 4

Check you can reverse lookup the domain controller and the local proxysrv ip from the DNS Server.
dig -x 192.168.1.2
dig -x 192.168.1.1

Install msktutil an Active Directory keytab manager
apt-get install msktutil

Configure the proxy's kerberos computer account and service principle by running msktutil

msktutil -c -b "CN=Computers" -s HTTP/proxysrv.xyz.com -k /etc/squid3/PROXY.keytab --computer-name PROXYSRV-HTTP --upn HTTP/proxysrv.xyz.com --server domain.xyz.com --verbose

Note:
  • --computer-name cannot be longer than 15 characters
  • --computer-name must be different from the proxy's hostname
Closely observer the output of the command to ensure success, because we are using --verbose output you should review it carefully.    

Set the permissions on the keytab so squid can read it.
chown proxy.proxy /etc/squid3/PROXY.keytab

Destroy the administrator credentials used to create the account.
kdestroy

On the Samb4 server reset the Computer Account proxysrv-http using Microsofts RSAT (Remote Server Administration Tools) on a Windows workstation. , then run msktutil as follows to ensure the keytab is updated as expected and that the keytab is being sourced by msktutil from /etc/krb5.conf correctly. This is not completely necessary but is useful to ensure msktutil works as expected.

msktutil --auto-update --verbose --computer-name proxysrv-http --server domain.xyz.com -s HTTP/proxysrv.xyz.com -k /etc/squid3/PROXY.keytab

Add the following to cron so it can automatically updates the computer account in active directory when it expires. I pipe it through logger so I can see any errors in syslog if necessary.

crontab -e
00 4  *   *   *  msktutil --auto-update --verbose --computer-name proxysrv-http --server domain.xyz.com -s HTTP/proxysrv.xyz.com -k /etc/squid3/PROXY.keytab | logger -t msktutil

Add the following configuration to /etc/default/squid3 so squid knows where to find the kerberos keytab.
vi /etc/default/squid3
KRB5_KTNAME=/etc/squid3/PROXY.keytab
export KRB5_KTNAME

Open required ports for kerberos:
vi /etc/iptables/rules.v4
-A INPUT -p tcp -m tcp --dport 88 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 464 -j ACCEPT

Set Full control for Authenticated Users on computer account proxysrv using Microsofts RSAT.

Configure squid
vi /etc/squid3/squid.conf
#configuration for kerberos auth
auth_param negotiate program /usr/lib/squid3/squid_kerb_auth -d -i -s GSS_C_NO_NAME
auth_param negotiate children 10
auth_param negotiate keep_alive off

#configure fall back ldap auth
auth_param basic program /usr/lib/squid3/squid_ldap_auth  -b dc=xyz,dc=com -D CN=squidadmin,OU=users,dc=xyz,dc=com -w **** -u sAMAccountName -h domain.xyz.com -s base -f objectClass=*
authenticate_ttl 0 seconds

acl auth proxy_auth REQUIRED
http_access allow all auth

Then restart squid and check for any errors.
service squid3 restart

Notes
  • Kerberos needs DNS to be configured properly (in that case you don't even need to configure /etc/krb5.conf)
  • DNS needs to have a host DNS-records (A-record and reverse-record) for the proxy server (proxysrv.xyz.com is in our example)
  • To use Kerberos in Ubuntu you just need to install "krb5-user" and run "kinit administrator@XYZ.COM"
  • You need to use proxy by full DNS-name (proxysrv.xyz.com is in our example) or by CNAME to this DNS-name to make Kerberos works. Overwise only LDAP plain text authentication will work.