Compare commits
	
		
			39 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9b9ba57ea0 | ||
| 
						 | 
					925b08fec4 | ||
| 
						 | 
					7a29e8e39b | ||
| 
						 | 
					16fbc4019d | ||
| 
						 | 
					63a2449705 | ||
| 
						 | 
					1b8374f818 | ||
| 
						 | 
					8d7bc7e2c5 | ||
| 
						 | 
					e30ee8eecf | ||
| 
						 | 
					9d730e166e | ||
| 
						 | 
					e00a72a3f6 | ||
| 
						 | 
					d974c0ac6a | ||
| 
						 | 
					c0ed8d468d | ||
| 
						 | 
					2a9059aa36 | ||
| 
						 | 
					074a07e40e | ||
| 
						 | 
					8c9d88b316 | ||
| 
						 | 
					78d612d181 | ||
| 
						 | 
					6bff62eb79 | ||
| 
						 | 
					8f2f27486c | ||
| 
						 | 
					3ee5479d78 | ||
| 
						 | 
					909744dd78 | ||
| 
						 | 
					5aea8b914c | ||
| 
						 | 
					a091bef13b | ||
| 
						 | 
					59644d953d | ||
| 
						 | 
					dcf3791d54 | ||
| 
						 | 
					76546e1823 | ||
| 
						 | 
					f996bbaa8e | ||
| 
						 | 
					861ed05c48 | ||
| 
						 | 
					ce690e5ab1 | ||
| 
						 | 
					e4821ec709 | ||
| 
						 | 
					808e2448b1 | ||
| 
						 | 
					fe2cdebea2 | ||
| 
						 | 
					892a3c9a1c | ||
| 
						 | 
					a3c96bc881 | ||
| 
						 | 
					22fcaf9477 | ||
| 
						 | 
					d454a20e80 | ||
| 
						 | 
					c8ba567333 | ||
| 
						 | 
					21ae2fcef4 | ||
| 
						 | 
					24944b0a11 | ||
| 
						 | 
					b74cbd5c74 | 
@@ -1,12 +1,12 @@
 | 
			
		||||
# Original credit: https://github.com/jpetazzo/dockvpn
 | 
			
		||||
 | 
			
		||||
# Smallest base image
 | 
			
		||||
FROM alpine:3.5
 | 
			
		||||
FROM alpine:edge
 | 
			
		||||
 | 
			
		||||
MAINTAINER Kyle Manna <kyle@kylemanna.com>
 | 
			
		||||
 | 
			
		||||
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
 | 
			
		||||
    echo "http://dl-4.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
 | 
			
		||||
# Testing: pamtester
 | 
			
		||||
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
 | 
			
		||||
    apk add --update openvpn iptables bash easy-rsa openvpn-auth-pam google-authenticator pamtester && \
 | 
			
		||||
    ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
 | 
			
		||||
    rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
 | 
			
		||||
@@ -17,6 +17,9 @@ ENV EASYRSA /usr/share/easy-rsa
 | 
			
		||||
ENV EASYRSA_PKI $OPENVPN/pki
 | 
			
		||||
ENV EASYRSA_VARS_FILE $OPENVPN/vars
 | 
			
		||||
 | 
			
		||||
# Prevents refused client connection because of an expired CRL
 | 
			
		||||
ENV EASYRSA_CRL_DAYS 3650
 | 
			
		||||
 | 
			
		||||
VOLUME ["/etc/openvpn"]
 | 
			
		||||
 | 
			
		||||
# Internally uses port 1194/udp, remap using `docker run -p 443:1194/tcp`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								Dockerfile.aarch64
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Dockerfile.aarch64
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# Original credit: https://github.com/jpetazzo/dockvpn
 | 
			
		||||
 | 
			
		||||
# Smallest base image
 | 
			
		||||
FROM aarch64/alpine:3.5
 | 
			
		||||
 | 
			
		||||
MAINTAINER Kyle Manna <kyle@kylemanna.com>
 | 
			
		||||
 | 
			
		||||
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
 | 
			
		||||
    echo "http://dl-4.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
 | 
			
		||||
    apk add --update openvpn iptables bash easy-rsa openvpn-auth-pam google-authenticator pamtester && \
 | 
			
		||||
    ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
 | 
			
		||||
    rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
 | 
			
		||||
 | 
			
		||||
# Needed by scripts
 | 
			
		||||
ENV OPENVPN /etc/openvpn
 | 
			
		||||
ENV EASYRSA /usr/share/easy-rsa
 | 
			
		||||
ENV EASYRSA_PKI $OPENVPN/pki
 | 
			
		||||
ENV EASYRSA_VARS_FILE $OPENVPN/vars
 | 
			
		||||
 | 
			
		||||
# Prevents refused client connection because of an expired CRL
 | 
			
		||||
ENV EASYRSA_CRL_DAYS 3650
 | 
			
		||||
 | 
			
		||||
VOLUME ["/etc/openvpn"]
 | 
			
		||||
 | 
			
		||||
# Internally uses port 1194/udp, remap using `docker run -p 443:1194/tcp`
 | 
			
		||||
EXPOSE 1194/udp
 | 
			
		||||
 | 
			
		||||
CMD ["ovpn_run"]
 | 
			
		||||
 | 
			
		||||
ADD ./bin /usr/local/bin
 | 
			
		||||
