Skip to content

Commit 21286b7

Browse files
author
willemvd
committed
initial version with client side encryption of the PostgreSQL database and upload to S3
0 parents  commit 21286b7

File tree

4 files changed

+198
-0
lines changed

4 files changed

+198
-0
lines changed

Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM alpine:3.4
2+
MAINTAINER Willem willemvd@github
3+
4+
COPY backup.sh /tmp/backup.sh
5+
6+
RUN apk --no-cache add \
7+
curl \
8+
less \
9+
groff \
10+
jq \
11+
python \
12+
py-pip \
13+
postgresql \
14+
openssl && \
15+
pip install --upgrade pip awscli && \
16+
chmod -R 777 /tmp
17+
18+
CMD /tmp/backup.sh

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# PostgreSQL, client-side encrypted, Amazon S3 backupper
2+
3+
Docker image that is used to backup a PostgreSQL database, encrypt the dump file locally and upload to a S3 bucket.
4+
Your own settings define how secure you want it to be :)
5+
6+
Import difference with other PostgreSQL to S3 backup tools is **client-side encryption**.
7+
This means that it is not necessary to send any unencrypted data towards Amazon
8+
9+
The following (required) environment variables need to be set in order to run everything smoothly:
10+
11+
```properties
12+
# Used in the backup file name
13+
# and to place the file inside a subfolder of the S3 bucket
14+
BACKUP_TYPE=<type of backup, should also be a folder/key in the S3 bucket>
15+
16+
# PostgreSQL settings
17+
PGHOST=<database hostname>
18+
PGPORT=<port of the database server, default 5432>
19+
PGDATABASE=<database name>
20+
PGUSER=<database user>
21+
PGPASSWORD=<database password>
22+
23+
# OpenSSL settings
24+
ENCRYPTION_PASS_PHRASE=<strong password>
25+
OPENSSL_CIPHER_TYPE=<strong cipher like aes-256-cbc>
26+
27+
# Amazon settings
28+
AWS_ACCESS_KEY_ID=<access key id got from Amazon>
29+
AWS_SECRET_ACCESS_KEY=<secret access key got from Amazon>
30+
AWS_DEFAULT_REGION=<Amazon region name e.g. eu-central-1>
31+
S3_BUCKET_NAME=<name of the bucket in S3>
32+
```

