Apache::AppSamurai - An Authenticating Mod_Perl Front End
"Protect your master, even if he is without honour...."
All configuration is done within Apache. Requires Apache 1.3.x/mod_perl1 or Apache 2.0.x/mod_perl2. See "EXAMPLES" for sample configuration segments.
Apache::AppSamurai protects web applications from direct attack by unauthenticated users, and adds a flexible authentication front end to local or proxied applications with limited authentication options.
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:
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.)
To protect the data on-disk, Apache::AppSamurai includes its own HMAC based session ID generator and 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
and can be used inside most configuration sections.
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.
(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.)
(Default:AUTHTYPE_AUTHNAME) The name of the session cookie to send to the browser.
(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.
(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.
(Default: All) Set
require behaviour within protected areas.
All to require all authentication checks to succeed,
Any to require only one to.
(Default: 1) Set to 1 to require the
secure flag to be set on the session cookie,
forcing the use of SSL/TLS.
(Default: 0) Set to 1 to require the Microsoft proprietary
http-only flag to be set on session cookies.
(Default: undef) Set an optional hard coded destination URI path all users will be directed to after login. (While full URLs are allowed, a path starting in / is recommended.) This setting only applies so form based login. Basic Auth logins always follow the requested URL.
(Default: undef) Set an optional hard coded destination URI path all users will be directed to after logging out. (While full URLs are allowed, a path starting in / is recommended.) This setting only applies so form based login. Basic Auth logins always follow the requested URL.
If LogoutDestination is unset and LoginDestination is set, users will be directed to LoginDestination after logout. (This is to prevent a user from logging back into the logout URI, which would log them back out again. Oh the humanity!)
Most authentication is specific to the authentication module(s) being used. Review their specific documentation while configuring.
(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.
credential_0 is always the username,
and is passed as such to all the authentication modules.)
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.
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.
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>
Bob, set the
LoginUrl for the
AuthBasic authentication module to
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
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:
(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::Generate::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::Session::Serialize::CryptBase64 This special module uses server key and a session authentication key to encrypt session data using a block cipher 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.
Crypt::CBC is used with a support block cipher module to perform encryption/decryption. (See the next section for information on configuring a cipher.)
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: undef) Select the block cipher provider module for Apache::AppSamurai::Session::Serialize::CryptBase64 to use. For production, you should use this to configure a specific block cipher to use. If not set, the cipher is autodetected from the list below. (Note that autodetect is slow and picks the first cipher module it finds, which may not be the one you want.)
The following block cipher modules are currently allowed:
Crypt::Rijndael - AES implementation (default) Crypt::OpenSSL::AES - OpenSSL AES wrapper Crypt::Twofish - Twofish implementation Crypt::Blowfish - Blowfish implementation
See Apache::AppSamurai::Session::Serialize::CryptBase64 for more information.
(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.
(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.
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.)
(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.
(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.
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.
If the session exists and is valid, the username is extracted from the session and the method returns
OK to allow the request through.
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.)
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.)
OK is returned if conditions are satisfied, otherwise
HTTP_FORBIDDEN is returned.
Should be configured in the Apache config as the PerlHandler, (or "PerlResponseHandler" for mod_perl 2.x), 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.
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.
login(), you may create a special pseudo file named LOGOUT and use PerlHandler, (or "PerlResponseHandler" for mod_perl 2.x), to map it to the
logout() method. This is particularly handy when paired with mod_rewrite to map a specific application URI to a pseudo file mapped to
logout() (See "EXAMPLES" for a sample config that uses this method.)
## This is a partial configuration example showing most supported ## configuration options and a reverse proxy setup. See examples/conf/ ## in the Apache::AppSamurai distribution for real-world example configs. ## Apache 1.x/mod_perl 1.x settings are enabled with Apache 2.x/mod_perl 2.x ## config alternatives commented out. ("*FOR MODPERL2 USE:" precedes ## the Apache 2.x/mod_perl 2.x version of any alternative config items.) ## Note that example configs in examples/conf/ use IfDefine to support ## both version sets without having to comment out items. Also note that it ## is far too ugly looking to include in this example. ## 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 #*FOR MODPERL2 USE: # PerlSwitches -wT # PerlModule ModPerl::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 with Crypt::Rijndael (AES) as the block # cipher provider PerlSetVar ExampleSessionSerialize "AppSamurai/CryptBase64" PerlSetVar ExampleSessionSerializeCipher "Crypt::Rijndael" # 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/htdocs/AppSamurai"> AllowOverride None deny from all <FilesMatch "\.pl$"> SetHandler perl-script Options +ExecCGI AuthType Apache::AppSamurai AuthName "Example" PerlHandler Apache::Registry #*FOR MODPERL2 USE: #PerlResponseHandler ModPerl::Registry allow from all </FilesMatch> <Files LOGIN> SetHandler perl-script AuthType Apache::AppSamurai AuthName "Example" PerlHandler Apache::AppSamurai->login #*FOR MODPERL2 USE: #PerlResponseHandler Apache::AppSamurai->login allow from all </Files> <Files LOGOUT> SetHandler perl-script AuthType Apache::AppSamurai AuthName "Example" PerlHandler Apache::AppSamurai->logout #*FOR MODPERL2 USE: #PerlResponseHandler Apache::AppSamurai->logout allow from all </Files> </Directory> <Directory "/var/www/htdocs/AppSamurai/images"> Options None allow from all </Directory> # Protected/proxied resource config 1: Form based <Directory "proxy:https://ex.amp.le/thing/*"> #*FOR MODPERL2 USE: #<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> #*FOR MODPERL2 USE: #</Proxy> # Protected/proxied resource config 2: Basic auth <Directory "proxy:https://ex.amp.le/thaang/*"> #*FOR MODPERL2 USE: #<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> #*FOR MODPERL2 USE: #</Proxy> # 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 a pseudo page mapped to logout() RewriteRule ^/thing/logout\.asp$ /AppSamurai/LOGOUT # Block all other requests RewriteRule .* - [F] #*FOR MODPERL2 YOU MUST UNCOMMENT AND PUT THE FOLLOWING INSIDE # RELEVANT VirtualHost SECTIONS (For most Apache2 setups, this would be # the "<VirtualHost _default_:443>" section inside ssl.conf) # ## Enable rewrite engine inside virtualhost #RewriteEngine on ## Inherit rewrite settings from parent (global) #RewriteOptions inherit ## Enable proxy connections to SSL #SSLProxyEngine on
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.)
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::AuthSimple, Apache::AppSamurai::Util,Apache::AppSamurai::Session::Generate::HMAC_SHA, Apache::AppSamurai::Session::Serialize::CryptBase64, Apache::Session
Paul M. Hirsch,
<paul at voltagenoir.org>
Please report any bugs or feature requests to
<paul at voltagnoir.org>
You can find documentation for this module with the perldoc command.
You can also look for information at:
AppSamurai.pm (the main Apache::AppSamurai module), contains some code from Apache::AuthCookie, which was developed by Ken Williams and others. The included Apache::AuthCookie code is under the same licenses as Perl and under the following copyright:
Copyright (c) 2000 Ken Williams. All rights reserved.
Copyright 2008 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.