Difference between revisions of "Apache Kerberos Authentication"
Michael.mast (talk | contribs) (→Docker) |
Michael.mast (talk | contribs) |
||
(One intermediate revision by the same user not shown) | |||
Line 109: | Line 109: | ||
Here I tried using the principle from the keytab, but for some reason the kvno kept getting logged as 3 instead of 6. So for now I told Apache to use any service name. Need to research security risks related to this. Also I might need to keep it at ANY if I can not specify more than one principal. | Here I tried using the principle from the keytab, but for some reason the kvno kept getting logged as 3 instead of 6. So for now I told Apache to use any service name. Need to research security risks related to this. Also I might need to keep it at ANY if I can not specify more than one principal. | ||
<pre> | <pre> | ||
− | <IF " | + | <IF "'%{REQUEST_URI}' != '/wp-admin'"> |
AuthType Kerberos | AuthType Kerberos | ||
AuthName "Kerberos authenticated site" | AuthName "Kerberos authenticated site" | ||
Line 122: | Line 122: | ||
</pre> | </pre> | ||
+ | |||
+ | If you want to allow access regardless of authentication (i.e. If you use the apache variable as part of your own authentication, but allow manual login if this fails) you are limited in options. In my case I ended up allowing a subnet and a single IP to access without kerberos authentication, but all others would be required to use it. | ||
+ | <ref>https://www.jeffgeerling.com/blogs/jeff-geerling/apache-kerberos-authentication</ref> | ||
+ | <ref>https://wiki.apache.org/httpd/BypassAuthenticationOrAuthorizationRequirements</ref> | ||
+ | <ref>https://httpd.apache.org/docs/trunk/mod/mod_access_compat.html</ref> | ||
+ | <pre> | ||
+ | <IF "'%{REQUEST_URI}' != '/wp-admin'"> | ||
+ | AuthType Kerberos | ||
+ | AuthName "Kerberos authenticated site" | ||
+ | KrbAuthRealms DOMAIN1.TLD DOMAIN2.TLD | ||
+ | #KrbServiceName HTTP/user@DOMAIN1.TLD | ||
+ | KrbServiceName Any | ||
+ | Krb5KeyTab /etc/httpd/merged.keytab | ||
+ | KrbMethodNegotiate On | ||
+ | KrbMethodK5Passwd On | ||
+ | Require valid-user | ||
+ | Satisfy any | ||
+ | Deny from all | ||
+ | Allow from xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx/xx | ||
+ | </IF> | ||
+ | </pre> | ||
+ | |||
==Docker== | ==Docker== | ||
===Host config=== | ===Host config=== |
Latest revision as of 19:00, 6 May 2019
Contents
Purpose
To allow users to authenticate using seamless SSO via kerberos.[1]
MultiRealm Authentication
In this case I want to authenticate more than one realm (two domains). After following the common instructions online I was unable to log in using the second realm. The first realm logged in without issue.
NOTE 1 : This is a messy post as I have worked on this for several days and am trying to record what I did before I forget.
NOTE 2 : I am not sure if all of this is necessary, but I wanted to track everything I did regardless
Environment
- Domains
Domain1.tld
Domain2.tld
- web server
intranet.tld
Keytab Creation
Please make sure that you do not have duplicate SPNs in AD. I ran into an issue where I converted a site to use dual realms, but the old one would not authenticate using the new keytab. Eventually I found the duplicate SPN.[2][3]
You can modify spns using two methods. If you like using a GUI, you can open the attribute editor for the service account and scroll down to SPNS and modify accordingly. Or you can use the CLI command setspn
setspn -d HTTP/your.server.com@YOURDOMAIN.COM serviceaccount setspn -A HTTP/your.server.com serviceaccount
On the domain controllers
On domain1.tld, create a user object that will be used for the service. Then create the keytab and map it to the user.
NOTE : This is case sensitive.
ktpass /out C:\Temp\domain1.keytab /princ HTTP/website@DOMAIN1.TLD /mapuser user /pass <password> /crypto ALL /ptype KRB5_NT_PRINCIPAL /kvno 1
On domain2.tld
ktpass /out C:\Temp\domain2.keytab /princ HTTP/website@DOMAIN2.TLD /mapuser user /pass <password> /crypto ALL /ptype KRB5_NT_PRINCIPAL /kvno 1
On the web server
[root@web ~]# ktutil ktutil: read_kt domain1.keytab ktutil: read_kt domain2.keytab ktutil: write_kt merged.keytab ktutil: exit [root@web ~]# mv merged.keytab /etc/httpd [root@web ~]# chgrp apache /etc/httpd/merged.keytab [root@web ~]# chmod 440 /etc/httpd/merged.keytab
krb5.conf
The server I am using was enrolled in domain1 using sssd and the "realm join" command many a year ago. We will be editing the krb5.conf file that was created during this process.
# Configuration snippets may be placed in this directory as well includedir /etc/krb5.conf.d/ includedir /var/lib/sss/pubconf/krb5.include.d/ [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] dns_lookup_realm = true ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false # default_realm = EXAMPLE.COM default_ccache_name = KEYRING:persistent:%{uid} default_realm = DOMAIN1.TLD [realms] # EXAMPLE.COM = { # kdc = kerberos.example.com # admin_server = kerberos.example.com # } DOMAIN1.TLD = { kdc = domain1.tld admin_server = domain1.tld } DOIMAIN2.TLD = { kdc = domain2.tld admin_server = domain2.tld } [domain_realm] # .example.com = EXAMPLE.COM # example.com = EXAMPLE.COM domain1.tld = DOMAIN1.TLD .domain1.tld = DOMAIN1.TLD domain2.tld = DOMAIN2.TLD .domain2.tld = DOMAIN2.TLD [capaths] DOMAIN1.TLD = { DOMAIN2.TLD = . } DOMAIN2.TLD = { DOMAIN1.TLD = . }
VHOST Config
Here I tried using the principle from the keytab, but for some reason the kvno kept getting logged as 3 instead of 6. So for now I told Apache to use any service name. Need to research security risks related to this. Also I might need to keep it at ANY if I can not specify more than one principal.
<IF "'%{REQUEST_URI}' != '/wp-admin'"> AuthType Kerberos AuthName "Kerberos authenticated site" KrbAuthRealms DOMAIN1.TLD DOMAIN2.TLD #KrbServiceName HTTP/user@DOMAIN1.TLD KrbServiceName Any Krb5KeyTab /etc/httpd/merged.keytab KrbMethodNegotiate On KrbMethodK5Passwd Off require valid-user </IF>
If you want to allow access regardless of authentication (i.e. If you use the apache variable as part of your own authentication, but allow manual login if this fails) you are limited in options. In my case I ended up allowing a subnet and a single IP to access without kerberos authentication, but all others would be required to use it. [4] [5] [6]
<IF "'%{REQUEST_URI}' != '/wp-admin'"> AuthType Kerberos AuthName "Kerberos authenticated site" KrbAuthRealms DOMAIN1.TLD DOMAIN2.TLD #KrbServiceName HTTP/user@DOMAIN1.TLD KrbServiceName Any Krb5KeyTab /etc/httpd/merged.keytab KrbMethodNegotiate On KrbMethodK5Passwd On Require valid-user Satisfy any Deny from all Allow from xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx/xx </IF>
Docker
Host config
In this example we are using Amazon Linux
sudo yum -y upgrade sudo yum -y install yum-cron oddjob oddjob-mkhomedir sssd samba-common-tools realmd docker amazon-efs-utils firewalld sudo systemctl enable firewalld sudo systemctl enable docker sudo realm join -U <username> <fqdn> sudo reboot
Container Config
- First, make sure SSSD is installed in the container.
- The container should have the environmental variable for the ticket cache set outside of kernel protected space (i.e. ENV KRB5CCNAME /tmp/ticket)
- Then we mount the local config into the container as read only when starting the container.
docker run --name website -v /var/lib/sss:/var/lib/sss:ro -p 80:80 -p 443:443 -e TZ=America/New_York -d --restart unless-stopped
- ↑ https://www.netiq.com/communities/cool-solutions/kerberos-authentication-against-multiple-domains
- ↑ https://community.microstrategy.com/s/article/KB37602-quot-No-credentials-cache-found-while-getting-client
- ↑ http://plosquare.blogspot.com/2013/02/solution-for-gss-api_8.html
- ↑ https://www.jeffgeerling.com/blogs/jeff-geerling/apache-kerberos-authentication
- ↑ https://wiki.apache.org/httpd/BypassAuthenticationOrAuthorizationRequirements
- ↑ https://httpd.apache.org/docs/trunk/mod/mod_access_compat.html