init
commit
ea14f2703d
|
@ -0,0 +1,12 @@
|
||||||
|
FROM debian:buster
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get upgrade -y \
|
||||||
|
&& apt-get install -y apache2 php php-curl php-mbstring \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN rm /var/www/html/index.html
|
||||||
|
ADD htdocs /var/www/html
|
||||||
|
RUN mkdir /var/www/data
|
||||||
|
RUN chown www-data:www-data /var/www/ -R
|
||||||
|
EXPOSE 80
|
||||||
|
CMD apachectl -D FOREGROUND
|
|
@ -0,0 +1,53 @@
|
||||||
|
# restic kumar connector
|
||||||
|
|
||||||
|
This is a restic connector for kumar. It allows you to check if you backups did run in time.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Running the Container
|
||||||
|
|
||||||
|
Just run the container, ideally using compose and expose port 80, maybe use something like traffic to make it https.
|
||||||
|
You could add a volume to /var/www/data to persist the data.
|
||||||
|
This is not necessary, but a fresh container will not report functional backups until you reported something.
|
||||||
|
If it's nor prevented on a network level for the world to submit data, you might whant to set RKC_USER and RKC_PASS to prevent random people from submitting data.
|
||||||
|
You need to use these credentials when reporting to the webservice.
|
||||||
|
|
||||||
|
### Reporting
|
||||||
|
|
||||||
|
To report your you need to post the output of `restic snapshots` to the webservice, eg:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
restic snapshots | curl -X POST -d @- http://restic_kumar_reporter/
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```bash
|
||||||
|
restic snapshots | curl -X POST -d @- -u "$USER:$PASS" http://restic_kumar_reporter/
|
||||||
|
```
|
||||||
|
|
||||||
|
when RKC_USER and RKC_PASS are set.
|
||||||
|
|
||||||
|
### Checking with kumar
|
||||||
|
|
||||||
|
Just point kumar to your webservice.
|
||||||
|
The Output looks something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
BACKUP|host1|/opt/mailcow|OK
|
||||||
|
BACKUP|host1|/var/lib/docker/volumes|OK
|
||||||
|
BACKUP|host2|/opt/docker|OK
|
||||||
|
BACKUP|host2|/var/lib/docker/volumes|OK
|
||||||
|
BACKUP|host3|/opt/docker|TOO_OLD
|
||||||
|
BACKUP|host3|/var/lib/docker/volumes|OK
|
||||||
|
BACKUP|host4|/opt/docker|OK
|
||||||
|
BACKUP|host4|/var/lib/docker/volumes|OK
|
||||||
|
BACKUP|host5|/opt/docker|TOO_OLD
|
||||||
|
BACKUP|host5|/var/lib/docker/volumes|TOO_OLD
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
output is always sorted by host and path. so you might check a whole block of hosts at once.
|
||||||
|
|
||||||
|
A Backup is okay if it is not older than X hours (default 28).
|
||||||
|
You can change this by requesting with `?maxage=XX` where XX is the maximum age in hours.
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
|
$user = getenv("RKC_USER");
|
||||||
|
$pass = getenv("RKC_PASS");
|
||||||
|
if (false !== $user or false !== $pass) {
|
||||||
|
if (
|
||||||
|
!isset($_SERVER["PHP_AUTH_USER"]) ||
|
||||||
|
!isset($_SERVER["PHP_AUTH_PW"]) ||
|
||||||
|
$_SERVER["PHP_AUTH_USER"] !== $user ||
|
||||||
|
$_SERVER["PHP_AUTH_PW"] !== $pass
|
||||||
|
) {
|
||||||
|
header('WWW-Authenticate: Basic realm="RKC"');
|
||||||
|
header("HTTP/1.0 401 Unauthorized");
|
||||||
|
echo "You are not authorized to access this page.";
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$resticData = file_get_contents("php://input");
|
||||||
|
$resticData = explode("\n", $resticData);
|
||||||
|
$backups = [];
|
||||||
|
foreach ($resticData as $snapshot) {
|
||||||
|
if (
|
||||||
|
!preg_match(
|
||||||
|
"/^(?<id>[a-z0-9]{8}) +(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) +(?<hour>\d{2}):+(?<minute>\d{2}):+(?<second>\d{2}) +(?<host>[^ ]+) +(?<path>[^ ]+).*/",
|
||||||
|
$snapshot,
|
||||||
|
$m
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$backupName = $m["host"] . "|" . $m["path"];
|
||||||
|
if (!isset($backups[$backupName])) {
|
||||||
|
$backups[$backupName] = 0;
|
||||||
|
}
|
||||||
|
$backupTime = mktime(
|
||||||
|
$m["hour"],
|
||||||
|
$m["minute"],
|
||||||
|
$m["second"],
|
||||||
|
$m["month"],
|
||||||
|
$m["day"],
|
||||||
|
$m["year"]
|
||||||
|
);
|
||||||
|
if ($backupTime > $backups[$backupName]) {
|
||||||
|
$backups[$backupName] = $backupTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksort($backups);
|
||||||
|
file_put_contents(
|
||||||
|
"/var/www/data/backups.json",
|
||||||
|
json_encode($backups, JSON_UNESCAPED_SLASHES + JSON_PRETTY_PRINT)
|
||||||
|
);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
header("Content-Type: text/plain");
|
||||||
|
$maxAge = isset($_GET["maxage"]) ? intval($_GET["maxage"]) : 28;
|
||||||
|
$maxAge = $maxAge * 60 * 60;
|
||||||
|
$backups = json_decode(file_get_contents("/var/www/data/backups.json"), true);
|
||||||
|
foreach ($backups as $backupName => $backupTime) {
|
||||||
|
echo "BACKUP|$backupName|";
|
||||||
|
if ($backupTime + $maxAge < time()) {
|
||||||
|
echo "TOO_OLD";
|
||||||
|
} else {
|
||||||
|
echo "OK";
|
||||||
|
}
|
||||||
|
echo "\n";
|
||||||
|
}
|
Loading…
Reference in New Issue