From 37fdc8641bae15e31804f2e610b7e9263b3cdbe7 Mon Sep 17 00:00:00 2001
From: "David\\ Beitey" <david@davidjb.com>
Date: Thu, 8 Jan 2015 12:47:31 +1000
Subject: [PATCH] Add initial config documentation

---
 CONFIG.rst | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 README.rst |  12 +-
 2 files changed, 341 insertions(+), 2 deletions(-)
 create mode 100644 CONFIG.rst

diff --git a/CONFIG.rst b/CONFIG.rst
new file mode 100644
index 0000000..9c5c9b1
--- /dev/null
+++ b/CONFIG.rst
@@ -0,0 +1,331 @@
+Configuration
+=============
+
+.. contents::
+   :local:
+   :backlinks: none
+
+Steps
+-----
+
+#. Obtain/rebuild Shibboleth SP with FastCGI support.
+#. Recompile Nginx with the ``nginx-http-shibboleth`` custom module.
+#. Configure Shibboleth FastCGI authorizer and reponsder applicatons to run.
+#. Configure Nginx to talk to both FastCGI authorizer and responder.
+#. Configure your Nginx application ``location`` block with ``shib_request
+   on``.
+#. Ensure your application code accepts the relevant incoming headers for
+   authN/authZ.
+
+Background
+----------
+
+Shibboleth supports Apache and IIS by default, but not Nginx.  The closest one
+gets to support is via FastCGI, which Shibboleth `does have
+<https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPFastCGIConfig>`_
+but the default distribution needs to be rebuilt to support it.  Nginx has
+support for FastCGI responders, but not for `FastCGI authorizers
+<http://www.fastcgi.com/drupal/node/22#S6.3>`_.  This current module,
+``nginx-http-shibboleth``, bridges this gap using sub-requests within Nginx.
+
+The design of Nginx is such that when handling sub-requests, it currently
+cannot forward the original request body, and likewise, cannot pass a
+sub-request response back to the client.  As such, this module does not fully
+comply with the FastCGI authorizer specification. However, for Shibboleth,
+these two factors are inconsequential as only HTTP redirections and HTTP
+headers (cookies) are used for authentication to succeed.
+
+
+Shibboleth SP with FastCGI Support
+----------------------------------
+
+For Debian-based distributions, your ``shibboleth-sp-utils`` package has
+likely already been built with FastCGI support, since default repositories
+feature the required FastCGI dev packages.
+
+For RPM-based distributions, you will either need to obtain a pre-built
+package with FastCGI support or build your own.  Since the ``fcgi-devel``
+libraries aren't present in RHEL or CentOS repositories, you likely require a
+thirty-party repository such as EPEL (or compile from source yourself).
+Recompilation of ``shibboleth-sp`` is simple, however, and an example script
+can be found at https://github.com/jcu-eresearch/shibboleth-fastcgi.
+
+
+Running the FastCGI authorizer and responder
+--------------------------------------------
+
+Nginx does not manage FastCGI applications and thus they must be running
+before Nginx can talk to them.
+
+A simple option is to use `Supervisor <http://supervisord.org/>`_ or another
+FastCGI controller to manage the applications.  An example Supervisor
+configuration to work with a rebuilt ``shibboleth-sp`` on 64-bit RHEL/CentOS
+looks like::
+
+    [fcgi-program:shibauthorizer]
+    command=/usr/lib64/shibboleth/shibauthorizer
+    socket=unix:///opt/shibboleth/shibauthorizer.sock
+    socket_owner=shibd:shibd
+    socket_mode=0660
+    user=shibd
+    stdout_logfile=/var/log/supervisor/shibauthorizer.log
+    stderr_logfile=/var/log/supervisor/shibauthorizer.error.log
+
+    [fcgi-program:shibresponder]
+    command=/usr/lib64/shibboleth/shibresponder
+    socket=unix:///opt/shibboleth/shibresponder.sock
+    socket_owner=shibd:shibd
+    socket_mode=0660
+    user=shibd
+    stdout_logfile=/var/log/supervisor/shibresponder.log
+    stderr_logfile=/var/log/supervisor/shibresponder.error.log
+
+Paths will need adjusting for Debian-based distributions, and the socket
+locations are arbitrary.  Make note of these socket locations as you will
+shortly configure Nginx with them.
+
+
+Compile Nginx with Shibboleth module
+--------------------------------------
+
+Compile Nginx with the ``nginx-http-shibboleth`` custom third-party module,
+following instructions at http://wiki.nginx.org/3rdPartyModules.  How you do
+this depends on your Nginx installation processes and existing workflow.  In
+general, however, you can clone this module from GitHub::
+
+    git clone https://github.com/nginx-shib/nginx-http-shibboleth.git
+
+and add it into your ``configure`` step of Nginx::
+
+    ./configure --add-module=/path/to/nginx-http-shibboleth
+
+Note that you'll almost certainly have other options being passed to
+``configure`` at the same time.  It may be easiest to re-build Nginx from your
+existing packages for your distribution, and patch the above ``configure``
+argument into the build processes.
+
+
+Configure Nginx
+---------------
+
+
+#. Configure one or more servers within your Nginx configuration like so.
+   You'll need the socket information for your FastCGI Shibboleth SP
+   applications.
+
+   The ``proxy_pass http://localhost:8080`` can be replaced
+   with whatever application or configuration should be receiving the
+   Shibboleth attributes as headers.  In my case, port 8080 is running Plone,
+   a Python-based CMS, but you might anything (PHP, FastCGI, etc) here.
+   Essentially, this is what would normally be the backend configured against
+   ``AuthType shibboleth`` in Apache.
+
+   .. code:: nginx
+
+      server {
+          listen 443 ssl;
+          ...
+
+          #FastCGI authorizer for Auth Request module
+          location = /shibauthorizer {
+              internal;
+              include fastcgi_params;
+              fastcgi_pass unix:/opt/shibboleth/shibauthorizer.sock;
+          }
+
+          #FastCGI responder for SSO
+          location /Shibboleth.sso {
+              include fastcgi_params;
+              fastcgi_pass unix:/opt/shibboleth/shibresponder.sock;
+          }
+
+          #Resources for the Shibboleth error pages. This can be customised.
+          location /shibboleth-sp {
+              alias /usr/share/shibboleth/;
+          }
+
+          #A secured location.  Here all incoming requests query the
+          #FastCGI authorizer.  Watch out for performance issues and spoofing.
+          location /secure {
+              more_clear_input_headers 'Variable-*' 'Shib-*' 'Remote-User' 'REMOTE_USER' 'Auth-Type' 'AUTH_TYPE';
+
+              #Add your attributes here. They get introduced as headers
+              #by the FastCGI authorizer so we must prevent spoofing.
+              more_clear_input_headers 'displayName' 'mail' 'persistent-id';
+              auth_request /shibauthorizer authorizer=on;
+              proxy_pass http://localhost:8080; 
+          }
+
+          #A secured location, but only a specific sub-path causes Shibboleth
+          #authentication.
+          location /secure2 {
+              proxy_pass http://localhost:8080; 
+
+              location = /secure2/shibboleth {
+                  more_clear_input_headers 'Variable-*' 'Shib-*' 'Remote-User' 'REMOTE_USER' 'Auth-Type' 'AUTH_TYPE';
+                  #Add your attributes here. They get introduced as headers
+                  #by the FastCGI authorizer so we must prevent spoofing.
+                  more_clear_input_headers 'displayName' 'mail' 'persistent-id';
+                  auth_request /shibauthorizer authorizer=on;
+                  proxy_pass http://localhost:8080; 
+              }
+          }
+      }
+
+   An explanation about the above is provided in the comments.  I should note
+   that:
+
+   * The first 3 locations are pure boilerplate for any host that requires
+     Shibboleth authentication, so you can (and should!) put these into an
+     ``include``-able configuration file and reuse them.
+
+   * The ``/shibboleth-sp`` location is purely there to help your default
+     install.  If you customise your error pages, feel free to change or delete
+     this location.
+
+   * Take note of the ``more_clear_input_headers`` calls. As the Shibboleth
+     authorizer will inject headers into the request before passing the
+     request onto the final upstream endpoint, you **must**
+     use these directives to protect from spoofing.  You should expand the 
+     second call to this directive when you have more incoming attributes 
+     from the Shibboleth authorizer.  Or else beware...
+
+   * The ``/secure`` location will ask the FastCGI authorizer for attributes
+     for **every** request that comes in. This may or may not be what you
+     want.  Keep in mind this means that each request will have Shibboleth
+     attributes dropped into the request for sending onto backend services,
+     and this will happen every time.  Did I mention for **every request**?
+
+   * The ``/secure2`` location only asks the FastCGI authorizer for auth
+     on a (very) specific sub-path.  Only upon the user hitting this specific
+     URL will the authentication process be triggered. This is a smarter
+     authentication technique to avoid extra overhead -- set the upstream
+     for the specific sub-path to be somewhere an application session is
+     created, and have that application session capture the Shibboleth
+     attributes.
+
+     Notice how the rest of the application doesn't refer to the authorizer.
+     This means the application can be used anonymously, too. Alternatively,
+     you can configure the ``requireSession`` option to be fa
+
+   * Adding the ``auth_request`` line into a location isn't all you need to
+     do to get the FastCGI authorizer to recognise your path as Shibboleth
+     protected.  You need to follow the instructions below and take care.
+
+#. Save the configuration and follow the next section.  You're almost done.
+
+
+Configuring Shibboleth to recognise secured paths
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Typically, within Apache, you can tell Shibboleth which paths to secure by
+using something like:
+
+.. code:: apache
+
+   <Location /secure>
+       ShibRequestSetting authType shibboleth
+       ShibRequestSetting requireSession false
+   </Location>
+
+However, the FastCGI authorizer for Shibboleth operates without such directives
+and thus path protection needs to be configured like it would be for IIS,
+using the ``<RequestMapper>`` configuration.  The same options are accepted
+within this section of the ``shibboleth2.xml`` configuration file, it's just
+that you need to know where to put them.  So let's do that.
+
+  
+#. Configure your ``shibboleth2.xml`` file like so.  Find the ``RequestMapper``
+   element and replace it with something like the following:
+
+   .. code:: xml
+
+       <RequestMapper type="XML">
+           <RequestMap>
+               <Host name="eresearch.jcu.edu.au"
+                     authType="shibboleth"
+                     requireSession="true"
+                     redirectToSSL="443">
+                   <Path name="/secure" />
+                   <Path name="/secure2/shibboleth" />
+                   ...
+               </Host>
+               ...
+           </RequestMap>
+       </RequestMapper>
+
+   Some notes:
+
+   * The Shibboleth FastCGI authorizer needs to see ``authType`` **and**
+     ``requireSession`` configured for the resultant path.  If they are not
+     present, then the authorizer will ignore the path it is passed and
+     the user will not be prompted for authentication (and you **will**
+     tear your hair out because no logging takes place!).
+
+   * ``<Path>`` names are **case sensitive** here.  You have hereby been warned!
+     -- although this shouldn't be too surprising to you hopefully.
+
+   * You can use other configuration items like ``<HostRegex>`` and
+     ``<PathRegex>`` and ``<AccessControl``> to configure what happens to 
+     requests.  Check out the documentation below - there's lots to learn. 
+
+   * An interesting aspect here is that configuration is inherited downwards
+     in the XML tree.  So, you could configure something like the ``authType``
+     on a ``<Host>`` and have it apply to all paths beneath it.
+
+     You don't need to do this, though.  You may put all the configuration
+     attributes onto the ``<Path>`` element, or even move them up to
+     higher levels in the tree if you want to reduce duplication.
+
+   * Nested ``<Path>`` elements will see their path segments being greedy.
+     So putting a path with ``name="shibboleth"`` within a path with
+     ``name="secure"`` really translates to a path with 
+     ``name="secure/shibboleth"``.  Whatever takes your fancy here.
+
+#. Once you're done, then restart the Shibboleth daemon, ensure that you
+   restart the Shibboleth FastCGI applications, and hard restart Nginx
+   just to make sure it finds those sockets::
+
+       service shibd restart
+       supervisorctl restart shibauthorizer shibresponder
+       service nginx restart
+
+   Assuming, of course, that you're using Supervisor to run your applications.
+   You should.  It's easy to work with and fun.  
+
+#. Try loading up your Shibboleth protected URL.  If all goes well, then you
+   should get a complete authentication cycle.  If not, check carefully through
+   everything above.
+
+Take a look at 
+https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMapper
+and
+https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPRequestMap
+for more information.
+
+Gotchas
+-------
+
+If you're experiencing issues with the Shibboleth authorizer appearing to fail
+to be invoked, check the following:
+
+* The authorizer requires a ``<Path>`` element in ``shib2.xml`` to be
+  *correctly* configured with ``authType`` and ``requireSession`` for auth to
+  take place.  If you don't (or say forget to restart ``shibd``), then the
+  authorizer will return a ``200 OK`` status response, which equates to
+  unconditionally allowing access.
+
+* No logs will get issued *anywhere* for anything related to the FastCGI
+  applications (standard ``shibd`` logging does apply, however).  If you're
+  testing for why the authentication cycle doesn't start, try killing your
+  FastCGI authorizer and make sure you see a ``502`` error come back from
+  Nginx.  If you still get a ``200``, then your ``shib_request`` configuration
+  in Nginx is probably wrong and the authorizer isn't being contacted.
+
+* When in doubt, hard restart the entire stack, and use something like ``curl``
+  to ensure you avoid any browser caching.
+
+* When in serious doubt, install a version of Nginx with debugging support,
+  configure full trace logging, and run it with your configuration instead.
+  If 
+
diff --git a/README.rst b/README.rst
index 07c8bf8..0dda562 100644
--- a/README.rst
+++ b/README.rst
@@ -89,8 +89,8 @@ Usage
     }
 
 
-Misc
-====
+Installation
+============
 
 To compile nginx with this module, use the::
 
@@ -100,3 +100,11 @@ option when you ``configure`` nginx.
 
 For further information on why this is a dedicated module, see
 http://forum.nginx.org/read.php?2,238523,238523#msg-238523
+
+
+Configuration
+=============
+
+For full details about configuring the Nginx/Shibboleth environment,
+see
+https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst.
-- 
GitLab