Archives pour l'étiquette ASR2004

CORNER : PHP & MySQL

Un coin de web

Un petit soft de blog appelé corner et réalisé en formation, très, très simple avec quelque fonction de base :

- Une identification (et encore)
- Vérification avant de poster définitivement
- Un cache pour limiter les requêtes SQL
- Un pseudo système de stat
- Une micro syntaxe wiki maison
- Des liens automatiques
- Le tout en XHTML exclusivement

Tout cela est éclaté dans plusieurs fichiers pour en faciliter l’utilisation. Il y a un fichier README qui comporte les requêtes SQL à copier coller dans phpmyadmin pour créer les tables MySQL nécessaires.

Vous trouverez également plusieurs fichier test avec des bouts de code ainsi que quelque répertoire contenant des versions précédentes ou des ébauches.

GZ - 78.4 ko
corner.tar.gz

Attention aucun support sur cette application, c’est du brutal, cela reste une simple mise en pratique de quelque éléments apprit en formation ou sur le tas. Libre à vous d’en faire n’importe quoi dans les limites de la GPL 🙂

Script de sauvegarde (perl)

Petit script de sauvegarde en perl utilisé dans le projet d’architecture réseau internet / intranet en environnement GNU / Linux Debian concrétisant la fin de ma formation Administrateur Système et Réseau au GRETA SUD TERTIAIRE 93

Le principe

Désirant faire des sauvegardes régulières de la configuration des serveur du réseau j’ai décider d’écrire un petit script perl pour me facilité la vie. Je suis parti du principe que je ne sauvegardais que les fichiers de configuration, ce qui représente que quelque centaine de ko.

L’organisation

La sauvegarde doit être souple pour juste sélectionner un fichier comme un répertoire en entier. L’archivage ce fait dans le répertoire /var/backups et je garde toujours une trace de la sauvegarde précédente. Enfin j’utilise évidement le cron pour faire une sauvegarde régulières.

Le fichier ini.

Mon script prend la liste des fichiers et répertoires à sauvegardé dans un fichier d’ini. Ce fichier à la syntaxe suivante :
- /etc/network/interface
Pour désigner un fichier a sauvegarder isolément, pas de compression.
- /etc/
Pour désigner un répertoire a sauvegarder en entier au format tar.gz
- /home@
Pour désigner un répertoire racine dont chaque sous répertoire doit être sauvegarder en entier et isolément au format tar.gz.

Voici un exemple de fichier d’ini :


# backlist.ini
#
# Liste des fichiers et rep a sauvegarder

/etc/network/interfaces
/etc/network/options
/home/karles/Desktop/gts93.greta.fr/dev_script/
/tmp@

Le script

A mon humble avis le script est suffisamment bien commenté pour être facile à comprendre :


#!/usr/bin/perl

######################################################################################
## ##
## Name : tovarbackup.pl ##
## Version : 0.1 ##
## Author : Charles Christian CROIX ##
## Thank to : Larry Wall ##
## ##
######################################################################################

#################
# APPEL MODULES #
#################
# use diagnostics;
# use strict;

##################
# VARIABLES PROG #
##################
$backlist="./backuplist.ini"; ## fichier listant les rep et file a sauvegarder
$backlogfile="./tovarbackup.log"; ## fichier log
$backupdir="/var/backups"; ## ou seront stocker les fichiers a sauvegarder /!\ / a la fin
$iWidth=60; ## Largeur de l'affichage fonction sub center

########################
# Sous Prog & Fonction #
########################

sub CENTER($$) {
my ($Temp,$Width) = @_;
my $Len = ($Width - length($Temp)) / 2;
return " " x int($Len), $Temp, " " x (int($Len) + (($Len != int($Len))? 1:0));
}

sub CALDATE() {
# Commande recuperant l'heure et la date systeme
# ATTENTION VARIABLE DATE & TIME DIFF EN Fr et Us
my ($month,$day) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ## Commande recuperant l'heure et la date systeme
$month = $mon + 1;
$month = sprintf ("%02d",$month);
$day = sprintf ("%02d",$mday);
$hour = sprintf ("%02d",$hour);
$min = sprintf ("%02d",$min);
$sec = sprintf ("%02d",$sec);
$time = "$hour.$min.$sec";
$year += 1900;
$date = "$day.$month.$year";
$datestamp = "$day/$month/$year";
$timestamp = "$hour.$min.$sec";
}

sub DOLOG($$) {
my ($file,$log)=@_;
# ecriture dans fichier log
# $file : fichier log
# $log : texte
local *LOG;
open (LOG, ">>$file") or warn "\n * Peux pas ouvrir $file \n * $!";
print LOG $log;
close LOG;
}

sub BACKLIST() {
# Appel du fichier INI donnant la liste des fichiers et rep a sauvegarder
open (BACKLIST,$backlist) || die "\U\n HOULA ouverture backlist.ini impossible \n $!";
@backlist = <BACKLIST> ;
close (BACKLIST);
}
sub FIN() {
print "\n\t+", "=" x ($iWidth), "+\n";
print "\t|", CENTER("FIN DU SCRIPT tovarbackup.pl", $iWidth), "|\n";
print "\t+", "=" x ($iWidth), "+\n";
EXIT;
}

