Cet article décrit un ensemble de techniques pour sécuriser un wiki. Ces techniques ont été implémentées pour le Wiki Infond. Bien sûr, nous ne dévoilons ici qu'une partie des techniques de sécurisation que nous avons déployées.
Sécuriser /tmp
Le répertoire /tmp a une taille limitée et n'est pas exécutable.
# source: http://snippets.prendreuncafe.com/snippet/54
# create a 40MB block device which will be the /tmp file system
cd /root
dd if=/dev/zero of=l/root/tmpMnt bs=1024 count=40000
mkfs.ext3 -F /root/tmpMnt
# mount it at /tmp
mv /tmp /tmp.backup
mkdir /tmp
mount -o loop,noexec,nosuid,rw /root/tmpMnt /tmp
chmod 0777 /tmp
# make it so it is used on boot up
if ! grep -qai tmpMnt /etc/fstab ; then
echo "/root/tmpMnt /tmp ext3 loop,noexec,nosuid,rw 0 0" >> /etc/fstab
fi
# check your syntax is ok
mount -a
# check that programs in /tmp will not run
cp /bin/ls /tmp/
/tmp/ls
Apparence du Wiki
Vocabulaire
- La bannière est un fichier png appelé fronton.png,
- Le dossier du Wiki est /var/www/wiki/,
- Le skin du Wiki est Monobook.
Afficher la bannière
Editer skins/Monobook.php,
A la place de :
........<div id="globalWrapper">.......
Ecrire :
........ <div id="p-banner">
<div id="p-bannerG">
<a href="<?php echo htmlspecialchars($this->data['nav_urls']['mainpage']['href'])?>">
<img src="infondskin2/frontonG.png"></a>
</div>
<div id="p-bannerD">
<img src="infondskin2/frontonD.png">
</div>
</div>
<div id="globalWrapper">
.......
Mettre le site sous la bannière
Editer skins/monobook/main.css. Ajouter ou modifier les lignes suivantes :
#p-banner {
position: relative;
height: 74px;
max-height: 74px;
}
#p-bannerG {
position: absolute;
left: 0;
z-index: 2;
}
#p-bannerD {
position: absolute;
right: 0px;
z-index: 1;
}
#globalWrapper
{
...
position: relative;
...
}
Supprimer logo
Editer skins/MonoBook.php et commenter cette section (<!-- -->) :
<div class="portlet" id="p-logo">
<a style="">text('logopath') ?>);"
href="<?php echo htmlspecialchars($this->data['nav_urls']['mainpage']['href'])?>"
title="<?php $this->msg('mainpage') ?>"></a>
</div>
Editer skins/monobook/main.css pour le modifier comme suit :
#column-one {
/* padding-top: 160px;*/
padding-top: 3em;
}
Cacher le footer
#footer
visibility: hidden;
Favicon
Pour modifier l'icone de la barre de navigation du navigateur, ajouter favicon.ico à la racine du site.
Configurer la Sidebar
http://monsite.com/index.php?title=MediaWiki:Sidebar&action=edit
Edit : Cette méthode est remplacée par l'extension SideBar. Cf à la fin de cet article.
Extension "Dynamic pages list"
Modifier la "secret key" dans LocalSettings.php
Modifier $wgSecretKey = "";
Utiliser le mail pour vérifier les nouveaux comptes
apt-get install php-net-smtp
pear install Net_SMTP
pear install Mail
Captcha
VisualMathCaptcha
$ apt-get install php5-gd
VisualMathCaptcha crée une page spéciale appelée VisualMathCaptcha. Il faut donc l'ajouter dans l'extension Lockdown :
$wgSpecialPageLockdown['VisualMathCaptcha'] = array('*');
Utilisation avec ConfirmEdit :
1. Ouvrir ConfirmEdit.php dans le répertoire de l'extension ConfirmEdit, et modifier la valeur $wgCaptchaClass en VisualMathConfirmCaptcha.
2. Ajouter la ligne suivante dans LocalSettings.php, après le contenu copié depuis le fichier LocalSettings.part :
$wgAutoloadClasses['VisualMathConfirmCaptcha'] = "$IP/extensions/VisualMathCaptcha/VisualMathConfirmCaptcha.class.php";
Sécuriser PHP
/etc/php5/apache2/php.ini
allow_url_fopen off (attention, cette fonction est nécessaire pour l'extension TitleBlackList).
Extension Lockdown
Dans Localsettings.php :
# extension Lockdown
require_once( "$IP/extensions/Lockdown/Lockdown.php" );
$wgSpecialPageLockdown['Listusers'] = array('sysop');
$wgSpecialPageLockdown['Search'] = array('*');
$wgSpecialPageLockdown['Userlogin'] = array('*');
$wgSpecialPageLockdown['Userlogout'] = array('*');
$wgSpecialPageLockdown['Preferences'] = array('*');
$wgSpecialPageLockdown['Watchlist'] = array('*');
$wgSpecialPageLockdown['Upload'] = array('uploadaccess');
$wgActionLockdown['history'] = array('sysop');
$wgSpecialPageLockdown['VisualMathCaptcha'] = array('*');
$wgSpecialPageLockdown['MultipleUpload'] = array('uploadaccess');
$wgSpecialPageLockdown['Confirmemail'] = array('*');
$wgSpecialPageLockdown['Invalidateemail'] = array('*');
$wgNamespacePermissionLockdown[NS_SPECIAL]['read'] = array('sysop');
$wgNamespacePermissionLockdown[NS_MEDIAWIKI]['read'] = array('sysop');
$wgNamespacePermissionLockdown[NS_USER]['read'] = array('sysop');
$wgNamespacePermissionLockdown[NS_TEMPLATE]['read'] = array('sysop');
Attention, pas de guillements autour de NS_SPECIAL !
Améliorer l'extension Lockdown
Nous ne suivons pas exactement ce tuto. Ajouter simplement les trois lignes suivantes :
Au lieu de :
$ns = $title->getNamespace();
if ( NS_SPECIAL == $ns ) {
if ( $action != 'read' ) {
Ecrire :
$ns = $title->getNamespace();
$groups = @$wgNamespacePermissionLockdown[$ns][$action];
if (!$groups) $groups = @$wgNamespacePermissionLockdown['*'][$action];
if (!$groups) $groups = @$wgNamespacePermissionLockdown[$ns]['*'];
if ( NS_SPECIAL == $ns ) {
if ( $action != 'read' ) {
Cacher la boîte à outils pour les utilisateurs n'étant pas sysop
Edit : Cette méthode est remplacée par l'ajout de l'extension SideBar.php cf en fin de cet article :
Trouver :
function toolbox() {
?>
<div class="portlet" id="p-tb">
<h5><?php $this->msg('toolbox') ?></h5>
...
</div>
</div>
<?php
}
Et le modifier par :
function toolbox() {
global $wgUser;
?>
<div class="portlet" id="p-tb">
<?php if (in_array( 'sysop', $wgUser->getGroups() ) == 1) { ?>
<h5><?php $this->msg('toolbox') ?></h5>
...
</div>
<?php } ?>
</div>
<?php
}
LocalSettings.php : quelques astuces
Modifier wgSitename :
# disallow edit for non logged-in users
$wgGroupPermissions['*']['edit'] = false;
# must have confirmed email before edit
$wgEmailConfirmToEdit=true;
URLs courts
Enlever contributions et mytalks de la barre personnelle
Solution dans skins (bof !)
Dans skins/Monobook.php,
Remplacer :
<?php foreach($this->data['personal_urls'] as $key => $item) { ?>
<li id="<?php echo Sanitizer::escapeId( "pt-$key" ) ?>"<?php
if ($item['active']) { ?> class="active"<?php } ?>><a href="<?php
echo htmlspecialchars($item['href']) ?>"<?php echo $skin->tooltipAndAccesskey('pt-'.$key) ?><?php
if(!empty($item['class'])) { ?> class="<?php
echo htmlspecialchars($item['class']) ?>"<?php } ?>><?php
echo htmlspecialchars($item['text']) ?></a></li>
<?php } ?>
Par:
<?php foreach($this->data['personal_urls'] as $key => $item) {
if ( ($key!="mycontris") && ($key !="mytalk") ) { ?>
<li id="<?php echo Sanitizer::escapeId( "pt-$key" ) ?>"<?php
if ($item['active']) { ?> class="active"<?php } ?>><a href="<?php
echo htmlspecialchars($item['href']) ?>"<?php echo $skin->tooltipAndAccesskey('pt-'.$key) ?><?php
if(!empty($item['class'])) { ?> class="<?php
echo htmlspecialchars($item['class']) ?>"<?php } ?>><?php
echo htmlspecialchars($item['text']) ?></a></li>
<?php } ?>
<?php } ?>
Solution plus esthétique
Créer une extension :
<pre>
<?php
$wgHooks['PersonalUrls'][] = 'persurl';
function persurl( &$personal_urls, &$title ) {
global $wgUser;
if ( in_array( 'sysop', $wgUser->getGroups() ) != 1) {
unset($personal_urls['anontalk']);
unset($personal_urls['mytalk']);
}
return true;
}
File upload
Attention de mettre les nouveaux droits de modification après les droits Lockdown.
Suppression historique, viewsource, talk pour users autres que sysop
Dans skin (moche !)
Dans skins/Monobook.php,
Au lieu de :
foreach($this->data['content_actions'] as $key => $tab) {
echo '
<li id="' . Sanitizer::escapeId( "ca-$key" ) . '"';
if( $tab['class'] ) {
echo ' class="'.htmlspecialchars($tab['class']).'"';
}
echo '><a href="'.htmlspecialchars($tab['href']).'"';
# We don't want to give the watch tab an accesskey if the
# page is being edited, because that conflicts with the
# accesskey on the watch checkbox. We also don't want to
# give the edit tab an accesskey, because that's fairly su-
# perfluous and conflicts with an accesskey (Ctrl-E) often
# used for editing in Safari.
if( in_array( $action, array( 'edit', 'submit' ) )
&& in_array( $key, array( 'edit', 'watch', 'unwatch' ))) {
echo $skin->tooltip( "ca-$key" );
} else {
echo $skin->tooltipAndAccesskey( "ca-$key" );
}
echo '>'.htmlspecialchars($tab['text']).'</a></li>';
} ?>
Lire :
global $wgUser;
foreach($this->data['content_actions'] as $key => $tab) {
if ((($key!="nstab-main")&&($key!="talk")&&($key!="viewsource")&&($key!="history")||(in_array( 'sysop', $wgUser->getGroups() ) == 1)) {
echo '
<li id="' . Sanitizer::escapeId( "ca-$key" ) . '"';
if( $tab['class'] ) {
echo ' class="'.htmlspecialchars($tab['class']).'"';
}
echo '><a href="'.htmlspecialchars($tab['href']).'"';
# We don't want to give the watch tab an accesskey if the
# page is being edited, because that conflicts with the
# accesskey on the watch checkbox. We also don't want to
# give the edit tab an accesskey, because that's fairly su-
# perfluous and conflicts with an accesskey (Ctrl-E) often
# used for editing in Safari.
if( in_array( $action, array( 'edit', 'submit' ) )
&& in_array( $key, array( 'edit', 'watch', 'unwatch' ))) {
echo $skin->tooltip( "ca-$key" );
} else {
echo $skin->tooltipAndAccesskey( "ca-$key" );
}
echo '>'.htmlspecialchars($tab['text']).'</a></li>';
}
} ?>
Via une extension (désuet dans 1.18)
<?php
$wgHooks['SkinTemplateContentActions'][] = 'caction';
function caction( &$content_actions ) {
global $wgUser;
if ( in_array( 'sysop', $wgUser->getGroups() ) != 1) {
unset($content_actions['talk']);
unset($content_actions['viewsource']);
unset($content_actions['history']);
}
return true;
}
Multi languages
Utiliser ParserFunctions.
Verrouiller la page Template:Languages pour les admin uniquement
Extension SyntaxHighLight
Vous pouvez aussi éditer la fichier "SyntaxHighlight_GeSHi.class.php", aux alentours de la ligne 215 :
$css[] = "\tline-height: normal; border: 0px none white;";
Et le modifier ainsi :
$css[] = "\tline-height: normal; border: 1px dashed #2f6fab;";
Autre solution pour modifier l'apparence (celle-ci fonctionne):
Editer /var/lib/mediawiki/skins/infondskin2/main.css
div.mw-geshi {
padding: 1em;
border: 1px dashed #2f6fab;
background-color: #F9F9F9;
color: black;
line-height: 1.1em;
}
Combattre le spam
Empecher les div hidden
Dans LocalSettings.php,
# antispam
$wgSpamRegex = "/\<.*style.*?(display|position|overflow|visibility|height)\s*:.*?>/i";
Blacklist d'IPs
#!/bin/bash
wget http://www.stopforumspam.com/downloads/bannedips.zip
unzip -u bannedips.zip
echo "<?php" > bannedips.php
echo \$"wgProxyList = array(" >> bannedips.php; echo -n "'" >> bannedips.php
sed -i 's/,/\x27,\n\x27/g' bannedips.csv
cat bannedips.csv >> bannedips.php
echo "');" >> bannedips.php
rm bannedips.csv
rm bannedips.zip*
chown root:www-data bannedips.php
chmod 740 bannedips.php
mv bannedips.php /var/www/wiki/extensions/bannedips.php
tail /var/www/wiki/extensions/bannedips.php
Ajouter dans LocalSettings.php :
require_once("$IP/extensions/bannedips.php");
DNS blacklists
Dans LocalSettings.php :
$wgEnableSorbs = true;
$wgSorbsURL = 'http.dnsbl.sorbs.net.';
Extension EmailAddressImage
Extension SpamBlackList
require_once( "$IP/extensions/SpamBlacklist/SpamBlacklist.php" );
$wgSpamBlacklistFiles = array(
"http://meta.wikimedia.org/wiki/Spam_blacklist"
);
Extension TitleBlackList
require_once( "{$IP}/extensions/TitleBlacklist/TitleBlacklist.php" );
$wgTitleBlacklistSources = array(
array(
'type' => TBLSRC_URL,
'src' => 'http://meta.wikimedia.org/w/index.php?title=Title_blacklist&action=raw',
)
);
MultiUpload
# extension MultiUpload
require_once("$IP/extensions/MultiUpload/MultiUpload.php");
$wgMaxUploadFiles = 10;
Ajouter dans TOOLBOX dans MediaWiki:Sidebar :
** Special:MultipleUpload|multiupload-toolbox ("Upload multiple files").
Attention de mettre les nouveaux droits de modification après les droits Lockdown
$wgSpecialPageLockdown['MultipleUpload'] = array('uploadaccess');
Sidebar
Version 1.16
Nous créons ici une extension pour modifier la Sidebar. Cette version ne fonctionne qu'à partir de 1.16.
$ cat extensions/SideBar.php
<?php
$wgHooks['SkinBuildSidebar'][] = 'efHideSidebar';
function efHideSidebar($skin, &$bar) {
global $wgUser;
// default bar, any user
$navigation = array(
array(text => wfMsg('mainpage-description'),
href => 'Accueil',
id => 'n-mainpage-description',
active => ''),
array(text => 'Aide',
href => 'Aide',
id => 'n-Aide',
active => ''),
array(text => 'Contact',
href => 'Contact',
id => 'n-Contact',
active => ''),
);
// users logged in
$users = array(
array( text => 'mindmeister',
href => 'http://www.mindmeister.com/fr/34461959/t0ka7a',
id => 'n-mindmeister',
active => ''),
);
// uploadaccess group
$upload = array(
array( text => 'téléversement',
href => SpecialPage::getTitleFor( 'MultipleUpload' )->getLocalUrl(),
id => 'n-téléversement',
active => ''),
);
$bar = array();
// every users (even not logged in)
$bar[navigation] = $navigation;
// if logged in
if ( $wgUser->isLoggedIn() ) {
$bar[users] = $users;
}
// if uploadaccess
if ( in_array( 'uploadaccess', $wgUser->getGroups() ) == 1) {
$bar[téléversement] = $upload;
}
return true;
}
Version 1.15
Cette solution nécessite de cacher la toolbox dans le skin !
<?php
$wgHooks['SkinBuildSidebar'][] = 'fnNewSidebarItem';
function fnNewSidebarItem( $skin, &$bar ) {
global $wgUser;
# any user
$out = '<div class="pBody"><ul>';
$out.= '<li id="n-mainpage-description"><a href="/wiki/Accueil">Accueil</a></li>';
$out.= '<li id="n-help"><a href="/wiki/Aide:Accueil">Aide</a></li>';
$out.= '<li id="n-contact"><a href="/wiki/Contact">Contact</a></li>';
$out.= '<li id="feedlinks"><a title="Flux RSS pour cette page" class="feedlink" type="application/rss+xml" rel="alternate" href="/mediawiki/index.php?title=Sp%C3%A9cial:Modifications_r%C3%A9centes&feed=rss" id="feed-rss">RSS </a><a title="Flux Atom pour cette page" class="feedlink" type="application/atom+xml" rel="alternate" href="/mediawiki/index.php?title=Sp%C3%A9cial:Modifications_r%C3%A9centes&feed=atom" id="feed-atom">Atom</a></li>';
// if logged in
if ( $wgUser->isLoggedIn() ) {
$out.= '<li id="n-print"><a accesskey="p" title="Version imprimable de cette page [alt-shift-p]" rel="alternate" href="/mediawiki/index.php?title=Accueil&printable=yes">Version imprimable</a></a></li>';
}
$out.= '</ul></div>';
$bar[ 'navigation' ] = $out;
# any user
$out = '<div class="pBody"><ul>';
$out.= '<li id="n-mindmeister"><a href="http://www.mindmeister.com/fr/34461959/t0ka7a">Mindmeister</a></li>';
$out.= '</ul></div>';
$bar[ 'liens' ] = $out;
// if uploadaccess
if ( in_array( 'uploadaccess', $wgUser->getGroups() ) == 1) {
$out = '<div class="pBody"><ul>';
$out.= '<li id="n-multipleupload"><a href="'.SpecialPage::getTitleFor( 'MultipleUpload' )->getLocalUrl().'">téléversement</a></li>';
$out.= '</ul></div>';
$bar['téléversement'] = $out;
}
// if sysop
if ( in_array( 'sysop', $wgUser->getGroups() ) == 1 ) {
$out = '<div class="pBody"><ul>';
$out.= '<li id="t-specialpages"><a accesskey="q" title="Liste de toutes les pages spéciales [alt-shift-q]" href="/wiki/Sp%C3%A9cial:Pages_sp%C3%A9ciales">Pages spéciales</a></li>';
$out.= '<li id="t-specialpages"><a accesskey="q" title="Liste de toutes les pages spéciales [alt-shift-q]" href="/wiki/Spécial:Modifications_récentes">Modifications récentes</a></li>';
$out.= '</ul></div>';
$bar['toolbox'] = $out;
}
return true;
}
Puis nous ajoutons cette extension dans LocalSettings.php.
# extension SideBar
require_once("$IP/extensions/SideBar.php");
Confirmation E-mail
Dans LocalSettings.php,
Remplacer "false" par "true" :
$wgEmailAuthentication = true;
Lockdown = autoriser :
$wgSpecialPageLockdown['Confirmemail'] = array('*');
$wgSpecialPageLockdown['Invalidateemail'] = array('*');
Table des références d'articles
Extension cite
RSS
Dans /var/www/wiki/skins/infondlinux.php
Juste après <head>, ajouter :
<link rel="alternate" type="application/rss+xml" href="/mediawiki/index.php?title=Special:Newpages&feed=rss" title="infond">
Aucun commentaire:
Enregistrer un commentaire