create new tag
, view all tags
ALERT! NOTE: This is a SupplementalDocument topic which is not included with the official TWiki distribution. Please help maintain high quality documentation by fixing any errors or incomplete content. Put questions and suggestions concerning the documentation of this topic in the comments section below! Use the Support web for problems you are having using TWiki.

Using SSL For Authentication Only

This topic presents a method that is successfully used to avoid transmitting passwords in plain-text readable form over a network.

Scope and Context

The method works with Apache 2 on Unix. It might also work with older Apache versions and Apache on Windows, but that has not been tested.

The method has a gotcha: Each run of configure damages it; one has to change a file afterwards. Refer to #CfgPatch for more information.

The presented configuration assumes that the whole server is used for TWiki (e.g., it might be a virtual server in your setup) and that one wants to use short TWiki URLs in such a setup. It is possible to use the same method for long (standard) TWiki URLs and when TWiki is not the only content that's served. Then the configuration must be adapted.

To make the following text more readable, we use some names and directory paths that you have to adapt to your local situation:

  • Web site name: wiki.example.com
  • Web server's IP address:
  • TWiki installation directory: /var/www/twiki
  • Apache configuration directory: /etc/apache2
Substitute your site-specific values accordingly.

For The Unpatient

  • You don't like reading documentation?
  • You are able to change your Apache configuration (named httpd.conf or apache2.conf) and are not restricted to .htaccess?
  • You didn't change many internal paths during configure?

Well, then you can proceed as follows:

  1. Download all attachments (5 files) of this topic to one directory.
  2. There, execute the command
         sh ssl-setup.sh wiki.example.com /var/www/twiki
  3. Create the directory /etc/apache2/include.d. From your download directory, copy twiki.full-server to that directory.
  4. The file wiki.example.com (i.e., the file with the same name as your Web server) contains the definitions for two virtual servers: One is an HTTP server, one is an HTTPS server, both are managed by TWiki. Use this file in the appropriate place for virtual host definitions in your Apache installation.
  5. Place your SSL key file into /etc/apache2/ssl/wiki.example.com.key and your SSL certificate into /etc/apache2/ssl/wiki.example.com.crt.
  6. Restart your Apache Web server.
  7. Use your Web browser to access https://wiki.example.com/configure; create your configuration as described in the TWikiInstallationGuide.
  8. Copy LocalSite.cfg.patch from the download directory to your TWiki lib directory. Go there and issue the command
        patch LocalSite.cfg <LocalSite.cfg.patch
  9. Change include.d/twiki.full-server and add a Deny from all clause to the access authentication of configure. Reload Apache to activate that change.

This should configure your TWiki site. You can access it as http://wiki.example.com/.

Try it out: Add the content of HttpUnauthorized.txt as Main.HttpUnauthorized topic. (This is not only a test; that topic is needed by the installation.)

Stop Every time that you use configure again, e.g., to install plugins, you need to run the patch command again afterwards, as specified above.

ALERT! Sorry, but I don't know of any other way to make the necessary changes to LocalSite.cfg permanent.

If the process doesn't work; well, then you need to learn what this configuration is all about, and you need to adapt it to your installation. But don't worry, it ain't too difficult.

Basics: Problem and Solution Approach

Most TWiki installations on a “normal” non-SSL Web server. Such typical installations use basic authentication for all write access (edit, manage) and maybe even authenticates read access to some topics.

In such an installation, passwords are sent unencrypted over the network in two cases:

  1. All authenticated accesses (passwords are transmitted in the HTTP request header).
  2. All forms where users enter passwords: The registration form and forms to change passwords or email addresses.
