Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Docker support for easier deployments #59

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
FROM python:3.11-slim
LABEL maintainer="github/alfonsrv <[email protected]>"

ENV APACHE_CONFDIR=/etc/apache2

RUN apt-get update \
&& apt-get install -y --no-install-recommends git \
apache2 libapache2-mod-wsgi-py3 \
krb5-k5tls \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN a2enmod wsgi \
&& a2enmod ssl \
&& a2enmod headers \
&& a2enmod setenvif

RUN ln -sf /proc/self/fd/1 /var/log/apache2/access.log && \
ln -sf /proc/self/fd/1 /var/log/apache2/error.log

COPY config/kdc-wsgi.conf ${APACHE_CONFDIR}/sites-available/

# Download + install kdcproxy and get install path to replace in apache config
RUN git clone https://github.com/latchset/kdcproxy.git /tmp/kdcproxy \
&& pip install /tmp/kdcproxy \
&& KDC_PROXY_PATH=$(python -c "import site; print(site.getsitepackages()[0])")/kdcproxy \
&& sed -ri -e "s!KDC_PROXY_PATH!${KDC_PROXY_PATH}!g" /etc/apache2/sites-available/*.conf \
&& sed -ri -e "s!SERVER_NAME!${SERVER_NAME}!g" /etc/apache2/sites-available/*.conf

RUN a2dissite 000-default.conf \
&& a2ensite kdc-wsgi.conf

CMD ["apachectl", "-D", "FOREGROUND"]
7 changes: 7 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# KDC Proxy Docker Container 🐋

* Rename `config/sample-kdcproxy.conf` to `config/kdcproxy.conf`
* Configure Domain Controller IP addresses via `extra_hosts` in `docker-compose.yml`
* Configure Realm and Domain Controller DNS Names in `config/kdcproxy.conf`
* Run `docker-compose up` and configure to run as service
* Run either behind reverse proxy or as a directly exposed server (bring your own certificates)
Empty file added docker/certs/.gitkeep
Empty file.
41 changes: 41 additions & 0 deletions docker/config/kdc-wsgi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<VirtualHost *:443>
ServerName SERVER_NAME
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLEngine on
SSLCertificateFile /certs/cert.crt
SSLCertificateKeyFile /certs/cert.key

# Prevent showing the default Apache2 website
RedirectMatch ^/(?!(?i:KdcProxy))(.*)$ https://opensource.org/

# Python WSGI KDC Proxy setup
WSGIDaemonProcess kdcproxy \
processes=2 \
threads=15 \
maximum-requests=1000 \
display-name=%{GROUP}
WSGIImportScript KDC_PROXY_PATH/__init__.py \
process-group=kdcproxy \
application-group=kdcproxy
WSGIScriptAliasMatch "(?i)^/KdcProxy" \
KDC_PROXY_PATH/__init__.py
WSGIScriptReloading Off

# Set headers if available
<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
<IfModule mod_headers.c>
RequestHeader set Host "%{REAL_HOST_HEADER}e"
</IfModule>
</IfModule>

<LocationMatch "(?i)^/KdcProxy">
Satisfy Any
Order Deny,Allow
Allow from all
WSGIProcessGroup kdcproxy
WSGIApplicationGroup kdcproxy
</LocationMatch>
</VirtualHost>
24 changes: 24 additions & 0 deletions docker/config/sample-kdcproxy.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[global]
# Use default libkrb5 configuration; if you load the mit config module in the master configuration file,
# kdcproxy will also read the config using libkrb5 (usually /etc/krb5.conf). If this module is used, kdcproxy
# will respect the DNS settings from the [libdefaults] section and the realm configuration from the [realms] section.
# For more information, see the documentation for MIT's krb5.conf.
configs = mit

# Use DNS SRV lookup to automatically resolve domain
use_dns = False

[CONTOSO.LOC]
# The realm configuration parameters may list multiple servers separated by a space.
# The order the realms are specified in will be respected by kdcproxy when forwarding requests. The port number is optional.
#
# Possible schemes are:
# * kerberos://
# * kerberos+tcp://
# * kerberos+udp://
# * kpasswd://
# * kpasswd+tcp://
# * kpasswd+udp://

kerberos = kerberos+tcp://test-dc1.contoso.loc:88
kpasswd = kpasswd+tcp://test-dc1.contoso.loc:464
45 changes: 45 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
version: '3'
services:
kdcproxy:
build:
context: .
dockerfile: ./Dockerfile
container_name: kdcproxy-apache
restart: unless-stopped
ports:
- "443:443"
environment:
- KDCPROXY_CONFIG=/config/kdcproxy.conf
- SERVER_NAME=${SERVER_NAME:-selfsign.rausys.de}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

his looks custom to your deployment or something, I am not sure we should have this file at all in the repository, sounds like configuration each deployment should deal with on their own.

volumes:
- config:/config:ro
- certs:/certs:ro
extra_hosts:
- "test-dc1.contoso.loc:10.10.10.10"

omgwtfssl:
image: paulczar/omgwtfssl
container_name: kdcproxy-ssl
restart: "no"
volumes:
- certs:/certs
environment:
- SSL_SUBJECT=${SERVER_NAME:-selfsign.rausys.de}
- SSL_KEY=/certs/cert.key
- SSL_CSR=/certs/cert.csr
- SSL_CERT=/certs/cert.crt

volumes:
config:
driver: local
driver_opts:
type: none
o: bind
device: ./config
certs:
driver: local
driver_opts:
type: none
o: bind
device: ./certs
1 change: 1 addition & 0 deletions kdcproxy/parse_pyasn1.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def decode_proxymessage(data):
realm = str(realm, "utf-8")
except TypeError: # Python 2.x
realm = str(realm)
realm = realm.upper()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you doing this ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now see your comment, realm is definitely a case sensitive name, even though Windows plays fast and lose with it. If you need a matching logic that is case -insensitive please do that. This change would break KDCs based on MIT kerberos or other more standard compliant Krb5 implementations.

else:
realm = None
flags = req.getComponentByName('flags')
Expand Down