backup.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/sh
2+
3+
#exit if one of the commands fail
4+
set -e
5+
6+
DATE=$(date +%Y-%m-%d-%H-%M-%S)
7+
8+
# backup type is used to seperate types like hourly or daily (folders in s3 bucket should be named like that)
9+
#BACKUP_TYPE=
10+
11+
BACKUP_FILE_NAME=$PGDATABASE-backup-$BACKUP_TYPE-$DATE.sql
12+
13+
cd /tmp
14+
15+
echo "Start dumping of database '$PGDATABASE' from '$PGHOST:$PGPORT/$PGDATABASE' with user '$PGUSER' to file '$BACKUP_FILE_NAME'"
16+
START_DUMP=$(date +%s)
17+
18+
# all PostgreSQL settings are set with environment variables
19+
#PGDATABASE=
20+
#PGUSER=
21+
#PGPASSWORD=
22+
#PGHOST=
23+
#PGPORT=
24+
pg_dump --format=custom > $BACKUP_FILE_NAME
25+
26+
DONE_DUMP_IN=$(($(date +%s)-$START_DUMP))
27+
echo "Done dumping ($DONE_DUMP_IN sec) database"
28+
29+
echo ""
30+
31+
# OpenSSL settings
32+
#OPENSSL_CIPHER_TYPE=
33+
#ENCRYPTION_PASS_PHRASE=
34+
35+
ENCRYPTION_FILE_NAME_SUFFIX=.enc
36+
37+
echo "Start encrypting database dump file '$BACKUP_FILE_NAME' with cipher type '$OPENSSL_CIPHER_TYPE' and password as defined in environment variable ENCRYPTION_PASS_PHRASE"
38+
START_ENC=$(date +%s)
39+
openssl enc -in $BACKUP_FILE_NAME -out $BACKUP_FILE_NAME$ENCRYPTION_FILE_NAME_SUFFIX -e -$OPENSSL_CIPHER_TYPE -pass pass:$ENCRYPTION_PASS_PHRASE
40+
41+
DONE_ENC_IN=$(($(date +%s)-$START_ENC))
42+
echo "Done encrypting ($DONE_ENC_IN sec) database dump file, now remove unencrypted file"
43+
44+
rm -f $BACKUP_FILE_NAME
45+
46+
echo ""
47+
48+
echo "Start uploading encrypted '$BACKUP_FILE_NAME' to 's3://$S3_BUCKET_NAME/$BACKUP_TYPE/$BACKUP_FILE_NAME'"
49+
START_UPLOAD=$(date +%s)
50+
51+
# AWS connection settings
52+
#AWS_ACCESS_KEY_ID=
53+
#AWS_SECRET_ACCESS_KEY=
54+
#AWS_DEFAULT_REGION=
55+
56+
# bucket name to upload to
57+
#S3_BUCKET_NAME=
58+
aws s3 cp ./$BACKUP_FILE_NAME$ENCRYPTION_FILE_NAME_SUFFIX s3://$S3_BUCKET_NAME/$BACKUP_TYPE/$BACKUP_FILE_NAME
59+
60+
DONE_UPLOAD_IN=$(($(date +%s)-$START_UPLOAD))
61+
echo "Done uploading ($DONE_UPLOAD_IN sec) 's3://$S3_BUCKET_NAME/$BACKUP_TYPE/$BACKUP_FILE_NAME'"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
apiVersion: v1
2+
kind: List
3+
items:
4+
- apiVersion: batch/v2alpha1
5+
kind: ScheduledJob
6+
metadata:
7+
name: postgresql-s3-hourly-backup
8+
spec:
9+
# every start of the hour
10+
schedule: "0 * * * *"
11+
jobTemplate:
12+
spec:
13+
template:
14+
spec:
15+
# 30 minutes timeout
16+
activeDeadlineSeconds: 1800
17+
containers:
18+
- name: postgresql-s3-hourly-backup
19+
image: willemvd/postgresql-client-side-encrypted-s3-backup
20+
env:
21+
- name: PGDATABASE
22+
value:
23+
- name: PGHOST
24+
value:
25+
- name: PGPORT
26+
value: "5432"
27+
- name: PGUSER
28+
value:
29+
- name: PGPASSWORD
30+
value:
31+
- name: ENCRYPTION_PASS_PHRASE
32+
value:
33+
- name: OPENSSL_CIPHER_TYPE
34+
value: aes-256-cbc
35+
- name: AWS_ACCESS_KEY_ID
36+
value:
37+
- name: AWS_SECRET_ACCESS_KEY
38+
value:
39+
- name: AWS_DEFAULT_REGION
40+
value:
41+
- name: S3_BUCKET_NAME
42+
value:
43+
- name: BACKUP_TYPE
44+
value: hourly
45+
restartPolicy: OnFailure
46+
- apiVersion: batch/v2alpha1
47+
kind: ScheduledJob
48+
metadata:
49+
name: postgresql-s3-daily-backup
50+
spec:
51+
# daily at 02:30 (do not run at the whole hour to prevent potential issues with hourly run)
52+
schedule: "30 2 * * *"
53+
jobTemplate:
54+
spec:
55+
template:
56+
spec:
57+
# 30 minutes timeout
58+
activeDeadlineSeconds: 1800
59+
containers:
60+
- name: postgresql-s3-daily-backup
61+
image: willemvd/postgresql-client-side-encrypted-s3-backup
62+
env:
63+
- name: PGDATABASE
64+
value:
65+
- name: PGHOST
66+
value:
67+
- name: PGPORT
68+
value: "5432"
69+
- name: PGUSER
70+
value:
71+
- name: PGPASSWORD
72+
value:
73+
- name: ENCRYPTION_PASS_PHRASE
74+
value:
75+
- name: OPENSSL_CIPHER_TYPE
76+
value: aes-256-cbc
77+
- name: AWS_ACCESS_KEY_ID
78+
value:
79+
- name: AWS_SECRET_ACCESS_KEY
80+
value:
81+
- name: AWS_DEFAULT_REGION
82+
value:
83+
- name: S3_BUCKET_NAME
84+
value:
85+
- name: BACKUP_TYPE
86+
value: daily
87+
restartPolicy: OnFailure

0 commit comments

Comments
 (0)