sub ENTETE() {
print "\n";
print "\t+", "=" x ($iWidth), "+\n";
print "\t|", CENTER("** PERL tovarbackup.pl **", $iWidth), "|\n";
print "\t|", CENTER("Version 0.1 ", $iWidth), "|\n";
print "\t|", CENTER("(c) Charles Christian CROIX", $iWidth), "|\n";
print "\t|", CENTER("Licence: GPL", $iWidth), "|\n";
print "\t|", CENTER("Syntaxe : tovarbackup.pl ", $iWidth), "|\n";
print "\t|", CENTER( $date , $iWidth), "|\n";
print "\t|", CENTER( $time , $iWidth), "|\n";
print "\t+", "=" x ($iWidth), "+\n"
}

##############################
# #
# TRAITEMENT PRINCIPALE #
# #
##############################

CALDATE();
ENTETE();
BACKLIST();

DOLOG $backlogfile,"\n[$datestamp] [$timestamp] --";
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] LANCEMENT ET INIT de tovarbackup";

# pour chaque ligne du ficier ini
foreach $line (@backlist) {
chomp $line;
@mots = split(/\s+/,$line);
next if (@mots[0] eq "#");
next if (@mots[0] eq "");

# recup du caractere de fin de ligne
$dirornot = substr (@mots[0],-1,1);

# recupe du nom de ficher / rep en fin de path
@filename = split(/\//,$mots[0]);
$nb_element_filename = @filename;
$nb_element_filename--;

###############################
# test si c'est un repertoire #
###############################
if ($dirornot eq "/") {
print "\n\t $mots[0] est un repertoire";
# on garde tjrs la version precedente
if (-e "$backupdir/$filename[$nb_element_filename].tar.gz") {
if (-e "$backupdir/$filename[$nb_element_filename].old.tar.gz") {
unlink ("$backupdir/$filename[$nb_element_filename].old.tar.gz")
}
system("mv $backupdir/$filename[$nb_element_filename].tar.gz $backupdir/$filename[$nb_element_filename].old.tar.gz ");
}
# appel systeme pour le tar
system("tar cvfz $backupdir/$filename[$nb_element_filename].tar.gz $mots[0] 2>&-, >&-");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] TAR REPERTOIRE $mots[0]";
}

######################################
# test si c'est un repertoire racine #
######################################
elsif ($dirornot eq "@") {
print "\n\t $mots[0] est un repertoire racine";
# suppression du carractere @
$mots[0]=substr($mots[0], 0, -1);
print "\n\t $backupdir$mots[0]";
# creation du rep racine dans le rep de backup
unless (-e "$backupdir$mots[0]") {
mkdir "$backupdir$mots[0]";
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] CREATION de $backupdir$mots[0]";
}
# recup de la liste des fichier dans le rep racine
@list_sousrep = glob ("$mots[0]/*");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] TAR.GZ des sous repertoire de $mots[0] ";
foreach $sousrep (@list_sousrep) {
#si c'est un rep on le tar
if (-d $sousrep) {
# on garde tjrs la version precedente
if (-e "$backupdir$sousrep.tar.gz") {
if (-e "$backupdir$sousrep.old.tar.gz") {
unlink ("$backupdir$sousrep.old.tar.gz");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] SUPPRESSION de $backupdir$sousrep.old.tar.gz";
}
system("mv $backupdir$sousrep.tar.gz $backupdir$sousrep.old.tar.gz ");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] DEPLACEMENT de $backupdir$sousrep.tar.gz vers $backupdir$sousrep.old.tar.gz ";
}
print "\n\t - $sousrep";
system("tar cvfz $backupdir/$sousrep.tar.gz $sousrep 2>&-, >&-");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp]\t TAR.GZ de $sousrep";
}
}
}

############################################
# et bien c'est ni un rep ni un rep racine #
# donc c'est un fichier #
############################################
else {
print "\n\t $mots[0] est un fichier ";
# on garde tjrs la version precedente
if (-e "$backupdir/$filename[$nb_element_filename]") {
if (-e "$backupdir/$filename[$nb_element_filename].old") {
unlink ("$backupdir/$filename[$nb_element_filename].old");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] SUPPRESSION DU FICHIER $backupdir/$filename[$nb_element_filename].old";
}
system("mv $backupdir/$filename[$nb_element_filename] $backupdir/$filename[$nb_element_filename].old ");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] DEPLACEMENT DU FICHER $backupdir/$filename[$nb_element_filename] vers $backupdir/$filename[$nb_element_filename].old ";
}
else {
}
# copie simple
system("cp $mots[0] $backupdir ");
DOLOG $backlogfile,"\n[$datestamp] [$timestamp] COPIE DU FICHER $mots[0]";
}
print "\n";
}

FIN();

Pour faire mieux

