Kerberos is a cryptographically secure authentication mechanism in use in many large organizations. Developers may want to make their applications work with Kerberos while developing inside containers. Here is a quick proof-of-concept that shows how to set up a container to work with mod_auth_gssapi., the Apache module that makes use of Kerberos.
Kerberos identity is based on hostnames. So, even though the webserver is running on localhost, we want to address it via a hostname. I allocated localdev.redhatfsi.com for my development. On the IdM server, I created a host called
localdev.redhatfsi.com,
a service principal called localdev.redhatfsi.com@REDHATFSI.COM.keytab
and allocated a keytab, which I then store on my local machine in
~/keytabs/HTTP/localdev.redhatfsi.com@REDHATFSI.COM.keytab.
I added the following entry to my /etc/hosts file:
0.0.0.0 localdev.redhatfsi.com |
I am still using the setup from my earlier post, although I have now created server and client subdirectories. The server code is here
I added the mod_auth_gssapi RPM in the yum install portion of the Dockerfile:
RUN yum -y install httpd mod_wsgi mod_auth_gssapi |
Here is my configuration for the apache server:
PidFile /tmp/apache.pid ErrorLog /dev/stderr TransferLog /dev/stdout <VirtualHost *> DocumentRoot /var/www/html WSGIScriptAlias /envvars /var/www/cgi-bin/envvars.wsgi <Directory /var/www/cgi-bin> Order allow,deny Allow from all </Directory> </VirtualHost> <Location /> AuthType GSSAPI AuthName "GSSAPI Single Sign On Login" GssapiCredStore keytab:/etc/httpd/localdev.redhatfsi.com@REDHATFSI.COM.keytab Require valid-user </Location> |
This is not the cleanest setup, as it was somewhat trial-and-error. I did peek at the file /etc/httpd/conf.d/ipa.conf on the IdM server to get a sense of what they are tracking, but there is far more there than I need.
To run the server, I bindmount in the Keytab:
podman run -P --name krbocp --mount type=bind,source=/home/ayoung/keytabs/HTTP/localdev.redhatfsi.com@REDHATFSI.COM.keytab,destination=/etc/httpd/localdev.redhatfsi.com@REDHATFSI.COM.keytab --rm admiyo:krbocp |
Most notable is that I am still usering the mod_wsgi code that dumps the environment. I am specifically looking for GSSAPI specific variables, as well as REMOTE_USER.
PORT=`podman port -l | cut -d':' -f2` curl -s --negotiate -u : localdev.redhatfsi.com:$PORT/envvars |
Returns the following Data
- euid
- 48
- UNIQUE_ID
- ‘XjY-1MjfUl0pGWTY63U-OAAAAA0’
- GSS_NAME
- ‘ayoung@REDHATFSI.COM’
- GSS_SESSION_EXPIRATION
- ‘1580698393’
- GATEWAY_INTERFACE
- ‘CGI/1.1’
- SERVER_PROTOCOL
- ‘HTTP/1.1’
- REQUEST_METHOD
- ‘GET’
- QUERY_STRING
- ”
- REQUEST_URI
- ‘/envvars’
- SCRIPT_NAME
- ‘/envvars’
- HTTP_HOST
- ‘localdev.redhatfsi.com:38319’
- HTTP_USER_AGENT
- ‘curl/7.66.0’
- HTTP_ACCEPT
- ‘*/*’
- SERVER_SIGNATURE
- ”
- SERVER_SOFTWARE
- ‘Apache/2.4.37 (centos) mod_auth_gssapi/1.6.1 mod_wsgi/4.6.4 Python/3.6’
- SERVER_NAME
- ‘localdev.redhatfsi.com’
- SERVER_ADDR
- ‘10.0.2.100’
- SERVER_PORT
- ‘38319’
- REMOTE_ADDR
- ‘10.0.2.2’
- DOCUMENT_ROOT
- ‘/var/www/html’
- REQUEST_SCHEME
- ‘http’
- CONTEXT_PREFIX
- ”
- CONTEXT_DOCUMENT_ROOT
- ‘/var/www/html’
- SERVER_ADMIN
- ‘root@localhost’
- SCRIPT_FILENAME
- ‘/var/www/cgi-bin/envvars.wsgi’
- REMOTE_PORT
- ‘53008’
- REMOTE_USER
- ‘ayoung@REDHATFSI.COM’
- AUTH_TYPE
- ‘Negotiate’
- PATH_INFO
- ”
- mod_wsgi.script_name
- ‘/envvars’
- mod_wsgi.path_info
- ”
- mod_wsgi.process_group
- ”
- mod_wsgi.application_group
- ‘10.0.2.100:38319|/envvars’
- mod_wsgi.callable_object
- ‘application’
- mod_wsgi.request_handler
- ‘wsgi-script’
- mod_wsgi.handler_script
- ”
- mod_wsgi.script_reloading
- ‘1’
- mod_wsgi.listener_host
- ”
- mod_wsgi.listener_port
- ‘8080’
- mod_wsgi.enable_sendfile
- ‘0’
- mod_wsgi.ignore_activity
- ‘0’
- mod_wsgi.request_start
- ‘1580613588392411’
- mod_wsgi.request_id
- ‘XjY-1MjfUl0pGWTY63U-OAAAAA0’
- mod_wsgi.script_start
- ‘1580613588404414’
- wsgi.version
- (1, 0)
- wsgi.multithread
- True
- wsgi.multiprocess
- True
- wsgi.run_once
- False
- wsgi.url_scheme
- ‘http’
- wsgi.errors
- <_io.TextIOWrapper name='
‘ encoding=’utf-8’> - wsgi.input
-
- wsgi.input_terminated
- True
- wsgi.file_wrapper
-
- apache.version
- (2, 4, 37)
- mod_wsgi.version
- (4, 6, 4)
- mod_wsgi.total_requests
- 3
- mod_wsgi.thread_id
- 4
- mod_wsgi.thread_requests
- 0