Monday, 24 October 2016

Apache config with mod_auth_openidc & openam

Okay, so we compiled mod_auth_openidc recently and now it's time to configure Apache so we can interact with an OAuth2 server.

We'll do this with OpenAM - it's free and fun(ish) to configure & customise in a kinda weird way. I'll blog separately on a simple configuration for OpenAM.

Stay with the series, because we'll get to an Alexa skill in due course!

First up a confession.. brew install of apache. Although the compile worked fine, I couldn't get that version of apache to work with certificates from letsencrypt.. so I basically followed the same things in that post but for the apache version from macports instead. Note that macports is a bit more "general" with it's install locations, but it all basically follows the exact same pattern as I laid out in the previous post. If you want me to spell this out in detail, then comment below and I'll sort something out.

<IfModule auth_openidc_module>
  OIDCProviderIssuer https://external.server.location:443/openam/oauth2
  OIDCProviderAuthorizationEndpoint https://external.server.location/openam/oauth2/authorize
  OIDCProviderTokenEndpoint https://external.server.location/openam/oauth2/access_token
  OIDCProviderTokenEndpointAuth client_secret_post
  OIDCProviderUserInfoEndpoint https://external.server.location/openam/oauth2/userinfo
  OIDCSSLValidateServer Off
  OIDCClientID <MOD_CLIENT_ID>
  OIDCClientSecret <MOD_CLIENT_PASSWORD>
  OIDCScope "openid email"
  OIDCRedirectURI https://external.server.location/protect/redirect_uri
  OIDCProviderJwksUri https://external.server.location/openam/oauth2/connect/jwk_uri
  OIDCCryptoPassphrase <CRYPTO_PASSWORD>
  OIDCOAuthSSLValidateServer Off
  OIDCOAuthRemoteUserClaim user_id
  OIDCOAuthIntrospectionEndpoint https://external.server.location/openam/oauth2/introspect
  OIDCOAuthIntrospectionTokenParamName token
  OIDCOAuthClientID <OAUTH_CLIENT_ID>
  OIDCOAuthClientSecret <OAUTH_CLIENT_PASSWORD>
</IfModule>

so what does all this do? you'll notice 2 sections, one lot to do with OIDC and the other all prefixed with OIDCOAuth.

Well, I mentioned we're going for Alexa skill at the end of all this right? In this mode I need mod_auth_openidc to act as a OAuth2 Resource Provider aligned with the Alexa skill (more on this in the later post), and the second mode is mod_auth_openidc as an OpenIdConnect Resource Provider. I use this second mode to protect the resources for my web server.

 For OpenAM I use JwksUri so that the token I give out from OpenAM can be validated by mod_auth_openidc. To do this is has to know the uri endpoiint it can hit (OIDCProviderJwksUri).

The OIDCRedirectURI is a endpoint that mod_auth_openidc can be in full control of so do not think of putting a real resource in this location (but you'll need to protect it nonetheless!).

I use this to protect it

<Location /protect/>
    Authtype openid-connect
    require valid-user
</Location>

The redirect_uri bit is important to, so leave it in.

The OIDCProviderUserInfoEndpoint provides the openid connect user auth point and the OIDCProviderTokenEndpointAuth tells the method we're using (client secret post). The issuer needs to match your openam configuration - it is validted by mod_auth_openidc so check it and get it right! (I got this worng lots of times and it had me tearing what little hair remains out until I sussed out what this meant). The OIDCClientID and password are the client id and password for the web server bit of my world.

the other bit you might need is how to protect your locations for this web server mode. I use things like

<Location /your_root_here/>
    Authtype openid-connect
    require valid-user
</Location>

As you can see, basically the same as the fake resource that is protected by mod_auth_openidc redirect stuff the second bit id for resources that Alexa hits. (OIDCOAuth stuff!). I'll go into that later!

Well, that's it for tonight... more on Alexa to follow...

Tuesday, 4 October 2016

Securing Apache on OSX using mod_auth_openidc

mod_auth_openidc on OSX

I recently bought an Alexa, and thought it would be nice to hook that into my home automation mini projects.

The first thing I need to do therefore was to get serious on Authorization and Authentication. It's for my home, so I'm happy enough to terminate SSL at the Apache boundary and then allow everything in the DMZ to just play together. The basic was to just tweak my Apache to do the authorization and loop back to the authenticator if not authorized.

I came across this project mod_auth_openidc which looked like just what the doctor ordered. Well, not quite as it turns out.

You see I'm on OSX, and there was no distribution available. No matter, I'm a developer right, so I'll just build it!

Build it


git clone https://github.com/pingidentity/mod_auth_openidc.git

Let's just check the INSTALL

You will require development headers and tools for the following
dependencies:
 Apache (>=2.0)
 cjose (>=0.4.1)
 OpenSSL (>=0.9.8) (>=1.0.1 for Elliptic Curve support)
 Curl (>=?)
 Jansson (>=2.0) (JSON parser for C)
 pcre3 (>=?) (Regular Expressions support)
 pkg-config

Install pre-requistes

Okay, so I've got a little bit more stuff to do before configure time... not problem lets get it started

brew install curl
brew install openssl
brew install jansson
brew install pcre

I'd better get the apache stuff as well

brew install apr-util
brew install apr
brew tap homebrew/apache
brew install httpd24


Oh yeah... this is a mac so I'd better tweak my xcode links...(see here)
sw_vers -productVersion | grep -E '^10\.([89]|10)' >/dev/null && bash -c "[ -d /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain ] && sudo -u $(ls -ld /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain | awk '{print $3}') bash -c 'ln -vs XcodeDefault.xctoolchain /Applications/Xcode.app/Contents/Developer/Toolchains/OSX$(sw_vers -productVersion).xctoolchain' || sudo bash -c 'mkdir -vp /Applications/Xcode.app/Contents/Developer/Toolchains/OSX$(sw_vers -productVersion).xctoolchain/usr && for i in bin include lib libexec share; do ln -s /usr/${i} /Applications/Xcode.app/Contents/Developer/Toolchains/OSX$(sw_vers -productVersion).xctoolchain/usr/${i}; done'"

Note the httpd version - this is important - I built with httpd22 initially - don't do that!  It sounds like my initial thoughts on this were wrong! 2.2 should work fine (not checked, but I've been reliably informed it all works - I thought I had unknown symbols on 2.2, but I may have had other problems and came to the wrong conclusion)
and now for that cjose thing...