Sending unencrypted plain-text passwords is not a good idea. That's obvious in an Internet context where you'll never know who listens to your traffic. But it is also a bad idea for Intranet environments where Bad Guys might listen to your passwords because they know that most people use similar passwords for several systems. In fact, many Intranet company policies explicitly forbid deployment of applications that use plain-text passwords without encryption. (This topic's author is one of the consultants who insist on such clauses in security policies... smile )

On the other hand, it is often not sensible to use encrypted traffic for all communication. Frankly, for TWiki that's the most easy implementation: Just put the whole TWiki on a secure Web server (a.k.a. HTTPS or SSL server), and both read and write access will be encrypted. But this approach has disadvantages, too:

  • Owing to the encryption, HTTPS servers need much more computation power than HTTP servers. One needs more powerful systems, or one can not place as many Web servers on one system.
  • SSL connection overhead is larger. This means that page load time is longer, which is always a Bad Thing(tm).
  • If you don't have an “official" certificate, your users will get security popup warnings when they access the SSL server. If we use SSL only for traffic that transmit passwords, such security warnings are issued much less often. If you have many more TWiki readers than writers, this might be the difference between a good and a bad first impression -- and we all know the importance of good first impressions, don't we?

Therefore, we want to use SSL only for traffic that contains passwords. We have two server instances (virtual hosts) for our TWiki:

  1. http://wiki.example.com for normal read traffic.
  2. https://wiki.example.com for traffic with passwords.
(I'd like to note here that virtual HTTPS servers are not a problem anymore, they are supported by all modern browsers.)

We use URL redirection to send traffic to the right server:

  • Requests where authentication is needed are redirected from the HTTP to the HTTPS server. Only the HTTPS server demands authentication, not the HTTP server.
  • Requests for forms that contain passwords are redirected from the HTTP to the HTTPS server. Redirecting the form's action URL on the server is not sufficient; the password would have been sent already unencrypted to the server.
  • Requests without passwords are redirected from the HTTPS to the HTTP server. This takes care of the case that we edited something and then view it again -- without this redirection we would afterwards stay at the HTTPS server also for unauthenticated read accesses.
Technically, we must take more cases into account because URL rewriting is accessed in more places. We will explain that below when we list the configuration.

Configuration in Detail

Since we will set up two server instances, we will first create the file twiki.full-server with TWiki-specific configuration that can be used independent of the server context. I.e., it can be used both in the HTTP and the HTTPS server. Then I will present the needed Apache configuration. Finally, a change in LocalSite.cfg is necessary.

TIP The presented configuration also shortens the URLs, as in ShorterUrlCookbook. The configuration can be easily adapted to the case of standard URLs, where not the complete server content is managed by TWiki. Of course, the configuration file should not be named twiki.full-server then, maybe only twiki.ssl-redirect or so.

TWiki Apache Configuration With Request Redirection

The Apache standard module mod_rewrite is used for URL redirection. (This section explains the attachment twiki.full-server.tmpl.)

But let's first start with the basic setup: We need to tell Apache where the TWiki scripts are and which of those scripts are authenticated.

  • It is mandatory that one uses the FilesMatch and Files directive to set up authentication and not Location: The latter would be checked too early in Apache's processing.
  • I use a special section for the authentication of configure. After the installation is finished, one adds a Deny from all clause there; or at least restrict the access to just the TWiki administrators.
  • Error documents are a special problem that we will need to explain in detail later.
Of course, you might have other directory path names than shown here.

  <Directory "/var/www/twiki/bin">
          Options       ExecCGI
          SetHandler    cgi-script
          Allow from all

          # Demand authentication
          AuthUserFile /var/www/twiki/data/.htpasswd
          AuthName 'Enter your WikiName: (First name and last name, no space, no dots, capitalized, e.g. JohnSmith). Cancel to register if you do not have one.'
          AuthType Basic

          <FilesMatch "(attach|edit|manage|rename|save|upload|mail|logon|.*auth).*">
                  require valid-user

          <Files "configure">
                  # Sadly, I cannot use TWiki groups here.
                  #require user TWIKI_ADMIN
                  require valid-user

          # File to return on access control error (e.g. no authentication or
          # wrong password) By convention this is the TWikiRegistration page,
          # that allows users to register with the TWiki. But the registration
          # page must only be used on our HTTPS server and Apache requires
          # this to be a *local* path; we will explain and ensure proper
          # behaviour later with our rewrite rules. For now it must suffice
          # that the error URL is abstract and does not really exist.
          ErrorDocument 401 /unathorized.to_be_rewritten

Access to the pub directory tree is allowed, but access to all other data directores are forbidden. Please note the comment about the used MIME type in the /pub section that's different than the one proposed in the 4.1.2 distribution.

  # Take care for access to pub directory tree. Turn off dangerous material.
  <Location "/pub">
          # Disallow PHP here if it's used.
          <IfModule mod_php3.c>
                  php3_engine off
          <IfModule mod_php5.c>
                  php_flag engine off
          <IfModule mod_php5.c>
                  php_flag engine off

          # Deliver many problematic attachments as download material.
          # We don't want to allow HTML attachments with XSS attacks. :-)
          # NOTE: Do not use application/octet-stream here; that MIME type is
          # regarded as "ambiguous" by IE and the actual file type will be
          # guessed and maybe executed on the client. See
          # http://msdn2.microsoft.com/en-us/library/ms775147.aspx for a
          # description of that brain-dead behaviour.
          # NOTE 2: Do not use text/plain either, as in the example from the
          # 4.1.2 distribution. It's not only a security risk and open your
          # site to XSS attacks, the intended purpose is questionable --
          # HTML, PHP and CGI attachments shall probably better be
          # downloaded and not shown.
          AddType application/x-download .html .htm .shtml .php .php3 .phtml .phtm .pl .py .cgi

  # Don't allow direct access to TWiki data URLs.
  # /tmp is added because it's an obvious choice to store session cookies.
  <LocationMatch "^/(data|lib|locale|templates|tmp|tools)">
          Order deny,allow
          Deny from all

Great, basic setup is done. Now we arrived at the part where URL redirection is configured.

We want really short URLs: Unauthenticated read access is done by http://wiki.example.com/Web/WikiTopic. No action in the URL at all, just name the page.

Write access, management actions, and authenticated read access are immediate top-level relative URLs at an HTTPS server. I.e., no /bin prefix, that's not needed. These URLs don't conflict with Web names, as all our Web names start with uppercase characters. They also don't conflict with /pub.

The use of mod_rewrite is hardwired in the TWiki configuration, without that module it wouldn't work. Therefore we have no IfModule here, without mod_rewrite we want to get an error.

  RewriteEngine on

Looking at the rewriting logs, we see that /pub URLs are most often requested: Here are the icons, where multiple of them are used per page. Even though they all return a not_changed response, they must traverse the rewriting rules first. So we shortcut them, no need to use all other tests on them. Flag PT means pass through to other URL-to-filename mapping, and L means to stop rewriting (last rule).

  RewriteRule ^/pub             - [PT,L]

Next we need to handle the 401 ErrorDocument; i.e., the document that tells a user that authentication has not succeeded or has been aborted. This document is sent by the server together with a password challenge and is shown when the user presses cancel on the password popup dialog. Above, we defined an abstract URL for it, that must now be matched to a file. This must never be redirected to an external server, otherwise the “client will not know to prompt the user for a password since it will not receive the 401 status code”. (From the Apache 2.2 documentation about the ErrorDocument directive.) Therefore we must assure that this URL is always satisfied by a file on the current server instance.

If our setup is correct, 401 responses can only be delivered on the HTTPS server: Only there authenticated requests are made at all. There we can also use the TWikiRegistration page, as intended. But we also care for the case of an incorrect setup and provide an alternative page for 401 responses in HTTP servers. This is a new page that is not part of the TWiki distribution.

  Rewritecond %{HTTPS}          =on
  RewriteRule ^/unathorized.to_be_rewritten /TWiki/TWikiRegistration
  Rewritecond %{HTTPS}          =off
  RewriteRule ^/unathorized.to_be_rewritten /Main/HttpUnauthorized

Next, forward all HTTP requests with forms that contain passwords to the HTTPS server -- we want encryption of the form content. Make sure that these requests stay at the HTTPS server and are not redirected back: Map them to the actual script that serves them and make the rewrite engine stop rewriting (flag L). Flag NE (no escape) tells no escaping of URL chars, R demands a permanent redirect.

  Rewritecond %{HTTPS}          =off
  RewriteRule ^/TWiki/(ChangeEmailAddress|.*Registration|.*Password).*  https://%{SERVER_NAME}$0  [NE,R=permanent,L]
  Rewritecond %{HTTPS}          =on
  RewriteRule ^/TWiki/(ChangeEmailAddress|.*Registration|.*Password).*  /var/www/twiki/bin/view$0 [L]

If you use other registration forms, you need to add equivalent rewrite rules for them. E.g., if one has localized registration and password change forms in the Main web, we would add the following rules:

  Rewritecond %{HTTPS}          =off
  RewriteRule ^/Main/(.*Registration).*  https://%{SERVER_NAME}$0  [NE,R=permanent,L]
  Rewritecond %{HTTPS}          =on
  RewriteRule ^/Main/(.*Registration).*  /var/www/twiki/bin/view$0 [L]

We can now care for the general switch between our HTTP and HTTPS server instances with the same name.

First, on the HTTP server all authenticated requests are redirected to the HTTPS server.

  RewriteCond %{HTTPS}          =off
  RewriteRule ^/(attach|edit|manage|rename|save|upload|mail|logon|\w+auth|configure).*  https://%{SERVER_NAME}$0 [NE,R=permanent,L]

On the HTTPS server, all non-authenticated user requests are redirected to the HTTP server. That's the requirement, and now we need to digress to some technical details how Apache works.

If we send an HTTP request, rewriting is not only used to determine how that URL is to be served.

  • If that request must be authenticated, another internal round of URL rewriting is used to determine the filename of the ErrorDocument. This must always be a local file; that requirement is handled above. That request is a normal redirection request.
  • All TWiki URLs have pathinfo parts. URL rewriting is used to map that part to a potential filename in the server's document root (called the path_translated parameter). In TWiki, that path_translated parameter is not used and does not exist anyhow, but nevertheless it is constructed. Such a request is called a sub-request, and luckily mod_rewrite allows to mask its rules that these requests are skipped for rewriting -- after all, we don't want a redirection triggered for them.

Thus, the complete URL is redirected if our request belongs not to the authenticated ones and is also not a subrequest (flag NS). A technical detail is that we must not use the negated match in the actual rewrite rule: In a negated match, $0 is always empty, we would redirect to the home page. Therefore we use rule chaining (flag C) to trigger the next rule if the negated test matches.

  RewriteCond %{HTTPS}          =on
  RewriteRule !^/(attach|edit|manage|rename|save|upload|mail|logon|\w+auth|configure|environment.cgi) - [NS,C]
  RewriteRule ^.*               http://%{SERVER_NAME}$0 [NE,R=permanent,L]

If we didn't get redirected, we're one of

  • an initial authenticated action on the HTTPS server
  • an initial authenticated action on the HTTP server
  • a subrequest on either the HTTP or the HTTPS server
  • a read-access URL that looks like /Web/TopicName on the HTTP server.
Let's handle the latter case: we rewrite all URLs that start with uppercase letters to use the view script. This is used for all unauthenticated views, and for subrequests of authenticated actions.
  RewriteRule ^/[A-Z].*         /var/www/twiki/bin/view$0  [L]

When we have not been redirected or no final filename has been determined, the rewrite module passes the URL to other URL-to-filename modules. According to the case above, we have now an action that shall be done in the current server. We provide ScriptAlias definitions for all actions, even though only some of them will be actually used -- the others will have been redirected above. But this way we can use the same definitions for both server instances, some of them are simply never invoked.

The actions are without any .../bin prefix. Please note that we still add a ScriptAlias definition for /view, in case some script constructs such a URL in spite our short-URL configuration. (That cares for the wrong base href bug in TWiki 4.1.2, see Bugs:Item3968.)

  ScriptAlias /attach           /var/www/twiki/bin/attach
  ScriptAlias /configure        /var/www/twiki/bin/configure
  ScriptAlias /changes          /var/www/twiki/bin/changes
  ScriptAlias /edit             /var/www/twiki/bin/edit
  ScriptAlias /login            /var/www/twiki/bin/login
  ScriptAlias /logon            /var/www/twiki/bin/logon
  ScriptAlias /manage           /var/www/twiki/bin/manage
  ScriptAlias /oops             /var/www/twiki/bin/oops
  ScriptAlias /passwd           /var/www/twiki/bin/passwd
  ScriptAlias /preview          /var/www/twiki/bin/preview
  ScriptAlias /rdiff            /var/www/twiki/bin/rdiff
  ScriptAlias /rdiffauth        /var/www/twiki/bin/rdiffauth
  ScriptAlias /register         /var/www/twiki/bin/register
  ScriptAlias /rename           /var/www/twiki/bin/rename
  ScriptAlias /resetpasswd      /var/www/twiki/bin/resetpasswd
  ScriptAlias /rest             /var/www/twiki/bin/rest
  ScriptAlias /save             /var/www/twiki/bin/save
  ScriptAlias /search           /var/www/twiki/bin/search
  ScriptAlias /statistics       var/www/twiki/bin/statistics
  # twiki is a dispatcher script; not used directly
  #ScriptAlias /twiki           /var/www/twiki/bin/twiki
  ScriptAlias /upload           /var/www/twiki/bin/upload
  ScriptAlias /view             /var/www/twiki/bin/view
  ScriptAlias /viewauth         /var/www/twiki/bin/viewauth
  ScriptAlias /viewfile         /var/www/twiki/bin/viewfile

Configuration of Apache Virtual Hosts

ALERT! Again, remember that you need to adapt hostnames, IP addresses, and directory names to your installation.

There's not much to say about that configuration, so we just list it in full. (This section explains the attachment vhost.tmpl.)

  # This file holds the configuration of the Web server
  # wiki.example.com.
  # The complete server content is managed by TWiki.
  # There exists two instances of that server: http and https. I.e., one
  # where traffic is unencrypted and one where traffic is secure. Any
  # traffic that sends plain-text passwords is done over SSL.


  ServerName wiki.example.com
  #ServerAlias alias.domain.tld
  UseCanonicalName On

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn
  ErrorLog /var/log/apache2/error.log
  CustomLog /var/log/apache2/access.log combined
  # Rewrite log is only needed for debugging.
  RewriteLog /var/log/apache2/rewrite.log
  RewriteLogLevel 0

  # Content basics

  DocumentRoot "/var/www/twiki"

  # Turn over content management to TWiki:
  Include include.d/twiki.full-server

  # Let's also add a specification for the homepage of this server.
  # We refrain from rewrite-by-redirection; we might want to use a different
  # page in the future for the homepage.
  RewriteRule ^/$               /var/www/twiki/bin/view/Main/WebHome [L]



  ServerName wiki.example.com
  UseCanonicalName On

  # The www.dante.de cert has (actually, should have) wiki.example.com in its
  # alternate names list.
  SSLEngine on
  SSLCertificateKeyFile ssl/wiki.example.com.key
  SSLCertificateFile    ssl/wiki.example.com.crt
  <Location "/">

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn
  ErrorLog /var/log/apache2/ssl-error.log
  CustomLog /var/log/apache2/ssl-access.log combined
  CustomLog /var/log/apache2/ssl-request.log            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
  # Rewrite log is only needed for debugging.
  RewriteLog /var/log/apache2/wiki.example.com/ssl-rewrite.log
  RewriteLogLevel 0

  # Content basics

  DocumentRoot "/var/www/twiki"

  # Turn over content management to TWiki:
  Include include.d/twiki.full-server


Patch LocalSite.cfg

That's the most hairy part of the whole configuration. (This section explains the attachment LocalSite.cfg.patch.tmpl.)

TWiki uses information from LocalSite.cfg (which gets created or updated by running configure) to construct URLs in links, in particular the URL host part in DefaultUrlHost. It uses a fixed string for that information. But we need variability here:

  • If we're on the secure site, that parameter must be https://wiki.example.com.
  • If we're on the normal site, that parameter must be http://wiki.example.com (without `s').

ALERT! I have found only one method to achieve that objective: I patch LocalSite.cfg every time after I ran configure. For that I exchange the line

  $TWiki::cfg{DefaultUrlHost} = 'https://wiki.example.com';
  $TWiki::cfg{DefaultUrlHost} = ( defined($ENV{HTTPS}) && $ENV{HTTPS} eq 'on' ? 'https://wiki.example.com' : 'http://wiki.example.com' );
Please note that $ENV{SCRIPT_URI} should not be used here, we might not be in a CGI environment.

To ease these updates, I use a patch file that is attached to this topic.

Add Missing ErrorDocument Page

The configuration above should actually not allow authentication requests over HTTP. To enhance the robustness of our realization, we play save and make nevertheless an ErrorDocument for that case available.

Attached is HttpUnauthorized.txt; you can use that as content for the topic Main.HttpUnauthorized. (If you use an other topic name, you need to adapt the RewriteRule above.)

-- Contributors: JoachimSchrod - 30 Apr 2007

Comments & Questions about this Supplemental Document Topic

Please add your comments where the description can or should be improved. Or where you need clarification why I used that approach and not some other mean. Of course, if you can point out errors or simplifications to achieve the same functionality, that would even be better.

And add your proposals what you deem important to add. (Though some of them might be better explained in separate topics.) E.g., what is more important:

  • How to set up an secure Apache SSL server at all?
  • Is the complete Apache configuration above superfluous?
  • How to do the above configuration when one has no access to apache2.conf and must use .htaccess?
  • Split off the short URL configuration and use “traditional” TWiki URLs?
After a review phase, a consolidated text might be added to the SupplementalDocuments in the TWiki web.

-- JoachimSchrod - 30 Apr 2007

There are limitations to the security the above described procedure offers. Once you are authenticated, a cookie or session id will be sent along with each request to the twiki. This cookie/session can be sniffed because it is not encrypted. An adversary can then use the sniffed cookie to get access to the TWiki.

So the above procedure can only be used to prevent the password to become known, it can not prevent people from getting into the TWiki unauthorized. For that, you would need to encrypt all traffic instead of just the logon.

-- KoenMartens - 20 Aug 2007

Thanks for this input. As the text states, this method is meant as a mitigation against password sniffing, under the assumption that people use similar passwords for several different causes. It is not meant as a method to set up a secure a TWiki installation against breakins, and nowhere it claims so. This should be pointed out explicitely.

If there will ever be any interest in this method at all (feedback up to now is almost nil), I'll incorporate that emphasis in the main description.

-- JoachimSchrod - 21 Aug 2007

I found this quite helpful, thanks. My config is simpler and I think avoids the problem above because it never redirects back to the http server after authentication with https. There seems little benefit in doing this. My main use case is for first impressions, allowing users read-only access without requiring accepting the self-signed cert and authenticating. If they want to edit, then they need to do both, so might as well keep them in the https site.

There is one bug in the configuration above. The RewriteEngine must be explicitly turned on in each VirtualHost. Add these directives to each VirtualHost declaration:

RewriteEngine On
RewriteOptions Inherit

-- ChuckWilliams - 20 Jan 2009

I moved this useful supplemental document from Support.UsingSslForAuthenticationOnly to here, linked to it from the TWikiUserAuthenticationSupplement document, and tagged it so that it can be found more easily. Thank you JoachimSchrod for contributing this document!

-- PeterThoeny - 2009-06-06

Please use the Support forum if you have questions about TWiki features. This comment section is about the documentation of this topic.
Topic attachments
I Attachment History Action Size Date Who Comment
Texttxt HttpUnauthorized.txt r1 manage 0.4 K 2007-04-30 - 17:45 JoachimSchrod Error document for authentication requests over HTTP
Unknown file formattmpl LocalSite.cfg.patch.tmpl r1 manage 0.6 K 2007-04-30 - 17:45 JoachimSchrod Patch to LocalSite.cfg, (re)apply after every configure run
Unix shell scriptsh ssl-setup.sh r1 manage 2.2 K 2007-04-30 - 17:41 JoachimSchrod setup shell script for quick default installation
Unknown file formattmpl twiki.full-server.tmpl r2 r1 manage 9.8 K 2007-06-05 - 18:14 JoachimSchrod Configure TWiki with URL redirection and short URLs
Unknown file formattmpl vhost.tmpl r1 manage 1.9 K 2007-04-30 - 17:44 JoachimSchrod Virtual host definitions for normal and secure Web server
Edit | Attach | Watch | Print version | History: r7 < r6 < r5 < r4 < r3 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r7 - 2012-02-14 - PeterThoeny
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2018 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.