RUN chmod a+x /usr/local/bin/*
 | 
			
		||||
 | 
			
		||||
# Add support for OTP authentication using a PAM module
 | 
			
		||||
ADD ./otp/openvpn /etc/pam.d/
 | 
			
		||||
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								README.md
									
									
									
									
									
								
							@@ -18,11 +18,16 @@ a corresponding [Digital Ocean Community Tutorial](http://bit.ly/1AGUZkq).
 | 
			
		||||
 | 
			
		||||
## Quick Start
 | 
			
		||||
 | 
			
		||||
* Pick a name for the `$OVPN_DATA` data volume container, it will be created automatically.
 | 
			
		||||
* Pick a name for the `$OVPN_DATA` data volume container. It's recommended to
 | 
			
		||||
  use the `ovpn-data-` prefix to operate seamlessly with the reference systemd
 | 
			
		||||
  service.  Users are encourage to replace `example` with a descriptive name of
 | 
			
		||||
  their choosing.
 | 
			
		||||
 | 
			
		||||
        OVPN_DATA="ovpn-data"
 | 
			
		||||
        OVPN_DATA="ovpn-data-example"
 | 
			
		||||
 | 
			
		||||
* Initialize the `$OVPN_DATA` container that will hold the configuration files and certificates
 | 
			
		||||
* Initialize the `$OVPN_DATA` container that will hold the configuration files
 | 
			
		||||
  and certificates.  The container will prompt for a passphrase to protect the
 | 
			
		||||
  private key used by the newly generated certificate authority.
 | 
			
		||||
 | 
			
		||||
        docker volume create --name $OVPN_DATA
 | 
			
		||||
        docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM
 | 
			
		||||
@@ -40,7 +45,22 @@ a corresponding [Digital Ocean Community Tutorial](http://bit.ly/1AGUZkq).
 | 
			
		||||
 | 
			
		||||
        docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
 | 
			
		||||
 | 
			
		||||
## Docker Compose
 | 
			
		||||
## Next Steps
 | 
			
		||||
 | 
			
		||||
### More Reading
 | 
			
		||||
 | 
			
		||||
Miscellaneous write-ups for advanced configurations are available in the
 | 
			
		||||
[docs](docs) folder.
 | 
			
		||||
 | 
			
		||||
### Systemd Init Scripts
 | 
			
		||||
 | 
			
		||||
A `systemd` init script is available to manage the OpenVPN container.  It will
 | 
			
		||||
start the container on system boot, restart the container if it exits
 | 
			
		||||
unexpectedly, and pull updates from Docker Hub to keep itself up to date.
 | 
			
		||||
 | 
			
		||||
Please refer to the [systemd documentation](docs/systemd.md) to learn more.
 | 
			
		||||
 | 
			
		||||
### Docker Compose
 | 
			
		||||
 | 
			
		||||
If you prefer to use `docker-compose` please refer to the [documentation](docs/docker-compose.md).
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@
 | 
			
		||||
TMP_PUSH_CONFIGFILE=$(mktemp -t vpn_push.XXXXXXX)
 | 
			
		||||
TMP_ROUTE_CONFIGFILE=$(mktemp -t vpn_route.XXXXXXX)
 | 
			
		||||
TMP_EXTRA_CONFIGFILE=$(mktemp -t vpn_extra.XXXXXXX)
 | 
			
		||||
TMP_EXTRA_CLIENT_CONFIGFILE=$(mktemp -t vpn_extra_client.XXXXXXX)
 | 
			
		||||
 | 
			
		||||
#Traceback on Error and Exit come from https://docwhat.org/tracebacks-in-bash/
 | 
			
		||||
set -eu
 | 
			
		||||
@@ -46,7 +45,6 @@ on_exit() {
 | 
			
		||||
  rm -f $TMP_PUSH_CONFIGFILE
 | 
			
		||||
  rm -f $TMP_ROUTE_CONFIGFILE
 | 
			
		||||
  rm -f $TMP_EXTRA_CONFIGFILE
 | 
			
		||||
  rm -f $TMP_EXTRA_CLIENT_CONFIGFILE
 | 
			
		||||
  local _ec="$?"
 | 
			
		||||
  if [[ $_ec != 0 && "${_showed_traceback}" != t ]]; then
 | 
			
		||||
    traceback 1
 | 
			
		||||
@@ -95,10 +93,12 @@ usage() {
 | 
			
		||||
    echo "optional arguments:"
 | 
			
		||||
    echo " -2    Enable two factor authentication using Google Authenticator."
 | 
			
		||||
    echo " -a    Authenticate  packets with HMAC using the given message digest algorithm (auth)."
 | 
			
		||||
    echo " -b    Disable 'push block-outside-dns'"
 | 
			
		||||
    echo " -c    Enable client-to-client option"
 | 
			
		||||
    echo " -C    A list of allowable TLS ciphers delimited by a colon (cipher)."
 | 
			
		||||
    echo " -d    Disable NAT routing and default route"
 | 
			
		||||
    echo " -d    Disable default route"
 | 
			
		||||
    echo " -D    Do not push dns servers"
 | 
			
		||||
    echo " -k    Set keepalive. Default: '10 60'"
 | 
			
		||||
    echo " -m    Set client MTU"
 | 
			
		||||
    echo " -N    Configure NAT to access external server network"
 | 
			
		||||
    echo " -t    Use TAP device (instead of TUN device)"
 | 
			
		||||
@@ -119,7 +119,7 @@ process_push_config() {
 | 
			
		||||
  local ovpn_push_config=''
 | 
			
		||||
  ovpn_push_config="$1"
 | 
			
		||||
  echo "Processing PUSH Config: '${ovpn_push_config}'"
 | 
			
		||||
  [[ -n "$ovpn_push_config" ]] && echo "push $ovpn_push_config" >> "$TMP_PUSH_CONFIGFILE"
 | 
			
		||||
  [[ -n "$ovpn_push_config" ]] && echo "push \"$ovpn_push_config\"" >> "$TMP_PUSH_CONFIGFILE"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
process_extra_config() {
 | 
			
		||||
@@ -127,14 +127,6 @@ process_extra_config() {
 | 
			
		||||
  ovpn_extra_config="$1"
 | 
			
		||||
  echo "Processing Extra Config: '${ovpn_extra_config}'"
 | 
			
		||||
  [[ -n "$ovpn_extra_config" ]] && echo "$ovpn_extra_config" >> "$TMP_EXTRA_CONFIGFILE"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
process_extra_client_config() {
 | 
			
		||||
  local ovpn_extra_config=''
 | 
			
		||||
  ovpn_extra_config="$1"
 | 
			
		||||
  echo "Processing Extra Client Config: '${ovpn_extra_config}'"
 | 
			
		||||
  [[ -n "$ovpn_extra_config" ]] && echo "$ovpn_extra_config" >> "$TMP_EXTRA_CLIENT_CONFIGFILE"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if [ "${DEBUG:-}" == "1" ]; then
 | 
			
		||||
@@ -150,35 +142,52 @@ if [ -z "${EASYRSA_PKI:-}" ]; then
 | 
			
		||||
    export EASYRSA_PKI="$OPENVPN/pki"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
OVPN_ENV=${OPENVPN}/ovpn_env.sh
 | 
			
		||||
OVPN_SERVER=192.168.255.0/24
 | 
			
		||||
OVPN_AUTH=''
 | 
			
		||||
OVPN_CIPHER=''
 | 
			
		||||
OVPN_CLIENT_TO_CLIENT=''
 | 
			
		||||
OVPN_CN=''
 | 
			
		||||
OVPN_COMP_LZO=0
 | 
			
		||||
OVPN_DEFROUTE=1
 | 
			
		||||
OVPN_NAT=0
 | 
			
		||||
OVPN_DNS=1
 | 
			
		||||
OVPN_DEVICE="tun"
 | 
			
		||||
OVPN_DEVICEN=0
 | 
			
		||||
OVPN_DNS_SERVERS=("8.8.8.8" "8.8.4.4")
 | 
			
		||||
TMP_DNS_SERVERS=()
 | 
			
		||||
OVPN_DISABLE_PUSH_BLOCK_DNS=0
 | 
			
		||||
OVPN_DNS=1
 | 
			
		||||
OVPN_DNS_SERVERS=()
 | 
			
		||||
OVPN_ENV=${OPENVPN}/ovpn_env.sh
 | 
			
		||||
OVPN_EXTRA_CLIENT_CONFIG=()
 | 
			
		||||
OVPN_EXTRA_SERVER_CONFIG=()
 | 
			
		||||
OVPN_FRAGMENT=''
 | 
			
		||||
OVPN_KEEPALIVE="10 60"
 | 
			
		||||
OVPN_MTU=''
 | 
			
		||||
OVPN_NAT=0
 | 
			
		||||
OVPN_PORT=''
 | 
			
		||||
OVPN_PROTO=''
 | 
			
		||||
OVPN_PUSH=()
 | 
			
		||||
OVPN_ROUTES=()
 | 
			
		||||
OVPN_SERVER=192.168.255.0/24
 | 
			
		||||
OVPN_SERVER_URL=''
 | 
			
		||||
OVPN_TLS_CIPHER=''
 | 
			
		||||
OVPN_CIPHER=''
 | 
			
		||||
OVPN_AUTH=''
 | 
			
		||||
OVPN_EXTRA_CONFIG=''
 | 
			
		||||
CUSTOM_ROUTE_CONFIG=''
 | 
			
		||||
 | 
			
		||||
# Import defaults if present
 | 
			
		||||
# Import existing configuration if present
 | 
			
		||||
[ -r "$OVPN_ENV" ] && source "$OVPN_ENV"
 | 
			
		||||
 | 
			
		||||
# Parse arguments
 | 
			
		||||
while getopts ":a:e:E:C:T:r:s:du:cp:n:DNmf:tz2" opt; do
 | 
			
		||||
while getopts ":a:e:E:C:T:r:s:du:bcp:n:k:DNm:f:tz2" opt; do
 | 
			
		||||
    case $opt in
 | 
			
		||||
        a)
 | 
			
		||||
            OVPN_AUTH="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        e)
 | 
			
		||||
            process_extra_config "$OPTARG"
 | 
			
		||||
            mapfile -t TMP_EXTRA_SERVER_CONFIG < <(echo "$OPTARG")
 | 
			
		||||
            for i in "${TMP_EXTRA_SERVER_CONFIG[@]}"; do
 | 
			
		||||
              OVPN_EXTRA_SERVER_CONFIG+=("$i")
 | 
			
		||||
            done
 | 
			
		||||
            ;;
 | 
			
		||||
        E)
 | 
			
		||||
            process_extra_client_config "$OPTARG"
 | 
			
		||||
            mapfile -t TMP_EXTRA_CLIENT_CONFIG < <(echo "$OPTARG")
 | 
			
		||||
            for i in "${TMP_EXTRA_CLIENT_CONFIG[@]}"; do
 | 
			
		||||
              OVPN_EXTRA_CLIENT_CONFIG+=("$i")
 | 
			
		||||
            done
 | 
			
		||||
            ;;
 | 
			
		||||
        C)
 | 
			
		||||
            OVPN_CIPHER="$OPTARG"
 | 
			
		||||
@@ -187,26 +196,38 @@ while getopts ":a:e:E:C:T:r:s:du:cp:n:DNmf:tz2" opt; do
 | 
			
		||||
            OVPN_TLS_CIPHER="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        r)
 | 
			
		||||
            CUSTOM_ROUTE_CONFIG=1
 | 
			
		||||
            process_route_config "$OPTARG"
 | 
			
		||||
            mapfile -t TMP_ROUTES < <(echo "$OPTARG")
 | 
			
		||||
            for i in "${TMP_ROUTES[@]}"; do
 | 
			
		||||
              OVPN_ROUTES+=("$i")
 | 
			
		||||
            done
 | 
			
		||||
            ;;
 | 
			
		||||
        s)
 | 
			
		||||
            OVPN_SERVER=$OPTARG
 | 
			
		||||
            OVPN_SERVER="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        d)
 | 
			
		||||
            OVPN_DEFROUTE=0
 | 
			
		||||
            OVPN_DISABLE_PUSH_BLOCK_DNS=1
 | 
			
		||||
            ;;
 | 
			
		||||
        u)
 | 
			
		||||
            OVPN_SERVER_URL=$OPTARG
 | 
			
		||||
            OVPN_SERVER_URL="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        b)
 | 
			
		||||
            OVPN_DISABLE_PUSH_BLOCK_DNS=1
 | 
			
		||||
            ;;
 | 
			
		||||
        c)
 | 
			
		||||
            OVPN_CLIENT_TO_CLIENT=1
 | 
			
		||||
            ;;
 | 
			
		||||
        p)
 | 
			
		||||
            process_push_config "$OPTARG"
 | 
			
		||||
            mapfile -t TMP_PUSH < <(echo "$OPTARG")
 | 
			
		||||
            for i in "${TMP_PUSH[@]}"; do
 | 
			
		||||
              OVPN_PUSH+=("$i")
 | 
			
		||||
            done
 | 
			
		||||
            ;;
 | 
			
		||||
        n)
 | 
			
		||||
            TMP_DNS_SERVERS+=("$OPTARG")
 | 
			
		||||
            mapfile -t TMP_DNS_SERVERS < <(echo "$OPTARG")
 | 
			
		||||
            for i in "${TMP_DNS_SERVERS[@]}"; do
 | 
			
		||||
              OVPN_DNS_SERVERS+=("$i")
 | 
			
		||||
            done
 | 
			
		||||
            ;;
 | 
			
		||||
        D)
 | 
			
		||||
            OVPN_DNS=0
 | 
			
		||||
@@ -214,8 +235,11 @@ while getopts ":a:e:E:C:T:r:s:du:cp:n:DNmf:tz2" opt; do
 | 
			
		||||
        N)
 | 
			
		||||
            OVPN_NAT=1
 | 
			
		||||
            ;;
 | 
			
		||||
        k)
 | 
			
		||||
            OVPN_KEEPALIVE="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        m)
 | 
			
		||||
            OVPN_MTU=$OPTARG
 | 
			
		||||
            OVPN_MTU="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        t)
 | 
			
		||||
            OVPN_DEVICE="tap"
 | 
			
		||||
@@ -227,7 +251,7 @@ while getopts ":a:e:E:C:T:r:s:du:cp:n:DNmf:tz2" opt; do
 | 
			
		||||
            OVPN_OTP_AUTH=1
 | 
			
		||||
            ;;
 | 
			
		||||
        f)
 | 
			
		||||
            OVPN_FRAGMENT=$OPTARG
 | 
			
		||||
            OVPN_FRAGMENT="$OPTARG"
 | 
			
		||||
            ;;
 | 
			
		||||
        \?)
 | 
			
		||||
            set +x
 | 
			
		||||
@@ -247,9 +271,6 @@ done
 | 
			
		||||
# Create ccd directory for static routes
 | 
			
		||||
[ ! -d "${OPENVPN:-}/ccd" ] && mkdir -p ${OPENVPN:-}/ccd
 | 
			
		||||
 | 
			
		||||
# if dns servers were not defined with -n, use google nameservers
 | 
			
		||||
[ ${#TMP_DNS_SERVERS[@]} -gt 0 ] && OVPN_DNS_SERVERS=("${TMP_DNS_SERVERS[@]}")
 | 
			
		||||
 | 
			
		||||
# Server name is in the form "udp://vpn.example.com:1194"
 | 
			
		||||
if [[ "${OVPN_SERVER_URL:-}" =~ ^((udp|tcp|udp6|tcp6)://)?([0-9a-zA-Z\.\-]+)(:([0-9]+))?$ ]]; then
 | 
			
		||||
    OVPN_PROTO=${BASH_REMATCH[2]};
 | 
			
		||||
@@ -262,24 +283,13 @@ else
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Apply defaults
 | 
			
		||||
# Apply defaults. If dns servers were not defined with -n, use google nameservers
 | 
			
		||||
set +u
 | 
			
		||||
[ -z "$OVPN_DNS_SERVERS" ] && OVPN_DNS_SERVERS=("8.8.8.8" "8.8.4.4")
 | 
			
		||||
[ -z "$OVPN_PROTO" ] && OVPN_PROTO=udp
 | 
			
		||||
[ -z "$OVPN_PORT" ] && OVPN_PORT=1194
 | 
			
		||||
[ -z "$CUSTOM_ROUTE_CONFIG" ] && process_route_config "192.168.254.0/24"
 | 
			
		||||
 | 
			
		||||
# Save extra client config from temp file only if temp file is not empty
 | 
			
		||||
if [ -s "$TMP_EXTRA_CLIENT_CONFIGFILE" ]; then
 | 
			
		||||
  OVPN_ADDITIONAL_CLIENT_CONFIG=$(cat $TMP_EXTRA_CLIENT_CONFIGFILE)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
export OVPN_SERVER OVPN_ROUTES OVPN_DEFROUTE
 | 
			
		||||
export OVPN_SERVER_URL OVPN_ENV OVPN_PROTO OVPN_CN OVPN_PORT
 | 
			
		||||
export OVPN_CLIENT_TO_CLIENT OVPN_PUSH OVPN_NAT OVPN_DNS OVPN_MTU OVPN_DEVICE
 | 
			
		||||
export OVPN_TLS_CIPHER OVPN_CIPHER OVPN_AUTH
 | 
			
		||||
export OVPN_COMP_LZO
 | 
			
		||||
export OVPN_OTP_AUTH
 | 
			
		||||
export OVPN_FRAGMENT
 | 
			
		||||
export OVPN_ADDITIONAL_CLIENT_CONFIG
 | 
			
		||||
set -u
 | 
			
		||||
[ "${#OVPN_ROUTES[@]}" == "0" ] && [ "$OVPN_DEFROUTE" == "1" ] && OVPN_ROUTES+=("192.168.254.0/24")
 | 
			
		||||
 | 
			
		||||
# Preserve config
 | 
			
		||||
if [ -f "$OVPN_ENV" ]; then
 | 
			
		||||
@@ -288,17 +298,10 @@ if [ -f "$OVPN_ENV" ]; then
 | 
			
		||||
    mv "$OVPN_ENV" "$bak_env"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Like `export | grep OVPN_ > "$OVPN_ENV"` but handles multiline variables
 | 
			
		||||
set +u
 | 
			
		||||
while read var ; do
 | 
			
		||||
  eval value=\$$var
 | 
			
		||||
  if [ -n "$value" ]; then
 | 
			
		||||
    echo "declare -x $var=\"$value\"" >> "$OVPN_ENV"
 | 
			
		||||
  else
 | 
			
		||||
# Save the current OVPN_ vars to the ovpn_env.sh file
 | 
			
		||||
while read -r var; do
 | 
			
		||||
  echo "declare -x $var"  >> "$OVPN_ENV"
 | 
			
		||||
  fi
 | 
			
		||||
done < <(export | egrep -o '(OVPN_[^=]+)')
 | 
			
		||||
set -u
 | 
			
		||||
done < <(set | grep '^OVPN_')
 | 
			
		||||
 | 
			
		||||
conf=${OPENVPN:-}/openvpn.conf
 | 
			
		||||
if [ -f "$conf" ]; then
 | 
			
		||||
@@ -307,6 +310,13 @@ if [ -f "$conf" ]; then
 | 
			
		||||
    mv "$conf" "$bak"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Echo extra client configurations
 | 
			
		||||
if [ ${#OVPN_EXTRA_CLIENT_CONFIG[@]} -gt 0 ]; then
 | 
			
		||||
  for i in "${OVPN_EXTRA_CLIENT_CONFIG[@]}"; do
 | 
			
		||||
    echo "Processing Extra Client Config: $i"
 | 
			
		||||
  done
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
cat > "$conf" <<EOF
 | 
			
		||||
server $(getroute $OVPN_SERVER)
 | 
			
		||||
verb 3
 | 
			
		||||
@@ -316,7 +326,7 @@ cert $EASYRSA_PKI/issued/${OVPN_CN}.crt
 | 
			
		||||
dh $EASYRSA_PKI/dh.pem
 | 
			
		||||
tls-auth $EASYRSA_PKI/ta.key
 | 
			
		||||
key-direction 0
 | 
			
		||||
keepalive 10 60
 | 
			
		||||
keepalive $OVPN_KEEPALIVE
 | 
			
		||||
persist-key
 | 
			
		||||
persist-tun
 | 
			
		||||
 | 
			
		||||
@@ -330,39 +340,57 @@ user nobody
 | 
			
		||||
group nogroup
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
#This was in the heredoc, we use the new function instead
 | 
			
		||||
if [ "${OVPN_DISABLE_PUSH_BLOCK_DNS}" == "1" ]; then
 | 
			
		||||
  echo "Disable default push of 'block-outside-dns'"
 | 
			
		||||
else
 | 
			
		||||
  process_push_config "block-outside-dns"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
[ -n "$OVPN_TLS_CIPHER" ] && echo "tls-cipher $OVPN_TLS_CIPHER" >> "$conf"
 | 
			
		||||
[ -n "$OVPN_CIPHER" ] && echo "cipher $OVPN_CIPHER" >> "$conf"
 | 
			
		||||
[ -n "$OVPN_AUTH" ] && echo "auth $OVPN_AUTH" >> "$conf"
 | 
			
		||||
 | 
			
		||||
[ -n "${OVPN_CLIENT_TO_CLIENT:-}" ] && echo "client-to-client" >> "$conf"
 | 
			
		||||
[ -n "${OVPN_COMP_LZO:-}" ] && echo "comp-lzo" >> "$conf"
 | 
			
		||||
[ "$OVPN_COMP_LZO" == "1" ] && echo "comp-lzo" >> "$conf"
 | 
			
		||||
 | 
			
		||||
[ -n "${OVPN_FRAGMENT:-}" ] && echo "fragment $OVPN_FRAGMENT" >> "$conf"
 | 
			
		||||
 | 
			
		||||
# Append route commands
 | 
			
		||||
if [ ${#OVPN_ROUTES[@]} -gt 0 ]; then
 | 
			
		||||
  for i in "${OVPN_ROUTES[@]}"; do
 | 
			
		||||
    process_route_config "$i"
 | 
			
		||||
  done
 | 
			
		||||
  echo -e "\n### Route Configurations Below" >> "$conf"
 | 
			
		||||
  cat $TMP_ROUTE_CONFIGFILE >> "$conf"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Append push commands
 | 
			
		||||
[ "$OVPN_DNS" == "1" ] && for i in "${OVPN_DNS_SERVERS[@]}"; do
 | 
			
		||||
  process_push_config "dhcp-option DNS $i"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Append route commands
 | 
			
		||||
echo -e "\n### Route Configurations Below" >> "$conf"
 | 
			
		||||
cat $TMP_ROUTE_CONFIGFILE >> "$conf"
 | 
			
		||||
[ ${#OVPN_PUSH[@]} -gt 0 ] && for i in "${OVPN_PUSH[@]}"; do
 | 
			
		||||
  process_push_config "$i"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# Append push commands
 | 
			
		||||
echo -e "\n### Push Configurations Below" >> "$conf"
 | 
			
		||||
cat $TMP_PUSH_CONFIGFILE >> "$conf"
 | 
			
		||||
 | 
			
		||||
# Optional OTP authentication support
 | 
			
		||||
# Append optional OTP authentication support
 | 
			
		||||
if [ -n "${OVPN_OTP_AUTH:-}" ]; then
 | 
			
		||||
    echo -e "\n\n# Enable OTP+PAM for user authentication" >> "$conf"
 | 
			
		||||
    echo "plugin /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn" >> "$conf"
 | 
			
		||||
    echo "reneg-sec 0" >> "$conf"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Append extra server configurations
 | 
			
		||||
if [ ${#OVPN_EXTRA_SERVER_CONFIG[@]} -gt 0 ]; then
 | 
			
		||||
  for i in "${OVPN_EXTRA_SERVER_CONFIG[@]}"; do
 | 
			
		||||
    process_extra_config "$i"
 | 
			
		||||
  done
 | 
			
		||||
  echo -e "\n### Extra Configurations Below" >> "$conf"
 | 
			
		||||
  cat $TMP_EXTRA_CONFIGFILE >> "$conf"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
set +e
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,6 @@ get_client_config() {
 | 
			
		||||
client
 | 
			
		||||
nobind
 | 
			
		||||
dev $OVPN_DEVICE
 | 
			
		||||
key-direction 1
 | 
			
		||||
remote-cert-tls server
 | 
			
		||||
 | 
			
		||||
remote $OVPN_CN $OVPN_PORT $OVPN_PROTO"
 | 
			
		||||
@@ -45,8 +44,9 @@ remote $OVPN_CN $OVPN_PORT $OVPN_PROTO"
 | 
			
		||||
    if [ "$OVPN_PROTO" == "tcp6" ]; then
 | 
			
		||||
        echo "remote $OVPN_CN $OVPN_PORT tcp"
 | 
			
		||||
    fi
 | 
			
		||||
    echo "$OVPN_ADDITIONAL_CLIENT_CONFIG
 | 
			
		||||
"
 | 
			
		||||
    for i in "${OVPN_EXTRA_CLIENT_CONFIG[@]}"; do
 | 
			
		||||
      echo "$i"
 | 
			
		||||
    done
 | 
			
		||||
    if [ "$mode" == "combined" ]; then
 | 
			
		||||
        echo "
 | 
			
		||||
<key>
 | 
			
		||||
@@ -97,7 +97,7 @@ tls-auth ta.key 1
 | 
			
		||||
        echo "auth-nocache"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if [ -n "$OVPN_COMP_LZO" ]; then
 | 
			
		||||
    if [ "$OVPN_COMP_LZO" == "1" ]; then
 | 
			
		||||
        echo "comp-lzo"
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
@@ -124,9 +124,9 @@ case "$parm" in
 | 
			
		||||
        get_client_config "combined" > "$dir/${cn}-combined.ovpn"
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        echo "This script can produce the client configuration in to formats:" >&2
 | 
			
		||||
        echo "This script can produce the client configuration in two formats:" >&2
 | 
			
		||||
        echo "    1. combined (default): All needed configuration and cryptographic material is in one file (Use \"combined-save\" to write the configuration file in the same path as the separated parameter does)." >&2
 | 
			
		||||
        echo "    2. separated: Separated files." >&2
 | 
			
		||||
        echo "Please specific one of those options as second parameter." >&2
 | 
			
		||||
        echo "Please specify one of those options as second parameter." >&2
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
 
 | 
			
		||||
@@ -38,3 +38,6 @@ openvpn --genkey --secret $EASYRSA_PKI/ta.key
 | 
			
		||||
 | 
			
		||||
# For a server key with a password, manually init; this is autopilot
 | 
			
		||||
easyrsa build-server-full "$OVPN_CN" nopass
 | 
			
		||||
 | 
			
		||||
# Generate the CRL for client/server certificates revocation.
 | 
			
		||||
easyrsa gen-crl
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								bin/ovpn_revokeclient
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										61
									
								
								bin/ovpn_revokeclient
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Revoke a client certificate
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [ "$DEBUG" == "1" ]; then
 | 
			
		||||
    set -x
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
if [ -z "$OPENVPN" ]; then
 | 
			
		||||
    export OPENVPN="$PWD"
 | 
			
		||||
fi
 | 
			
		||||
if ! source "$OPENVPN/ovpn_env.sh"; then
 | 
			
		||||
    echo "Could not source $OPENVPN/ovpn_env.sh."
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
if [ -z "$EASYRSA_PKI" ]; then
 | 
			
		||||
    export EASYRSA_PKI="$OPENVPN/pki"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
cn="$1"
 | 
			
		||||
parm="$2"
 | 
			
		||||
 | 
			
		||||
if [ ! -f "$EASYRSA_PKI/private/${cn}.key" ]; then
 | 
			
		||||
    echo "Unable to find \"${cn}\", please try again or generate the key first" >&2
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
revoke_client_certificate(){
 | 
			
		||||
    easyrsa revoke "$1"
 | 
			
		||||
    echo "Generating the Certificate Revocation List :"
 | 
			
		||||
    easyrsa gen-crl
 | 
			
		||||
    cp -f "$EASYRSA_PKI/crl.pem" "$OPENVPN/crl.pem"
 | 
			
		||||
    chmod 644 "$OPENVPN/crl.pem"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
remove_files(){
 | 
			
		||||
    rm -v "$EASYRSA_PKI/issued/${1}.crt"
 | 
			
		||||
    rm -v "$EASYRSA_PKI/private/${1}.key"
 | 
			
		||||
    rm -v "$EASYRSA_PKI/reqs/${1}.req"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$parm" in
 | 
			
		||||
    "remove")
 | 
			
		||||
        revoke_client_certificate "$cn"
 | 
			
		||||
        remove_files "$cn"
 | 
			
		||||
        ;;
 | 
			
		||||
    "" | "keep")
 | 
			
		||||
        revoke_client_certificate "$cn"
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        echo "When revoking a client certificate, this script let you choose if you want to remove the corresponding crt, key and req files." >&2
 | 
			
		||||
        echo "Pease note that the removal of those files is required if you want to generate a new client certificate using the revoked certificate's CN." >&2
 | 
			
		||||
        echo "    1. keep (default): Keep the files." >&2
 | 
			
		||||
        echo "    2. remove: Remove the files." >&2
 | 
			
		||||
        echo "Please specify one of those options as second parameter." >&2
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
							
								
								
									
										10
									
								
								bin/ovpn_run
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bin/ovpn_run
									
									
									
									
									
								
							@@ -74,13 +74,14 @@ if [ "$OVPN_DEFROUTE" != "0" ] || [ "$OVPN_NAT" == "1" ] ; then
 | 
			
		||||
	setupIptablesAndRouting
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Use a hacky hardlink as the CRL Needs to be readable by the user/group
 | 
			
		||||
# Use a copy of crl.pem as the CRL Needs to be readable by the user/group
 | 
			
		||||
# OpenVPN is running as.  Only pass arguments to OpenVPN if it's found.
 | 
			
		||||
if [ -r "$EASYRSA_PKI/crl.pem" ]; then
 | 
			
		||||
    if [ ! -r "$OPENVPN/crl.pem" ]; then
 | 
			
		||||
        ln "$EASYRSA_PKI/crl.pem" "$OPENVPN/crl.pem"
 | 
			
		||||
if [ "$EASYRSA_PKI/crl.pem" -nt "$OPENVPN/crl.pem" ]; then
 | 
			
		||||
    cp -f "$EASYRSA_PKI/crl.pem" "$OPENVPN/crl.pem"
 | 
			
		||||
    chmod 644 "$OPENVPN/crl.pem"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ -r "$OPENVPN/crl.pem" ]; then
 | 
			
		||||
    addArg "--crl-verify" "$OPENVPN/crl.pem"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
@@ -90,6 +91,7 @@ if [ $? = 0 ]; then
 | 
			
		||||
    # If this fails, ensure the docker container is run with --privileged
 | 
			
		||||
    # Could be side stepped with `ip netns` madness to drop privileged flag
 | 
			
		||||
 | 
			
		||||
    sysctl -w net.ipv6.conf.all.disable_ipv6=0 || echo "Failed to enable IPv6 support"
 | 
			
		||||
    sysctl -w net.ipv6.conf.default.forwarding=1 || echo "Failed to enable IPv6 Forwarding default"
 | 
			
		||||
    sysctl -w net.ipv6.conf.all.forwarding=1 || echo "Failed to enable IPv6 Forwarding"
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,12 @@ After doing so, you will find the following files in each of the `$cn` directori
 | 
			
		||||
 | 
			
		||||
## Revoking Client Certificates
 | 
			
		||||
 | 
			
		||||
Revoke `client1`'s certificate and generate the certificate revocation list (CRL):
 | 
			
		||||
Revoke `client1`'s certificate and generate the certificate revocation list (CRL) using [`ovpn_revokeclient`](/bin/ovpn_revokeclient) script :
 | 
			
		||||
 | 
			
		||||
    docker run --rm -it -v $OVPN_DATA:/etc/openvpn kylemanna/openvpn easyrsa revoke client1
 | 
			
		||||
    docker run --rm -it -v $OVPN_DATA:/etc/openvpn kylemanna/openvpn easyrsa gen-crl
 | 
			
		||||
    docker run --rm -it -v $OVPN_DATA:/etc/openvpn kylemanna/openvpn ovpn_revokeclient client1
 | 
			
		||||
 | 
			
		||||
The OpenVPN server will read this change every time a client connects (no need to restart server) and deny clients access using revoked certificates.
 | 
			
		||||
 | 
			
		||||
You can optionally pass `remove` as second parameter to ovpn_revokeclient to remove the corresponding crt, key and req files :
 | 
			
		||||
 | 
			
		||||
    docker run --rm -it -v $OVPN_DATA:/etc/openvpn kylemanna/openvpn ovpn_revokeclient client1 remove
 | 
			
		||||
 
 | 
			
		||||
@@ -59,6 +59,15 @@ docker-compose run --rm openvpn easyrsa build-client-full $CLIENTNAME nopass
 | 
			
		||||
docker-compose run --rm openvpn ovpn_getclient $CLIENTNAME > $CLIENTNAME.ovpn
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* Revoke a client certificate
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Keep the corresponding crt, key and req files.
 | 
			
		||||
docker-compose run --rm openvpn ovpn_revokeclient $CLIENTNAME
 | 
			
		||||
# Remove the corresponding crt, key and req files.
 | 
			
		||||
docker-compose run --rm openvpn ovpn_revokeclient $CLIENTNAME remove
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Debugging Tips
 | 
			
		||||
 | 
			
		||||
* Create an environment variable with the name DEBUG and value of 1 to enable debug output (using "docker -e").
 | 
			
		||||
 
 | 
			
		||||
@@ -15,11 +15,17 @@ are harmless for those not using IPv6.
 | 
			
		||||
To use and enable automatic start by systemd:
 | 
			
		||||
 | 
			
		||||
1. Create a Docker volume container named `ovpn-data-NAME` where `NAME` is the
 | 
			
		||||
   user's choice to describe the use of the container.  In the example
 | 
			
		||||
   configuration given in the [README](/README.md) `NAME=data`.
 | 
			
		||||
2. Initialize the data container according to the [docker-openvpn
 | 
			
		||||
   README](/README.md), but don't start the container. Stop the Docker
 | 
			
		||||
   container if started.
 | 
			
		||||
   user's choice to describe the use of the container.  In this example
 | 
			
		||||
   configuration, `NAME=example`.
 | 
			
		||||
   
 | 
			
		||||
        OVPN_DATA="ovpn-data-example"
 | 
			
		||||
        docker volume create --name $OVPN_DATA
 | 
			
		||||
   
 | 
			
		||||
2. Initialize the data container, but don't start the container :
 | 
			
		||||
   
 | 
			
		||||
       docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM
 | 
			
		||||
       docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
 | 
			
		||||
   
 | 
			
		||||
3. Download the [docker-openvpn@.service](https://raw.githubusercontent.com/kylemanna/docker-openvpn/master/init/docker-openvpn%40.service)
 | 
			
		||||
   file to `/etc/systemd/system`:
 | 
			
		||||
 | 
			
		||||
@@ -27,11 +33,11 @@ To use and enable automatic start by systemd:
 | 
			
		||||
 | 
			
		||||
4. Enable and start the service with:
 | 
			
		||||
 | 
			
		||||
        systemctl enable --now docker-openvpn@NAME.service
 | 
			
		||||
        systemctl enable --now docker-openvpn@example.service
 | 
			
		||||
 | 
			
		||||
5. Verify service start-up with:
 | 
			
		||||
 | 
			
		||||
        systemctl status docker-openvpn@NAME.service
 | 
			
		||||
        journalctl --unit docker-openvpn@NAME.service
 | 
			
		||||
        systemctl status docker-openvpn@example.service
 | 
			
		||||
        journalctl --unit docker-openvpn@example.service
 | 
			
		||||
 | 
			
		||||
For more information, see the [systemd manual pages](https://www.freedesktop.org/software/systemd/man/index.html).
 | 
			
		||||
 
 | 
			
		||||
@@ -4,5 +4,5 @@ start on filesystem and started docker
 | 
			
		||||
stop on runlevel [!2345]
 | 
			
		||||
respawn
 | 
			
		||||
script
 | 
			
		||||
  exec docker run -v ovpn-data:/etc/openvpn --rm -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
 | 
			
		||||
  exec docker run -v ovpn-data-example:/etc/openvpn --rm -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
 | 
			
		||||
end script
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,11 @@ imageTests+=(
 | 
			
		||||
	[openvpn]='
 | 
			
		||||
	paranoid
 | 
			
		||||
        conf_options
 | 
			
		||||
        client
 | 
			
		||||
        basic
 | 
			
		||||
        dual-proto
 | 
			
		||||
        otp
 | 
			
		||||
	iptables
 | 
			
		||||
	revocation
 | 
			
		||||
	'
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								test/tests/client/container.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								test/tests/client/container.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
SERV_IP=$(ip -4 -o addr show scope global  | awk '{print $4}' | sed -e 's:/.*::' | head -n1)
 | 
			
		||||
SERVER_CONF="/etc/openvpn/openvpn.conf"
 | 
			
		||||
TEST1_OVPN="/etc/openvpn/test1.ovpn"
 | 
			
		||||
 | 
			
		||||
# Function to fail
 | 
			
		||||
abort() { cat <<< "$@" 1>&2; exit 1; }
 | 
			
		||||
 | 
			
		||||
# Check a config (haystack) for a given line (needle) exit with error if not
 | 
			
		||||
# found.
 | 
			
		||||
test_config() {
 | 
			
		||||
 | 
			
		||||
    local needle="${2}"
 | 
			
		||||
    local file="${1}"
 | 
			
		||||
 | 
			
		||||
    busybox grep -q "${needle}" "${file}"
 | 
			
		||||
    if [ $? -ne 0 ]; then
 | 
			
		||||
        abort "==> Config match not found: ${needle}"
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Check a config (haystack) for absence of given line (needle) exit with error
 | 
			
		||||
# if found.
 | 
			
		||||
test_not_config() {
 | 
			
		||||
 | 
			
		||||
    local needle="${2}"
 | 
			
		||||
    local file="${1}"
 | 
			
		||||
 | 
			
		||||
    busybox grep -vq "${needle}" "${file}"
 | 
			
		||||
    if [ $? -ne 0 ]; then
 | 
			
		||||
        abort "==> Config match found: ${needle}"
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Generate openvpn.config file
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
ovpn_genconfig \
 | 
			
		||||
    -u udp://$SERV_IP \
 | 
			
		||||
    -m 1337 \
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
EASYRSA_BATCH=1 EASYRSA_REQ_CN="Travis-CI Test CA" ovpn_initpki nopass
 | 
			
		||||
 | 
			
		||||
easyrsa build-client-full test1 nopass 2>/dev/null
 | 
			
		||||
 | 
			
		||||
ovpn_getclient test1 > "${TEST1_OVPN}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Simple test cases
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# 1. client MTU
 | 
			
		||||
test_config "${TEST1_OVPN}" "^tun-mtu\s\+1337"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Test udp client with tcp fallback
 | 
			
		||||
#
 | 
			
		||||
ovpn_genconfig -u udp://$SERV_IP -E "remote $SERV_IP 443 tcp" -E "remote vpn.example.com 443 tcp"
 | 
			
		||||
# nopass is insecure
 | 
			
		||||
EASYRSA_BATCH=1 EASYRSA_REQ_CN="Travis-CI Test CA" ovpn_initpki nopass
 | 
			
		||||
easyrsa build-client-full client-fallback nopass
 | 
			
		||||
ovpn_getclient client-fallback > "${TEST1_OVPN}"
 | 
			
		||||
 | 
			
		||||
test_config "${TEST1_OVPN}" "^remote\s\+$SERV_IP\s\+443\s\+tcp"
 | 
			
		||||
test_config "${TEST1_OVPN}" "^remote\s\+vpn.example.com\s\+443\s\+tcp"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Test non-defroute config
 | 
			
		||||
#
 | 
			
		||||
ovpn_genconfig -d -u udp://$SERV_IP -r "172.33.33.0/24" -r "172.34.34.0/24"
 | 
			
		||||
# nopass is insecure
 | 
			
		||||
EASYRSA_BATCH=1 EASYRSA_REQ_CN="Travis-CI Test CA" ovpn_initpki nopass
 | 
			
		||||
easyrsa build-client-full non-defroute nopass
 | 
			
		||||
ovpn_getclient non-defroute > "${TEST1_OVPN}"
 | 
			
		||||
 | 
			
		||||
# The '!' inverts the match to test that the string isn't present
 | 
			
		||||
test_not_config "${TEST1_OVPN}" "^redirect-gateway\s\+def1"
 | 
			
		||||
							
								
								
									
										1
									
								
								test/tests/client/run.sh
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								test/tests/client/run.sh
									
									
									
									
									
										Symbolic link
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
../run-bash-in-container.sh
 | 
			
		||||
@@ -1,8 +1,37 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
SERV_IP=$(ip -4 -o addr show scope global  | awk '{print $4}' | sed -e 's:/.*::' | head -n1)
 | 
			
		||||
SERVER_CONF="/etc/openvpn/openvpn.conf"
 | 
			
		||||
TEST1_OVPN="/etc/openvpn/test1.ovpn"
 | 
			
		||||
 | 
			
		||||
# Function to fail
 | 
			
		||||
abort() { cat <<< "$@" 1>&2; exit 1; }
 | 
			
		||||
 | 
			
		||||
# Check a config (haystack) for a given line (needle) exit with error if not found.
 | 
			
		||||
test_config() {
 | 
			
		||||
 | 
			
		||||
    local needle="${2}"
 | 
			
		||||
    local file="${1}"
 | 
			
		||||
 | 
			
		||||
    busybox grep -q "${needle}" "${file}"
 | 
			
		||||
    if [ $? -ne 0 ]; then
 | 
			
		||||
        abort "==> Config match not found: ${needle}"
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Check a config (haystack) for absence of given line (needle) exit with error
 | 
			
		||||
# if found.
 | 
			
		||||
test_not_config() {
 | 
			
		||||
 | 
			
		||||
    local needle="${2}"
 | 
			
		||||
    local file="${1}"
 | 
			
		||||
 | 
			
		||||
    busybox grep -vq "${needle}" "${file}"
 | 
			
		||||
    if [ $? -ne 0 ]; then
 | 
			
		||||
        abort "==> Config match found: ${needle}"
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Generate openvpn.config file
 | 
			
		||||
@@ -12,183 +41,76 @@ management localhost 7505
 | 
			
		||||
max-clients 10
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
SERV_IP=$(ip -4 -o addr show scope global  | awk '{print $4}' | sed -e 's:/.*::' | head -n1)
 | 
			
		||||
ovpn_genconfig -u udp://$SERV_IP -f 1400 -e "$MULTILINE_EXTRA_SERVER_CONF" -e 'duplicate-cn' -e 'topology subnet' -p 'route 172.22.22.0 255.255.255.0'
 | 
			
		||||
ovpn_genconfig \
 | 
			
		||||
    -u udp://$SERV_IP \
 | 
			
		||||
    -f 1400 \
 | 
			
		||||
    -k '60 300' \
 | 
			
		||||
    -e "$MULTILINE_EXTRA_SERVER_CONF" \
 | 
			
		||||
    -e 'duplicate-cn' \
 | 
			
		||||
    -e 'topology subnet' \
 | 
			
		||||
    -p 'route 172.22.22.0 255.255.255.0' \
 | 
			
		||||
 | 
			
		||||
# Run ovpn_genconfig a second time with no arguments to test its repeatability.
 | 
			
		||||
ovpn_genconfig
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# grep for config lines from openvpn.conf
 | 
			
		||||
# add more tests for more configs as required
 | 
			
		||||
# Simple test cases
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# 1. verb config
 | 
			
		||||
CONFIG_REQUIRED_VERB="verb 3"
 | 
			
		||||
CONFIG_MATCH_VERB=$(busybox grep verb /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^verb\s\+3"
 | 
			
		||||
 | 
			
		||||
# 2. fragment config
 | 
			
		||||
CONFIG_REQUIRED_FRAGMENT="fragment 1400"
 | 
			
		||||
CONFIG_MATCH_FRAGMENT=$(busybox grep fragment /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^fragment\s\+1400"
 | 
			
		||||
 | 
			
		||||
## Tests for extra configs
 | 
			
		||||
# 3. management config
 | 
			
		||||
CONFIG_REQUIRED_MANAGEMENT="^management localhost 7505"
 | 
			
		||||
CONFIG_MATCH_MANAGEMENT=$(busybox grep management /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^management\s\+localhost\s\+7505"
 | 
			
		||||
 | 
			
		||||
# 4. max-clients config
 | 
			
		||||
CONFIG_REQUIRED_MAX_CLIENTS="^max-clients 10"
 | 
			
		||||
CONFIG_MATCH_MAX_CLIENTS=$(busybox grep max-clients /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^max-clients\s\+10"
 | 
			
		||||
 | 
			
		||||
# 5. duplicate-cn config
 | 
			
		||||
CONFIG_REQUIRED_DUPCN="^duplicate-cn"
 | 
			
		||||
CONFIG_MATCH_DUPCN=$(busybox grep duplicate-cn /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^duplicate-cn"
 | 
			
		||||
 | 
			
		||||
# 6. topology config
 | 
			
		||||
CONFIG_REQUIRED_TOPOLOGY="^topology subnet"
 | 
			
		||||
CONFIG_MATCH_TOPOLOGY=$(busybox grep 'topology subnet' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^topology\s\+subnet"
 | 
			
		||||
 | 
			
		||||
## Tests for push config
 | 
			
		||||
# 7. push route
 | 
			
		||||
CONFIG_REQUIRED_PUSH_ROUTE="^push route 172.22.22.0 255.255.255.0"
 | 
			
		||||
CONFIG_MATCH_PUSH_ROUTE=$(busybox grep 'push route 172.22.22.0 255.255.255.0' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" '^push\s\+"route\s\+172.22.22.0\s\+255.255.255.0"'
 | 
			
		||||
 | 
			
		||||
## Test for default
 | 
			
		||||
# 8. Should see default route if none provided
 | 
			
		||||
CONFIG_REQUIRED_DEFAULT_ROUTE="^route 192.168.254.0 255.255.255.0"
 | 
			
		||||
CONFIG_MATCH_DEFAULT_ROUTE=$(busybox grep 'route 192.168.254.0 255.255.255.0' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^route\s\+192.168.254.0\s\+255.255.255.0"
 | 
			
		||||
 | 
			
		||||
# 9. Should see a push of 'block-outside-dns' by default
 | 
			
		||||
CONFIG_REQUIRED_DEFAULT_ROUTE="^push block-outside-dns"
 | 
			
		||||
CONFIG_MATCH_DEFAULT_ROUTE=$(busybox grep 'push block-outside-dns' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" '^push\s\+"block-outside-dns"'
 | 
			
		||||
 | 
			
		||||
# 10. Should see a push of 'dhcp-option DNS' by default
 | 
			
		||||
CONFIG_REQUIRED_DEFAULT_DNS_1="^push dhcp-option DNS 8.8.8.8"
 | 
			
		||||
CONFIG_MATCH_DEFAULT_DNS_1=$(busybox grep 'push dhcp-option DNS 8.8.8.8' /etc/openvpn/openvpn.conf)
 | 
			
		||||
CONFIG_REQUIRED_DEFAULT_DNS_2="^push dhcp-option DNS 8.8.4.4"
 | 
			
		||||
CONFIG_MATCH_DEFAULT_DNS_2=$(busybox grep 'push dhcp-option DNS 8.8.4.4' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" '^push\s\+"dhcp-option\s\+DNS\s\+8.8.8.8"'
 | 
			
		||||
test_config "${SERVER_CONF}" '^push\s\+"dhcp-option\s\+DNS\s\+8.8.4.4"'
 | 
			
		||||
 | 
			
		||||
## Test for keepalive
 | 
			
		||||
# 11. keepalive config
 | 
			
		||||
test_config "${SERVER_CONF}" '^keepalive\s\+60\s\+300'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Tests
 | 
			
		||||
# More elaborate route tests
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_VERB =~ $CONFIG_REQUIRED_VERB ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_VERB == $CONFIG_MATCH_VERB"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_VERB != $CONFIG_MATCH_VERB"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_FRAGMENT =~ $CONFIG_REQUIRED_FRAGMENT ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_FRAGMENT == $CONFIG_MATCH_FRAGMENT"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_FRAGMENT != $CONFIG_MATCH_FRAGMENT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_MANAGEMENT =~ $CONFIG_REQUIRED_MANAGEMENT ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_MANAGEMENT == $CONFIG_MATCH_MANAGEMENT"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_MANAGEMENT != $CONFIG_MATCH_MANAGEMENT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_MAX_CLIENTS =~ $CONFIG_REQUIRED_MAX_CLIENTS ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_MAX_CLIENTS == $CONFIG_MATCH_MAX_CLIENTS"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_MAX_CLIENTS != $CONFIG_MATCH_MAX_CLIENTS"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_DUPCN =~ $CONFIG_REQUIRED_DUPCN ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_DUPCN == $CONFIG_MATCH_DUPCN"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_DUPCN != $CONFIG_MATCH_DUPCN"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_TOPOLOGY =~ $CONFIG_REQUIRED_TOPOLOGY ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_TOPOLOGY == $CONFIG_MATCH_TOPOLOGY"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_TOPOLOGY != $CONFIG_MATCH_TOPOLOGY"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_PUSH_ROUTE =~ $CONFIG_REQUIRED_PUSH_ROUTE ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_PUSH_ROUTE == $CONFIG_MATCH_PUSH_ROUTE"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_PUSH_ROUTE != $CONFIG_MATCH_PUSH_ROUTE"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_DEFAULT_ROUTE =~ $CONFIG_REQUIRED_DEFAULT_ROUTE ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_DEFAULT_ROUTE == $CONFIG_MATCH_DEFAULT_ROUTE"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_DEFAULT_ROUTE != $CONFIG_MATCH_DEFAULT_ROUTE"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_DEFAULT_DNS_1 =~ $CONFIG_REQUIRED_DEFAULT_DNS_1 ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_DEFAULT_DNS_1 == $CONFIG_MATCH_DEFAULT_DNS_1"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_DEFAULT_DNS_1 != $CONFIG_MATCH_DEFAULT_DNS_1"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_DEFAULT_DNS_2 =~ $CONFIG_REQUIRED_DEFAULT_DNS_2 ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_DEFAULT_DNS_2 == $CONFIG_MATCH_DEFAULT_DNS_2"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_DEFAULT_DNS_2 != $CONFIG_MATCH_DEFAULT_DNS_2"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
SERV_IP=$(ip -4 -o addr show scope global  | awk '{print $4}' | sed -e 's:/.*::' | head -n1)
 | 
			
		||||
ovpn_genconfig -u udp://$SERV_IP -r "172.33.33.0/24" -r "172.34.34.0/24"
 | 
			
		||||
 | 
			
		||||
CONFIG_REQUIRED_ROUTE_1="^route 172.33.33.0 255.255.255.0"
 | 
			
		||||
CONFIG_MATCH_ROUTE_1=$(busybox grep 'route 172.33.33.0 255.255.255.0' /etc/openvpn/openvpn.conf)
 | 
			
		||||
test_config "${SERVER_CONF}" "^route\s\+172.33.33.0\s\+255.255.255.0"
 | 
			
		||||
test_config "${SERVER_CONF}" "^route\s\+172.34.34.0\s\+255.255.255.0"
 | 
			
		||||
 | 
			
		||||
CONFIG_REQUIRED_ROUTE_2="^route 172.34.34.0 255.255.255.0"
 | 
			
		||||
CONFIG_MATCH_ROUTE_2=$(busybox grep 'route 172.34.34.0 255.255.255.0' /etc/openvpn/openvpn.conf)
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_ROUTE_1 =~ $CONFIG_REQUIRED_ROUTE_1 ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_ROUTE_1 == $CONFIG_MATCH_ROUTE_1"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_ROUTE_1 != $CONFIG_MATCH_ROUTE_1"
 | 
			
		||||
fi
 | 
			
		||||
#
 | 
			
		||||
# Block outside DNS test
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_ROUTE_2 =~ $CONFIG_REQUIRED_ROUTE_2 ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_ROUTE_2 == $CONFIG_MATCH_ROUTE_2"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_ROUTE_2 != $CONFIG_MATCH_ROUTE_2"
 | 
			
		||||
fi
 | 
			
		||||
ovpn_genconfig -u udp://$SERV_IP -b
 | 
			
		||||
 | 
			
		||||
# Test generated client config
 | 
			
		||||
 | 
			
		||||
# gen udp client with tcp fallback
 | 
			
		||||
ovpn_genconfig -u udp://$SERV_IP -E "remote $SERV_IP 443 tcp" -E "remote vpn.example.com 443 tcp"
 | 
			
		||||
# nopass is insecure
 | 
			
		||||
EASYRSA_BATCH=1 EASYRSA_REQ_CN="Travis-CI Test CA" ovpn_initpki nopass
 | 
			
		||||
easyrsa build-client-full client-fallback nopass
 | 
			
		||||
ovpn_getclient client-fallback | tee /etc/openvpn/config-fallback.ovpn
 | 
			
		||||
 | 
			
		||||
CONFIG_REQUIRED_TCP_REMOTE="^remote $SERV_IP 443 tcp"
 | 
			
		||||
CONFIG_MATCH_TCP_REMOTE=$(busybox grep "remote $SERV_IP 443 tcp" /etc/openvpn/config-fallback.ovpn)
 | 
			
		||||
 | 
			
		||||
CONFIG_REQUIRED_TCP_REMOTE_2="^remote vpn.example.com 443 tcp"
 | 
			
		||||
CONFIG_MATCH_TCP_REMOTE_2=$(busybox grep "remote vpn.example.com 443 tcp" /etc/openvpn/config-fallback.ovpn)
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_TCP_REMOTE =~ $CONFIG_REQUIRED_TCP_REMOTE ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_TCP_REMOTE == $CONFIG_MATCH_TCP_REMOTE"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_TCP_REMOTE != $CONFIG_MATCH_TCP_REMOTE"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $CONFIG_MATCH_TCP_REMOTE_2 =~ $CONFIG_REQUIRED_TCP_REMOTE_2 ]]
 | 
			
		||||
then
 | 
			
		||||
  echo "==> Config match found: $CONFIG_REQUIRED_TCP_REMOTE_2 == $CONFIG_MATCH_TCP_REMOTE_2"
 | 
			
		||||
else
 | 
			
		||||
  abort "==> Config match not found: $CONFIG_REQUIRED_TCP_REMOTE_2 != $CONFIG_MATCH_TCP_REMOTE_2"
 | 
			
		||||
fi
 | 
			
		||||
test_not_config "${SERVER_CONF}" '^push "block-outside-dns"'
 | 
			
		||||
cat ${SERVER_CONF} >&1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								test/tests/revocation/run.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										101
									
								
								test/tests/revocation/run.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
[ -n "${DEBUG+x}" ] && set -x
 | 
			
		||||
 | 
			
		||||
OVPN_DATA="basic-data"
 | 
			
		||||
CLIENT1="travis-client1"
 | 
			
		||||
CLIENT2="travis-client2"
 | 
			
		||||
IMG="kylemanna/openvpn"
 | 
			
		||||
NAME="ovpn-test"
 | 
			
		||||
CLIENT_DIR="$(readlink -f "$(dirname "$BASH_SOURCE")/../../client")"
 | 
			
		||||
SERV_IP="$(ip -4 -o addr show scope global  | awk '{print $4}' | sed -e 's:/.*::' | head -n1)"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Initialize openvpn configuration and pki.
 | 
			
		||||
#
 | 
			
		||||
docker volume create --name $OVPN_DATA
 | 
			
		||||
docker run --rm -v $OVPN_DATA:/etc/openvpn $IMG ovpn_genconfig -u udp://$SERV_IP
 | 
			
		||||
docker run --rm -v $OVPN_DATA:/etc/openvpn -it -e "EASYRSA_BATCH=1" -e "EASYRSA_REQ_CN=Travis-CI Test CA" $IMG ovpn_initpki nopass
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Fire up the server.
 | 
			
		||||
#
 | 
			
		||||
sudo iptables -N DOCKER || echo 'Firewall already configured'
 | 
			
		||||
sudo iptables -I FORWARD 1 -j DOCKER
 | 
			
		||||
docker run -d -v $OVPN_DATA:/etc/openvpn --cap-add=NET_ADMIN --privileged -p 1194:1194/udp --name $NAME $IMG
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Test that easy_rsa generate CRLs with 'next publish' set to 3650 days.
 | 
			
		||||
#
 | 
			
		||||
crl_next_update="$(docker exec $NAME openssl crl -nextupdate -noout -in /etc/openvpn/crl.pem | cut -d'=' -f2 | tr -d 'GMT')"
 | 
			
		||||
crl_next_update="$(date -u -d "$crl_next_update" "+%s")"
 | 
			
		||||
now="$(docker exec $NAME date "+%s")"
 | 
			
		||||
crl_remain="$(( $crl_next_update - $now ))"
 | 
			
		||||
crl_remain="$(( $crl_remain / 86400 ))"
 | 
			
		||||
if (( $crl_remain < 3649 )); then
 | 
			
		||||
    echo "easy_rsa CRL next publish set to less than 3650 days." >&2
 | 
			
		||||
    exit 2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Generate a first client certificate and configuration using $CLIENT1 as CN then revoke it.
 | 
			
		||||
#
 | 
			
		||||
docker exec -it $NAME easyrsa build-client-full $CLIENT1 nopass
 | 
			
		||||
docker exec -it $NAME ovpn_getclient $CLIENT1 > $CLIENT_DIR/config.ovpn
 | 
			
		||||
docker exec -it $NAME bash -c "echo 'yes' | ovpn_revokeclient $CLIENT1 remove"
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Test that openvpn client can't connect using $CLIENT1 config.
 | 
			
		||||
#
 | 
			
		||||
if docker run --rm -v $CLIENT_DIR:/client --cap-add=NET_ADMIN --privileged --net=host $IMG /client/wait-for-connect.sh; then
 | 
			
		||||
    echo "Client was able to connect after revocation test #1." >&2
 | 
			
		||||
    exit 2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Generate and revoke a second client certificate using $CLIENT2 as CN, then test for failed client connection.
 | 
			
		||||
#
 | 
			
		||||
docker exec -it $NAME easyrsa build-client-full $CLIENT2 nopass
 | 
			
		||||
docker exec -it $NAME ovpn_getclient $CLIENT2 > $CLIENT_DIR/config.ovpn
 | 
			
		||||
docker exec -it $NAME bash -c "echo 'yes' | ovpn_revokeclient $CLIENT2 remove"
 | 
			
		||||
 | 
			
		||||
if docker run --rm -v $CLIENT_DIR:/client --cap-add=NET_ADMIN --privileged --net=host $IMG /client/wait-for-connect.sh; then
 | 
			
		||||
    echo "Client was able to connect after revocation test #2." >&2
 | 
			
		||||
    exit 2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Restart the server
 | 
			
		||||
#
 | 
			
		||||
docker stop $NAME && docker start $NAME
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Test for failed connection using $CLIENT2 config again.
 | 
			
		||||
#
 | 
			
		||||
if docker run --rm -v $CLIENT_DIR:/client --cap-add=NET_ADMIN --privileged --net=host $IMG /client/wait-for-connect.sh; then
 | 
			
		||||
    echo "Client was able to connect after revocation test #3." >&2
 | 
			
		||||
    exit 2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Stop the server and clean up
 | 
			
		||||
#
 | 
			
		||||
docker kill $NAME && docker rm $NAME
 | 
			
		||||
docker volume rm $OVPN_DATA
 | 
			
		||||
sudo iptables -D FORWARD 1
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Celebrate
 | 
			
		||||
#
 | 
			
		||||
cat <<EOF
 | 
			
		||||
 ___________
 | 
			
		||||
< it worked >
 | 
			
		||||
 -----------
 | 
			
		||||
        \   ^__^
 | 
			
		||||
         \  (oo)\_______
 | 
			
		||||
            (__)\       )\/\\
 | 
			
		||||
                ||----w |
 | 
			
		||||
                ||     ||
 | 
			
		||||
EOF
 | 
			
		||||
		Reference in New Issue
	
	Block a user