Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added password encryption for ZIP files #47

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
# in the database such as database credentials, secret keys, etc.
PBW_ENCRYPTION_KEY="encryption-key"

# Password for encrypting ZIP files. Applied after getting output of `psql_dump`,
# so works for both local and remote destinations.
PBW_BACKUP_PASSWORD="test-password"

# Database connection string for a PostgreSQL database where the pgbackweb
# will store its data.
PBW_POSTGRES_CONN_STRING="postgresql://postgres:[email protected]:5432/pgbackweb?sslmode=disable"
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# in the database such as database credentials, secret keys, etc.
PBW_ENCRYPTION_KEY=""

# Password for encrypting ZIP files. Applied after getting output of `psql_dump`,
# so works for both local and remote destinations.
PBW_BACKUP_PASSWORD=""

# Database connection string for a PostgreSQL database where the pgbackweb
# will store its data.
PBW_POSTGRES_CONN_STRING=""
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ services:
- ./backups:/backups # If you only use S3 destinations, you don't need this volume
environment:
PBW_ENCRYPTION_KEY: "my_secret_key" # Change this to a strong key
PBW_BACKUP_PASSWORD: "zip_password" # Optional password for ZIP files (both local and S3)
PBW_POSTGRES_CONN_STRING: "postgresql://postgres:password@postgres:5432/pgbackweb?sslmode=disable"
TZ: "America/Guatemala" # Set your timezone, optional
depends_on:
Expand Down Expand Up @@ -97,6 +98,8 @@ You only need to configure the following environment variables:

- `PBW_ENCRYPTION_KEY`: Your encryption key. Generate a strong one and store it in a safe place, as PG Back Web uses it to encrypt sensitive data.

- `PBW_BACKUP_PASSWORD`: (Optional) Password to protect ZIP files for both local and remote backups. Once password changes, old backups won't be available for restoration.

- `PBW_POSTGRES_CONN_STRING`: The connection string for the PostgreSQL database that will store PG Back Web data.

- `TZ`: Your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) (optional). Default is `UTC`. This impacts logging, backup filenames and default timezone in the web interface.
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COPY --from=golang /usr/local/go /usr/local/go
RUN apt update && apt install -y postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt update && apt install -y \
wget unzip tzdata git \
wget p7zip-full tzdata git \
postgresql-client-13 postgresql-client-14 \
postgresql-client-15 postgresql-client-16 && \
rm -rf /var/lib/apt/lists/*
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.cicd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COPY --from=golang /usr/local/go /usr/local/go
RUN apt update && apt install -y postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt update && apt install -y \
wget unzip tzdata git \
wget p7zip-full tzdata git \
postgresql-client-13 postgresql-client-14 \
postgresql-client-15 postgresql-client-16 && \
rm -rf /var/lib/apt/lists/*
Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ COPY --from=golang /usr/local/go /usr/local/go
RUN apt update && apt install -y postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt update && apt install -y \
wget unzip tzdata git \
wget p7zip-full tzdata git \
postgresql-client-13 postgresql-client-14 \
postgresql-client-15 postgresql-client-16 && \
rm -rf /var/lib/apt/lists/*
Expand Down
4 changes: 4 additions & 0 deletions docker/compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ services:
dockerfile: ./docker/Dockerfile.dev
ports:
- "8085:8085"
environment:
PBW_ENCRYPTION_KEY: "my_secret_key" # Change this to a strong key
PBW_BACKUP_PASSWORD: "testpassword"
PBW_POSTGRES_CONN_STRING: "postgresql://postgres:password@postgres:5432/pgbackweb?sslmode=disable"
volumes:
- ../:/app
- pbw_vol_app_ssh:/root/.ssh
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/maragudk/gomponents v0.20.4
github.com/orsinium-labs/enum v1.4.0
github.com/stretchr/testify v1.9.0
github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0
golang.org/x/crypto v0.25.0
golang.org/x/sync v0.7.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/adhocore/gronx v1.8.1 h1:F2mLTG5sB11z7vplwD4iydz3YCEjstSfYmCrdSm3t6A=
github.com/adhocore/gronx v1.8.1/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg=
github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0 h1:BVts5dexXf4i+JX8tXlKT0aKoi38JwTXSe+3WUneX0k=
github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0/go.mod h1:FDIQmoMNJJl5/k7upZEnGvgWVZfFeE6qHeN7iCMbCsA=
github.com/aws/aws-sdk-go v1.54.20 h1:FZ2UcXya7bUkvkpf7TaPmiL7EubK0go1nlXGLRwEsoo=
github.com/aws/aws-sdk-go v1.54.20/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down
5 changes: 5 additions & 0 deletions internal/config/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

type Env struct {
PBW_ENCRYPTION_KEY *string
PBW_BACKUP_PASSWORD *string
PBW_POSTGRES_CONN_STRING *string
}

Expand All @@ -26,6 +27,10 @@ func GetEnv(disableLogs ...bool) *Env {
name: "PBW_ENCRYPTION_KEY",
isRequired: true,
}),
PBW_BACKUP_PASSWORD: getEnvAsString(getEnvAsStringParams{
name: "PBW_BACKUP_PASSWORD",
isRequired: false,
}),
PBW_POSTGRES_CONN_STRING: getEnvAsString(getEnvAsStringParams{
name: "PBW_POSTGRES_CONN_STRING",
isRequired: true,
Expand Down
22 changes: 19 additions & 3 deletions internal/integration/postgres/postgres.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package postgres

import (
"archive/zip"
"bytes"
"fmt"
"github.com/alexmullins/zip"
"io"
"os"
"os/exec"

"github.com/eduardolat/pgbackweb/internal/config"
"github.com/eduardolat/pgbackweb/internal/util/strutil"
"github.com/orsinium-labs/enum"
)
Expand Down Expand Up @@ -176,14 +177,23 @@ func (c *Client) DumpZip(
) io.Reader {
dumpReader := c.Dump(version, connString, params...)
reader, writer := io.Pipe()
env := config.GetEnv()

go func() {
defer writer.Close()

zipWriter := zip.NewWriter(writer)
defer zipWriter.Close()

fileWriter, err := zipWriter.Create("dump.sql")
var fileWriter io.Writer
var err error

if env.PBW_BACKUP_PASSWORD != nil {
fileWriter, err = zipWriter.Encrypt("dump.sql", *env.PBW_BACKUP_PASSWORD)
} else {
fileWriter, err = zipWriter.Create("dump.sql")
}

if err != nil {
writer.CloseWithError(fmt.Errorf("error creating zip file: %w", err))
return
Expand All @@ -210,6 +220,7 @@ func (c *Client) DumpZip(
func (Client) RestoreZip(
version PGVersion, connString string, isLocal bool, zipURLOrPath string,
) error {
env := config.GetEnv()
workDir, err := os.MkdirTemp("", "pbw-restore-*")
if err != nil {
return fmt.Errorf("error creating temp dir: %w", err)
Expand Down Expand Up @@ -238,7 +249,12 @@ func (Client) RestoreZip(
return fmt.Errorf("zip file not found: %s", zipPath)
}

cmd := exec.Command("unzip", "-o", zipPath, "dump.sql", "-d", workDir)
var cmd *exec.Cmd
if env.PBW_BACKUP_PASSWORD != nil {
cmd = exec.Command("7z", "x", "-p"+*env.PBW_BACKUP_PASSWORD, "-o"+workDir, zipPath)
} else {
cmd = exec.Command("7z", "x", "-o"+workDir, zipPath)
}
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error unzipping ZIP file: %s", output)
Expand Down