Yop

Aller au contenu | Aller au menu | Aller à la recherche

mercredi, 26 juillet 2017

Personnalisation de bannière SSH avec image et texte


  • Récupérer une image idéalement en 32x32

J'ai pris un .png par exemple sur IconArchive.
(Mes 2 lecteurs, partagez vos sources d'icônes pour bannière en commentaires)

  • Installation de quelques paquets

Je ne suis plus trop sûr de ce qu'il faut exactement mais probablement

$ sudo apt-get install imagemagick texinfo openjdk-7-jdk coreutils perl git
  • Installation de util-say pour convertir les images en "texte"
$ git clone https://github.com/maandree/util-say.git
$ ./util-say/img2ponysay dilbert.png > dilbert.txt
Error: Unable to access jarfile ./util-say/util-say.jar
$ cd util-say &&  make && cd ..
$ ./util-say/img2ponysay dilbert.png > dilbert.txt
$  cat dilbert.txt 

  • ponysay a rajouté les lignes avec les $ qu'il faut virer dans notre cas

Suppression de la ligne qui contient "balloon":

 $ sed '/balloon/d' dilbert.txt  

Suppression des lignes avec les $:

 $ sed s/\\$\\\\\\$//g dilbert.txt 

Suppression des 5 premiers caractères de chaque ligne pour décaller l'image vers la gauche:

 $ sed 's/^.\{5\}//g' dilbert.txt 

Suppression des 3 premières lignes:

 $  sed 1,3d dilbert.txt 

Donc la ligne globale:

 $  sed '/balloon/d' dilbert.txt | sed s/\\$\\\\\\$//g | sed 's/^.\{5\}//g' | sed 1,3d > dilbert_cleaned.txt 

  • Script pour rajouter du texte

On édite le script ci-dessous pour modifier la police, les couleurs, et toutes les infos que l'on souhaite.

#!/bin/bash
NAME="Server"
OUT="/tmp/$NAME"
IP_PRV=""
IP_NAT=""
IP_PUB="1.2.3.4"
SERVICE="XXXX Paris"
HD="1 x 50GB"

echo "" > $OUT
echo "" >> $OUT
echo "" >> $OUT

toilet -f Graffiti $NAME | lolcat -f -F 0.3 >> $OUT

cecho () {
  local _color=$1; shift
  echo -ne "$(tput setaf $_color)$@$(tput sgr0)"
}

black=0; red=1; green=2; yellow=3; blue=4; pink=5; cyan=6; white=7;
echo "" >> $OUT

#cecho $white "IP Prv:  " >> $OUT
#echo "$IP_PRV" | toilet -f term | lolcat -f -F 0.4 >> $OUT

#cecho $white "IP NAT:  " >> $OUT
#echo "$IP_NAT" | toilet -f term | lolcat -f -F 0.4 >> $OUT

cecho $white "IP Pub:  " >> $OUT
echo "$IP_PUB" | toilet -f term | lolcat -f -F 0.4 >> $OUT

cecho $white "Service: " >> $OUT
echo "$SERVICE" | toilet -f term | lolcat -f -F 0.4 >> $OUT

cecho $white "Disks: " >> $OUT
echo "$HD" | toilet -f term | lolcat -f -F 0.4 >> $OUT

cat $OUT


echo ""
echo ""
echo "File output into $OUT"

On peut bien entendu modifier le script pour récupérer les infos automatiquement du serveur et ne pas avoir a modifier les valeurs à la main.

  • On installe les 2 paquets suivants utilisés par le script au-dessus
 $ sudo apt-get install toilet lolcat 

Allez voir le man de chaque commande pour les options.

  • On execute le script
 $ ./ip.sh 

A chaque execution, les couleurs seront un peu différentes

  • On joint les 2 fichiers en un seul
 $  paste dilbert_cleaned.txt  /tmp/Server > server.motd 

  • On copie le fichier server.motd dans /etc/motd du serveur
  • Vérifier dans le /etc/ssh/sshd_config que vous avez bien la ligne:
 PrintMotd yes 

vendredi, 3 juillet 2015

ESP8266 - Projet d'indicateur de réveil pour enfant

L'idée est de pouvoir indiquer avec un ESP8266 à mes jeunes enfants qu'il a beau faire jour dehors en ce mois de Juin, ce n'est pas l'heure de venir réveiller leurs pauvres parents en manque de sommeil.

Je ne suis pas le premier à avoir eu la même idée de père fatigué, puisqu'en cherchant un peu je suis tombé sur l'excellent blog de Dani Eichhorn.

Son billet explique qu'il fait une connection HTTP à intervalle régulier, afin de récupérer l'heure sur Internet, puis allume une LED ou une autre suivant qu'il est l'heure de se lever ou non.

Cependant, j'avais imaginé une autre façon de procéder, donc je suis resté sur ma première idée qui a "l'inconvénient" d'utiliser mon Rasp à tout faire sur le réseau local, mais l'avantage de pouvoir changer l'heure de "réveil" sans avoir à modifier le script sur l'ESP8266. Et puis c'est plus sympa d'essayer de faire à sa sauce.

L'idée est la suivante:
- L'ESP8266 faire tourner les serviettes un petit serveur HTTP.
- S'il recoit une requête "jour", il allume la LED verte
- S'il recoit une requête "nuit", il allume la LED rouge "laisse tes parents dormir, ils ne se couchent pas à 20h30 eux ! ".
- Le Rasp sur le réseau local exécute le script toutes les minutes, regarde l'heure, et en fonction, envoi la requête HTTP "jour" ou "nuit" à l'ESP 8266.
- Il y a en réalité 2 scripts dans la cron du Rasp, un qui s'exécute les jours de la semaine, et un autre le WE. L'heure de l'allumage "jour" est donc reglé plus tardivement le WE.
- Une page web pourrait éventuellement être créée à l'avenir sur le Rasp pour que Madame Yop puisse elle même changer l'heure avec un navigateur... sans aller modifier le Rasp en SSH... (WAF) Mais avant cela, faudrait d'abord voir si les 2 loustics vont bien vouloir suivre les indications des LEDs...

Tests sur Breadboard:

esp-led-verte.jpg

esp-led-rouge.jpg

On soude un peu et on range tout çà:

esp-led-boitier1.jpg

esp-led-boitier2.jpg

Schéma

esp-led-schema.png

Scripts

init.lua
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","Password")
wifi.sta.connect()
wifi.sta.setip({ip="192.168.1.247",netmask="255.255.255.0",gateway="192.168.1.1"})
print("ESP8266 mode is: " .. wifi.getmode())
print("The module MAC address is: " .. wifi.ap.getmac())
print("Config done, IP is "..wifi.sta.getip())
dofile("jour-nuit.lua")@@

J'ai récupéré le code suivant sur un github, mais je ne retouve pas lequel...

jour-nuit.lua
-- Relay pin as output
gpio.mode(5, gpio.OUTPUT)
gpio.mode(6, gpio.OUTPUT)

-- Include url_parser module
local parser = require "url_parser"

-- Create server
srv=net.createServer(net.TCP) 

srv:listen(80,function(conn) 
  conn:on("receive",function(conn,payload) 
    
    -- Parse request
    parsed_request = parser.parse(payload)

    if parsed_request == 'jour' then gpio.write(6, gpio.LOW) gpio.write(5, gpio.HIGH) end
    if parsed_request == 'nuit' then gpio.write(5, gpio.LOW) gpio.write(6, gpio.HIGH) end

    -- Display main page
    conn:send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n")
    conn:send('<head>')
    conn:send('<meta name="viewport" content="width=device-width, initial-scale=1">')
    conn:send('<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>')
    conn:send('<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">')
    conn:send('</head>')
    
    conn:send('<div class="container">')
    conn:send("<h1>Control Sommeil</h1>")
    conn:send('<div class="row">')
    
    conn:send('<div class="col-md-2"><input class="btn btn-block btn-lg btn-primary" type="button" value="Jour" onclick="jour()"></div>')
    conn:send('<div class="col-md-2"><input class="btn btn-block btn-lg btn-danger" type="button" value="Nuit" onclick="nuit()"></div>')

    conn:send('</div></div>')
    
    conn:send('<script>function jour() {$.get("/jour");}</script>')
    conn:send('<script>function nuit() {$.get("/nuit");}</script>')
  end) 
  conn:on("sent",function(conn) conn:close() end)
end)@@
url_parser.lua
-- Module declaration
local parser = {}

function parser.parse(request)

     -- Find start
     local e = string.find(request, "/")
     local request_handle = string.sub(request, e + 1)
     
     -- Cut end
     e = string.find(request_handle, "HTTP")
     request_handle = string.sub(request_handle, 0, (e-2))

     return request_handle

end

return parser
jour-nuit.sh sur le Rasp
 
#!/bin/bash
# Control de la LED pour jour/nuit enfants

LEVER="0720"
COUCHER="2030"

IP="192.168.1.247"
CUR_TIME=`date +%H%M`

if [ $CUR_TIME -ge $LEVER -a $CUR_TIME -le $COUCHER ]
    then 
        echo "Jour"
	curl http://$IP/jour > /dev/null 2>&1
    else
        echo "Nuit"
	curl http://$IP/nuit > /dev/null 2>&1
fi

Le résultat final

ou presque (manque les autocollants de Spiderman et de la Reine de Neige)

esp-led-end.jpg

Evolutions possibles futures

(ou pas) dépendra surtout si les bambins suivent les indications des LEDs:

- Serveur web de configuration de l'heure
- Ajout d'une sonde de température ds18b20
- Utilisation du mode "veille" / utilisation sur batterie

lundi, 23 février 2015

Problème de dimension du terminal lors de connexions à travers un port série

Amené à travailler avec le terminal, à travers des connexions série, on constate un problème d'ajustement de la taille après l'utilisation de certaines commandes telles que vi etc...

J'utilise généralement la commande suivante pour me connecter sur le port série /dev/ttyUSB0

screen /dev/ttyUSB0 115200

Le problème est que certains logiciels comme l'éditeur vi considèrent que le la fenêtre de terminal n'est que de 24 lignes. Cela reste ainsi ensuite même après être sorti de l'éditeur. Ce qui laisse une bande vide en bas empêchant d'utiliser toute la hauteur du terminal.

serialProblemeLignesVides.png

Le problème, expliqué par Akkana Peck sur son blog est que screen n'a pas de possibilité d'envoyer par le port série, la taille originale de la fenêtre du terminal, (alors que c'est ce qui se passe en SSH par exemple).

Il ne semble pas non plus y avoir une commande qui permet de demander au terminal sa taille.

Cela n'a pas l'air simple à résoudre, heureusement pour nous, Akkana partage un petit script en python qui ruse en allant déplacer le curseur pour trouver la bonne taille etc.. et permet de résoudre le problème.

TerminalSerialResolution.png

On peut également le mettre par exemple dans le fichier .bash_profile pour qu'il se lance à l'ouverture de la session.

Je ne sais pas s'il quelqu'un connait une meilleure solution à ce problème ? Mais en tout cas cela fonctionne parfaitement pour moi depuis plusieurs mois... et je me suis dit qu'il pouvait être utile de partager l'astuce :)

vendredi, 6 décembre 2013

Backup incrémental avec le Rasp - rdiff-backup


  • Introduction

J'avais lu cet article de Benjamin concernant des sauvergardes distantes chiffrées.

Disposant désormais moi aussi d'un "site distant" où placer un Raspberry (celui avec la chaudière, j'ai pu me lancer également il y a quelques mois.. Mais en utilisant quelques variantes des outils.

- rdiff-backup (au lieu de rsync)
- LoopAES (au lieu de TrueCrypt )

Les raisons principales qui m'ont fait choisir rdiff-backup (par rapport a rsync ou à Duplicity ou encore rsnapshot ou certaines autres solutions sont principalement:

- Incrémental
Donc ne transfère que les modifications.

- Le backup est toujours le mirroir de la dernière version (hormis le répertoire additionel "rdiff-backup-data" qui contient les changements (et suppression).
En gros, il suffit de recopier le répertoire de backup pour repartir comme si de rien n'était si on veut juste restaurer la dernière version de la sauvegarde.

- Conserve les modifications (et suppressions).
Si un fichier est supprimé par erreur de la source, on ne veut PAS qu'il le soit aussi coté backup après synchronisation. Comme il y a bien quand même un "mirroir", le fichier "supprimé" est déplacé dans le répertoire additionel "rdiff-backup-data"

- Permet de restaurer un fichier/répertoire dans sa version à une date donnée.

- Permet de supprimer les anciennes versions de + de XX jours (ou de XX backups) afin de ne pas saturer le disque de backup.

  • Chiffrement

J'ai choisi LoopAES au lieu de Truecrypt uniquement pour des raisons de vitesse d'accès.

Des 2 cotés les données sont chiffrées et rendues accessible dans le répertoire /mnt/.data/

Les passphrases pour déchiffrer les données sont saisient manuellement une fois les Rasps démarrés.
Vu qu'un Rasp ne consomme qu'environ 4€ d'électricité par an, est silencieux et ne chauffe pas, ils restent allumés en théorie en permanence (en + j'ai un petit onduleur).
Les données sont accessible ensuite tout le temps que le Rasp reste allumé.
Mon but est principalement de restreindre l'accès aux données en cas de vol du Rasp/Disque dur. (Le voleur, même geek, à des chances de débrancher le Rasp/disque dur pour le voler ;) )

  • Configuration

- Installation de rdiff-backup des 2 cotés

$ sudo apt-get install rdiff-backup

- Principe

L'authentification SSH se fait par une clé SSH spécifique à la tâche de backup, ce qui permet d'automatiser la connexion et de restreindre les commandes utilisables par cette clé.

Il y a 2 choix possibles dans le sens des connexions.
- Le serveur qui envoit ses données à backuper sur le serveur de backup.
- Le serveur de backup qui vient récupérer les données sur le serveur à backuper.

J'ai choisi la 2ème option:

En cas de compromission du serveur à backuper, aucun accès possible sur le serveur de backup.
En cas de compromission du serveur de backup, un accès restreint à la commande rdiff-backup en lecture seule sur le serveur à backuper (pas d'accès au shell).

command="rdiff-backup --server --restrict-read-only...."

En cas de compromission de la clé privée. Celle ci ne peux pas être utilisée depuis une machine autre que celle déclarée sur le serveur à backuper.

from="1.2.3.4"

- Mise en place des clés SSH

Sur le serveur de backup:

$ ssh-keygen

pas de passphrase car on veut ensuite que la connexion puisse se faire automatiquement

on appelle ces clés par exemple:
id_rsa.backup
id_rsa.backup.pub

dans le fihier .ssh/config du serveur de backup

host ServeurABackuper
hostname host.example.org
user yop
identityfile /home/user/.ssh/id_rsa.backup
port 80

Ajout de la clé publique sur le serveur à backuper dans authorized_keys.
Pensez pour les tests à ne pas utiliser de "SSH Agent Forwarding" ;)
Tester avec une connexion SSH "normale"
Si ok, sécuriser en ajoutant les restrictions suivantes devant la clé:

from="1.2.3.4",command="rdiff-backup --server --restrict-read-only /",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAABCDxxxx

Tester à nouveaux avec une connexion SSH "normale" (et sans "SSH Agent Forwarding"), la connexion doit être refusée (car seulement la commande rdiff-backup est authorisée avec cette clé)

PTY allocation request failed on channel 0

- Backup

Sur le serveur de backup:

$ rdiff-backup ServeurABackuper::/mnt/.data/ /mnt/.data/backup/ServeurABackuper

Le contenu de /mnt/.data/ du serveur à backuper se retrouve donc dans /mnt/.data/backup/ServeurABackuper/ du serveur de backup.

Est créé en plus, un répertoire propre à rdiff-backup "rdiff-backup-data"

Pour plus d'infos, utiliser les options:

$ rdiff-backup -v5 --print-statistics

- Exemple de suppression d'un fichier

On supprime un fichier sur le serveur à backuper.
On relance un backup.
Le fichier est bien "supprimé" coté répertoire de backup MAIS une copie (compressée en gz et renommée avec la date) est conservée dans le répertoire rdiff-backup-data/increments/

On peut voir les différentes "versions" d'un fichier

rdiff-backup --list-increments file

- Restaurer

Pour une restauration, on peut soit passer par une bête copie classique (cp / scp etc.. ), soit utiliser les options suivantes

rdiff-backup -r now host.net::/remote-dir/file local-dir/file
rdiff-backup -r 10D host.net::/remote-dir/file /tmp/file

10D étant bien entendu la version du fichier "file" d'il y a 10 jours.

Exemple pour restaurer un fichier qui a été supprimé du serveur à backuper hier, puis un backup a eu lieu cette nuit., dans ce cas le fichier a été supprimé le l'image "mirroir", mais est toujours présent dans rdiff-backup-data/increments:

rdiff-backup -r 2D SrvDeBackup::/mnt/.data/backup/xxxxx/yyyyy/file localrep/file

La commande ici est lançée depuis le serveur à backuper. On ne peut pas utiliser "now" car le fichier n'est déjà plus dans le mirroir à cause de la synchro de la nuit. Le fichier zzz n'est en fait plus présent dans /mnt/.data/backup/xxxxx/yyyyy/ mais la commande fonctionnera et ira chercher le fichier en réalité dans rdiff-backup-data/increments/

- Supprimer les anciennes versions de fichiers.

Comme on a pas non plus un espace illimité pour garder 10 000 versions de tous les fichiers (ou les fichiers supprimés) , il est nécessaire de supprimer régulièrement les "vielles" versions.

Ceci est réalisé par la commande suivante:

rdiff-backup --remove-older-than 2W host.net::/remote-dir

Ici les anciennes versions de plus de 2 semaines seront supprimées.
Bien ententu, ceci n'efface PAS les fichiers de la sauvegarde, même s'il datent de 10 ans, uniquement les anciennes versions.

rdiff-backup --remove-older-than 20B host.net::/remote-dir

Ici seules les modifications des 20 dernières sessions de Backups sont conservés.

J'aurais bien vu aussi une option qui aurait pris une taille en paramètre. Par exemple, "tu me supprimes les modifications de sessions de sorte que je n'utilise pas plus de 10Gio d'anciennes sessions"... Mais ceci n'existe pas. Il y a peut être une bonne raison ?

Dans mon cas, la commande est lancée en "local" dans le script tournant sur le serveur de backup

rdiff-backup --remove-older-than 12M --force /mnt/.data/backup/ServeurABackuper

  • Script et mise en cron

Mon script tourne sur le serveur de backup et fonctionne ainsi dans une cron chaque nuit:

- Vérification que le répertoire chiffré est bein accessible en clair et si oui:
- Backup
- Supression des anciennes versions
- Un petit mail récaptulatif

Sinon, petit mail d'alerte, car il y a du avoir un reboot.

  • Conlusion

La solution permet donc d'avoir à moindre frais (Un Rasp + un Disque dur + 4€ d'électricité par an + des beaux parents pour héberger le Rasp ;) ) une solution de backup:

- Discrète (ne prend pas trop de place et est silencieux)
- Incrémental (Optimisation bande passante et temps de backup)
- Securisé (Chiffré + SSH + pas dans le Cloud de la NSA + site distant)
- On peut restaurer tout notre backup facilement. Même en copiant simplement le répertoire.
- On conserve les anciennes versions des modifications/supressions que l'on peut restaurer facilement également.

mardi, 4 octobre 2011

Modification de valeurs dans beaucoup de zones

Rien d'extraordinaire.. mais vu que j'ai beaucoup de zones à modifier.. et que je devrais faire la même chose dans l'autre sens...

  • Modification du MX pour toutes les zones:

$ for FICHIER in `find /var/chroot-named/etc/namedb/zones/pri/ -type f`; do sed -i 's/10 smtp.example.org./50 smtp.example.org./g' $FICHIER ; done

  • Modification du serial pour toutes les zones:

$ for FICHIER in `find /var/chroot-named/etc/namedb/zones/pri/ -type f`; do sed -i '/serial - YYYYMMDDxx/s/[0-9][0-9]*/2011100401/' $FICHIER ; done

Car la ligne qui contient le serial dans mes zones contient:

1111111111 ; serial - YYYYMMDDxx

Source

- page 1 de 3