Pour faire mieux je prendrais soins de prévoir la possibilité de choisir entre la compression d’un répertoire ou sa simple copie. J’inclurais également la gestion des fichiers présent dans un répertoire racine car pour le moment seul les sous répertoires sont pris en compte. Les messages sur STDOUT devrait également être optionnel.

SSH authentification par clé

SSH configuration de l’authentification par clé

Au lieu de s’authentifier par mot de passe, les utilisateurs peuvent s’authentifier grâce à la cryptographie asymétrique et son couple de clés privée/publique SSH utilise pour cela la cryptographie symétrique. Son principe est simple : si A veut envoyer un message confidentiel à B, A et B doivent d’abord posséder une même clé secrète. A crypte le message avec la clé secrète et l’envoie à B sur un canal qui n’est pas forcément sécurisé. B décrypte le message grâce à la clé secrète. Toute autre personne en possession de la clé secrète peut décrypter le message.

La cryptographie symétrique est beaucoup moins gourmande en ressources processeur que la cryptographie asymétrique… mais le gros problème est l’échange de la clé secrète entre A et B. Dans le protocole SSL, qui est utilisé par SSH et par les navigateurs Web, la cryptographie asymétrique est utilisée au début de la communication pour que A et B puissent s’échanger un clé secrète de manière sécurisée… puis la suite la communication est sécurisée grâce à la cryptographie symétrique en utilisant la clé secrète échangée.

Mon exemple

Nous allons réaliser la configuration de ssh sur le mode de l’authentification par clé entre deux serveurs. Dans ma réalisation l’un est un routeur / firewall important l’autre un serveur de backup. L’idée est d’utiliser ssh pour établir la communication entre les deux serveurs au moment des sauvegardes.

Générer ses clés

Pour générer un couple de clés DSA, loger vous sur le serveur, dans mon cas je commence par le firewall. Pour cela j’ouvre un shell avec un compte utilisateur créé pour faire les sauvegardes, en l’occurrence c’est le compte « admin » tapez :

admin@Firewall: ssh-keygen -t dsa

Les clés générées ont par défaut une longueur de 1024 bits, ce qui est aujourd’hui considéré comme suffisant pour une bonne protection.

Par défaut (il demande confirmation lors du processus de création), la clé privée est stockée dans le fichier /home/user/.ssh/id_dsa avec les permissions 600 et la clé publique est stockée dans le fichier /.ssh/id_dsa.pub avec les permissions 644.

Lors de la création, il vous demande une pass phrase qui est un mot de passe pour protéger la clé privée. Cette pass phrase sert à crypter la clé privée. La « pass phrase » vous sera alors demandée à chaque utilisation de la clé privée, c’est à dire à chaque fois que vous vous connecterez en utilisant cette méthode d’authentification. Un mécanisme appelé ssh-agent permet de ne pas rentrer le mot de passe à chaque fois.

Dans mon cas comme je souhaite établir des connexions automatique entre les machines et que ne serais pas présent au milieu de la nuit pour saisir le mot de passe je ne vais pas rentrer de « pass phrase. ». A note que vous pouvez à tout moment changer la « pass phrase » qui protège votre clé privée avec la commande

admin@Firewall: ssh-keygen -p.

Autoriser votre clé publique

Pour cela, il suffit de copier votre clé publique dans le fichier /.ssh/authorized_keys du compte utilisateur local de la machine ou vous désirez vous connecter. La commande suivante permet de réaliser cette opération via SSH depuis la machine ou vous venez de créé le couple cléf publique cléf privé vers la machine :

admin@Firewall: ssh-copy-id -i ~/.ssh/id_dsa.pub login@nom_DNS_du_serveur

Bon dans mon cas comme j’ai décider que les compte utilisateur local « admin » était prévus pour cette tache ma commande aura cette forme :

admin@Firewall: ssh-copy-id -i ~/.ssh/id_dsa.pub admin@backup0

Si tous ce passe bien le mots de passe du compte « backup » sur la machine « backup0 » est demandé. Donc entrez le mot de passe de votre compte sur le serveur. En cas d’échec de connections avec la machine « backup0 » le message est explicite, merci de faire attention.

Se logguer

Bien normalement la machine « backup0 » connaît la clef de la machine firewall ceci pour le compte « admin » local depuis le compte « admin » de firewall, vous suivez ? Maintenant pour vous connecter vous n’avez plus à taper le mots de passe :


ssh admin@gtw0
Linux gtw0 2.4.18-bf2.4 #1 Son Apr 14 09:53:28 CEST 2002 i686 unknown

Most of the programs included with the Debian GNU/Linux system are
freely redistributable; the exact distribution terms for each program
are described in the individual files in /usr/share/doc/*/copyright

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Mon Jun 28 15:19:45 2004 from backup0.asr2004.ligfy.org
admin@gtw0:~$

et dans l’autre sens ?

Depuis le compte utilisateur local de la machine backup0 vers le compte admin de la machine « firewall » vous devez toujours entrer un mots de passe. Pour éviter cela reprenez cette méthode et appliquer la depuis la machine « backup0 » pour enregistrer la clef de l’utilisateur admin sur « firew