Categories
IT Web

DokuWiki – Verschlüsselung auf dem Dateisystem hinzufügen

Um von überall aus auf diverse persönliche Informationen, Notizen, Kochrezepte usw. zugreifen zu können, habe ich mir DokuWiki auf dem Server installiert.

DokuWiki ist ein Wiki-System, welches in PHP umgesetzt ist, und sämtliche Daten auf dem Filesystem ablegt.

Ich habe das Wiki soweit “abgeschottet”, dass kein einziger Beitrag öffentlich einsehbar ist. Besucher müssen sich also mit einem Benutzernamen und Passwort einloggen um Beiträge zu sehen.
Der Button zum Registrieren neuer Benutzer wird ebenfalls nicht angezeigt.

Und natürlich ist der komplette Zugriff auf https umgebogen.
Das kann man einfach mit einer entsprechenden .htaccess Datei erledigen:

RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*) https://<DOKUWIKI_URL>/$1 [R,L]

 Sicherheitstechnisch ist das schon einmal gar nicht so schlecht.

 

Allerdings:
Wenn sich ein Hacker Zugang zum Server verschafft hat, dann hält ihn die Login-Restriktion im Browser auch nicht mehr auf, sämtliche Daten einfach direkt im Filesystem zu lesen!

 

Lösung:
Um dieses Problem zu umgehen, habe ich DokuWiki ein wenig mit Code erweitert.
Per Knopfdruck kann man das komplette data-Verzeichnis (in dem sämtliche Wiki-Seiten abgelegt werden) auf dem Dateisystem verschlüsseln bzw. wieder entschlüsseln.
Dadurch ist der Zugriff auch auf Filesystem-Ebene abgesichert.

decrypt box
decrypt box

Für meine Lösung sind folgende Schritte notwendig:
(ich beschreibe das jetzt für die Standard-Installation, ich habe bei mir ein anderes Theme gewählt. Dann müssen die Anpassungen natürlich im jeweiligen Theme geschehen.)

1. Dojo Toolkit nachrüsten
Für einen schönen Dialog zur Passwort-Eingabe habe ich mich für das Dojo Toolkit entschieden.

cd lib/tpl/dokuwiki
wget http://download.dojotoolkit.org/release-1.9.2/dojo-release-1.9.2.tar.gz
tar xvfz dojo-release-1.9.2.tar.gz
ln -s dojo-release-1.9.2 dojo

2. Dojo über die main.php Datei auf jeder Seite laden. Dazu einfach vor dem </head> Tag folgenden Code einfügen:

  <link rel="StyleSheet" type="text/css" href="<?php echo DOKU_TPL?>dojo/dijit/themes/tundra/tundra.css">
    <script type="text/javascript">
      var djConfig = {
        parseOnLoad : true
      };
    </script>
    <script type="text/javascript" src="<?php echo DOKU_TPL?>dojo/dojo/dojo.js"></script>
    <script>
      dojo.require("dojo.parser");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.Dialog");
      dojo.require("dijit.form.TextBox");
      //dojo.addOnLoad(hideDialog);

      function hideDialog()
      {
        dijit.byId('dialog1').hide();
      }

      function showDialog()
      {
        dijit.byId('dialog1').show();
      }
    </script>

3. Im <body> Tag noch die CSS Klasse einfügen

<body class="tundra">

 4. Den Code für den Button in die tpl_footer.php einbinden

<?php
/**
 * Template footer, included in the main and detail files
 */

// must be run from within DokuWiki
if (!defined('DOKU_INC')) die();
// check if encrypted file exists
 $msg="";
 $url="#";
 if(is_file("dokuwiki_data_backup.tar.gz.enc"))
 {
   $msg="Decrypt";
   $url="<cgi-path>/dec";
 }
 else
 {
   $msg="Encrypt";
   $url="<cgi-path>/enc";
 }
?>
<script language="javascript">
  function checkPw(dialogFields)
  {
     if (dialogFields.password.value != dialogFields.confpassword.value)
     {
        alert("Confirmation password is different.");
        return false;
     }
     dialogFields.type.value=dialogFields.password.value;
     return true;
  }
</script>

<!-- ********** FOOTER ********** -->
<div id="dokuwiki__footer"><div>
    <?php tpl_license(''); // license text ?>
<div>
  <div style="font-size:8pt;position:absolute;height:65px;"><a style="color:black" onclick="javascript:showDialog();" href="#"><?=$msg?></a>
</div>

    <div>
        <?php
            tpl_license('button', true, false, false); // license button, no wrapper
            $target = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : '';
        ?>
        <a href="http://www.dokuwiki.org/donate" title="Donate" <?php echo $target?>><img
            src="<?php echo tpl_basedir(); ?>images/button-donate.gif" width="80" height="15" alt="Donate" /></a>
        <a href="http://www.php.net" title="Powered by PHP" <?php echo $target?>><img
            src="<?php echo tpl_basedir(); ?>images/button-php.gif" width="80" height="15" alt="Powered by PHP" /></a>
        <a href="http://validator.w3.org/check/referer" title="Valid HTML5" <?php echo $target?>><img
            src="<?php echo tpl_basedir(); ?>images/button-html5.png" width="80" height="15" alt="Valid HTML5" /></a>
        <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS" <?php echo $target?>><img
            src="<?php echo tpl_basedir(); ?>images/button-css.png" width="80" height="15" alt="Valid CSS" /></a>
        <a href="http://dokuwiki.org/" title="Driven by DokuWiki" <?php echo $target?>><img
            src="<?php echo tpl_basedir(); ?>images/button-dw.png" width="80" height="15" alt="Driven by DokuWiki" /></a>
    </div>
