Skip to content

Commit 4e0e1ef

Browse files
committed
Merge branch 'develop'
2 parents 2473ae3 + 8e8882b commit 4e0e1ef

30 files changed

+481
-59
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Data folder for docker data
2+
/data
3+
/tmp.txt
4+
/tmp

CONTRIBUTING.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ Sections:
4646
ssl
4747
safessl-easyrsa.cnf
4848
vars
49-
example # Example configs
50-
config # Example client & server configs (see root/defaults/example/README.md)
49+
example # Example configs (see root/defaults/example/README.md)
50+
config # Example client & server configs
5151
hook # Example hook configs
5252
module # Modules for openvpn
5353
hooks # Put your custom scripts in one of subfolders
@@ -89,4 +89,5 @@ Sections:
8989
**OpenVPN:**
9090

9191
- [OpenVPN docs](https://community.openvpn.net/openvpn/wiki/GettingStartedwithOVPN)
92+
- [Setup OpenVPN on alpine linux](https://wiki.alpinelinux.org/wiki/Setting_up_a_OpenVPN_server#Alternative_Certificate_Method)
9293
- [EasyRSA](https://community.openvpn.net/openvpn/wiki/GettingStartedwithOVPN)

Dockerfile

+30-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
1-
1+
#
22
# Base image
3+
# @see https://github.com/linuxserver/docker-baseimage-alpine
4+
# @see https://github.com/linuxserver/docker-baseimage-alpine-python3
5+
#
36
FROM lsiobase/alpine.python3:latest
47

8+
# Build arguments
9+
ARG BUILD_DATE
10+
ARG VCS_REF
11+
ARG VCS_SRC
12+
ARG VERSION
13+
514
#
615
# Image labels
716
# @see https://github.com/opencontainers/image-spec/blob/master/annotations.md
17+
# @see http://label-schema.org/rc1/
818
# @see https://semver.org/
919
#
10-
LABEL org.opencontainers.image.title = "OpenVPN Server" \
11-
org.opencontainers.image.description = "Docker image with OpenVPN server" \
12-
org.opencontainers.image.url = "" \
13-
org.opencontainers.image.authors = "Martin Dagarin <>" \
14-
org.opencontainers.image.version = "0.0.2"
20+
LABEL org.opencontainers.image.title="OpenVPN Server" \
21+
org.label-schema.name="OpenVPN Server" \
22+
org.opencontainers.image.description="Docker image with OpenVPN server" \
23+
org.label-schema.description="Docker image with OpenVPN server" \
24+
org.opencontainers.image.url="https://github.com/SloCompTech/docker-openvpn" \
25+
org.label-schema.url="https://github.com/SloCompTech/docker-openvpn" \
26+
org.opencontainers.image.authors="Martin Dagarin <[email protected]>" \
27+
org.opencontainers.image.version=$VERSION \
28+
org.label-schema.version=$VERSION \
29+
org.opencontainers.image.revision=$VCS_REF \
30+
org.label-schema.vcs-ref=$VCS_REF \
31+
org.opencontainers.image.source=$VCS_SRC \
32+
org.label-schema.vcs-url=$VCS_SRC \
33+
org.opencontainers.image.created=$BUILD_DATE \
34+
org.label-schema.build-date=$BUILD_DATE \
35+
org.label-schema.schema-version="1.0"
36+
1537

1638
#
1739
# Environment variables
@@ -26,7 +48,6 @@ ENV PATH="/app/bin:$PATH" \
2648
EASYRSA_SAFE_CONF=/config/ssl/safessl-easyrsa.cnf \
2749
EASYRSA_TEMP_FILE=/config/temp \
2850
OVPN_ROOT=/config \
29-
OVPN_CONFIG=/config/openvpn \
3051
OVPN_HOOKS=/config/hooks \
3152
OVPN_RUN=system.conf
3253

@@ -42,14 +63,12 @@ RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/main/" >> /etc/apk/repositor
4263
# Remove any temporary files created by apk
4364
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/* && \
4465
# Add permission for network management to user abc
45-
echo "abc ALL=(ALL) NOPASSWD: /sbin/ip" >> /etc/sudoers && \
46-
# Create tunnel interface
47-
mkdir -p /dev/net && \
48-
mknod /dev/net/tun c 10 200
66+
echo "abc ALL=(ALL) NOPASSWD: /sbin/ip, /sbin/iptables" >> /etc/sudoers
4967

5068
# Add repo files to image
5169
COPY root/ /
5270

5371
# Configure
5472
RUN chmod +x /app/bin/* && \
73+
chmod +x /usr/local/sbin/* && \
5574
chmod -R 0644 /etc/logrotate.d

LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
The MIT License (MIT)
33

4-
Copyright (c) 2019 Martin
4+
Copyright (c) 2019 Martin Dagarin
55

66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal

Makefile

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#
2+
# Makefile
3+
# to build image easier
4+
#
5+
6+
IMAGE_NAME=slocomptech/openvpn
7+
DATA_DIR=$(shell pwd)/data
8+
CONTAINER=ovpn
9+
10+
11+
default: build
12+
13+
#
14+
# Build docker image
15+
#
16+
build:
17+
@echo "Building image"
18+
docker build \
19+
--build-arg BUILD_DATE=$(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\") \
20+
--build-arg VCS_REF="$(shell git rev-parse --short HEAD)" \
21+
--build-arg VCS_SRC="https://github.com/SloCompTech/docker-openvpn/commit/$(shell git rev-parse HEAD)" \
22+
--build-arg VERSION=latest \
23+
-t ${IMAGE_NAME} .
24+
25+
#
26+
# Run setup command
27+
# Opens temporary container to setup environment
28+
#
29+
config:
30+
@echo "Running temporary container"
31+
mkdir -p data
32+
docker run -it --rm --cap-add NET_ADMIN -v ${DATA_DIR}:/config ${IMAGE_NAME}:latest bash
33+
34+
#
35+
# Setups & starts real container
36+
# Run only once, then use docker start|stop|restart|exec
37+
#
38+
setup:
39+
@echo "Running temporary container"
40+
docker run -it --cap-add NET_ADMIN -p 1194:1194/udp -v ${DATA_DIR}:/config --name ${CONTAINER} ${IMAGE_NAME}:latest
41+
42+
#
43+
# Starts container
44+
#
45+
start:
46+
docker start ${CONTAINER}
47+
48+
#
49+
# Stops container
50+
#
51+
stop:
52+
docker stop ${CONTAINER}
53+
54+
#
55+
# Restart container
56+
#
57+
restart:
58+
docker restart ${CONTAINER}
59+
60+
#
61+
# Open terminal inside container
62+
# Only when container is running
63+
#
64+
term:
65+
docker exec -it ${CONTAINER} bash

README.md

+17-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
# [slocomptech/docker-openvpn]()
33

44

5+
Features:
6+
7+
- OpenVPN is running as non-root user, soo it has limited permission.
8+
- OpenVPN is running in isolated environment (container) so you don't break it with updates, upgrades of your PC.
9+
- Easy managed (has helper scripts).
10+
- Easy start (Simple first-start guide).
11+
- Easly modified to your needs (see [docs](CONTRIBUTING.md)).
12+
- Easy scripting (python3 installed).
13+
514
## Usage
615

716
### docker
@@ -68,17 +77,18 @@ Feel free to contribute new features to this container, but first see [Contribut
6877

6978
Planed features:
7079

71-
- Hooks
72-
- Example configs
73-
- Setup instructions
74-
- Setup scripts
75-
- Setup & run via environment variables
76-
- Config overwrite protection
77-
7880
Wanted features (please help implement):
7981

8082
- LDAP authentication script
8183
- Google authenticator
8284

85+
## Licenses
86+
87+
- [This project](LICENSE.md)
88+
- [OpenVPN]()
89+
- [Base image](https://github.com/linuxserver/docker-baseimage-alpine)
90+
- [s6 Layer](https://github.com/just-containers/s6-overlay/blob/master/LICENSE.md)
91+
92+
8393
## Versions
8494

hooks/build

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
#
4+
# DockerHub build hook (overrides default build command)
5+
# @see https://docs.docker.com/docker-hub/builds/advanced/
6+
# @see https://microbadger.com/labels
7+
#
8+
9+
echo "Building image"
10+
11+
docker build \
12+
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
13+
--build-arg VCS_REF=`git rev-parse --short HEAD` \
14+
--build-arg VCS_SRC="https://github.com/SloCompTech/docker-openvpn/commit/$SOURCE_COMMIT" \
15+
--build-arg VERSION="$SOURCE_BRANCH" \
16+
-t $IMAGE_NAME .

root/app/bin/ovpn_backup

100644100755
+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ elif [ $1 = "pki" ]; then
3737
elif [ $1 = "hooks" ]; then
3838
$RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_hooks_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_HOOKS
3939
elif [ $1 = "openvpn" ]; then
40-
$RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_conf_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_CONFIG
40+
$RUNAS $ARCHIVE_CMD $OVPN_ROOT/backup/backup_conf_$(date +%H%M%S%d%m%Y).tar.gz $OVPN_ROOT/openvpn
4141
else
4242
usage
4343
exit 1

root/app/bin/ovpn_client

100644100755
+21-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ function build_ovpn() {
3131
cat $file
3232
done
3333

34+
# Check if server config is using tls-crypt or tls-auth
35+
local crypto=""
36+
for srv_file in $OVPN_ROOT/openvpn/server/*.conf
37+
do
38+
crypto="$(ovpn_findopt $srv_file tls-crypt tls-auth)"
39+
if [ -n "$crypto" ]; then
40+
break
41+
fi
42+
done
43+
3444
# CA
3545
echo "<ca>"
3646
cat $EASYRSA_PKI/ca.crt
@@ -47,10 +57,17 @@ function build_ovpn() {
4757
cat $EASYRSA_PKI/private/$1.key
4858
echo "</key>"
4959

50-
# tls-crypt
51-
echo "<tls-crypt>"
52-
cat $EASYRSA_PKI/ta.key
53-
echo "</tls-crypt>"
60+
if [ "$crypto" = "tls-crypt" ]; then
61+
# tls-crypt
62+
echo "<tls-crypt>"
63+
cat $EASYRSA_PKI/ta.key
64+
echo "</tls-crypt>"
65+
elif [ "$crypto" = "tls-auth" ]; then
66+
# tls-auth
67+
echo "<tls-auth>"
68+
cat $EASYRSA_PKI/ta.key
69+
echo "</tls-auth>"
70+
fi
5471
fi
5572
}
5673

root/app/bin/ovpn_disconf

100644100755
File mode changed.

root/app/bin/ovpn_enconf

100644100755
+4-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ if [ $# -gt 0 ]; then
150150
if [ -f "$config_path/wizard" ] && [ -x "$config_path/wizard" ]; then
151151
tmp_path=/tmp/wizard
152152

153-
# Delete existing tmp dir
153+
# Delete existing tmp directory
154154
if [ -e "$tmp_path" ]; then
155155
rm -rf $tmp_path
156156
fi
@@ -172,6 +172,9 @@ if [ $# -gt 0 ]; then
172172
install_server $tmp_path $OVPN_ROOT/openvpn
173173
install_client $tmp_path $OVPN_ROOT/openvpn
174174
install_hooks $tmp_path $OVPN_ROOT
175+
176+
# Remove temporary directory
177+
rm -rf $tmp_path
175178
else
176179
# Directly copy files
177180
install_server $config_path $OVPN_ROOT/openvpn

root/app/bin/ovpn_findopt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/python
2+
3+
#
4+
# Finds first of specified options in config file
5+
# @author Martin Dagarin
6+
# @version 1
7+
# @since 19/03/2019
8+
#
9+
# Usage: ovpn_findopt <config_file> <opt1> <opt2> <opt3> ...
10+
#
11+
import sys
12+
13+
# Import libraries included in this docker
14+
sys.path.insert(0, '/app/lib')
15+
import libovpn
16+
17+
if len(sys.argv) < 3:
18+
# Invalid command
19+
print("")
20+
sys.exit(0)
21+
22+
config_file = sys.argv[1]
23+
found = libovpn.conf_optFindFirst(config_file, sys.argv[2:])
24+
25+
if found is not None:
26+
print(found)
27+
else:
28+
print("")

root/app/bin/ovpn_init

100644100755
File mode changed.

root/app/bin/run_hooks

100644100755
File mode changed.

root/app/lib/libovpn.py

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/python
2+
3+
#
4+
# Functions to help with scripting
5+
# @author Martin Dagarin
6+
# @version 1
7+
# @since 19/03/2019
8+
#
9+
10+
#
11+
# Checks if OpenVPN file has configuration option enabled
12+
# @param file Path to OpenVPN config file
13+
# @param opt Option to check for
14+
# @return Returns True if found, else false
15+
#
16+
17+
def conf_hasOpt(file, opt):
18+
with open(file, "r") as f:
19+
for line in f:
20+
line = line.strip()
21+
if line.startswith(opt):
22+
return True
23+
return False
24+
25+
#
26+
# Finds option which is enabled in config
27+
# @param file Path to OpenVPN config file
28+
# @param opts Array of options, which to check
29+
# @return Returns first options which was found or None
30+
#
31+
def conf_optFindFirst(file, opts):
32+
with open(file, "r") as f:
33+
for line in f:
34+
line = line.strip()
35+
for opt in opts:
36+
if line.startswith(opt):
37+
return opt
38+
return None
39+
40+
#
41+
# Replaces $VARIABLES in file with values
42+
# @param file Path to file
43+
# @param var Array of tuples with key value ("$KEY","VALUE")
44+
#
45+
def conf_envsubst(file, vars):
46+
with open(file, "r") as f:
47+
lines = f.readlines()
48+
with open(file, "w") as f:
49+
for line in lines:
50+
# Dont proces comments
51+
if not line.strip().startswith("#"):
52+
for kv in vars:
53+
line = line.replace(kv[0],kv[1])
54+
f.write(line)

0 commit comments

Comments
 (0)