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.

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"> </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>
<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:
- Um die Optik aufzubessern, kann man natürlich den Text Entschlüsseln/Verschlüsseln durch eine schöne Grafik austauschen.
- Es macht auch Sinn, die verschlüsselte Datei außerhalb des Webservers, also nicht im httpdocs-Verzeichnis, abzulegen.
- 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