</div></div><!-- /footer -->
<div dojoType="dijit.Dialog" id="dialog1" title="<?=$msg?>">
      <form action="<?=$url?>" method="post" validate="true" id="encdec_form" onsubmit="return checkPw(this);">
        <input type="hidden" name="type" id="type" value="<?=$msg?>" />
        <table width="350">
          <tr>
            <td><label>Password:</label></td>
            <td><input type="password" trim="true" dojoType="dijit.form.TextBox" value="" name="password" id="password"/></td>
          </tr>
          <tr>
            <td><label>Confirm Password:</label></td>
            <td><input type="password" trim="true" dojoType="dijit.form.TextBox" value="" name="confpassword" id="confpassword"/></td>
          </tr>
          <tr><td colspan="2">&nbsp;</td></tr>
          <tr>
            <td colspan="2" align="center">
            <table border="0" cellspacing="0" cellpadding="0">
                <tr>
                  <td align="center" valign="top"><button dojoType="dijit.form.Button" type="submit" id="LoginButton">Ok</button></td>
                  &nbsp;
                  <td align="left" valign="top"><button dojoType="dijit.form.Button" type="button"
                  onclick="document.getElementById('encdec_form').reset();" id="Cancel">Cancel</button></td>
                </tr>
           </table>
           </td>
          </tr>
        </table>
      </form>
    </div>

<?php
tpl_includeFile('footer.html');

 5. Jetzt noch zwei Skripten im cgi-Verzeichnis

Einmal zum verschlüsseln: enc

#!/bin/sh

echo Content-type: text/html
echo ""

if [ -f "<PATH_TO_WIKI>/dokuwiki_data_backup.tar.gz.enc" ] ; then
  echo ""
else
  #get pass
  read passfromform
  pass=`echo "$passfromform" | cut -d"=" -f2 | cut -d"&" -f1`

  # check pass
  if [ "" != "${pass}" ] ; then
    # change dir
    cd <PATH_TO_WIKI>
 
    # create file
    tar cf dokuwiki_data_backup.tar data 2>/dev/null 1>/dev/null
    gzip -9 dokuwiki_data_backup.tar
    openssl des3 -k $pass -in dokuwiki_data_backup.tar.gz -out dokuwiki_data_backup.tar.gz.enc
    rm dokuwiki_data_backup.tar.gz
    rm -rf data

    # add directories
    mkdir data
    mkdir data/attic
    mkdir data/cache
    mkdir data/index
    mkdir data/locks
    mkdir data/media
    mkdir data/media_attic
    mkdir data/media_meta
    mkdir data/meta
    mkdir data/pages
    mkdir data/tmp
    mkdir data/cache/c
    mkdir data/cache/e
    mkdir data/cache/6
    chmod -R 777 data

    cd -
  fi
fi

echo "<html><body><script>history.back();</script></body></html>"

 Und einmal zum entschlüsseln: dec

#!/bin/sh

echo Content-type: text/html
echo ""

if [ -f "<PATH_TO_WIKI>/dokuwiki_data_backup.tar.gz.enc" ] ; then
  #get pass
  read passfromform
  pass=`echo "$passfromform" | cut -d"=" -f2 | cut -d"&" -f1`

  if [ "" != "${pass}" ] ; then
    # change directory
    cd <PATH_TO_WIKI> 

    # decrypt file
    openssl des3 -k $pass -d -in dokuwiki_data_backup.tar.gz.enc -out dokuwiki_data_backup.tar.gz

    # check for errors
    if [ $? -eq 0 ] ; then
      # remove directory
      rm -rf data

      # unzip
      gunzip dokuwiki_data_backup.tar.gz

      # untar
      tar xf dokuwiki_data_backup.tar
      chmod -R a+rw data
      rm dokuwiki_data_backup.tar
      rm dokuwiki_data_backup.tar.gz.enc
    else
      rm dokuwiki_data_backup.tar.gz
    fi
    cd -
    echo ""
  fi
else
  echo ""
fi

echo "<html><body><script>history.back();</script></body></html>"

 

Anmerkungen:

  1. Um die Optik aufzubessern, kann man natürlich den Text Entschlüsseln/Verschlüsseln durch eine schöne Grafik austauschen.
  2. Es macht auch Sinn, die verschlüsselte Datei außerhalb des Webservers, also nicht im httpdocs-Verzeichnis, abzulegen.
  3. Ein Backup der Wiki-Daten ist durch die einzelne, verschlüsselte Datei natürlich auch recht einfach.

 

 

One reply on “DokuWiki – Verschlüsselung auf dem Dateisystem hinzufügen”

Ich bin gerade am Recherchieren, welche software gut sein könnte für eine zentrale Wissensablage einer Firma. DokuWiki scheint mir dafür sehr gut geeignet.
Dabei stellte sich mir die Frage, ob es möglich ist alles Wissen zu verschlüsseln, so dass es dem besitzer des Webservers nicht möglich ist, alle Inhalte zu lesen.
Daher die Frage: Ist die oben beschriebene Lösung funktionsfähig für kollaboratives Arbeiten? Sprich, dass neue Teilnehmer jederzeit zum Wiki hinzugefügt werden können, alte gelöscht werden und alle registrierten Teilnehmer lese und schreib-Zugriff auf alle Wiki-Seiten haben?

Lieber Gruss

Leave a Reply

Your email address will not be published. Required fields are marked *