Sunday, November 9, 2014

Implementing Splunk SSO with Google Apps

Trying to setup Splunk with Google Apps authentication?

1. You can download a reverse proxy module for Nginx released by's engineering team. It requires installing Go (apt-get install go). You can compile it by typing go build, and the binary should be built.  The download link is listed below:

The instructions in the README walk you through what you need to do to setup with Google's API console. Since Google is phasing out OpenID support, using Google Oauth is now the expected way to authenticate.

To start running the proxy, you'll need the accepted Google Apps domain, the callback URL (should end with /oauth2/callback), client ID, and client secret from the Google API console.

./google_auth_proxy -cookie-secret=abcd -http-address= -redirect-url= -upstream= --client-secret=1234

2. Setup your Nginx configuration to reverse proxy to 4180:

server {
  listen 80;

  location / {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Scheme $scheme;
      proxy_connect_timeout 1;
      proxy_send_timeout 30;
      proxy_read_timeout 30;

3. Next, you'll have to setup your configuration in etc/system/local/web.conf with this config. The goal is to use the email address used during login, which gets passed as X-Forwarded-Email, to Splunk. SSOMode set to strict will require all logins to depend on this header.  The tools.proxy.on seems to be used for older Apache reverse proxy setups, but doesn't need to be used for this setup.

SSOMode = strict
trustedIP =
remoteUser = X-Forwarded-Email
tools.proxy.on = False

4. Before you restart Splunk, make sure to create your usernames as the email address.  If you need to rename your existing ones, you'll need to edit the Splunk etc/passwd entries manually.

5. Once you restart, Splunk provides a /debug/sso endpoint, which lets you verify that the X-Forwarded-Email is being set correctly.   If you have any issues, turn off SSOMode = permissive until your are confident that the reverse proxy is setup correctly.

Tuesday, October 21, 2014

Why do you need colons for gesture recognizers

Apparently stuff that interacts with Objective C API's needs them..

What does the parenthesis in Swift does..

The completion parameter in animateWithDuration takes a block which takes one boolean parameter. In swift, like in Obj C blocks, you must specify the parameters that a closure takes:
UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: {
    (value: Bool) in
    self.blurBg.hidden = true
The important part here is the (value: Bool) in. That tells the compiler that this closure takes a Bool labeled 'value' and returns void.
For reference, if you wanted to write a closure that returned a bool the syntax would be
{(value: Bool) -> bool in
    //your stuff

Thursday, October 16, 2014

pip lxml fails

Not sure when these errors started showing up for lxml, but pip install lxml started failing without disabling these CLANG options:
export CFLAGS=-Qunused-arguments
export CPPFLAGS=-Qunused-arguments

Friday, October 3, 2014

Internet Explorer 10's new compatibility view list

LinkedIn is listed as Emulate-IE9, which explains why anyone logging in via LinkedIn authentication has a User-Agent string that denotes IE9 even though they may have a later IE version.

Sunday, September 21, 2014

Why themes are not taken into account when using custom ArrayAdapters..

While trying to implement basic extensions of ArrayAdapter with a ListView (see, I noticed none of the themes that I used was being followed by the adapter:
   if (convertView == null) {
          convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false);

It turns out that the use of getContext() matters a lot.  I found that if I used parent.getContext(), the styles do get applied.
   if (convertView == null) {
          convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false);

Here is more background of why getContext() use matters..

The less obvious issue is inflating layouts. If you read my last piece on layout inflation, you already know that it can be a slightly mysterious process with some hidden behaviors; using the right Context is linked to another one of those behaviors. While the framework will not complain and will return a perfectly good view hierarchy from a LayoutInflater created with the application context, the themes and styles from your app will not be considered in the process. This is because Activity is the only Context on which the themes defined in your manifest are actually attached. Any other instance will use the system default theme to inflate your views, leading to a display output you probably didn’t expect.

Thursday, August 28, 2014

Patching OpenSSL in Python

Ubuntu 14.04 comes with a newer version of OpenSSL 1.0.1, which can cause TLS Client Hello messages on some web servers to break (, especially when sending a handshake of more than 255 bytes.  With additional cipher suites and extensions, this number can easily exceed the expected amount.  By doing a tshark capture on port 443, we can see that the actual payload is 267 bytes:
tshark port 443

SSL Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 267
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 263
            Version: TLS 1.2 (0x0303)
                gmt_unix_time: Aug 26, 1973 10:35:41.000000000 UTC
                random_bytes: 46f445e55a639f227706f911bac2c2b312e64fa6f95dd630...
            Session ID Length: 0
            Cipher Suites Length: 86
            Cipher Suites (43 suites)

How to avoid this issue?  If you're using the Python requests library, one way is to take advantage of the PyOpenSSL extensions that will patch the underlying SSL implementation (  This way, you don't need to get into the nitty/gritty details of patching the code yourself.  

In order to do so, you must first install the libffi-dev package before doing a pip install:
pip install pyopenssl ndg-httpsclient pyasn1
The requests library automatically tries to import this library (see, but in order to fix the above issue, you may have to set the DEFAULT_SSL_CIPHER_LIST to MEDIUM instead of DEFAULT. Note: do not make this change unless you understand the implications to reduce the cipher strength. For more options, see
# Attempt to enable urllib3's SNI support, if possible
from requests.packages.urllib3.contrib import pyopenssl
One other issue to note: pip installs also rely on the requests library, so adding this change will also enable certificate validation.  Be sure to be using pip v1.5.6 since older pip installs have 301/302 redirect issues when using this package.

Addendum: you can download and use to probe the supported ciphers (i.e. python --sslv3 AES-128 and AES-256 based encryption may need to be added to your cipher list.