brew install cjose

ah. not present....

Oh well, I'm a developer, I'll build it...

Build pre-requisites


git clone https://github.com/cisco/cjose.git
cd cjose

now on to building it..

./configure CFLAGS="-I/usr/local/include" --with-openssl=/usr/local/opt/openssl --with-jansson=/usr/local/opt/jansson --prefix /usr/local/opt/cjose
make
make install

Note this install cjose into /usr/local/opt/cjose (that's the prefix part in configure! important!) - this is important, you'll need this for the mod_auth_openidc build!

Build mod_auth_openidc

change into your mod_auth_openidc directory,

brew install curl
export  CURL_CFLAGS=-I/usr/local/opt/curl/include
export CURL_LIBS=-L/usr/local/opt/curl/lib
./configure --with-apxs2=/usr/sbin/apxs

at this point, after doing a make and installing it to the httpd24 libexec and adding it in my config, it all went a bit wrong. Symbols and things not found. No matter, I'm a developer, right... I can do this... well... after getting some help from pings' mod_auth_openidc google group, I settled on this.

Edit the Makefile

change the CFLAGS and LIBS to...

CFLAGS=-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib -I/usr/local/opt/curl/include -I/usr/local/Cellar/jansson/2.7/include  -I/usr/local/opt/cjose/include -I/usr/local/Cellar/pcre/8.39/include  $(REDIS_CFLAGS)
LIBS=-lssl -lcrypto -lz  -L/usr/local/opt/curl/lib -lcurl -L/usr/local/Cellar/jansson/2.7/lib -ljansson  -L/usr/local/opt/cjose/lib -lcjose -L/usr/local/Cellar/pcre/8.39/lib -lpcre  $(REDIS_LIBS)

change the install directory to...
.PHONY: install
install: src/mod_auth_openidc.la
        /usr/sbin/apxs  -i -S LIBEXECDIR=/usr/local/Cellar/httpd24/2.4.23_2/libexec -n mod_auth_openidc src/mod_auth_openidc.la

now finish the build

make clean
make
make install
and we'd better check all those dependencies and things...
$ otool -L /usr/local/Cellar/httpd24/2.4.23_2/libexec/mod_auth_openidc.so 
/usr/local/Cellar/httpd24/2.4.23_2/libexec/mod_auth_openidc.so:
 /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
 /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
 /usr/local/opt/curl/lib/libcurl.4.dylib (compatibility version 9.0.0, current version 9.0.0)
 /usr/local/opt/cjose/lib/libcjose.0.dylib (compatibility version 1.0.0, current version 1.0.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
 /usr/local/opt/jansson/lib/libjansson.4.dylib (compatibility version 12.0.0, current version 12.0.0)
 /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
 /usr/local/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.7.0)
If you see that then I think you are good to go! now edit the httpd.conf... but we'll do that in a later blog