From 994187c1f1898ece7d65719ecb7aeed34f9c80bc Mon Sep 17 00:00:00 2001 From: Mastermindzh Date: Sun, 19 Mar 2023 21:07:09 +0100 Subject: [PATCH] feat: initial version --- .drone.yml | 31 +++++++++++++++++++++ .gitignore | 2 ++ .vscode/settings.json | 3 ++ CHANGELOG.md | 10 +++++++ Dockerfile | 16 +++++++++++ README.md | 51 +++++++++++++++++++++++++++++++++ ci/docker-publish.sh | 18 ++++++++++++ export.sh | 65 +++++++++++++++++++++++++++++++++++++++++++ package.json | 16 +++++++++++ 9 files changed, 212 insertions(+) create mode 100644 .drone.yml create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 ci/docker-publish.sh create mode 100644 export.sh create mode 100644 package.json diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..d23bbb8 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,31 @@ +kind: pipeline +name: default +type: docker + +steps: + - name: build + image: docker:dind + volumes: + - name: dockersock + path: "/var/run/docker.sock" + environment: + DOCKER_USERNAME: + from_secret: docker_hub_username + DOCKER_PASSWORD: + from_secret: docker_hub_password + commands: + - echo $DOCKER_PASSWORD | docker login --username "$DOCKER_USERNAME" --password-stdin + - bash docker-publish.sh + +services: + - name: docker + image: docker:dind + privileged: true + volumes: + - name: dockersock + path: /var/run + +volumes: + - name: dockersock + host: + path: /var/run/docker.sock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad2e049 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.docker-export +results diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f2ac120 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.words": ["Bitwarden", "bw", "nopad", "aes-256-cbc", "openssl"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7749972 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] + +Initial version of the export script diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a2dd100 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:lts-slim + +# install openssl +RUN apt-get update && \ + apt-get install -y --no-install-recommends openssl && \ + rm -rf /var/cache/apk/* + +# install bitwarden-cli +RUN npm install -g @bitwarden/cli@2023.2.0 + +# add the export script +RUN mkdir -p /opt/bw-export +COPY export.sh /opt/bw-export/export.sh + +WORKDIR /opt/bw-export +ENTRYPOINT [ "bash", "export.sh" ] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..642ab5f --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# bw-export + +bw-export is a simple bash script that exports a raw, encrypted JSON copy of your Bitwarden vault. +It will encrypt the JSON file with OpenSSL and lock it, by default, with your vault password. + + + +- [bw-export](#bw-export) + - [getting started](#getting-started) + - [getting started with docker](#getting-started-with-docker) + - [Decrypting the backup file](#decrypting-the-backup-file) + - [Environment variables](#environment-variables) + + + +## getting started + +Either edit the variables in the script itself or use the [Environment variables](#environment-variables) to configure the script and simply run it: +`bash export.sh` + +## getting started with docker + +Run the following command to quickly create an encrypted backup of your vault: + +`docker run --rm -e BW_ACCOUNT='your_email' -e BW_PASS='your_password' -v "$PWD:/export" mastermindzh/bw-export` + +## Decrypting the backup file + +By default, bw-export will use the following settings to make your backup: + +`-aes-256-cbc -pbkdf2 -iter 100000 -k ""` + +To decrypt that simply run OpenSSL with the same params in export mode: + +`openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -d -nopad -in input.enc -out output.json` + +## Environment variables + +You can tweak a lot of the internal workings of bw-export with simple environmental variables. +The list below outlines most of them: + +| Variable | Default value | Description | +| ------------------- | ---------------------------------------- | -------------------------------------------------------------- | +| BW_ACCOUNT | `bitwarden_vault_test@mastermindzh.tech` | Bitwarden email address | +| BW_PASS | `VGhpc0lzQVZhdWx0UGFzc3dvcmQK` | Bitwarden password | +| BW_FILENAME_PREFIX | `bitwarden_vault_export_` | Prefix to use for generated files ($prefix$timestamp.enc) | +| BW_TIMESTAMP | `Y-%m-%d %H:%M:%S` | Timestamp to use for generated files | +| BW_EXPORT_FOLDER | `export` | Folder to put export files in | +| BW_FOLDER_STRUCTURE | `Y/%m` | Date/timestamp to generate folders | +| BW_PASSWORD_ENCODE | `base64` | "plain", or "base64", depending on whether you encoded BW_PASS | +| BW_OPENSSL_OPTIONS | `aes-256-cbc -pbkdf2 -iter 100000` | Options passed to openssl's "enc" command | diff --git a/ci/docker-publish.sh b/ci/docker-publish.sh new file mode 100644 index 0000000..48875ae --- /dev/null +++ b/ci/docker-publish.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +DOCKER_SCOPE=${DOCKER_USERNAME:-"mastermindzh"} + +TAGS=( + "latest" + "$(cat package.json | grep version | head -1 | awk -F: '{ print $2}' | sed 's/[\",]//g' | tr -d '[[:space:]]')" + "$(git rev-parse HEAD)" +) + +NAME=$(cat package.json | grep name | head -1 | awk -F: '{ print $2}' | sed 's/[\",]//g' | tr -d '[[:space:]]') + +docker build -t "$DOCKER_SCOPE/$NAME:latest" . + +for tag in "${TAGS[@]}"; do + docker tag "$DOCKER_SCOPE/$NAME:latest" "$DOCKER_SCOPE/$NAME:$tag" + docker push "$DOCKER_SCOPE/$NAME:$tag" +done diff --git a/export.sh b/export.sh new file mode 100644 index 0000000..403089c --- /dev/null +++ b/export.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# input password might be encrypted/hashed/etc + +set -e +export LC_CTYPE=C +export LC_ALL=C + +bw_logout() { + bw logout &>/dev/null || true +} + +# environment variables +BW_ACCOUNT=${BW_ACCOUNT:-"bitwarden_vault_test@mastermindzh.tech"} +BW_PASS=${BW_PASS:-"VGhpc0lzQVZhdWx0UGFzc3dvcmQK"} +BW_FILENAME_PREFIX=${BW_FILENAME_PREFIX:-"bitwarden_vault_export_"} +BW_TIMESTAMP=${BW_TIMESTAMP:-"+%Y-%m-%d %H:%M:%S"} +BW_EXPORT_FOLDER=${BW_EXPORT_FOLDER:-"/export"} +BW_FOLDER_STRUCTURE=${BW_FOLDER_STRUCTURE:-"+%Y/%m"} +BW_PASSWORD_ENCODE=${BW_PASSWORD_ENCODE:-"base64"} +BW_OPENSSL_OPTIONS=${BW_OPENSSL_OPTIONS:-"-aes-256-cbc -pbkdf2 -iter 100000"} + +# construct internal variables +BW_INTERNAL_TIMESTAMP=$(date "$BW_TIMESTAMP") +BW_INTERNAL_PASSWORD="$BW_PASS" +BW_INTERNAL_FOLDER_STRUCTURE="$BW_EXPORT_FOLDER" +BW_ENC_OUTPUT_FILE="$BW_FILENAME_PREFIX$BW_INTERNAL_TIMESTAMP.enc" +if [ -n "$BW_FOLDER_STRUCTURE" ]; then + BW_INTERNAL_FOLDER_STRUCTURE="$BW_INTERNAL_FOLDER_STRUCTURE/$(date "$BW_FOLDER_STRUCTURE")" + mkdir -p "$BW_INTERNAL_FOLDER_STRUCTURE" + BW_ENC_OUTPUT_FILE="$BW_INTERNAL_FOLDER_STRUCTURE/$BW_ENC_OUTPUT_FILE" +fi + +# we need to control the session so we're making sure to logout if we are logged in +bw_logout + +case $BW_PASSWORD_ENCODE in + +"base64") + BW_INTERNAL_PASSWORD=$(echo "$BW_INTERNAL_PASSWORD" | base64 -d) + ;; +"none" | "plain") + echo "using un-encoded password." + ;; + +*) + echo "unrecognized encoding method. Aborting." + exit 1 + ;; +esac + +#login +BW_SESSION=$(bw login "$BW_ACCOUNT" "$BW_INTERNAL_PASSWORD" --raw) + +# commands +echo "Exporting to \"$BW_ENC_OUTPUT_FILE\"" +echo "$BW_ENCRYPTION_PASSWORD" +bw --raw --session "$BW_SESSION" export --format json | openssl enc $BW_OPENSSL_OPTIONS -k "$BW_INTERNAL_PASSWORD" -out "$BW_ENC_OUTPUT_FILE" +bw_logout + +# make sure none of these are available later +unset BW_SESSION +unset BW_PASS +unset BW_ACCOUNT +unset BW_INTERNAL_PASSWORD diff --git a/package.json b/package.json new file mode 100644 index 0000000..13fd353 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "bw-export", + "version": "1.0.0", + "description": "bw-export is a simple bash script that exports a raw, encrypted JSON copy of your Bitwarden vault.", + "main": "export.sh", + "scripts": { + "docker-build": "docker build -t bw-export .", + "publish": "bash ci/docker-publish.sh" + }, + "repository": { + "type": "git", + "url": "git@git.mastermindzh.tech:mastermindzh/bitwarden-encrypted-json-sync.git" + }, + "author": "Rick van Lieshout (http://rickvanlieshout.com/)", + "license": "MIT" +} \ No newline at end of file