Skip to content
Merged
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
20 changes: 20 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches: ['main']
tags:
- 'v*.*.*'
schedule:
# Weekly on Mondays at 00:00 UTC
- cron: '0 0 * * 1'

concurrency: ${{ github.ref }}

Expand All @@ -14,6 +17,7 @@ jobs:
permissions:
contents: read
packages: write
security-events: write
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 https://github.com/actions/checkout/releases/tag/v6.0.0
- name: qemu
Expand Down Expand Up @@ -41,6 +45,10 @@ jobs:
type=match,pattern=v(.*),group=1
# branch
type=ref,event=branch
- name: Extract first tag
run: |
FIRST_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "FIRST_TAG=$FIRST_TAG" >> $GITHUB_ENV
- name: push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 https://github.com/docker/build-push-action/releases/tag/v6.18.0
with:
Expand All @@ -49,6 +57,18 @@ jobs:
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1
with:
scan-type: 'image'
scan-ref: 'ghcr.io/blinklabs-io/openvpn:${{ env.FIRST_TAG }}'
format: 'sarif'
output: 'trivy-results-${{ env.FIRST_TAG }}.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@d3ced5c96c16c4332e2a61eb6f3649d6f1b20bb8 # v3.31.5
if: always()
with:
sarif_file: 'trivy-results-${{ env.FIRST_TAG }}.sarif'
# Update Docker Hub from README
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 https://github.com/peter-evans/dockerhub-description/releases/tag/v5.0.0
Expand Down
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
FROM ubuntu:24.04 AS base
FROM debian:bookworm-slim AS base

COPY bin/ /usr/local/bin

RUN apt-get update \
&& apt-get dist-upgrade -y \
&& apt-get install -y openvpn iptables \
# Install OpenVPN (latest 2.6.x from Debian repos; rebuild image periodically for security updates)
&& apt-get install -y --no-install-recommends openvpn iptables \
&& apt-get purge -y --auto-remove cron rsyslog \
&& rm -rf /var/log/* \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& chmod +x /usr/local/bin/*

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD pgrep -f openvpn || exit 1

EXPOSE 1194/udp

ENTRYPOINT ["/usr/local/bin/entrypoint"]
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# docker-openvpn

Simple OpenVPN image with updated version
Simple OpenVPN image with updated version, optimized for privacy-focused VPN services.

## Using the image

Expand All @@ -12,3 +12,41 @@ docker run -d -n openvpn -v /path/to/openvpn.conf:/etc/openvpn/openvpn.conf ghcr

The image provides for the ability to provide a custom startup script. It looks for a user script at `/usr/local/bin/entrypoint-user.sh` by default,
but the location can be overridden with the `USER_STARTUP_SCRIPT` environment variable

## Privacy and Security Recommendations

For a no-log, privacy-focused setup:

### OpenVPN Configuration
Use these options in your `openvpn.conf` for strong encryption and no logging:
```conf
# Disable logging
log /dev/null
verb 0

# Strong ciphers
cipher AES-256-GCM
auth SHA256
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
tls-version-min 1.2

# Privilege drop
user nobody
group nogroup

# Other privacy settings
persist-key
persist-tun
```

### Docker Run Options
- Use Docker secrets for certificates/keys: `--secret mykey=/path/to/key`
- Run with necessary capabilities only: `--cap-add=NET_ADMIN` (avoid `--privileged`)
- For Kubernetes (Helm), use `securityContext` to limit privileges.

### Maintenance
- Rebuild images regularly to pull security updates from Debian repos.
- Scan for vulnerabilities with tools like Trivy (automated via GitHub Actions).
- Test for leaks using services like ipleak.net while connected.

**Warning**: Running in privileged mode increases security risks—use only when necessary.
4 changes: 4 additions & 0 deletions bin/entrypoint
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ fi

if [[ $ENABLE_NAT = 1 ]]; then
iptables -t nat -A POSTROUTING -s ${NAT_SOURCE} -o ${NAT_DEVICE} -j MASQUERADE
# Basic kill switch: Drop forwarded traffic by default, allow only VPN-related
iptables -P FORWARD DROP
iptables -A FORWARD -i tun+ -o ${NAT_DEVICE} -j ACCEPT
iptables -A FORWARD -i ${NAT_DEVICE} -o tun+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
fi

# Execute user startup script if it exists
Expand Down