Apache::AppSamurai - An Authenticating Reverse Proxy/Application Front End
"Protect your master, even if he is without honour...."
All configuration is done within Apache. Requires Apache 1.3.x and mod_perl 1.24 or above with StackedHandlers, MethodHandlers, Authen, and Authz compiled in. See "EXAMPLES" for a sample configuration snippet.
Apache::AppSamurai protects web applications by providing a sessionable, multi-factor authentication capable, and flexible front end for use in a reverse proxy configuration.
Unauthenticated users are presented with either a login form, or a basic authentication popup (depending on configuration.) User supplied credentials are checked against one or more authentication systems before the user's session is created and a session authentication cookie is passed back to the browser. Only authenticated and authorized requests are proxied through to the backend server.
Apache::AppSamurai is based on, and includes some code from, Apache::AuthCookie. Upon that core is added a full authentication and session handling framework. (No coding required.) Features include:
Modular authentication - Uses authentication sub-modules for the easy addition custom authentication methods
Form or basic user login - Forms for users, basic auth for client programs that are not form aware
Apache::Session - Used for core session handling
Session data encrypted on server - By default, all session data encrypted before storing to proxy's filesystem (Uses custom Apache::Session compatible session generator and session serialization modules)
Form based or Basic Auth login - On the front end, supports standard form based logins, or optionally Basic Auth login. (For use with automated systems that can not process a form.)
Apache::AppSamurai is meant to be relatively easy to configure and deploy for anyone familiar with Apache administration.
There are countless web interfaces and applications that are insecurely deployed to the Internet. Reverse proxies and Identity and Access Management systems are becoming widespread, and many greatly reduce the risk of Internet deployment. However, most systems are big and complicated. Fine for an organization-wide deployment, but too heavy for protecting one or a handful of apps.
Apache::AppSamurai is not a full request/response filtering proxy, nor is it part of a Single Sign On or Federation system. (Though it should integrate into one.) Future versions may add more extensive filtering, or include response filtering.
Server side session data may include sensitive information, including the basic authentication Authorization header to be sent to the backend server. (This is just a Base64 encoded value, revealing the username and password if stolen.)
Authorization
To protect the data on-disk, Apache::AppSamurai includes its own HMAC based session ID generator and AES encrypting session serializer. (Apache::AppSamurai::Session::Generate::HMAC_SHA and Apache::AppSamurai::Session::Serialize::CryptBase64 , respectively.) These modules are configured by default and may be used directly with Apache::Session, or outside of Apache::AppSamurai if desired.
Almost all options are set using PerlSetVar statements, and can be placed in any global, virtual server, directory, location, or files section.
PerlSetVar
Each configuration option must be prefixed by the AuthName for the Apache::AppSamurai instance you wish to apply the option to. This AuthName is then referenced within the protected area(s). Most of setups only require one AuthName. You can call it "BOB" or "MegaAuthProtection". You can even call it "authname".
IMPORTANT NOTE - The AuthName is omitted in the configuration descriptions below for brevity. "Example" is used as the AuthName in the "EXAMPLES" section.
Most setups will include a set of global configuration values to setup the Apache::AppSamurai instance. Each protected area then points to a specific AuthName and Apache::AppSamurai methods for authentication and authorization.
0|1
(Default: 0) Set to 1 to send debugging output to the Apache logs. (Note - you must have a log configured to catch errors, including debug level errors, to see the output.)
NAME
(Default:AUTHTYPE_AUTHNAME) The name of the session cookie to send to the browser.
PATH
(Default: undef) The URL path (location) of the proxy's login page for form based login. (Sample script provided with the Apache::AppSamurai distribution.)
(Default: /) The URL path to protect.
DOMAIN
(Default: not set) The optional domain to set for all session cookies. Do not configure this unless you are sure you need it: A misconfigured domain can result in session stealing.
All|Any
(Default: All) Set require behavior within protected areas. Either All to require all authentication checks to succeed, or Any to require only one to.
require
All
Any
(Default: 1) Set to 1 to require the secure flag to be set on the session cookie, forcing the use of SSL/TLS.
secure
(Default: 0) Set to 1 to require the Microsoft proprietary http-only flag to be set on session cookies.
http-only
Most authentication is specific to the authentication module(s) being used. Review their specific documentation while configuring.
METHOD1,METHOD2...
(Default: undef) A comma separated list of the authentication sub-modules to use. The order of the list must match the order of the credentials_X parameters in the login form. (Note - credential_0 is always the username, and is passed as such to all the authentication modules.)
credentials_X
credential_0
N1,N2,.. = REGEX
(Default: undef)
Custom mapping of Basic authentication password input to specific and separate individual credentials. This allows for AppSamurai to request basic authentication for an area, then split the input into credentials that can be checked against multiple targets, just like a form based login. This is very useful for clients, like Windows Mobile ActiveSync, that only support basic auth logins. Using this feature you can add SecurID or other additional authentication factors without having to pick only one.
The syntax is a bit odd. First, specify a list of the credential numbers you want mapped, in order they will be found within the input. Then create a regular expression that will match the input, and group each item you want mapped.
Example:
PerlSetVar BobAuthBasicAuthMap "2,1=(.+);([^;]+)"
If the user logs into the basic auth popup with the password: myRockinPassword;1234123456 ,the map above will set credential_1 as 1234123456 and credential_2 as myRockinPassword, then proceed as if the same were entered into a form login.
myRockinPassword;1234123456
1234123456
myRockinPassword
Authentication submodules usually have one or more required settings. All settings are passed using PerlSetVar directives with variable names prefixed with the AuthName and the module's name.
PerlSetVar BobAuthBasicLoginUrl C<https://bob.org/login>
For AuthName Bob, set the LoginUrl for the AuthBasic authentication module to https://bob.org/login
Bob
LoginUrl
AuthBasic
https://bob.org/login
See Apache::AppSamurai::AuthBase for general authentication module information. If you need an authentication type that is not supported by the authentication modules shipped with AppSamurai, and is not available as an add on module, please review Apache::AppSamurai::AuthBase and use the skeletal code from AuthTest.pm, which is included under /examples/auth/ in the AppSamurai distribution.
Each Apache::AppSamurai instance must have its local (proxy server side) session handling defined. Apache::Session provides the majority of the session framework. Around Apache::Session is wrapped Apache::AppSamurai::Session, which adds features to allow for more flexible selection of sub-modules.
Most Apache::Session style configuration options can be passed directly to the session system by prefixing them with authnameSession.
authnameSession
Module selection is slightly different than the default supplied with Apache::Session. Plain names, without any path or ::, are handled exactly the same: Modules are loaded from within the Apache::Session tree. Two additional alternatives are provided:
AppSamurai/MODULE - Load MODULE from under the Apache::AppSamurai::Session tree instead of the Apache::Session tree.
PATH::MODULE - Load PATH::MODULE literally. Note - Since :: is required to be present, a root module name will not work.
The most common configuration options follow. See Apache::AppSamurai::Session and Apache::Session for more advanced options, like using a database for storage.
NOTE - "Session" is shown prepending each of these directives, Inside the Apache::AppSamurai::Session and Apache::Session documentation, "Session" is omitted.
SECONDS
(Default: 0) The maximum session lifetime in seconds. After a user has been logged in this long, they are logged out. (Ignores weather the user is idle or not.)
The maximum time a session can be idle before being removed. After a user has not accessed the protected application for this many seconds, they are logged out.
(Default: File) The session storage module name. "File" is the default, which maps to Apache::Session::Store::File|Apache::Session::Store::File (Note - See the top of this section, "SESSION CONFIGURATION", for details on the three ways to specify a path for this option and the following options that point to a module.)
(Default: File) The session locking module name. "File" is used by default, which maps to Apache::Session::Lock::File|Apache::Session::Lock::File
(Default: AppSamurai/HMAC_SHA) The session ID generator module name. "AppSamurai/HMAC_SHA" is used by default, which maps to Apache::AppSamurai::Session::Generator::HMAC_SHA This special module takes a server key and a session authentication key and returns a HMAC code representing the local ("real") session ID. (Input and output are all SHA256 hex strings that are passed in using the sessionconfig hash.)
As this is tied closely into the current Apache::AppSamurai code, please do not use an alternate serializer without first reviewing the related code.
(Default: AppSamurai/CryptBase64) The session data serializer module. "AppSamurai/CryptBase64" is used by default, which maps to Apache::AppSamurai::Serialize::CryptBase64 This special module uses server key and a session authentication key to encrypt session data using AES before Base64 encoding it. (All keys are 256 bit hex strings.)
Base64 allows for storage in file, database, etc without worrying about binary data issues. In addition, this module allows for safer storage of data on disk, requiring both the local server key and the secret session key from the user before unlocking the data.
KEY
(Default: undef) Define the server's "server key". (This option is mutually exclusive with the SessionServerPass option.) If you configure ServerKey, it MUST be a 64 character hex string. (Use "SessionServerPass PASSPHRASE" if you prefer using an arbitrary length prase in your configuration.)
The server key is used to look up local session IDs and encrypt/decrypt them when the HMAC_SHA session generator and CryptBase64 session serializer are used.
As this is tied closely into the current AppSamurai code, it is a required configuration directive. Either ServerPass or ServerKey must be defined. Standard Apache::Session generator/serializer modules ignore this setting.
IMPORTANT NOTE FOR CLUSTERS/MULTIPLE PROXIES: If you use a shared session storage back end (database), and a cluster of AppSamurai proxies to protect a single application (using the same AuthName on each), you must use the same key or pass in the AuthName on each server in the cluster. The key is used both the authenticate the user and to decrypt the session data.
PASSPHRASE
(Default: undef) Sets an arbitrary length pass code that will be passed through SHA256 to produce the server's server key. See "SessionServerKey KEY" for how that key is used.
See Apache::AppSamurai::Session and Apache::Session for more on the session system.
The Tracker system is a based on a set of special Apache::Session stores that are visible between Apache processes. (In fact, with a shared central database, they could be visible to an entire cluster of servers.) It is provided to store various state information for built-in and add-on features.
Tracker storage uses Apache::AppSamurai::Tracker, which is a modified version of Apache::AppSamurai::Session.
Security Note - The Tracker system does not use encryption, so never store sensitive information in a tracker. If you need to track sensitive items, encrypt or hash them beforehand.
(Default: File) The tracker storage module name. "File" is the default, which maps to Apache::Session::Store::File|Apache::Session::Store::File (Note - See the top of this section, "SESSION CONFIGURATION", for details on the three ways to specify a path for this option and the following options that point to a module.)
(Default: File) The tracker locking module name. "File" is used by default, which maps to Apache::Session::Lock::File|Apache::Session::Lock::File
(Default: undef) If defined, tracked items that have been untouched in this many seconds are removed. In the future this may be configurable per-tracker type, but for now it provides a rudimentary cleanup system.
See Apache::AppSamurai::Tracker for more on tracker system configuration.
The following features require the tracker system to be configured. These are pretty basic and static at this point. (Should probably be split out into modules.)
COUNT:SECONDS
(Defualt: undef) Block further login attempts from IPs that send COUNT failures with no more than SECONDS seconds between each subsequent failure. Once blocked, the block will remain in effect till at least SECONDS has elapsed since the last connection attempt.
COUNT
(Default: 0) If set to 1, forces at least one credential to be unique per-login. (Requires dynamic token or other non-static authentication type.)
(Default: 0) If 1, prohibits a new session from using the same session ID as a previous session. This is generally only relevant for non-random sessions that use the Keysource directive to calculate a pseudo-cookie value.
Keysource
The following methods are to be used directly by Apache. (This is not a full list of all Apache::AppSamurai methods.)
Should be configured in the Apache config as the PerlAuthenHandler for areas protected by Apache::AppSamurai.
authenticate() is called by object reference and expects an Apache request object as input.authenticate() uses a session authentication key, either from a cookie or from the optional Keysource, and tries to open the session tied to the session authentication key.
authenticate()
If the session exists and is valid, the username is extracted from the session and the method returns OK to allow the request through.
OK
If no key is present, if the session is not present, or if the session is invalid, a login request is returned. (Either a redirect to a login form, or in the case of an area set to basic authentication, a 401 Authorization Required code.)
401 Authorization Required
Should be configured in the Apache config as the PerlAuthzHandler for areas protected by Apache::AppSamurai.
authorize() is called by object reference and expects an Apache request object as input. It then checks the authorization requirements for the requested location. In most cases, "require valid-user" is used in conjunction with the "Satisfy All" Apache::AppSamurai setting. This authorizes any logged in user to pass. This method could be replaced or expanded at a later date if more granular authorization is required. (Groups, roles, etc.)
authorize()
OK is returned if conditions are satisfied, otherwise FORBIDDEN is returned.
FORBIDDEN
Should be configured in the Apache config as the PerlHandler for a special pseudo file under the AppSamurai/ directory. In example configs and the example login.pl form page, the pseudo file is named LOGIN.
login() expects an Apache request with a list of credentials included as arguments. credential_0 is the username. All further credentials are mapped in order to the authentication modules defined in "AuthMethods". Each configured authentication method is checked, in order. If all succeed, a session is created and a session authentication cookie is returned along with a redirect to the page requested by the web browser.
login()
If login fails, the browser is redirected to the login form.
Should be called directly by your logout page or logout pseudo file. This expects an Apache request handle. It can also take a second option, which should be a scalar URI path to redirect users to after logout.
logout() attempts to look up and destroy the session tied to the passed in session authentication key.
logout()
## This is a partial configuration example showing most supported ## configuration options. See the examples/conf/ folder in the ## Apache::AppSamurai distribution for real-world example configs. ## General mod_perl setup ## # Apache::AppSamurai is always strict, warn, and taint clean. (Unless # I mucked something up ;) PerlWarn On PerlTaintCheck On PerlModule Apache::Registry # Load the main module and define configuration options for the # "Example" auth_name PerlModule Apache::AppSamurai PerlSetVar ExampleDebug 0 PerlSetVar ExampleCookieName MmmmCookies PerlSetVar ExamplePath / PerlSetVar ExampleLoginScript /login.pl # Defaults to All by may also be Any #PerlSetVar ExampleSatisty All # Optional session cookie domain (Avoid unless absolutely needed.) #PerlSetVar ExampleDomain ".thing.er" # Require secure sessions (default: 1) #PerlSetVar ExampleSecure 1 # Set proprietary MS flag PerlSetVar ExampleHttpOnly 1 # Define authentication sources, in order PerlSetVar ExampleAuthMethods "AuthRadius,AuthBasic" # Custom mapping of xxxxxx;yyyyyy Basic authentication password input # to specific and separate individual credentials. (default: undef) PerlSetVar ExampleBasicAuthMap "2,1=(.+);([^;]+)" ## Apache::AppSamurai::AuthRadius options ## # (Note - See L<Apache::AppSamurai::AuthRadius> for more info) PerlSetVar ExampleAuthRadiusConnect "192.168.168.168:1645" PerlSetVar ExampleAuthRadiusSecret "radiuspassword" ## Apache::AppSamurai::AuthBasic options.## # (Note - See L<Apache::AppSamurai::AuthBasic> for more info) # Set the URL to send Basic auth checks to PerlSetVar ExampleAuthBasicLoginUrl "https://ex.amp.le/thing/login" # Always send Basic authentication header to backend server PerlSetVar ExampleAuthBasicKeepAuth 1 # Capture cookies from AuthBasic login and set in client browser PerlSetVar ExampleAuthBasicPassBackCookies 1 # Abort the check unless the "realm" returned by the server matches PerlSetVar ExampleAuthBasicRequireRealm "blah.bleh.blech" # Pass the named header directly through to the AuthBasic server PerlSetVar ExampleAuthBasicUserAgent "header:User-Agent" ## Session storage options ## # (Note - See L<Apache::AppSamurai::Session> and L<Apache::Session> for # more information.) # Inactivity timeout (in seconds) PerlSetVar ExampleSessionTimeout 1800 # Use the File storage and lock types from Apache::Session PerlSetVar ExampleSessionStore "File" PerlSetVar ExampleSessionLock "File" # File storage options (Relevant only to File storage and lock types) PerlSetVar ExampleSessionDirectory "/var/www/session/sessions" PerlSetVar ExampleSessionLockDirectory "/var/www/session/slock" # Use the Apache::AppSamurai::Session::Generate::HMAC_SHA generator PerlSetVar ExampleSessionGenerate "AppSamurai/HMAC_SHA" # Use the Apache::AppSamurai::Session::Serialize::CryptBase64 # data serializer module. PerlSetVar ExampleSessionSerialize "AppSamurai/CryptBase64" # Set the server's encryption passphrase (for use with HMAC session # generation and/or encrypted session storage) PerlSetVar ExampleSessionServerPass "This is an example passphrase" ## Tracker storage options ## # Cleanup tracker entries that have not changed in 1 day PerlSetVar ExampleTrackerCleanup 86400 # Block further login attempts from IPs that send 10 failures with # no more than 60 seconds between each subsequent failure PerlSetVar ExampleIPFailures "10:60" # Force at least one credential to be unique per-login. (Requires # token or other non-static authentication type.) PerlSetVar ExampleAuthUnique 1 # Prohibit a new session from using the same session ID as a previous # session. (Only relevant for non-random sessions that use the # Keysource directive to calculate a pseudo-cookie.) PerlSetVar ExampleSessionUnique 1 ## Special AppSamurai directory options ## # (These will vary widely depending on your specific setup and requirements.) <Directory "/var/www/AppSamurai"> deny from all <FilesMatch "\.pl$"> SetHandler perl-script PerlHandler Apache::Registry Options +ExecCGI AuthType Apache::AppSamurai AuthName "Example" allow from all </FilesMatch> <Files LOGIN> SetHandler perl-script AuthType Apache::AppSamurai AuthName "Example" PerlHandler Apache::AppSamurai->login allow from all </Files> </Directory> <Directory "/var/www/AppSamurai/images"> Options None allow from all </Directory> # Protected/proxied resource config 1: Form based <Directory "proxy:https://ex.amp.le/thing/*"> AuthType Apache::AppSamurai AuthName "Example" PerlAuthenHandler Apache::AppSamurai->authenticate PerlAuthzHandler Apache::AppSamurai->authorize Order deny,allow Allow from all require valid-user </Directory> # Protected/proxied resource config 2: Basic auth <Directory "proxy:https://ex.amp.le/thaang/*"> AuthType Basic AuthName "Example" PerlAuthenHandler Apache::AppSamurai->authenticate PerlAuthzHandler Apache::AppSamurai->authorize # Add some local overrides to this directory. (Has # no affect on other directories/locations) # Switch from an inactivity timeout to a hard expiration PerlSetVar ExampleSessionExpire 3600 PerlSetVar ExampleSessionTimeout 0 # In lieu of cookies, calculate the session key using the # basic auth header from the client, and an argument called # "Sessionthing" from the request URL. (NOTE - Keysource # should be used with care! Do not use it unless you are # sure of what you are doing!!!) PerlAddVar ExampleKeysource header:Authorization PerlAddVar ExampleKeysource arg:Sessionthing Order deny,allow Allow from all require valid-user </Directory> # Do not allow forward proxying ProxyRequests Off # Proxy requests for /thing/* to https://ex.amp.le/thing/* RewriteRule ^/thing/(.*)$ https://ex.amp.le/thing/$1 [P] # Similar for /thaang/* RewriteRule ^/thaang/(.*)$ https://ex.amp.le/thaang/$1 [P] # Redirect requests to / into our default app RewriteRule ^/?$ /thing/ [R,L] # Allow in AppSamurai requests to proxy server RewriteRule ^/AppSamurai - # Capture logout URL from app and send to the AppSamurai logout RewriteRule ^/thing/logout\.asp$ /AppSamurai/logout.pl # Block all other requests RewriteRule .* - [F]
Additional authentication modules, tracking features, and other options can be added to Apache::AppSamurai. In the case of authentication modules, all that is required is creating a new module that inherits from Apache::AppSamurai::AuthBase.
Other features may be more difficult to add. (Apache::AppSamurai could use some refactoring.)
Interface and utility methods are not documented at this time. Please consult the code, and also the Apache::AuthCookie documentation.
Directory that holds Apache::AppSamurai login/logout pages and related content. This must be served by Apache and reachable. (This is generally mapped to /AppSamurai/ on the server.) When starting from scratch, copy the contents of /examples/htdocs/ from the Apache-AppSamurai distribution into this directory.
The default login mod_perl script. Must be modified to match your setup.
The default HTML login form template. (Split out from login.pl to ease customization.)
The default logout mod_perl script. (Must call the "logout()" method.)
Generic "deny all" robots file. (You don't want your login area appearing on Google. Note that the default login page also has a META tag to prevent indexing.)
Image files for login page.
Apache::AppSamurai::Session, Apache::AppSamurai::Tracker, Apache::AppSamurai::AuthBase, Apache::AppSamurai::AuthBasic, Apache::AppSamurai::AuthRadius, Apache::AppSamurai::Util, Apache::AppSamurai::Session::Generate::HMAC_SHA, Apache::AppSamurai::Session::Serialize::CryptBase64, Apache::Session
Paul M. Hirsch, <paul at voltagenoir.org>
<paul at voltagenoir.org>
Please report any bugs or feature requests to <paul at voltagnoir.org>
<paul at voltagnoir.org>
You can find documentation for this module with the perldoc command.
perldoc Apache::AppSamurai
You can also look for information at:
AppSamurai Project Homepage http://appsamurai.sourceforge.net
AppSamurai Project Homepage (backup) http://www.voltagenoir.org/AppSamurai/
AnnoCPAN: Annotated CPAN documentation http://annocpan.org/dist/Apache-AppSamurai
This system uses some code written by Ken Williams and the Apache::AuthCookie developers from the Apache::AuthCookie module. While all Apache::AuthCookie functionality has been rolled into the AppSamurai package, (based on Apache::AuthCookie version 3.10), this project would not exist without it.
Copyright 2007 Paul M. Hirsch, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Apache::AppSamurai, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Apache::AppSamurai
CPAN shell
perl -MCPAN -e shell install Apache::AppSamurai
For more information on module installation, please visit the detailed CPAN module installation guide.