11 Commits
master ... next

Author SHA1 Message Date
Xiaonan Shen
967beefb2f Add linux/arm/v7 2021-10-05 10:20:07 +08:00
Xiaonan Shen
7b72698ad5 Add github actions to build next 2021-09-13 20:12:06 +08:00
Xiaonan Shen
9c56bb2861 Improve dockerfile 2021-09-04 18:00:23 +08:00
Xiaonan Shen
0fb64c241c Remove build images 2021-09-04 13:17:19 +08:00
Xiaonan Shen
73ed583bf2 Fix gpg-agent run and provide automated login process (#35) 2021-09-04 11:22:58 +08:00
Xiaonan Shen
6fd883204d Merge branch 'next' into master 2021-09-04 11:15:36 +08:00
Xiaonan Shen
eb44376525 run as non-root in docker (#38) 2021-09-04 11:10:58 +08:00
Thibault Godouet
07d1004e09 run as non-root in docker 2021-07-25 17:42:10 +01:00
Jeffrey Stoke
83c08489c7 build: hide password input (best effort)
Signed-off-by: Jeffrey Stoke <me@arhat.dev>
2021-06-15 04:08:24 +02:00
Jeffrey Stoke
dbcf6d27b0 build: fix environment name
Signed-off-by: Jeffrey Stoke <me@arhat.dev>
2021-06-15 04:07:56 +02:00
Jeffrey Stoke
da0dfab9d3 build: gpg-agent run fix & automated login process
The gpg-agent could not start if the /root is mounted by docker when
the external path is long enough, a workaround is to use a different
GNUPGHOME for gpg key generation, and copy generated files to
/root/.gnupg afterwards

bonus: thanks to expect, we can a automated login process, if both
PROTONMAIL_USERNAME and PROTONMAIL_PASSWORD are set

Signed-off-by: Jeffrey Stoke <me@arhat.dev>
2021-06-14 22:38:44 +02:00
25 changed files with 412 additions and 557 deletions

View File

@@ -1,232 +0,0 @@
name: build from source
on:
push:
paths:
- .github/workflows/build.yaml
- build/*
- VERSION
pull_request:
paths:
- .github/workflows/build.yaml
- build/*
workflow_dispatch:
env:
GHCR_REPO: shenxn/protonmail-bridge-docker
DOCKERHUB_REPO: shenxn/protonmail-bridge
DOCKER_REPO_DEV: ghcr.io/shenxn/protonmail-bridge
PLATFORMS: linux/amd64,linux/arm64/v8,linux/arm/v7,linux/riscv64
jobs:
test:
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/master'
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set version
id: version
run: echo "version=`cat VERSION`" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKER_REPO_DEV }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.DOCKER_REPO_DEV }}",push-by-digest=false,name-canonical=true,push=true
context: ./build
file: ./build/Dockerfile
tags: "${{ env.DOCKER_REPO_DEV }}:dev-${{ github.ref_name }}"
build-args: |
version=${{ env.version }}
- name: Run Trivy vulnerability scan
uses: aquasecurity/trivy-action@0.30.0
with:
image-ref: "${{ env.DOCKER_REPO_DEV }}:dev-${{ github.ref_name }}"
format: 'sarif'
exit-code: 0
severity: 'CRITICAL,HIGH'
output: 'trivy-results.sarif'
- name: Upload Trivy scan SARIF report
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
build:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64/v8
- linux/arm/v7
- linux/riscv64
steps:
- name: Checkout
uses: actions/checkout@master
- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Set version
id: version
run: echo "version=`cat VERSION`" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_REPO }}
${{ env.GHCR_REPO }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=name=${{ env.DOCKERHUB_REPO }},${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=false
context: ./build
file: ./build/Dockerfile
tags: |
"${{ env.DOCKERHUB_REPO }}:build"
"${{ env.DOCKERHUB_REPO }}:${{ env.version }}-build"
"${{ env.GHCR_REPO }}:build"
"${{ env.GHCR_REPO }}:${{ env.version }}-build"
provenance: false
sbom: false
build-args: |
version=${{ env.version }}
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Set version
id: version
run: echo "version=`cat VERSION`" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_REPO }}
${{ env.GHCR_REPO }}
tags: |
type=raw,enable=true,value=${{ env.version }}-build
type=raw,enable=true,suffix=,value=build
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.DOCKERHUB_REPO }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *)
- name: Run Trivy vulnerability scan
uses: aquasecurity/trivy-action@0.30.0
with:
image-ref: "${{ env.DOCKERHUB_REPO }}:${{ env.version }}-build"
format: 'sarif'
exit-code: 0
severity: 'CRITICAL,HIGH'
output: 'trivy-results.sarif'
- name: Upload Trivy scan SARIF report
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.DOCKERHUB_REPO }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.GHCR_REPO }}:${{ steps.meta.outputs.version }}

View File

@@ -1,79 +0,0 @@
name: pack from deb
on:
push:
paths:
- .github/workflows/deb.yaml
- deb/*
- VERSION
pull_request:
paths:
- .github/workflows/deb.yaml
- deb/*
workflow_dispatch:
env:
DOCKER_REPO: shenxn/protonmail-bridge
DOCKER_REPO_DEV: ghcr.io/shenxn/protonmail-bridge-dev
jobs:
deb:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set version
id: version
run: echo "version=`cat VERSION`" >> $GITHUB_ENV
- name: Set repo
id: repo
run: if [[ $GITHUB_REF == "refs/heads/master" ]]; then echo "::set-output name=repo::${DOCKER_REPO}"; else echo "::set-output name=repo::${DOCKER_REPO_DEV}"; fi
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: ${{ steps.repo.outputs.repo }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build image without push
uses: docker/build-push-action@v2
with:
context: ./deb
file: ./deb/Dockerfile
load: true
tags: protonmail-bridge:latest
- name: Scan image
id: scan
uses: anchore/scan-action@v2
with:
image: protonmail-bridge:latest
fail-build: true
severity-cutoff: critical
acs-report-enable: true
- name: Upload Anchore scan SARIF report
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
- name: Login to DockerHub
uses: docker/login-action@v1
if: ${{ github.event_name != 'pull_request' }}
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
if: ${{ github.event_name != 'pull_request' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Push image
uses: docker/build-push-action@v2
with:
context: ./deb
file: ./deb/Dockerfile
tags: |
${{ steps.repo.outputs.repo }}:latest
${{ steps.repo.outputs.repo }}:${{ env.version }}
labels: ${{ steps.docker_meta.outputs.labels }}
push: ${{ github.event_name != 'pull_request' }}

99
.github/workflows/next.yaml vendored Normal file
View File

@@ -0,0 +1,99 @@
name: build next
on:
push:
branches:
- next
paths:
- .github/workflows/next.yaml
- docker/*
- protonmail_version/*
- VERSION
pull_request:
paths:
- .github/workflows/next.yaml
- docker/*
- protonmail_version/*
- VERSION
env:
DOCKER_REPO: shenxn/protonmail-bridge-ng
DOCKER_REPO_DEV: ghcr.io/shenxn/protonmail-bridge-ng-dev
PLATFORMS: linux/amd64,linux/arm64/v8,linux/arm/v7
jobs:
build:
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set version
id: version
run: |
echo "::set-output name=image_version::$(cat VERSION)" && \
echo "::set-output name=protonmail_bridge_version::$(cat protonmail_bridge_version/VERSION_LATEST)"
- name: Set repo
id: repo
run: if [[ $GITHUB_REF == "refs/heads/master" ]]; then echo "::set-output name=repo::${DOCKER_REPO}"; else echo "::set-output name=repo::${DOCKER_REPO_DEV}"; fi
- name: Docker meta
id: docker_meta
uses: crazy-max/ghaction-docker-meta@v1
with:
images: ${{ steps.repo.outputs.repo }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
driver-opts: network=host
- name: Build image without push to registry
uses: docker/build-push-action@v2
with:
context: ./docker
file: ./docker/Dockerfile
build-args: PROTONMAIL_BRIDGE_VERSION=${{ steps.version.outputs.protonmail_bridge_version }}
platforms: ${{ env.PLATFORMS }}
push: true
tags: localhost:5000/protonmail-bridge:latest
- name: Scan image
id: scan
uses: anchore/scan-action@v2
with:
image: localhost:5000/protonmail-bridge:latest
fail-build: true
severity-cutoff: critical
acs-report-enable: true
- name: Upload Anchore scan SARIF report
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
- name: Login to DockerHub
uses: docker/login-action@v1
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/master' }}
with:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/next' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Push image
uses: docker/build-push-action@v2
with:
context: ./docker
file: ./docker/Dockerfile
build-args: PROTONMAIL_BRIDGE_VERSION=${{ steps.version.outputs.protonmail_bridge_version }}
platforms: ${{ env.PLATFORMS }}
tags: |
${{ steps.repo.outputs.repo }}:latest
${{ steps.repo.outputs.repo }}:${{ steps.version.outputs.image_version }}-${{ steps.version.outputs.protonmail_bridge_version }}
labels: ${{ steps.docker_meta.outputs.labels }}
push: ${{ github.event_name != 'pull_request' }}

View File

@@ -2,6 +2,9 @@ name: update check
on:
push:
branches:
- master
- dev
paths:
- .github/workflows/update-check.yaml
- update-check.py

3
.gitignore vendored
View File

@@ -1,3 +0,0 @@
# Ignoring IDE-specific files
.idea/*
.vscode

View File

@@ -12,6 +12,10 @@ Docker Hub: [https://hub.docker.com/r/shenxn/protonmail-bridge](https://hub.dock
GitHub: [https://github.com/shenxn/protonmail-bridge-docker](https://github.com/shenxn/protonmail-bridge-docker)
## ARMv7 Builds
Currently there is a problem building the new parser targeting 32-bit architectures (i.e. `arm/v7`). The latest working build is `1.4.5-build`. Therefore, if you are using an `arm/v7` device like Raspberry Pi, do not upgrade to newer version. More information about the problem can be found [here](https://www.reddit.com/r/ProtonMail/comments/jvzm12/issue_building_bridge_150/). If you have any idea on how to fix this, a PR is welcome.
## ARM Support
We now support ARM devices (`arm64` and `arm/v7`)! Use the images tagged with `build`. See next section for details.
@@ -20,43 +24,42 @@ We now support ARM devices (`arm64` and `arm/v7`)! Use the images tagged with `b
There are two types of images.
- `deb`: Images based on the official [.deb release](https://protonmail.com/bridge/install). It only supports the `amd64` architecture.
- `build`: Images based on the [source code](https://github.com/ProtonMail/proton-bridge). It supports `amd64`, `arm64`, `arm/v7` and `riscv64`. Supporting to more architectures is possible. PRs are welcome.
- `build`: Images based on the [source code](https://github.com/ProtonMail/proton-bridge). It supports `amd64`, `arm64`, and `arm/v7`. Supporting to more architectures is possible. PRs are welcome.
tag | description
-- | --
`latest` | latest `deb` image
`[version]` | `deb` images
`build` | latest `build` image
`[version]-build` | `build` images
| tag | description |
| ----------------- | -------------------- |
| `latest` | latest `deb` image |
| `[version]` | `deb` images |
| `build` | latest `build` image |
| `[version]-build` | `build` images |
## Environment Variables for images with `build` in tag
| Name | Description | Default Value |
| --------------------- | --------------------------------------------------------------------------------- | ------------- |
| `PROTONMAIL_USERNAME` | your protonmail account username | (not set) |
| `PROTONMAIL_PASSWORD` | the password for your protonmail account | (not set) |
| `KEY_ID` | the pgp-id for the internal password manager required by protonmail-bridge | `pass-key` |
| `GNUPGHOME` | change the defulat `/root/.gnupg` to this directory as a workaround for gpg error | `/tmp/gnupg` |
## Initialization
To initialize and add account to the bridge, run the following command.
```
docker run --rm -it -v protonmail:/root shenxn/protonmail-bridge init
```bash
docker run --rm -it -v protonmail:/home/protonmail shenxn/protonmail-bridge init
```
If you want to use Docker Compose instead, you can create a copy of the provided example [docker-compose.yml](docker-compose.yml) file, modify it to suit your needs, and then run the following command:
Wait for the bridge to startup, use `login` command and follow the instructions to add your account into the bridge. Then use `info` to see the configuration information (username and password). After that, use `exit` to exit the bridge. You may need `CTRL+C` to exit the docker entirely.
```
docker compose run protonmail-bridge init
```
Wait for the bridge to startup, then you will see a prompt appear for [Proton Mail Bridge interactive shell](https://proton.me/support/bridge-cli-guide). Use the `login` command and follow the instructions to add your account into the bridge. Then use `info` to see the configuration information (username and password). After that, use `exit` to exit the bridge. You may need `CTRL+C` to exit the docker entirely.
__NOTE:__ If you have `PROTONMAIL_USERNAME` and `PROTONMAIL_PASSWORD` set for `docker run` with `-e`, the login process will finish automatically.
## Run
To run the container, use the following command.
```
docker run -d --name=protonmail-bridge -v protonmail:/root -p 1025:25/tcp -p 1143:143/tcp --restart=unless-stopped shenxn/protonmail-bridge
```
Or, if using Docker Compose, use the following command.
```
docker compose up -d
```bash
docker run -d --name=protonmail-bridge -v protonmail:/home/protonmail -p 1025:25/tcp -p 1143:143/tcp --restart=unless-stopped shenxn/protonmail-bridge
```
## Kubernetes
@@ -69,8 +72,8 @@ If you don't want to use Helm, you can also reference to the guide ([#6](https:/
Please be aware that running the command above will expose your bridge to the network. Remember to use firewall if you are going to run this in an untrusted network or on a machine that has public IP address. You can also use the following command to publish the port to only localhost, which is the same behavior as the official bridge package.
```
docker run -d --name=protonmail-bridge -v protonmail:/root -p 127.0.0.1:1025:25/tcp -p 127.0.0.1:1143:143/tcp --restart=unless-stopped shenxn/protonmail-bridge
```bash
docker run -d --name=protonmail-bridge -v protonmail:/home/protonmail -p 127.0.0.1:1025:25/tcp -p 127.0.0.1:1143:143/tcp --restart=unless-stopped shenxn/protonmail-bridge
```
Besides, you can publish only port 25 (SMTP) if you don't need to receive any email (e.g. as a email notification service).

View File

@@ -1 +1 @@
v3.21.2
0.1

View File

@@ -1,33 +0,0 @@
# The build image could be golang, but it currently does not support riscv64. Only debian:sid does, at the time of writing.
FROM debian:sid-slim AS build
ARG version
# Install dependencies
RUN apt-get update && apt-get install -y golang build-essential libsecret-1-dev
# Build
ADD https://github.com/ProtonMail/proton-bridge.git#${version} /build/
WORKDIR /build/
RUN make build-nogui vault-editor
FROM debian:sid-slim
LABEL maintainer="Simon Felding <sife@adm.ku.dk>"
EXPOSE 25/tcp
EXPOSE 143/tcp
# Install dependencies and protonmail bridge
RUN apt-get update \
&& apt-get install -y --no-install-recommends socat pass libsecret-1-0 ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Copy bash scripts
COPY gpgparams entrypoint.sh /protonmail/
# Copy protonmail
COPY --from=build /build/bridge /protonmail/
COPY --from=build /build/proton-bridge /protonmail/
COPY --from=build /build/vault-editor /protonmail/
ENTRYPOINT ["bash", "/protonmail/entrypoint.sh"]

View File

@@ -1,35 +0,0 @@
#!/bin/bash
set -ex
# Initialize
if [[ $1 == init ]]; then
# Initialize pass
gpg --generate-key --batch /protonmail/gpgparams
pass init pass-key
# Kill the other instance as only one can be running at a time.
# This allows users to run entrypoint init inside a running conainter
# which is useful in a k8s environment.
# || true to make sure this would not fail in case there is no running instance.
pkill protonmail-bridge || true
# Login
/protonmail/proton-bridge --cli $@
else
# socat will make the conn appear to come from 127.0.0.1
# ProtonMail Bridge currently expects that.
# It also allows us to bind to the real ports :)
socat TCP-LISTEN:25,fork TCP:127.0.0.1:1025 &
socat TCP-LISTEN:143,fork TCP:127.0.0.1:1143 &
# Start protonmail
# Fake a terminal, so it does not quit because of EOF...
rm -f faketty
mkfifo faketty
cat faketty | /protonmail/proton-bridge --cli $@
fi

View File

@@ -1,28 +0,0 @@
### The Deb install is just a repack of the official ProtonMail Bridge deb package with less dependencies.
### I recommend you don't use this. It's here for legacy reasons.
FROM debian:sid-slim AS build
COPY install.sh PACKAGE /
RUN apt-get update && apt-get install -y wget binutils
# Repack deb (removes unnecessary dependencies and produces /protonmail.deb)
RUN bash /install.sh
FROM debian:sid-slim
LABEL maintainer="Simon Felding <sife@adm.ku.dk>"
EXPOSE 25/tcp
EXPOSE 143/tcp
WORKDIR /protonmail
# Copy bash scripts
COPY gpgparams entrypoint.sh PACKAGE /protonmail/
COPY --from=build /protonmail.deb /tmp/protonmail.deb
RUN apt-get update \
&& apt-get install -y --no-install-recommends /tmp/protonmail.deb socat pass libsecret-1-0 ca-certificates procps \
&& rm -rf /var/lib/apt/lists/*
CMD ["bash", "/protonmail/entrypoint.sh"]

View File

@@ -1 +0,0 @@
https://github.com/ProtonMail/proton-bridge/releases/download/v3.21.2/protonmail-bridge_3.21.2-1_amd64.deb

View File

@@ -1,49 +0,0 @@
#!/bin/bash
set -ex
# Initialize
if [[ $1 == init ]]; then
# # Parse parameters
# TFP="" # Default empty two factor passcode
# shift # skip `init`
# while [[ $# -gt 0 ]]; do
# key="$1"
# case $key in
# -u|--username)
# USERNAME="$2"
# ;;
# -p|--password)
# PASSWORD="$2"
# ;;
# -t|--twofactor)
# TWOFACTOR="$2"
# ;;
# esac
# shift
# shift
# done
# Initialize pass
gpg --generate-key --batch /protonmail/gpgparams
pass init pass-key
# Login
protonmail-bridge --cli
else
# socat will make the conn appear to come from 127.0.0.1
# ProtonMail Bridge currently expects that.
# It also allows us to bind to the real ports :)
socat TCP-LISTEN:25,fork TCP:127.0.0.1:1025 &
socat TCP-LISTEN:143,fork TCP:127.0.0.1:1143 &
# Start protonmail
# Fake a terminal, so it does not quit because of EOF...
rm -f faketty
mkfifo faketty
cat faketty | protonmail-bridge --cli
fi

View File

@@ -1,8 +0,0 @@
%no-protection
%echo Generating a basic OpenPGP key
Key-Type: RSA
Key-Length: 2048
Name-Real: pass-key
Expire-Date: 0
%commit
%echo done

View File

@@ -1,16 +0,0 @@
#!/bin/bash
set -ex
# Repack deb (remove unnecessary dependencies)
mkdir deb
wget -i /PACKAGE -O /deb/protonmail.deb
cd deb
ar x -v protonmail.deb
mkdir control
tar zxvf control.tar.gz -C control
sed -i "s/^Depends: .*$/Depends: libgl1, libc6, libsecret-1-0, libstdc++6, libgcc1/" control/control
cd control
tar zcvf ../control.tar.gz .
cd ../
ar rcs -v /protonmail.deb debian-binary control.tar.gz data.tar.gz

View File

@@ -1,14 +0,0 @@
version: '2.1'
services:
protonmail-bridge:
image: shenxn/protonmail-bridge
ports:
- 1025:25/tcp
- 1143:143/tcp
restart: unless-stopped
volumes:
- protonmail:/root
volumes:
protonmail:
name: protonmail

42
docker/Dockerfile Normal file
View File

@@ -0,0 +1,42 @@
FROM golang:1.16 AS build
# Install dependencies
RUN apt-get update && apt-get install -y libsecret-1-dev
ARG PROTONMAIL_BRIDGE_VERSION
# Build
WORKDIR /build/
RUN curl -L https://github.com/ProtonMail/proton-bridge/archive/refs/tags/${PROTONMAIL_BRIDGE_VERSION}.tar.gz \
| tar zx --strip-component 1
RUN make build-nogui
FROM ubuntu:bionic
LABEL maintainer="Xiaonan Shen <s@sxn.dev>"
EXPOSE 25/tcp
EXPOSE 143/tcp
# Install dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
expect socat pass libsecret-1-0 ca-certificates \
&& rm -rf /var/lib/apt/lists/*
ENV PATH="/srv/protonmail:$PATH"
# Copy protonmail
COPY --from=build /build/proton-bridge /srv/protonmail/
# Copy bash scripts
COPY gpgparams entrypoint.sh auto-login.exp login.sh /srv/protonmail/
# Create use and group for protonmail
RUN groupadd --gid 8535 protonmail \
&& useradd --uid 8535 --gid 8535 --home-dir /protonmail protonmail \
&& mkdir /protonmail \
&& chown protonmail:protonmail /protonmail
USER protonmail
WORKDIR /protonmail
ENTRYPOINT ["bash", "/srv/protonmail/entrypoint.sh"]

1
docker/VERSION Normal file
View File

@@ -0,0 +1 @@
v1.8.9

98
docker/auto-login.exp Executable file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/expect -f
set timeout 15;
spawn proton-bridge -cli {*}$argv ;
# wait for inital prompt
expect {
">>> " {
# protonmail-bridge started without error, do nothing
}
timeout {
puts "Timed out"
exit 2
}
}
send "login\n"
expect {
"Username: " {
# login start, enter username
}
timeout {
puts "Timed out"
exit 2
}
}
send "$::env(PROTONMAIL_USERNAME)\n"
expect {
"Password: " {
# username entered, enter password
}
timeout {
puts "Timed out"
exit 2
}
}
stty -echo
sleep 1
send "$::env(PROTONMAIL_PASSWORD)\n"
stty echo
expect {
"was added successfully." {
# login ok
}
"Two factor code: " {
# 2FA enabled, enter OTP
if ![info exists ::env(PROTONMAIL_OTP)] {
puts "\n2FA enabled but PROTONMAIL_OTP is not set. Exiting"
exit 1
}
send "$::env(PROTONMAIL_OTP)\n"
expect {
"was added successfully." {
# login ok
}
"Server error" {
# login failed
exit 1
}
timeout {
puts "Timed out"
exit 2
}
}
}
"Server error" {
# login failed
exit 1
}
timeout {
puts "Timed out"
exit 2
}
}
send "info\n"
expect {
"Configuration for " {
# successfully got info. Wait for printing
sleep 1
}
timeout {
puts "Timed out"
exit 2
}
}

62
docker/entrypoint.sh Normal file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
set -e
# Generate gpg keys
if [ ! -f ${HOME}/.gnupg ]; then
echo "Generateing gpg keys..."
# set GNUPGHOME as a workaround for
#
# gpg-agent[106]: error binding socket to '/root/.gnupg/S.gpg-agent': File name too long
#
# when using docker volume mount
#
# ref: https://dev.gnupg.org/T2964
#
export GNUPGHOME=/tmp/gnupg
mkdir ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
gpg --generate-key --batch /srv/protonmail/gpgparams
pkill gpg-agent
mv ${GNUPGHOME} ${HOME}/.gnupg
export GNUPGHOME=""
fi
# Initialize pass
if [ ! -f ${HOME}/.password-store/.gpg-id ]; then
echo "Initializing pass"
pass init pass-key
fi
# Login
if [ ! -f ${HOME}/.logged-in ]; then
if [[ -n ${PROTONMAIL_USERNAME} && -n ${PROTONMAIL_PASSWORD} ]]; then
echo "Logging in"
auto-login.exp $@
echo "" > ${HOME}/.logged-in
else
# Wait for manual login
echo "=============================================================================="
echo "PROTONMAIL_USERNAME or PROTONMAIL_PASSWORD is not set. Will not do auto login."
echo "Run docker exec -it protonmail login.sh to login manually."
echo "Waiting for manual login..."
while [ ! -f ${HOME}/.logged-in ]; do
sleep 5
done
fi
fi
echo "Logged in flag detected. Starting protonmail bridge"
# socat will make the conn appear to come from 127.0.0.1
# ProtonMail Bridge currently expects that.
# It also allows us to bind to the real ports :)
socat TCP-LISTEN:2025,fork TCP:127.0.0.1:1025 &
socat TCP-LISTEN:2143,fork TCP:127.0.0.1:1143 &
# Start protonmail
# Fake a terminal, so it does not quit because of EOF...
rm -f faketty
mkfifo faketty
cat faketty | proton-bridge --cli $@

12
docker/login.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
echo "Start manual login"
echo "========================================================================"
echo "IMPORTANT: Use `exit` instead of CTRL-C when you successfully logged in."
echo "Otherwise protonmail bridge will not start."
echo "========================================================================"
proton-bridge -cli
echo "Consider logged in. Add flag."
echo "" > $HOME/.logged-in

View File

@@ -0,0 +1 @@
v1.8.7

View File

@@ -0,0 +1 @@
v1.8.9

View File

@@ -1,37 +1,64 @@
import requests, os, sys
import sys
import os
import requests
import json
import re
def git(command):
return os.system(f"git {command}")
release = requests.get("https://api.github.com/repos/protonmail/proton-bridge/releases/latest").json()
version = release['tag_name']
deb = [asset for asset in release ['assets'] if asset['name'].endswith('.deb')][0]['browser_download_url']
print(f"Latest release is: {version}")
with open("VERSION", 'w') as f:
f.write(version)
with open("deb/PACKAGE", 'w') as f:
f.write(deb)
git("config --local user.name 'GitHub Actions'")
git("config --local user.email 'actions@github.com'")
git("add -A")
if git("diff --cached --quiet") == 0: # Returns 0 if there are no changes
print("Version didn't change")
exit(0)
git(f"commit -m 'Bump version to {version}'")
is_pull_request = sys.argv[1] == "true"
print(f"is_pull_request={is_pull_request}")
if is_pull_request:
print("This is a pull request, skipping push step.")
exit(0)
if git("push") != 0:
print("Git push failed!")
exit(1)
def check_version(directory, new_version):
print(f"Checking version for {directory}")
if not new_version:
print("Failed to get new version. Exiting.")
exit(1)
with open(f"{directory}/VERSION", "r") as f:
old_version = f.read().rstrip()
print(f"Up-to-date version {new_version}")
print(f"Current version: {old_version}")
if old_version != new_version:
print(f"New release found: {new_version}")
# bump up to new release
with open(f"{directory}/VERSION", "w") as f:
f.write(new_version)
# commit
result = os.system(f"git config --local user.email 'actions@github.com' \
&& git config --local user.name 'GitHub Actions' \
&& git add {directory}/VERSION \
&& git commit -m 'Bump {directory} version to {new_version}'")
if result != 0:
print("Failed to commit the bump. Exiting")
exit(1)
if is_pull_request:
print("Action triggered by pull request. Do not push.")
else:
result = os.system("git push")
if result != 0:
print("Failed to push. Exiting")
exit(1)
else:
print(f"Already newest version {old_version}")
# check deb version
response = requests.get("https://protonmail.com/download/current_version_linux.json")
content = json.loads(response.content)
version = re.match(".*_([0-9.-]+)_amd64\.deb", content["DebFile"]).group(1)
check_version("deb", version)
# check build version
response = requests.get(
"https://api.github.com/repos/ProtonMail/proton-bridge/tags",
headers={"Accept": "application/vnd.github.v3+json"},
)
tags = json.loads(response.content)
version_re = re.compile("v\d+\.\d+\.\d+")
releases = [tag["name"][1:] for tag in tags if version_re.match(tag["name"])]
check_version("build", releases[0])

4
version-config.yaml Normal file
View File

@@ -0,0 +1,4 @@
image_version: 0.1
protonmail_version:
latest: v1.8.7 # Latest stable version
pre: v1.8.9 # Latest preview version