Monday, September 8, 2014

Dockerize Nginx with LDAP support

Nginx, by default doesn't come with LDAP integration. There is an addon script though that enables it to integrate with LDAP called nginx-auth-ldap. 

I've recently been tasked to come up with an implementation of this using docker virtualization technology and just wanted to share this so other won't have to go through the same process I did when I was testing this out.

Dockerfile content below:
# Nginx-Auth-LDAP Dockerfile

FROM ubuntu:latest

RUN apt-get update
RUN apt-get install -y wget build-essential libldap2-dev libssl-dev zlib1g-dev libpcre3 libpcre3-dev git libc6 libexpat1 libgd2-xpm-dev libgeoip1 libgeoip-dev libpam0g libssl1.0.0 libxml2 libxslt1.1 libxslt-dev zlib1g perl openssl
RUN cd /root && wget http://nginx.org/download/nginx-1.6.0.tar.gz && tar xvzf nginx-1.6.0.tar.gz
RUN cd /root/nginx-1.6.0 && git clone https://github.com/kvspb/nginx-auth-ldap.git
RUN mkdir -p /opt/nginx

ADD config /root/nginx-1.6.0/nginx-auth-ldap/config

RUN cd /root/nginx-1.6.0 && ./configure --prefix=/opt/nginx --user=www-data --group=www-data --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_gzip_static_module --with-http_stub_status_module --add-module=nginx-auth-ldap && make && make install 

ADD nginx /etc/init.d/nginx

RUN chmod +x /etc/init.d/nginx
ADD nginx.conf /opt/nginx/conf/nginx.conf

VOLUME ["/data", "/opt/nginx/sites-enabled", "/opt/nginx/log"]
EXPOSE 8000

WORKDIR /opt/nginx

CMD ["/etc/init.d/nginx", "start"]

config file content:
ngx_addon_name=ngx_http_auth_ldap_module
HTTP_MODULES="$HTTP_MODULES ngx_http_auth_ldap_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_auth_ldap_module.c"
CORE_LIBS="$CORE_LIBS -lldap -llber"
case "$NGX_PLATFORM" in
   SunOS:*)
       CORE_LIBS="$CORE_LIBS -llber"
   ;;
esac
CFLAGS="$CFLAGS"

CFLAGS="$CFLAGS"

nginx.conf file content:
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    ldap_server test1 {
        url ldap://ldapurl/DC=maindc,DC=com?sAMAccountName?sub?(objectClass=person);
        binddn "cn=root";
        binddn_passwd password;
        group_attribute uniquemember;
        group_attribute_is_dn on;
        require valid_user;
    }

server {
        listen       8000;
        server_name  localhost;

        auth_ldap "Forbidden";
        auth_ldap_servers test1;

        location / {
            root   html;
            index  index.html index.htm;
        }

     }    
}

nginx file content:
#! /bin/sh
### BEGIN INIT INFO
* Provides:          nginx
* Required-Start:    $all
* Required-Stop:     $all
* Default-Start:     2 3 4 5
* Default-Stop:      0 1 6
* Short-Description: starts the nginx web server
* Description:       starts nginx using start-stop-daemon
### END INIT INFO
PATH=/opt/nginx/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
* Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
  . /etc/default/nginx
fi
set -e
case "$1" in
  start)
  echo -n "Starting $DESC: "
  start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
    --exec $DAEMON -- $DAEMON_OPTS
  echo "$NAME."
  ;;
  stop)
  echo -n "Stopping $DESC: "
  start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
    --exec $DAEMON
  echo "$NAME."
  ;;
  restart|force-reload)
  echo -n "Restarting $DESC: "
  start-stop-daemon --stop --quiet --pidfile \
    /var/run/$NAME.pid --exec $DAEMON
  sleep 1
  start-stop-daemon --start --quiet --pidfile \
    /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
  echo "$NAME."
  ;;
  reload)
      echo -n "Reloading $DESC configuration: "
      start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
          --exec $DAEMON
      echo "$NAME."
      ;;
  *)
  N=/etc/init.d/$NAME
  echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
  exit 1
  ;;
esac
exit 0