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.

3 comments:

  1. Hello, i'm trying to generate keytab but receive this error, may you help, please ?

    msktutil -c -b "CN=Computers" -s HTTP/workgroup.testdomain.local -k /etc/squid.keytab --computer-name WORKGROUP-PROXY --upn HTTP/workgroup.testdomain.local --server testdomain.local --verbose
    -- init_password: Wiping the computer password structure
    -- generate_new_password: Generating a new, random password for the computer account
    -- generate_new_password: Characters read from /dev/udandom = 76
    -- create_fake_krb5_conf: Created a fake krb5.conf file: /tmp/.msktkrb5.conf-oOBYsY
    -- reload: Reloading Kerberos Context
    -- finalize_exec: SAM Account Name is: WORKGROUP-PROXY$
    -- try_machine_keytab_princ: Trying to authenticate for WORKGROUP-PROXY$ from local keytab...
    -- try_machine_keytab_princ: Error: krb5_get_init_creds_keytab failed (Cannot contact any KDC for requested realm)
    -- try_machine_keytab_princ: Authentication with keytab failed
    -- try_machine_keytab_princ: Trying to authenticate for host/testdomain.local from local keytab...
    -- try_machine_keytab_princ: Error: krb5_get_init_creds_keytab failed (Cannot contact any KDC for requested realm)
    -- try_machine_keytab_princ: Authentication with keytab failed
    -- try_machine_password: Trying to authenticate for WORKGROUP-PROXY$ with password.
    -- create_default_machine_password: Default machine password for WORKGROUP-PROXY$ is workgroup-prox
    -- try_machine_password: Error: krb5_get_init_creds_keytab failed (Cannot contact any KDC for requested realm)
    -- try_machine_password: Authentication with password failed
    -- try_user_creds: Checking if default ticket cache has tickets...
    -- finalize_exec: Authenticated using method 4

    -- ldap_connect: Connecting to LDAP server: testdomain.local try_tls=YES
    -- ldap_connect: Connecting to LDAP server: testdomain.local try_tls=NO
    SASL/GSSAPI authentication started
    Error: ldap_sasl_interactive_bind_s failed (Local error)
    Error: ldap_connect failed
    --> Is your kerberos ticket expired? You might try re-"kinit"ing.
    -- ~KRB5Context: Destroying Kerberos Context

    ReplyDelete
  2. And in squid cache.log while probe to autenticate from browser to squid:

    2014/11/14 23:42:03| authenticateNegotiateHandleReply: Error validating user via Negotiate. Error returned 'BH received type 1 NTLM token'
    2014/11/14 23:42:04| squid_kerb_auth: DEBUG: Got 'YR TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==' from squid (length: 59).
    2014/11/14 23:42:04| squid_kerb_auth: DEBUG: Decode 'TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==' (decoded length: 40).
    2014/11/14 23:42:04| squid_kerb_auth: WARNING: received type 1 NTLM token
    2014/11/14 23:42:04| authenticateNegotiateHandleReply: Error validating user via Negotiate. Error returned 'BH received type 1 NTLM token'

    ReplyDelete
  3. i have the same like Alex Scherbakov, what could be the reason?

    ReplyDelete