Python-exempel som använder BackupPC dolda API

BackupPC är en backuplösning skriven i Perl och är öppen källkod. Det är ganska simpelt men trots det kraftfullt program. Det kan utan problem konkurrera med andra lösning såsom Bacula.

En sak som inte är dokumenterad alls är möjligheten att prata prata med BackupPC via ett API. BackupPC i sig består av flera delar, t.ex. BackupPC_archive, BackupPC_restore, index.cgi, m.fl. Dessa delar pratar via en socket. Men, det är också möjligt att ställa in BackupPC att använda sig av en IP-adress och en port. Det gör det möjligt för ett externt program att ge kommandon och få svar. T.ex. kan man övervaka BackupPC, starta backup eller återställa filer.

Eftersom det inte är dokumenterat annat än i koden så krävs det lite ”reverse-engineering” och Perl-kunskaper. Här kommer ett Python-exempel.

Börja med att ställ in att BackupPC lyssnar på en port och IP genom att ändra i /etc/backuppc/config.pl:

$Conf{ServerPort} = '2359';
$Conf{ServerMesgSecret} = 'hemligt';

Ändringen gör att port 2359 kommer att användas med den delade nyckeln ‘hemligt’.

Kommunikationen börjar med att BackupPC genererar en s.k. seed. Det används sedan av klienten att skapa en md5-hash som består av seed+nr+delade nyckeln+kommando. Nr är ett löpnummer som börjar med 0 ökar med ett varje kommando som skickas.

För att t.ex. lista status med ett enkelt Python-script:

#!/usr/bin/python
import hashlib
import base64
import socket

# backuppc host and port
host = "backuppc.example.com"
port = 2359

# connect to backuppc
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((host, port)) 
 
msg = "status info"

# sequence nr, increase one per request
seqno = 0

# shared secret, same as $Conf{ServerMesgSecret} in config.pl
secret = "hemligt"

# backuppc will give us a seed to use when calculating md5
seed = s.recv(1024)

# calculate md5 on seed+seqno+secret+message
md5 = hashlib.md5()
md5.update(seed)
md5.update(str(seqno))
md5.update(secret)
md5.update(msg)
md5hash = base64.b64encode(md5.digest())[:22]

# send:  
s.send(md5hash+" "+msg+"
")

# receive reply
print s.recv(1024)
s.close() 

Scriptet kommer att spotta ur sig svar om status. Andra kommandon som finns är t.ex. ”backup all”, ”restore”, ”reload”, ”status info”, ”status ” m.fl. Om du vill ha tips om fler kommando så kolla i /usr/share/backuppc/bin/BackupPC och funktionen Main_Check_Client_Messages runt rad 1200.