Merge ~gary-wzl77/snappy-hwe-snaps/+git/easy-openvpn:refactor into ~snappy-hwe-team/snappy-hwe-snaps/+git/easy-openvpn:master

Proposed by Gary.Wang
Status: Merged
Approved by: Simon Fels
Approved revision: 7a96dcf7e2967a88de5833ac50d7229542674f6e
Merged at revision: 8f66ccb40284d6614bbc33a2eef73aa9bb009090
Proposed branch: ~gary-wzl77/snappy-hwe-snaps/+git/easy-openvpn:refactor
Merge into: ~snappy-hwe-team/snappy-hwe-snaps/+git/easy-openvpn:master
Diff against target: 2023 lines (+913/-40)
27 files modified
.gitignore (+7/-0)
MAINTAINERS (+2/-0)
README.md (+59/-13)
TODO.md (+4/-5)
bin/configure (+53/-0)
bin/help (+47/-0)
bin/ovpn_addclient (+16/-2)
bin/ovpn_setup (+15/-1)
dev/null (+0/-14)
patches/0001-Enable-docker-openvpn-working-in-snappy-world.patch (+179/-0)
run-tests.sh (+70/-0)
snapcraft.yaml (+53/-5)
spread.yaml (+50/-0)
spread/lib/prepare-all.sh (+16/-0)
spread/lib/prepare.sh (+64/-0)
spread/lib/restore-each.sh (+33/-0)
spread/lib/snap-names.sh (+7/-0)
spread/lib/utilities.sh (+12/-0)
spread/main/add_client/task.yaml (+24/-0)
spread/main/connect_server/task.yaml (+31/-0)
spread/main/hooks/task.yaml (+13/-0)
spread/main/installation/task.yaml (+8/-0)
spread/main/launch_server/task.yaml (+16/-0)
spread/main/monitor_status/task.yaml (+43/-0)
spread/main/revoke_after_connection/task.yaml (+51/-0)
spread/main/revoke_client/task.yaml (+22/-0)
spread/main/setup_server/task.yaml (+18/-0)
Reviewer Review Type Date Requested Status
Simon Fels Approve
System Enablement Bot continuous-integration Approve
Konrad Zapałowicz (community) code Approve
Alfonso Sanchez-Beato Approve
Jim Hodapp (community) Needs Fixing
Gary.Wang Pending
Review via email: mp+329298@code.launchpad.net

Commit message

* Refactor to follow the upstream to get server setup scripts.
* Add spread tests.
* Add three commands. [revoke-client, connect-server, help]
* Support hooks to set env variables.

Description of the change

* Refactor to follow the upstream to get server setup scripts.
* Add spread tests.
* Add three commands. [revoke-client, connect-server, help]
* Support hooks to set env variables.

To post a comment you must log in.
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

comments inline

review: Needs Fixing (code)
Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jim Hodapp (jhodapp) wrote :

Some grammar changes needed along with a few other types. Looks good though!

review: Needs Fixing
Revision history for this message
Gary.Wang (gary-wzl77) wrote :

Thanks for the code review. I'll get it fixed in the next commit.

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Looks great, just some minor comments.

review: Needs Fixing
Revision history for this message
Gary.Wang (gary-wzl77) wrote :

Thanks for this, especially for HERE doc.
I'll fix it soon

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM, thanks for the changes!

review: Approve
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

ack

review: Approve (code)
Revision history for this message
Simon Fels (morphis) :
review: Needs Fixing
Revision history for this message
Gary.Wang (gary-wzl77) wrote :

Thanks for your review.
As mentioned, I'll import the upstream into a tracking branch and use it as the source for this snap creation.

Revision history for this message
System Enablement Bot (system-enablement-ci-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000..a21d85c
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,7 @@
7+/*.snap
8+/parts
9+/prime
10+/stage
11+/snap/plugins/__pycache__/
12+/snap/.snapcraft/
13+.tests-extras
14diff --git a/MAINTAINERS b/MAINTAINERS
15new file mode 100644
16index 0000000..b9d3341
17--- /dev/null
18+++ b/MAINTAINERS
19@@ -0,0 +1,2 @@
20+Casey Marshall <casey.marshall@canonical.com>
21+Gary Wang <gary.wang@canonical.com>
22diff --git a/README.md b/README.md
23index 2396bf5..120c043 100644
24--- a/README.md
25+++ b/README.md
26@@ -6,10 +6,9 @@ spot deployment of secure yet disposable OpenVPN instances.
27
28 # Status
29
30-We disable user and group setup for openvpn server for the time being as an
31-open bug can be found on launchpad. [lp#1606510](https://bugs.launchpad.net/snappy/+bug/1606510)
32-)] :( See [TODO](TODO.md) for current issues. Consider this
33-currently experimental quality.
34+We disable user and group setup for OpenVPN server for the time being as an
35+open bug can be found on Launchpad. [lp#1606510](https://bugs.launchpad.net/snappy/+bug/1606510).
36+Adding [user and group management](https://forum.snapcraft.io/t/multiple-users-and-groups-in-snaps/1461/2) support is on the roadmap of snapd. We'll support it accordingly when the feature lands. See [TODO](TODO.md) for current issues.
37
38 # Operate
39
40@@ -17,37 +16,84 @@ Commands subject to change as I refine things, but here goes:
41
42 ## Install
43
44- sudo snap install easy-openvpn
45+ $ sudo snap install easy-openvpn
46+
47+## Connect two necessary plugs as they're not auto-connected by default:
48+
49+ $ sudo snap connect easy-openvpn:network-control :network-control
50+ $ sudo snap connect easy-openvpn:firewall-control :firewall-control
51+ $ sudo snap connect easy-openvpn:home :home
52
53 ## Configure
54
55- sudo easy-openvpn.setup -u udp://<public ip>
56+ $ sudo easy-openvpn.setup -u udp://<public ip>
57
58 You'll be prompted to set a passphrase for your CA. This passphrase will be
59 used to create clients later.
60
61 ## Start
62
63- sudo service snap.easy-openvpn.easy-openvpn start
64+ $ sudo service snap.easy-openvpn.easy-openvpn start
65+
66+Beginning with snapd 2.26.9, snapd can currently take connections of interfaces dynamically
67+and update the mount namespaces of the snap in-place without any processes
68+restarting or any other change after connecting interfaces above. But to be safe,
69+we could reload the snap manually with the following commands:
70+
71+ $ sudo disable easy-openvpn
72+ $ sudo enable easy-openvpn
73
74 ## Use
75
76- sudo service snap.easy-openvpn.add-client foo > foo.ovpn
77+ $ sudo easy-openvpn.add-client foo > foo.ovpn
78
79-Enter the same passphrase you set during setup above. Use the .ovpn file to
80-connect to your VPN server.
81+Add a client and enter the same passphrase you set during setup above. Use the
82+.ovpn file to connect to your VPN server.
83
84 ## Manage
85
86 ### List clients
87
88- sudo easy-openvpn.clients
89+ $ sudo easy-openvpn.clients
90
91 ### Show client ovpn
92
93- sudo easy-openvpn.show-client foo
94+ $ sudo easy-openvpn.show-client foo
95
96 ### Tail the log
97
98- sudo easy-openvpn.status
99+ $ sudo easy-openvpn.status
100+
101+## Testing
102+
103+We rely on spread (https://github.com/snapcore/spread) to run full-system test on Ubuntu Core 16. A utility script (run-spread-test.sh) being used to launch the spread test can be found in this project.
104+
105+Firstly, install ubuntu-image tool since we need to create a custom Ubuntu Core image during test preparation.
106+
107+ $ sudo snap install --beta --classic ubuntu-image
108+
109+Secondly, install qemu-kvm package since we use it as the backend to run the spread test.
110+
111+ $ sudo apt install qemu-kvm
112+
113+Meanwhile, you need a classic-mode supported spread binary to launch kvm from its context. You can either build spread from this [branch](https://github.com/rmescandon/spread/tree/snap-as-classic) or download the spread snap package [here](http://people.canonical.com/~gary-wzl77/spread_2017.05.24_amd64.snap).
114+
115+ $ sudo snap install --classic --dangerous spread_2017.05.24_amd64.snap
116+
117+You may build the easy-openvpn snap locally in advance and then execute the spread tests with the following commands:
118+
119+ $ snapcraft
120+ $ ./run-tests.sh
121+
122+When doing a local build, you can also specify --test-from-channel to fetch the snap from the specific channel of the store. The snap from `candidate` channel is used by default as test target if `--channel` option is not specified.
123+
124+ $ ./run-tests.sh --test-from-channel --channel=candidate
125+
126+In order to execute an individual spread test, please run the following command:
127+
128+ $ spread spread/main/installation
129+
130+This will run the test case under spread/main/installation folder.
131+You can specify the `SNAP_CHANNEL` environment variable to install a snap from a specific channel for the testing as well.
132
133+ $ SNAP_CHANNEL=candidate spread spread/main/installation
134diff --git a/TODO.md b/TODO.md
135index 1b01c94..284f3ac 100644
136--- a/TODO.md
137+++ b/TODO.md
138@@ -16,13 +16,12 @@ We disable user and group setup for openvpn server for the time being as an open
139
140 ## generate some clients and test connection is working
141
142-## simplify things further
143-- single command to set up server
144-- single command to create/revoke client ovpns
145-
146 # DONE
147 - figure out why iptables nat rules aren't allowed with firewall-control
148 - need to snap connect :firewall-control, :network-control
149 - tun/tap access for openvpn in strict mode
150 - read/write acccess to /dev/net/tun is allowed in snapd with network-control connected
151-
152+- single command to set up server
153+ - please check easy-openvpn.setup command
154+- single command to create/revoke client ovpns
155+ - please check easy-openvpn.add-client command
156diff --git a/bin/LICENSE b/bin/LICENSE
157deleted file mode 100644
158index a1a87e0..0000000
159--- a/bin/LICENSE
160+++ /dev/null
161@@ -1,23 +0,0 @@
162-The MIT License (MIT)
163-
164-Copyright (c) 2016 Casey Marshall
165-
166-Copyright (c) 2014 Kyle Manna
167-
168-Permission is hereby granted, free of charge, to any person obtaining a copy
169-of this software and associated documentation files (the "Software"), to deal
170-in the Software without restriction, including without limitation the rights
171-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
172-copies of the Software, and to permit persons to whom the Software is
173-furnished to do so, subject to the following conditions:
174-
175-The above copyright notice and this permission notice shall be included in all
176-copies or substantial portions of the Software.
177-
178-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
179-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
180-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
181-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
182-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
183-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
184-SOFTWARE.
185diff --git a/bin/configure b/bin/configure
186new file mode 100755
187index 0000000..8ef9823
188--- /dev/null
189+++ b/bin/configure
190@@ -0,0 +1,53 @@
191+#!/bin/sh
192+#
193+# Copyright (C) 2017 Canonical Ltd
194+#
195+# This program is free software: you can redistribute it and/or modify
196+# it under the terms of the GNU General Public License version 3 as
197+# published by the Free Software Foundation.
198+#
199+# This program is distributed in the hope that it will be useful,
200+# but WITHOUT ANY WARRANTY; without even the implied warranty of
201+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
202+# GNU General Public License for more details.
203+#
204+# You should have received a copy of the GNU General Public License
205+# along with this program. If not, see <http://www.gnu.org/licenses/>.
206+
207+PROFILE="${SNAP_DATA}/easy-openvpn.profile"
208+
209+test -f $PROFILE && rm $PROFILE
210+
211+if ! debug=$(snapctl get debug); then
212+ echo "Failed to get debug option."
213+ exit 1
214+fi
215+
216+if ! nopasswd=$(snapctl get nopasswd); then
217+ echo "Failed to get nopasswd option."
218+ exit 1
219+fi
220+
221+cat << EOF > $PROFILE
222+export OPENVPN=$SNAP_DATA/openvpn
223+export EASYRSA=$SNAP/usr/local/easyrsa
224+export EASYRSA_PKI=$SNAP_DATA/openvpn/pki
225+export EASYRSA_VARS_FILE=$SNAP_DATA/openvpn/vars
226+export PATH=$SNAP/usr/local/easyrsa:$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH
227+export DEBUG=$debug
228+export NOPASSWD=$nopasswd
229+EOF
230+
231+# Set default domain common name and call easy-rsa explicitly in batch mode.
232+# It's helpful to execute spread test in non-interactive mode.
233+if [ "$nopasswd" = "1" ]; then
234+ # Ugly, set env var and pass it to ovpn.
235+ # export nopass=1 makes more sense but this is the least code changes.
236+ cat << EOF >> $PROFILE
237+export nopass=nopass
238+export EASYRSA_BATCH=1
239+export EASYRSA_REQ_CN=SNAPPY_SPREAD_TEST
240+EOF
241+fi
242+
243+chmod 600 $PROFILE
244diff --git a/bin/easy-openvpn.profile b/bin/easy-openvpn.profile
245deleted file mode 100644
246index 865d283..0000000
247--- a/bin/easy-openvpn.profile
248+++ /dev/null
249@@ -1,7 +0,0 @@
250-export OPENVPN=$SNAP_DATA/openvpn
251-export OPENVPN_CMD=$SNAP/usr/sbin/openvpn
252-export EASYRSA=$SNAP/usr/local/easyrsa
253-export EASYRSA_CMD=$EASYRSA/easyrsa
254-export EASYRSA_PKI=$OPENVPN/pki
255-export EASYRSA_VARS_FILE=$OPENVPN/vars
256-export IPTABLES=$SNAP/sbin/iptables
257diff --git a/bin/easyrsa_vars b/bin/easyrsa_vars
258deleted file mode 100755
259index 715ac1d..0000000
260--- a/bin/easyrsa_vars
261+++ /dev/null
262@@ -1,41 +0,0 @@
263-#!/bin/bash
264-
265-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
266-
267-#
268-# Import/export EasyRSA default settings
269-#
270-
271-if [ "$DEBUG" == "1" ]; then
272- set -x
273-fi
274-
275-set -e
276-
277-if [ $# -lt 1 ]; then
278- echo "No command provided"
279- echo
280- echo "$0 export > /path/to/file"
281- echo "$0 import < /path/to/file"
282- exit 1
283-fi
284-
285-cmd=$1
286-shift
287-
288-case "$cmd" in
289- export)
290- if [ -f "$EASYRSA_VARS_FILE" ]; then
291- cat "$EASYRSA_VARS_FILE"
292- else
293- cat "$EASYRSA/vars.example"
294- fi
295- ;;
296- import)
297- cat > "$EASYRSA_VARS_FILE"
298- ;;
299- *)
300- echo "Unknown cmd \"$cmd\""
301- exit 2
302- ;;
303-esac
304diff --git a/bin/help b/bin/help
305new file mode 100755
306index 0000000..0375715
307--- /dev/null
308+++ b/bin/help
309@@ -0,0 +1,47 @@
310+#!/bin/bash
311+#
312+# Copyright (C) 2017 Canonical Ltd
313+#
314+# This program is free software: you can redistribute it and/or modify
315+# it under the terms of the GNU General Public License version 3 as
316+# published by the Free Software Foundation.
317+#
318+# This program is distributed in the hope that it will be useful,
319+# but WITHOUT ANY WARRANTY; without even the implied warranty of
320+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
321+# GNU General Public License for more details.
322+#
323+# You should have received a copy of the GNU General Public License
324+# along with this program. If not, see <http://www.gnu.org/licenses/>.
325+
326+source ${SNAP_DATA}/easy-openvpn.profile
327+
328+DEFAULT_DEBUG=0
329+DEFAULT_NOPASSWD=0
330+
331+SNAPPY_DEBUG=debug
332+SNAPPY_NOPASSWD=nopasswd
333+
334+KEYS=("DEBUG" "NOPASSWD")
335+DESC_DEBUG="Enable debug mode in OpenVPN server if it's set to 1."
336+DESC_NOPASSWD="Enable generating private key without a passphrase during server setup if it's set to 1"
337+
338+cat << 'EOF'
339+OpenVPN snap with management scripts that simplify PKI
340+and client management for fast, cheap and disposable VPNs.
341+It's based on https://github.com/kylemanna/docker-openvpn."
342+$ snap set easy-openvpn <key name>='<key value>'"
343+EOF
344+
345+for key in "${KEYS[@]}"
346+do
347+ default_value="DEFAULT_$key"
348+ description="DESC_$key"
349+ snappy_key="SNAPPY_$key"
350+ echo -e "\t${!snappy_key}: ${!description}"
351+ if [ "x" == "x${!key}" ]; then
352+ echo -e "\t\tNo value set for: '${!snappy_key}', using default value: '${!default_value}'"
353+ else
354+ echo -e "\t\t'${!snappy_key}' current value set to: '${!key}', (default value: '${!default_value}')"
355+ fi
356+done
357diff --git a/bin/ovpn_addclient b/bin/ovpn_addclient
358index 0860240..bc1e1b4 100755
359--- a/bin/ovpn_addclient
360+++ b/bin/ovpn_addclient
361@@ -1,6 +1,20 @@
362 #!/bin/bash
363+#
364+# Copyright (C) 2016-2017 Canonical Ltd
365+#
366+# This program is free software: you can redistribute it and/or modify
367+# it under the terms of the GNU General Public License version 3 as
368+# published by the Free Software Foundation.
369+#
370+# This program is distributed in the hope that it will be useful,
371+# but WITHOUT ANY WARRANTY; without even the implied warranty of
372+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
373+# GNU General Public License for more details.
374+#
375+# You should have received a copy of the GNU General Public License
376+# along with this program. If not, see <http://www.gnu.org/licenses/>.
377
378-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
379+source $SNAP_DATA/easy-openvpn.profile
380
381 if [ "$DEBUG" == "1" ]; then
382 set -x
383@@ -10,6 +24,6 @@ set -e
384
385 cn="$1"
386
387-$EASYRSA_CMD build-client-full ${cn} nopass
388+easyrsa build-client-full ${cn} nopass
389
390 $SNAP/bin/ovpn_getclient ${cn}
391diff --git a/bin/ovpn_copy_server_files b/bin/ovpn_copy_server_files
392deleted file mode 100755
393index 85affab..0000000
394--- a/bin/ovpn_copy_server_files
395+++ /dev/null
396@@ -1,43 +0,0 @@
397-#!/bin/bash
398-## @licence MIT <http://opensource.org/licenses/MIT>
399-## @author Copyright (C) 2015 Robin Schneider <ypid@riseup.net>
400-
401-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
402-
403-set -e
404-
405-if [ -z "$OPENVPN" ]; then
406- export OPENVPN="$PWD"
407-fi
408-if ! source "$OPENVPN/ovpn_env.sh"; then
409- echo "Could not source $OPENVPN/ovpn_env.sh."
410- exit 1
411-fi
412-
413-TARGET="$OPENVPN/server"
414-if [ -n "$1" ]; then
415- TARGET="$1"
416-fi
417-mkdir -p "${TARGET}"
418-
419-## Ensure that no other keys then the one for the server is present.
420-rm -rf "$TARGET/pki/private" "$TARGET/pki/issued"
421-
422-FILES=(
423- "openvpn.conf"
424- "ovpn_env.sh"
425- "pki/private/${OVPN_CN}.key"
426- "pki/issued/${OVPN_CN}.crt"
427- "pki/dh.pem"
428- "pki/ta.key"
429- "pki/ca.crt"
430-)
431-
432-# rsync isn't available to keep size down
433-# cp --parents isn't in busybox version
434-# hack the directory structure with tar
435-tar cf - -C "${OPENVPN}" "${FILES[@]}" | tar xvf - -C "${TARGET}"
436-
437-mkdir -p "$TARGET/ccd"
438-
439-echo "Created the openvpn configuration for the server: $TARGET"
440diff --git a/bin/ovpn_genconfig b/bin/ovpn_genconfig
441deleted file mode 100755
442index d626deb..0000000
443--- a/bin/ovpn_genconfig
444+++ /dev/null
445@@ -1,275 +0,0 @@
446-#!/bin/bash
447-
448-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
449-
450-#
451-# Generate OpenVPN configs
452-#
453-
454-# Convert 1.2.3.4/24 -> 255.255.255.0
455-cidr2mask()
456-{
457- local i
458- local subnetmask=""
459- local cidr=${1#*/}
460- local full_octets=$(($cidr/8))
461- local partial_octet=$(($cidr%8))
462-
463- for ((i=0;i<4;i+=1)); do
464- if [ $i -lt $full_octets ]; then
465- subnetmask+=255
466- elif [ $i -eq $full_octets ]; then
467- subnetmask+=$((256 - 2**(8-$partial_octet)))
468- else
469- subnetmask+=0
470- fi
471- [ $i -lt 3 ] && subnetmask+=.
472- done
473- echo $subnetmask
474-}
475-
476-# Used often enough to justify a function
477-getroute() {
478- echo ${1%/*} $(cidr2mask $1)
479-}
480-
481-usage() {
482- echo "usage: $0 [-d]"
483- echo " -u SERVER_PUBLIC_URL"
484- echo " [-s SERVER_SUBNET]"
485- echo " [-r ROUTE ...]"
486- echo " [-p PUSH ...]"
487- echo " [-n DNS_SERVER ...]"
488- echo
489- echo "optional arguments:"
490- echo " -d Disable NAT routing and default route"
491- echo " -c Enable client-to-client option"
492- echo " -D Do not push dns servers"
493- echo " -N Configure NAT to access external server network"
494- echo " -m Set client MTU"
495- echo " -t Use TAP device (instead of TUN device)"
496- echo " -T Encrypt packets with the given cipher algorithm instead of the default one (tls-cipher)."
497- echo " -C A list of allowable TLS ciphers delimited by a colon (cipher)."
498- echo " -a Authenticate packets with HMAC using the given message digest algorithm (auth)."
499- echo " -z Enable comp-lzo compression."
500- echo " -2 Enable two factor authentication using Google Authenticator."
501- echo " -f Set the fragment directive."
502- echo " -e Add extra server config"
503-}
504-
505-if [ "$DEBUG" == "1" ]; then
506- set -x
507-fi
508-
509-set -e
510-
511-OVPN_ENV=$OPENVPN/ovpn_env.sh
512-OVPN_SERVER=192.168.255.0/24
513-OVPN_DEFROUTE=1
514-OVPN_NAT=0
515-OVPN_DNS=1
516-OVPN_DEVICE="tun"
517-OVPN_DEVICEN=0
518-OVPN_ROUTES=()
519-TMP_ROUTES=()
520-OVPN_PUSH=()
521-TMP_PUSH=()
522-OVPN_DNS_SERVERS=("8.8.8.8" "8.8.4.4")
523-TMP_DNS_SERVERS=()
524-OVPN_TLS_CIPHER=''
525-OVPN_CIPHER=''
526-OVPN_AUTH=''
527-OVPN_EXTRA_CONFIG=''
528-
529-# Import defaults if present
530-[ -r "$OVPN_ENV" ] && source "$OVPN_ENV"
531-
532-# Parse arguments
533-while getopts ":a:e:C:T:r:s:du:cp:n:DNmf:tz2" opt; do
534- case $opt in
535- a)
536- OVPN_AUTH="$OPTARG"
537- ;;
538- e)
539- OVPN_EXTRA_CONFIG="$OPTARG"
540- ;;
541- C)
542- OVPN_CIPHER="$OPTARG"
543- ;;
544- T)
545- OVPN_TLS_CIPHER="$OPTARG"
546- ;;
547- r)
548- TMP_ROUTES+=("$OPTARG")
549- ;;
550- s)
551- OVPN_SERVER=$OPTARG
552- ;;
553- d)
554- OVPN_DEFROUTE=0
555- ;;
556- u)
557- OVPN_SERVER_URL=$OPTARG
558- ;;
559- c)
560- OVPN_CLIENT_TO_CLIENT=1
561- ;;
562- p)
563- TMP_PUSH+=("$OPTARG")
564- ;;
565- n)
566- TMP_DNS_SERVERS+=("$OPTARG")
567- ;;
568- D)
569- OVPN_DNS=0
570- ;;
571- N)
572- OVPN_NAT=1
573- ;;
574- m)
575- OVPN_MTU=$OPTARG
576- ;;
577- t)
578- OVPN_DEVICE="tap"
579- ;;
580- z)
581- OVPN_COMP_LZO=1
582- ;;
583- 2)
584- OVPN_OTP_AUTH=1
585- ;;
586- f)
587- OVPN_FRAGMENT=$OPTARG
588- ;;
589- \?)
590- set +x
591- echo "Invalid option: -$OPTARG" >&2
592- usage
593- exit 1
594- ;;
595- :)
596- set +x
597- echo "Option -$OPTARG requires an argument." >&2
598- usage
599- exit 1
600- ;;
601- esac
602-done
603-
604-# Create ccd directory for static routes
605-[ ! -d "$OPENVPN/ccd" ] && mkdir -p $OPENVPN/ccd
606-
607-# if new routes were not defined with -r, use default
608-[ ${#TMP_ROUTES[@]} -gt 0 ] && OVPN_ROUTES=("${TMP_ROUTES[@]}")
609-
610-# if new push directives were not defined with -p, use default
611-[ ${#TMP_PUSH[@]} -gt 0 ] && OVPN_PUSH=("${TMP_PUSH[@]}")
612-
613-# if dns servers were not defined with -n, use google nameservers
614-[ ${#TMP_DNS_SERVERS[@]} -gt 0 ] && OVPN_DNS_SERVERS=("${TMP_DNS_SERVERS[@]}")
615-
616-# Server name is in the form "udp://vpn.example.com:1194"
617-if [[ "$OVPN_SERVER_URL" =~ ^((udp|tcp)://)?([0-9a-zA-Z\.\-]+)(:([0-9]+))?$ ]]; then
618- OVPN_PROTO=${BASH_REMATCH[2]};
619- OVPN_CN=${BASH_REMATCH[3]};
620- OVPN_PORT=${BASH_REMATCH[5]};
621-else
622- set +x
623- echo "Common name not specified, see '-u'"
624- usage
625- exit 1
626-fi
627-
628-# Apply defaults
629-[ -z "$OVPN_PROTO" ] && OVPN_PROTO=udp
630-[ -z "$OVPN_PORT" ] && OVPN_PORT=1194
631-[ ${#OVPN_ROUTES[@]} -eq 0 ] && OVPN_ROUTES=("192.168.254.0/24")
632-
633-export OVPN_SERVER OVPN_ROUTES OVPN_DEFROUTE
634-export OVPN_SERVER_URL OVPN_ENV OVPN_PROTO OVPN_CN OVPN_PORT
635-export OVPN_CLIENT_TO_CLIENT OVPN_PUSH OVPN_NAT OVPN_DNS OVPN_MTU OVPN_DEVICE
636-export OVPN_TLS_CIPHER OVPN_CIPHER OVPN_AUTH
637-export OVPN_COMP_LZO
638-export OVPN_OTP_AUTH
639-export OVPN_FRAGMENT
640-
641-# Preserve config
642-if [ -f "$OVPN_ENV" ]; then
643- bak_env=$OVPN_ENV.$(date +%s).bak
644- echo "Backing up $OVPN_ENV -> $bak_env"
645- mv "$OVPN_ENV" "$bak_env"
646-fi
647-export | grep OVPN_ > "$OVPN_ENV"
648-
649-conf=$OPENVPN/openvpn.conf
650-if [ -f "$conf" ]; then
651- bak=$conf.$(date +%s).bak
652- echo "Backing up $conf -> $bak"
653- mv "$conf" "$bak"
654-fi
655-
656-cat > "$conf" <<EOF
657-server $(getroute $OVPN_SERVER)
658-verb 3
659-key $EASYRSA_PKI/private/${OVPN_CN}.key
660-ca $EASYRSA_PKI/ca.crt
661-cert $EASYRSA_PKI/issued/${OVPN_CN}.crt
662-dh $EASYRSA_PKI/dh.pem
663-tls-auth $EASYRSA_PKI/ta.key
664-key-direction 0
665-keepalive 10 60
666-persist-key
667-persist-tun
668-push block-outside-dns
669-
670-proto $OVPN_PROTO
671-port 1194
672-dev $OVPN_DEVICE$OVPN_DEVICEN
673-status $SNAP_DATA/openvpn-status.log
674-EOF
675-
676-[ -n "$OVPN_TLS_CIPHER" ] && echo "tls-cipher $OVPN_TLS_CIPHER" >> "$conf"
677-[ -n "$OVPN_CIPHER" ] && echo "cipher $OVPN_CIPHER" >> "$conf"
678-[ -n "$OVPN_AUTH" ] && echo "auth $OVPN_AUTH" >> "$conf"
679-
680-[ -n "$OVPN_CLIENT_TO_CLIENT" ] && echo "client-to-client" >> "$conf"
681-[ -n "$OVPN_COMP_LZO" ] && echo "comp-lzo" >> "$conf"
682-
683-[ -n "$OVPN_FRAGMENT" ] && echo "fragment $OVPN_FRAGMENT" >> "$conf"
684-
685-[ -n "$OVPN_EXTRA_CONFIG" ] && echo "$OVPN_EXTRA_CONFIG" >> "$conf"
686-
687-[ "$OVPN_DNS" == "1" ] && for i in "${OVPN_DNS_SERVERS[@]}"; do
688- echo "push dhcp-option DNS $i" >> "$conf"
689-done
690-# Append Routes
691-for i in "${OVPN_ROUTES[@]}"; do
692- # If user passed "0" skip this, assume no extra routes
693- [ "$i" = "0" ] && break;
694- echo route $(getroute "$i") >> "$conf"
695-done
696-
697-# Append push commands
698-for i in "${OVPN_PUSH[@]}"; do
699- echo push \"$i\" >> "$conf"
700-done
701-
702-# Optional OTP authentication support
703-if [ -n "$OVPN_OTP_AUTH" ]; then
704- echo -e "\n\n# Enable OTP+PAM for user authentication" >> "$conf"
705- echo "plugin /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so openvpn" >> "$conf"
706-fi
707-
708-set +e
709-
710-# Clean-up duplicate configs
711-if diff -q "$bak_env" "$OVPN_ENV" 2>/dev/null; then
712- echo "Removing duplicate back-up: $bak_env"
713- rm -fv "$bak_env"
714-fi
715-if diff -q "$bak" "$conf" 2>/dev/null; then
716- echo "Removing duplicate back-up: $bak"
717- rm -fv "$bak"
718-fi
719-
720-echo "Successfully generated config"
721diff --git a/bin/ovpn_getclient b/bin/ovpn_getclient
722deleted file mode 100755
723index 2e67da3..0000000
724--- a/bin/ovpn_getclient
725+++ /dev/null
726@@ -1,123 +0,0 @@
727-#!/bin/bash
728-
729-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
730-
731-#
732-# Get an OpenVPN client configuration file
733-#
734-
735-if [ "$DEBUG" == "1" ]; then
736- set -x
737-fi
738-
739-set -e
740-
741-if [ -z "$OPENVPN" ]; then
742- export OPENVPN="$PWD"
743-fi
744-if ! source "$OPENVPN/ovpn_env.sh"; then
745- echo "Could not source $OPENVPN/ovpn_env.sh."
746- exit 1
747-fi
748-if [ -z "$EASYRSA_PKI" ]; then
749- export EASYRSA_PKI="$OPENVPN/pki"
750-fi
751-
752-cn="$1"
753-parm="$2"
754-
755-if [ ! -f "$EASYRSA_PKI/private/${cn}.key" ]; then
756- echo "Unable to find \"${cn}\", please try again or generate the key first" >&2
757- exit 1
758-fi
759-
760-get_client_config() {
761- mode="$1"
762- echo "
763-client
764-nobind
765-dev $OVPN_DEVICE
766-key-direction 1
767-remote-cert-tls server
768-
769-remote $OVPN_CN $OVPN_PORT $OVPN_PROTO
770-"
771- if [ "$mode" == "combined" ]; then
772- echo "
773-<key>
774-$(cat $EASYRSA_PKI/private/${cn}.key)
775-</key>
776-<cert>
777-$(openssl x509 -in $EASYRSA_PKI/issued/${cn}.crt)
778-</cert>
779-<ca>
780-$(cat $EASYRSA_PKI/ca.crt)
781-</ca>
782-<tls-auth>
783-$(cat $EASYRSA_PKI/ta.key)
784-</tls-auth>
785-key-direction 1
786-"
787- elif [ "$mode" == "separated" ]; then
788- echo "
789-key ${cn}.key
790-ca ca.crt
791-cert ${cn}.crt
792-tls-auth ta.key 1
793-$OVPN_ADDITIONAL_CLIENT_CONFIG
794-"
795- fi
796-
797- if [ "$OVPN_DEFROUTE" != "0" ];then
798- echo "redirect-gateway def1"
799- fi
800-
801- if [ -n "$OVPN_MTU" ]; then
802- echo "tun-mtu $OVPN_MTU"
803- fi
804-
805- if [ -n "$OVPN_TLS_CIPHER" ]; then
806- echo "tls-cipher $OVPN_TLS_CIPHER"
807- fi
808-
809- if [ -n "$OVPN_CIPHER" ]; then
810- echo "cipher $OVPN_CIPHER"
811- fi
812-
813- if [ -n "$OVPN_AUTH" ]; then
814- echo "auth $OVPN_AUTH"
815- fi
816-
817- if [ -n "$OVPN_OTP_AUTH" ]; then
818- echo "auth-user-pass"
819- echo "auth-nocache"
820- fi
821-
822- if [ -n "$OVPN_COMP_LZO" ]; then
823- echo "comp-lzo"
824- fi
825-}
826-
827-dir="$OPENVPN/clients/$cn"
828-case "$parm" in
829- "separated")
830- mkdir -p "$dir"
831- get_client_config "$parm" > "$dir/${cn}.ovpn"
832- cp "$EASYRSA_PKI/private/${cn}.key" "$dir/${cn}.key"
833- cp "$EASYRSA_PKI/ca.crt" "$dir/ca.crt"
834- cp "$EASYRSA_PKI/issued/${cn}.crt" "$dir/${cn}.crt"
835- cp "$EASYRSA_PKI/ta.key" "$dir/ta.key"
836- ;;
837- "" | "combined")
838- get_client_config "combined"
839- ;;
840- "combined-save")
841- get_client_config "combined" > "$dir/${cn}-combined.ovpn"
842- ;;
843- *)
844- echo "This script can produce the client configuration in to formats:" >&2
845- 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
846- echo " 2. separated: Separated files." >&2
847- echo "Please specific one of those options as second parameter." >&2
848- ;;
849-esac
850diff --git a/bin/ovpn_getclient_all b/bin/ovpn_getclient_all
851deleted file mode 100755
852index 794fb8a..0000000
853--- a/bin/ovpn_getclient_all
854+++ /dev/null
855@@ -1,27 +0,0 @@
856-#!/bin/bash
857-## @licence MIT <http://opensource.org/licenses/MIT>
858-## @author Copyright (C) 2015 Robin Schneider <ypid@riseup.net>
859-
860-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
861-
862-if [ -z "$OPENVPN" ]; then
863- export OPENVPN="$PWD"
864-fi
865-if ! source "$OPENVPN/ovpn_env.sh"; then
866- echo "Could not source $OPENVPN/ovpn_env.sh."
867- exit 1
868-fi
869-if [ -z "$EASYRSA_PKI" ]; then
870- export EASYRSA_PKI="$OPENVPN/pki"
871-fi
872-
873-pushd "$EASYRSA_PKI"
874-for name in issued/*.crt; do
875- name=${name%.crt}
876- name=${name#issued/}
877- if [ "$name" != "$OVPN_CN" ]; then
878- ovpn_getclient "$name" separated
879- ovpn_getclient "$name" combined-save
880- fi
881-done
882-popd
883diff --git a/bin/ovpn_initpki b/bin/ovpn_initpki
884deleted file mode 100755
885index 124a39f..0000000
886--- a/bin/ovpn_initpki
887+++ /dev/null
888@@ -1,42 +0,0 @@
889-#!/bin/bash
890-
891-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
892-
893-#
894-# Initialize the EasyRSA PKI
895-#
896-
897-if [ "$DEBUG" == "1" ]; then
898- set -x
899-fi
900-
901-set -e
902-
903-source "$OPENVPN/ovpn_env.sh"
904-
905-# Specify "nopass" as arg[2] to make the CA insecure (not recommended!)
906-nopass=$1
907-
908-# Provides a sufficient warning before erasing pre-existing files
909-$EASYRSA_CMD init-pki
910-
911-# CA always has a password for protection in event server is compromised. The
912-# password is only needed to sign client/server certificates. No password is
913-# needed for normal OpenVPN operation.
914-$EASYRSA_CMD build-ca $nopass
915-
916-$EASYRSA_CMD gen-dh
917-$OPENVPN_CMD --genkey --secret $EASYRSA_PKI/ta.key
918-
919-# Was nice to autoset, but probably a bad idea in practice, users should
920-# have to explicitly specify the common name of their server
921-#if [ -z "$cn"]; then
922-# #TODO: Handle IPv6 (when I get a VPS with IPv6)...
923-# ip4=$(dig +short myip.opendns.com @resolver1.opendns.com)
924-# ptr=$(dig +short -x $ip4 | sed -e 's:\.$::')
925-#
926-# [ -n "$ptr" ] && cn=$ptr || cn=$ip4
927-#fi
928-
929-# For a server key with a password, manually init; this is autopilot
930-$EASYRSA_CMD build-server-full "$OVPN_CN" nopass
931diff --git a/bin/ovpn_listclients b/bin/ovpn_listclients
932deleted file mode 100755
933index df51abc..0000000
934--- a/bin/ovpn_listclients
935+++ /dev/null
936@@ -1,47 +0,0 @@
937-#!/bin/bash
938-
939-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
940-
941-if [ -z "$OPENVPN" ]; then
942- export OPENVPN="$PWD"
943-fi
944-if ! source "$OPENVPN/ovpn_env.sh"; then
945- echo "Could not source $OPENVPN/ovpn_env.sh."
946- exit 1
947-fi
948-if [ -z "$EASYRSA_PKI" ]; then
949- export EASYRSA_PKI="$OPENVPN/pki"
950-fi
951-
952-cd "$EASYRSA_PKI"
953-
954-if [ -e crl.pem ]; then
955- cat ca.crt crl.pem > cacheck.pem
956-fi
957-
958-echo "name,begin,end,status"
959-for name in issued/*.crt; do
960- path=$name
961- begin=$(openssl x509 -noout -startdate -in $path | awk -F= '{ print $2 }')
962- end=$(openssl x509 -noout -enddate -in $path | awk -F= '{ print $2 }')
963-
964- name=${name%.crt}
965- name=${name#issued/}
966- if [ "$name" != "$OVPN_CN" ]; then
967- if [ -e crl.pem ]; then
968- if openssl verify -crl_check -CAfile cacheck.pem $path &> /dev/null; then
969- status="VALID"
970- else
971- status="REVOKED"
972- fi
973- else
974- status="VALID"
975- fi
976-
977- echo "$name,$begin,$end,$status"
978- fi
979-done
980-
981-if [ -e crl.pem ]; then
982- rm cacheck.pem
983-fi
984diff --git a/bin/ovpn_otp_user b/bin/ovpn_otp_user
985deleted file mode 100755
986index 8ea2d30..0000000
987--- a/bin/ovpn_otp_user
988+++ /dev/null
989@@ -1,35 +0,0 @@
990-#!/bin/bash
991-
992-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
993-
994-#
995-# Generate OpenVPN users via google authenticator
996-#
997-
998-if ! source "$OPENVPN/ovpn_env.sh"; then
999- echo "Could not source $OPENVPN/ovpn_env.sh."
1000- exit 1
1001-fi
1002-
1003-if [ "x$OVPN_OTP_AUTH" != "x1" ]; then
1004- echo "OTP authentication not enabled, please regenerate configuration using -2 flag"
1005- exit 1
1006-fi
1007-
1008-if [ -z $1 ]; then
1009- echo "Usage: ovpn_otp_user USERNAME"
1010- exit 1
1011-fi
1012-
1013-# Ensure the otp folder is present
1014-[ -d /etc/openvpn/otp ] || mkdir -p /etc/openvpn/otp
1015-
1016-# Binary is present in image, save an $user.google_authenticator file in /etc/openvpn/otp
1017-if [ "$2" == "interactive" ]; then
1018- # Authenticator will ask for other parameters. User can choose rate limit, token reuse policy and time window policy
1019- # Always use time base OTP otherwise storage for counters must be configured somewhere in volume
1020- google-authenticator --time-based --force -l "${1}@${OVPN_CN}" -s /etc/openvpn/otp/${1}.google_authenticator
1021-else
1022- google-authenticator --time-based --disallow-reuse --force --rate-limit=3 --rate-time=30 --window-size=3 \
1023- -l "${1}@${OVPN_CN}" -s /etc/openvpn/otp/${1}.google_authenticator
1024-fi
1025diff --git a/bin/ovpn_run b/bin/ovpn_run
1026deleted file mode 100755
1027index 0fecec3..0000000
1028--- a/bin/ovpn_run
1029+++ /dev/null
1030@@ -1,90 +0,0 @@
1031-#!/bin/bash
1032-
1033-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
1034-
1035-#
1036-# Run the OpenVPN server normally
1037-#
1038-
1039-if [ "$DEBUG" == "1" ]; then
1040- set -x
1041-fi
1042-
1043-set -e
1044-
1045-cd $OPENVPN
1046-
1047-# Build runtime arguments array based on environment
1048-USER_ARGS=("${@}")
1049-ARGS=()
1050-
1051-# Checks if ARGS already contains the given value
1052-function hasArg {
1053- local element
1054- for element in "${@:2}"; do
1055- [ "${element}" == "${1}" ] && return 0
1056- done
1057- return 1
1058-}
1059-
1060-# Adds the given argument if it's not already specified.
1061-function addArg {
1062- local arg="${1}"
1063- [ $# -ge 1 ] && local val="${2}"
1064- if ! hasArg "${arg}" "${USER_ARGS[@]}"; then
1065- ARGS+=("${arg}")
1066- [ $# -ge 1 ] && ARGS+=("${val}")
1067- fi
1068-}
1069-
1070-addArg "--config" "$OPENVPN/openvpn.conf"
1071-
1072-source "$OPENVPN/ovpn_env.sh"
1073-
1074-mkdir -p /dev/net
1075-if [ ! -c /dev/net/tun ]; then
1076- mknod /dev/net/tun c 10 200
1077-fi
1078-
1079-if [ -d "$OPENVPN/ccd" ]; then
1080- addArg "--client-config-dir" "$OPENVPN/ccd"
1081-fi
1082-
1083-# When using --net=host, use this to specify nat device.
1084-[ -z "$OVPN_NATDEVICE" ] && OVPN_NATDEVICE=eth0
1085-
1086-# Setup NAT forwarding if requested
1087-if [ "$OVPN_DEFROUTE" != "0" ] || [ "$OVPN_NAT" == "1" ] ; then
1088- $IPTABLES -t nat -C POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE || {
1089- $IPTABLES -t nat -A POSTROUTING -s $OVPN_SERVER -o $OVPN_NATDEVICE -j MASQUERADE
1090- }
1091- for i in "${OVPN_ROUTES[@]}"; do
1092- $IPTABLES -t nat -C POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE || {
1093- $IPTABLES -t nat -A POSTROUTING -s "$i" -o $OVPN_NATDEVICE -j MASQUERADE
1094- }
1095- done
1096-fi
1097-
1098-# Use a hacky hardlink as the CRL Needs to be readable by the user/group
1099-# OpenVPN is running as. Only pass arguments to OpenVPN if it's found.
1100-if [ -r "$EASYRSA_PKI/crl.pem" ]; then
1101- if [ ! -r "$OPENVPN/crl.pem" ]; then
1102- ln "$EASYRSA_PKI/crl.pem" "$OPENVPN/crl.pem"
1103- chmod 644 "$OPENVPN/crl.pem"
1104- fi
1105- addArg "--crl-verify" "$OPENVPN/crl.pem"
1106-fi
1107-
1108-ip -6 route show default 2>/dev/null
1109-if [ $? = 0 ]; then
1110- echo "Enabling IPv6 Forwarding"
1111- # If this fails, ensure the docker container is run with --privileged
1112- # Could be side stepped with `ip netns` madness to drop privileged flag
1113-
1114- sysctl -w net.ipv6.conf.default.forwarding=1 || echo "Failed to enable IPv6 Forwarding default"
1115- sysctl -w net.ipv6.conf.all.forwarding=1 || echo "Failed to enable IPv6 Forwarding"
1116-fi
1117-
1118-echo "Running 'openvpn ${ARGS[@]} ${USER_ARGS[@]}'"
1119-exec $OPENVPN_CMD ${ARGS[@]} ${USER_ARGS[@]}
1120-
1121diff --git a/bin/ovpn_setup b/bin/ovpn_setup
1122index 7ef3dc3..0bc1275 100755
1123--- a/bin/ovpn_setup
1124+++ b/bin/ovpn_setup
1125@@ -1,6 +1,20 @@
1126 #!/bin/bash
1127+#
1128+# Copyright (C) 2016-2017 Canonical Ltd
1129+#
1130+# This program is free software: you can redistribute it and/or modify
1131+# it under the terms of the GNU General Public License version 3 as
1132+# published by the Free Software Foundation.
1133+#
1134+# This program is distributed in the hope that it will be useful,
1135+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1136+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1137+# GNU General Public License for more details.
1138+#
1139+# You should have received a copy of the GNU General Public License
1140+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1141
1142-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
1143+source ${SNAP_DATA}/easy-openvpn.profile
1144
1145 if [ "$DEBUG" == "1" ]; then
1146 set -x
1147diff --git a/bin/ovpn_status b/bin/ovpn_status
1148deleted file mode 100755
1149index 3af312e..0000000
1150--- a/bin/ovpn_status
1151+++ /dev/null
1152@@ -1,14 +0,0 @@
1153-#!/bin/bash
1154-
1155-source $(cd $(dirname "$0"); pwd)/easy-openvpn.profile
1156-
1157-#
1158-# Get OpenVPN server status
1159-#
1160-if [ "$DEBUG" == "1" ]; then
1161- set -x
1162-fi
1163-
1164-set -e
1165-
1166-tail -F $SNAP_DATA/openvpn-status.log
1167diff --git a/patches/0001-Enable-docker-openvpn-working-in-snappy-world.patch b/patches/0001-Enable-docker-openvpn-working-in-snappy-world.patch
1168new file mode 100644
1169index 0000000..6924ac6
1170--- /dev/null
1171+++ b/patches/0001-Enable-docker-openvpn-working-in-snappy-world.patch
1172@@ -0,0 +1,179 @@
1173+From 5ca0a46e00b5fecff135b3b5d024d721c94a79fd Mon Sep 17 00:00:00 2001
1174+From: gary-wzl77 <gary.wang@canonical.com>
1175+Date: Tue, 29 Aug 2017 16:43:20 +0800
1176+Subject: [PATCH] Enable docker-openvpn working in snappy world.
1177+
1178+*. Read global env variables.
1179+*. Disable user and group settings in config file.
1180+
1181+Signed-off-by: gary-wzl77 <gary.wang@canonical.com>
1182+---
1183+ bin/easyrsa_vars | 2 ++
1184+ bin/ovpn_copy_server_files | 2 ++
1185+ bin/ovpn_genconfig | 5 ++---
1186+ bin/ovpn_getclient | 2 ++
1187+ bin/ovpn_getclient_all | 2 ++
1188+ bin/ovpn_initpki | 4 +++-
1189+ bin/ovpn_listclients | 2 ++
1190+ bin/ovpn_otp_user | 2 ++
1191+ bin/ovpn_revokeclient | 2 ++
1192+ bin/ovpn_run | 2 ++
1193+ bin/ovpn_status | 4 +++-
1194+ 11 files changed, 24 insertions(+), 5 deletions(-)
1195+
1196+diff --git a/bin/easyrsa_vars b/bin/easyrsa_vars
1197+index e2fb56f..38fde48 100755
1198+--- a/bin/easyrsa_vars
1199++++ b/bin/easyrsa_vars
1200+@@ -1,5 +1,7 @@
1201+ #!/bin/sh
1202+
1203++source $SNAP_DATA/easy-openvpn.profile
1204++
1205+ #
1206+ # Import/export EasyRSA default settings
1207+ #
1208+diff --git a/bin/ovpn_copy_server_files b/bin/ovpn_copy_server_files
1209+index b99f54c..c8b7347 100755
1210+--- a/bin/ovpn_copy_server_files
1211++++ b/bin/ovpn_copy_server_files
1212+@@ -2,6 +2,8 @@
1213+ ## @licence MIT <http://opensource.org/licenses/MIT>
1214+ ## @author Copyright (C) 2015 Robin Schneider <ypid@riseup.net>
1215+
1216++source $SNAP_DATA/easy-openvpn.profile
1217++
1218+ set -e
1219+
1220+ if [ -z "$OPENVPN" ]; then
1221+diff --git a/bin/ovpn_genconfig b/bin/ovpn_genconfig
1222+index b965f12..825d514 100755
1223+--- a/bin/ovpn_genconfig
1224++++ b/bin/ovpn_genconfig
1225+@@ -1,5 +1,7 @@
1226+ #!/bin/bash
1227+
1228++source $SNAP_DATA/easy-openvpn.profile
1229++
1230+ #
1231+ # Generate OpenVPN configs
1232+ #
1233+@@ -335,9 +337,6 @@ proto $OVPN_PROTO
1234+ port 1194
1235+ dev $OVPN_DEVICE$OVPN_DEVICEN
1236+ status /tmp/openvpn-status.log
1237+-
1238+-user nobody
1239+-group nogroup
1240+ EOF
1241+
1242+ if [ "${OVPN_DISABLE_PUSH_BLOCK_DNS}" == "1" ]; then
1243+diff --git a/bin/ovpn_getclient b/bin/ovpn_getclient
1244+index 9619e25..820081a 100755
1245+--- a/bin/ovpn_getclient
1246++++ b/bin/ovpn_getclient
1247+@@ -1,5 +1,7 @@
1248+ #!/bin/bash
1249+
1250++source $SNAP_DATA/easy-openvpn.profile
1251++
1252+ #
1253+ # Get an OpenVPN client configuration file
1254+ #
1255+diff --git a/bin/ovpn_getclient_all b/bin/ovpn_getclient_all
1256+index f760495..9c9b958 100755
1257+--- a/bin/ovpn_getclient_all
1258++++ b/bin/ovpn_getclient_all
1259+@@ -2,6 +2,8 @@
1260+ ## @licence MIT <http://opensource.org/licenses/MIT>
1261+ ## @author Copyright (C) 2015 Robin Schneider <ypid@riseup.net>
1262+
1263++source $SNAP_DATA/easy-openvpn.profile
1264++
1265+ if [ -z "$OPENVPN" ]; then
1266+ export OPENVPN="$PWD"
1267+ fi
1268+diff --git a/bin/ovpn_initpki b/bin/ovpn_initpki
1269+index 14b8ec9..cf3e8ae 100755
1270+--- a/bin/ovpn_initpki
1271++++ b/bin/ovpn_initpki
1272+@@ -1,5 +1,7 @@
1273+ #!/bin/bash
1274+
1275++source $SNAP_DATA/easy-openvpn.profile
1276++
1277+ #
1278+ # Initialize the EasyRSA PKI
1279+ #
1280+@@ -13,7 +15,7 @@ set -e
1281+ source "$OPENVPN/ovpn_env.sh"
1282+
1283+ # Specify "nopass" as arg[2] to make the CA insecure (not recommended!)
1284+-nopass=$1
1285++# nopass=$1
1286+
1287+ # Provides a sufficient warning before erasing pre-existing files
1288+ easyrsa init-pki
1289+diff --git a/bin/ovpn_listclients b/bin/ovpn_listclients
1290+index 120ab50..2a6b4f4 100755
1291+--- a/bin/ovpn_listclients
1292++++ b/bin/ovpn_listclients
1293+@@ -1,5 +1,7 @@
1294+ #!/bin/bash
1295+
1296++source $SNAP_DATA/easy-openvpn.profile
1297++
1298+ if [ -z "$OPENVPN" ]; then
1299+ export OPENVPN="$PWD"
1300+ fi
1301+diff --git a/bin/ovpn_otp_user b/bin/ovpn_otp_user
1302+index 7af9c1e..d81887e 100755
1303+--- a/bin/ovpn_otp_user
1304++++ b/bin/ovpn_otp_user
1305+@@ -1,5 +1,7 @@
1306+ #!/bin/bash
1307+
1308++source $SNAP_DATA/easy-openvpn.profile
1309++
1310+ #
1311+ # Generate OpenVPN users via google authenticator
1312+ #
1313+diff --git a/bin/ovpn_revokeclient b/bin/ovpn_revokeclient
1314+index c1c175f..b656d19 100755
1315+--- a/bin/ovpn_revokeclient
1316++++ b/bin/ovpn_revokeclient
1317+@@ -1,5 +1,7 @@
1318+ #!/bin/bash
1319+
1320++source $SNAP_DATA/easy-openvpn.profile
1321++
1322+ #
1323+ # Revoke a client certificate
1324+ #
1325+diff --git a/bin/ovpn_run b/bin/ovpn_run
1326+index 9e9f3d5..1354210 100755
1327+--- a/bin/ovpn_run
1328++++ b/bin/ovpn_run
1329+@@ -1,5 +1,7 @@
1330+ #!/bin/bash
1331+
1332++source $SNAP_DATA/easy-openvpn.profile
1333++
1334+ #
1335+ # Run the OpenVPN server normally
1336+ #
1337+diff --git a/bin/ovpn_status b/bin/ovpn_status
1338+index 56260fb..2040865 100755
1339+--- a/bin/ovpn_status
1340++++ b/bin/ovpn_status
1341+@@ -1,4 +1,6 @@
1342+-#!/bin/sh
1343++#!/bin/bash
1344++
1345++source $SNAP_DATA/easy-openvpn.profile
1346+
1347+ #
1348+ # Get OpenVPN server status
1349+--
1350+2.7.4
1351+
1352diff --git a/run-tests.sh b/run-tests.sh
1353new file mode 100755
1354index 0000000..4f18f03
1355--- /dev/null
1356+++ b/run-tests.sh
1357@@ -0,0 +1,70 @@
1358+#!/bin/sh
1359+#
1360+# Copyright (C) 2016 Canonical Ltd
1361+#
1362+# This program is free software: you can redistribute it and/or modify
1363+# it under the terms of the GNU General Public License version 3 as
1364+# published by the Free Software Foundation.
1365+#
1366+# This program is distributed in the hope that it will be useful,
1367+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1368+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1369+# GNU General Public License for more details.
1370+#
1371+# You should have received a copy of the GNU General Public License
1372+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1373+
1374+set -e
1375+
1376+TESTS_EXTRAS_URL="https://git.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/tests-extras"
1377+TESTS_EXTRAS_PATH=".tests-extras"
1378+
1379+show_help() {
1380+ exec cat <<'EOF'
1381+Usage: run-tests.sh [OPTIONS]
1382+
1383+This is fetch & forget script and what it does is to fetch the
1384+tests-extras repository and execute the run-tests.sh script from
1385+there passing arguments as-is.
1386+
1387+When you see this message you don't have the tests-extras repository
1388+successfully populated in your workspace yet. Please rerun without
1389+specifying --help to proceed with the initial clone of the git repository.
1390+EOF
1391+}
1392+
1393+# Clone the tests-extras repository
1394+clone_tests_extras() {
1395+ echo "INFO: Fetching tests-extras scripts into $TESTS_EXTRAS_PATH ..."
1396+ git clone -b master $TESTS_EXTRAS_URL $TESTS_EXTRAS_PATH >/dev/null 2>&1
1397+ if [ $? -ne 0 ]; then
1398+ echo "ERROR: Failed to fetch the $TESTS_EXTRAS_URL repo, exiting.."
1399+ exit 1
1400+ fi
1401+}
1402+
1403+# Make sure the already cloned tests-extras repository is in a known and update
1404+# state before it is going to be used.
1405+restore_and_update_tests_extras() {
1406+ echo "INFO: Restoring and updating $TESTS_EXTRAS_PATH"
1407+ cd $TESTS_EXTRAS_PATH && git reset --hard && git clean -dfx && git pull
1408+ cd -
1409+}
1410+
1411+# ==============================================================================
1412+# This is fetch & forget script and what it does is to fetch the tests-extras
1413+# repo and execute the run-tests.sh script from there passing arguments as-is.
1414+#
1415+# The tests-extras repository ends up checked out in the snap tree but as a
1416+# hidden directory which is re-used since then.
1417+
1418+[ ! -d "$TESTS_EXTRAS_PATH" ] && [ "$1" = "--help" ] && show_help
1419+
1420+if [ -d "$TESTS_EXTRAS_PATH" ]; then
1421+ restore_and_update_tests_extras
1422+else
1423+ clone_tests_extras
1424+fi
1425+
1426+echo "INFO: Executing tests runner"
1427+cd $TESTS_EXTRAS_PATH && ./tests-runner.sh "$@"
1428diff --git a/snapcraft.yaml b/snapcraft.yaml
1429index be5273d..680dca7 100644
1430--- a/snapcraft.yaml
1431+++ b/snapcraft.yaml
1432@@ -1,10 +1,13 @@
1433 name: easy-openvpn
1434-version: 2.3.10-1
1435+version: 2.3.10-2
1436 summary: An easy-to-manage OpenVPN deployment.
1437 description: |
1438 OpenVPN snap with management scripts that simplify PKI and client
1439 management for fast, cheap and disposable VPNs. Based on
1440 https://github.com/kylemanna/docker-openvpn.
1441+ It is an open source project distributed under MIT License.
1442+ See the project homepage for more details:
1443+ https://code.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/easy-openvpn
1444 confinement: strict
1445 grade: stable
1446
1447@@ -23,18 +26,56 @@ apps:
1448 command: bin/ovpn_listclients
1449 add-client:
1450 command: bin/ovpn_addclient
1451+ revoke-client:
1452+ command: bin/ovpn_revokeclient
1453 show-client:
1454 command: bin/ovpn_getclient
1455+ connect-server:
1456+ command: openvpn --config
1457+ plugs:
1458+ - home
1459+ - network-control
1460 status:
1461 command: bin/ovpn_status
1462+ help:
1463+ command: bin/help
1464
1465 parts:
1466 packages:
1467 plugin: nil
1468 stage-packages:
1469 - openvpn
1470- - openssl
1471 - iptables
1472+ openvpn-utils:
1473+ plugin: dump
1474+ source: https://git.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/easy-openvpn
1475+ prepare: git apply $SNAPCRAFT_STAGE/0001-Enable-docker-openvpn-working-in-snappy-world.patch
1476+ source-type: git
1477+ source-branch: docker-openvpn/latest
1478+ filesets:
1479+ exclude:
1480+ - -docs
1481+ - -init
1482+ - -otp
1483+ - -test
1484+ - -.gitignore
1485+ - -.travis.yml
1486+ - -CONTRIBUTING.md
1487+ - -Dockerfile
1488+ - -Dockerfile.aarch64
1489+ - -README.md
1490+ - -alpine
1491+ stage:
1492+ - $exclude
1493+ prime:
1494+ - $exclude
1495+ after:
1496+ - patch
1497+ patch:
1498+ source: patches
1499+ plugin: dump
1500+ prime:
1501+ - -*
1502 easyrsa:
1503 plugin: dump
1504 source: https://github.com/OpenVPN/easy-rsa/releases/download/3.0.1/EasyRSA-3.0.1.tgz
1505@@ -42,10 +83,17 @@ parts:
1506 easyrsa: usr/local/easyrsa/easyrsa
1507 openssl-1.0.cnf: usr/local/easyrsa/openssl-1.0.cnf
1508 x509-types: usr/local/easyrsa/x509-types
1509- snap:
1510+ prime:
1511 - usr/local/easyrsa
1512 scripts:
1513 plugin: dump
1514 source: .
1515- snap:
1516- - bin/*
1517+ organize:
1518+ "bin/configure": meta/hooks/configure
1519+ prime:
1520+ - -patches
1521+ - -README.md
1522+ - -spread.yaml
1523+ - -run-tests.sh
1524+ - -spread
1525+
1526diff --git a/spread.yaml b/spread.yaml
1527new file mode 100644
1528index 0000000..480f0a9
1529--- /dev/null
1530+++ b/spread.yaml
1531@@ -0,0 +1,50 @@
1532+#
1533+# Copyright (C) 2017 Canonical Ltd
1534+#
1535+# This program is free software: you can redistribute it and/or modify
1536+# it under the terms of the GNU General Public License version 3 as
1537+# published by the Free Software Foundation.
1538+#
1539+# This program is distributed in the hope that it will be useful,
1540+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1541+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1542+# GNU General Public License for more details.
1543+#
1544+# You should have received a copy of the GNU General Public License
1545+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1546+
1547+
1548+project: easy-openvpn
1549+
1550+environment:
1551+ PROJECT_PATH: /home/easy-openvpn
1552+ TESTSLIB: $PROJECT_PATH/spread/lib
1553+ SNAP_NAME: easy-openvpn
1554+ # Allow the host to pass the channel to use for the test run
1555+ SNAP_CHANNEL: $(HOST:echo $SNAP_CHANNEL)
1556+
1557+backends:
1558+ qemu:
1559+ systems:
1560+ - ubuntu-core-16:
1561+ username: test
1562+ password: test
1563+
1564+# Put this somewhere where we have read-write access
1565+path: /home/easy-openvpn
1566+
1567+exclude:
1568+ - .git
1569+
1570+prepare: |
1571+ . $TESTSLIB/prepare-all.sh
1572+
1573+suites:
1574+ spread/main/:
1575+ summary: Full-system tests for OpenVPN running with tun mode.
1576+ systems:
1577+ - ubuntu-core-16
1578+ prepare: |
1579+ . $TESTSLIB/prepare.sh
1580+ restore-each: |
1581+ . $TESTSLIB/restore-each.sh
1582diff --git a/spread/lib/prepare-all.sh b/spread/lib/prepare-all.sh
1583new file mode 100644
1584index 0000000..8938c7a
1585--- /dev/null
1586+++ b/spread/lib/prepare-all.sh
1587@@ -0,0 +1,16 @@
1588+#!/bin/bash
1589+
1590+# We don't have to build a snap when we should use one from a
1591+# channel
1592+if [ -n "$SNAP_CHANNEL" ] ; then
1593+ exit 0
1594+fi
1595+
1596+# If there is a easy-openvpn snap prebuilt for us, lets take
1597+# that one to speed things up.
1598+if [ -e /home/easy-openvpn/easy-openvpn_*_amd64.snap ] ; then
1599+ exit 0
1600+fi
1601+
1602+echo "Not trying to build easy-openvpn on the test target: provide a pre-built snap"
1603+test -e /home/easy-openvpn/easy-openvpn_*_amd64.snap
1604diff --git a/spread/lib/prepare.sh b/spread/lib/prepare.sh
1605new file mode 100644
1606index 0000000..d75086f
1607--- /dev/null
1608+++ b/spread/lib/prepare.sh
1609@@ -0,0 +1,64 @@
1610+#!/bin/bash
1611+
1612+echo "Wait for firstboot change to be ready"
1613+while ! snap changes | grep -q "Done"; do
1614+ snap changes || true
1615+ snap change 1 || true
1616+ sleep 1
1617+done
1618+
1619+echo "Ensure fundamental snaps are still present"
1620+. $TESTSLIB/snap-names.sh
1621+for name in $gadget_name $kernel_name $core_name; do
1622+ if ! snap list | grep -q $name ; then
1623+ echo "Not all fundamental snaps are available, all-snap image not valid"
1624+ echo "Currently installed snaps:"
1625+ snap list
1626+ exit 1
1627+ fi
1628+done
1629+
1630+echo "Kernel has a store revision"
1631+snap list | grep ^${kernel_name} | grep -E " [0-9]+\s+canonical"
1632+
1633+# Pre-install easy-openvpn
1634+if [ -n "$SNAP_CHANNEL" ] ; then
1635+ # Don't reinstall if we have it installed already
1636+ if ! snap list | grep easy-openvpn ; then
1637+ snap install --$SNAP_CHANNEL easy-openvpn
1638+ snap connect easy-openvpn:network-control :network-control
1639+ snap connect easy-openvpn:firewall-control :firewall-control
1640+ snap connect easy-openvpn:home :home
1641+ fi
1642+else
1643+ # Install prebuilt easy-openvpn snap
1644+ snap install --dangerous /home/easy-openvpn/easy-openvpn_*_amd64.snap
1645+ # As we have a snap which we build locally its unasserted and therefor
1646+ # we don't have any snap-declarations in place and need to manually
1647+ # connect all plugs.
1648+ snap connect easy-openvpn:network-control :network-control
1649+ snap connect easy-openvpn:firewall-control :firewall-control
1650+ snap connect easy-openvpn:home :home
1651+fi
1652+
1653+# Remove any existing state archive from other test suites
1654+rm -f $SPREAD_PATH/snapd-state.tar.gz
1655+rm -f $SPREAD_PATH/easy-openvpn-state.tar.gz
1656+
1657+# Snapshot of the current snapd state for a later restore
1658+if [ ! -f $SPREAD_PATH/snapd-state.tar.gz ] ; then
1659+ sudo systemctl stop snapd.service snapd.socket
1660+ tar czfP $SPREAD_PATH/snapd-state.tar.gz /var/lib/snapd
1661+ sudo systemctl start snapd.socket
1662+fi
1663+
1664+# And also snapshot current easy-openvpn's state
1665+if [ ! -f $SPREAD_PATH/easy-openvpn-state.tar.gz ] ; then
1666+ sudo systemctl stop snap.easy-openvpn.easy-openvpn
1667+ tar czfP $SPREAD_PATH/easy-openvpn-state.tar.gz /var/snap/easy-openvpn
1668+ sudo systemctl start snap.easy-openvpn.easy-openvpn
1669+fi
1670+
1671+# For debugging dump all snaps and connected slots/plugs
1672+snap list
1673+snap interfaces
1674diff --git a/spread/lib/restore-each.sh b/spread/lib/restore-each.sh
1675new file mode 100644
1676index 0000000..6cd72b0
1677--- /dev/null
1678+++ b/spread/lib/restore-each.sh
1679@@ -0,0 +1,33 @@
1680+#!/bin/bash
1681+
1682+. $TESTSLIB/snap-names.sh
1683+. $TESTSLIB/utilities.sh
1684+
1685+# Remove all snaps not being the core, gadget, kernel or snap we're testing
1686+for snap in /snap/*; do
1687+ snap="${snap:6}"
1688+ case "$snap" in
1689+ "bin" | "$gadget_name" | "$kernel_name" | "$core_name" | "$SNAP_NAME" )
1690+ ;;
1691+ *)
1692+ snap remove "$snap"
1693+ ;;
1694+ esac
1695+done
1696+
1697+# Ensure we have the same state for snapd as we had before
1698+sudo systemctl stop snapd.service snapd.socket
1699+rm -rf /var/lib/snapd/*
1700+ls -al $SPREAD_PATH/snapd-state.tar.gz
1701+tar xzf $SPREAD_PATH/snapd-state.tar.gz -C /
1702+rm -rf /root/.snap
1703+sudo systemctl start snapd.service snapd.socket
1704+wait_for_systemd_service snapd.service
1705+wait_for_systemd_service snapd.socket
1706+
1707+# Ensure we have the same state for openvpn as we had before
1708+sudo systemctl stop snap.easy-openvpn.easy-openvpn
1709+ls -al /home/easy-openvpn
1710+rm -rf /var/snap/easy-openvpn/*
1711+ls -al $SPREAD_PATH/easy-openvpn-state.tar.gz
1712+tar xzf $SPREAD_PATH/easy-openvpn-state.tar.gz -C /
1713diff --git a/spread/lib/snap-names.sh b/spread/lib/snap-names.sh
1714new file mode 100644
1715index 0000000..f15b09a
1716--- /dev/null
1717+++ b/spread/lib/snap-names.sh
1718@@ -0,0 +1,7 @@
1719+#!/bin/bash
1720+gadget_name=$(snap list | sed -n 's/^\(pc\|pi[23]\|dragonboard\) .*/\1/p')
1721+kernel_name=$gadget_name-kernel
1722+core_name=$(snap list | awk '/^(ubuntu-)?core / {print $1; exit}')
1723+if [ "$kernel_name" = "pi3-kernel" ] ; then
1724+ kernel_name=pi2-kernel
1725+fi
1726diff --git a/spread/lib/utilities.sh b/spread/lib/utilities.sh
1727new file mode 100644
1728index 0000000..82a0e76
1729--- /dev/null
1730+++ b/spread/lib/utilities.sh
1731@@ -0,0 +1,12 @@
1732+#!/bin/bash
1733+
1734+SERVICE_UNIT="snap.easy-openvpn.easy-openvpn"
1735+
1736+SERVER_IP=$(hostname -I | cut -f1 -d' ')
1737+
1738+wait_for_systemd_service() {
1739+ while ! systemctl status $1 ; do
1740+ sleep 1
1741+ done
1742+ sleep 1
1743+}
1744diff --git a/spread/main/add_client/task.yaml b/spread/main/add_client/task.yaml
1745new file mode 100644
1746index 0000000..1d0b480
1747--- /dev/null
1748+++ b/spread/main/add_client/task.yaml
1749@@ -0,0 +1,24 @@
1750+summary: Test add a client configuration.
1751+
1752+execute: |
1753+ . $TESTSLIB/utilities.sh
1754+
1755+ # so enable to setup server in non-interactive mode
1756+ sudo snap set easy-openvpn nopasswd=1
1757+
1758+ # setup openvpn server
1759+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1760+
1761+ # add a client
1762+ sudo easy-openvpn.add-client foo > foo.ovpn
1763+
1764+ # check if foo exists in the client list
1765+ client_name=$(sudo easy-openvpn.clients | awk -F',' '{if(NR>1)print $1}')
1766+ [ "${client_name}" = foo ] || exit 1
1767+
1768+ # test client config
1769+ sudo easy-openvpn.show-client foo > tmp.ovpn
1770+ ! cmp --silent foo.ovpn tmp.ovpn
1771+
1772+ # test duplicated client
1773+ sudo easy-openvpn.add-client foo > foo.ovpn && exit 1 || exit 0
1774diff --git a/spread/main/connect_server/task.yaml b/spread/main/connect_server/task.yaml
1775new file mode 100644
1776index 0000000..d1a34ec
1777--- /dev/null
1778+++ b/spread/main/connect_server/task.yaml
1779@@ -0,0 +1,31 @@
1780+summary: Test connect openvpn server.
1781+
1782+execute: |
1783+ . $TESTSLIB/utilities.sh
1784+ # so enable to setup server in non-interactive mode
1785+ sudo snap set easy-openvpn nopasswd=1
1786+
1787+ # setup openvpn server
1788+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1789+
1790+ # launch openvpn server
1791+ sudo service ${SERVICE_UNIT} start
1792+
1793+ # wait openvpn server to launch
1794+ wait_for_systemd_service ${SERVICE_UNIT}
1795+ sudo journalctl -n 10 --no-pager -u ${SERVICE_UNIT} | MATCH 'Initialization Sequence Completed'
1796+
1797+ # add a client
1798+ sudo easy-openvpn.add-client foo > foo.ovpn
1799+
1800+ # change foo.ovpn owner to avoid dac_override denied in snappy world.
1801+ # Note the denial is an expected behavior. For more, please check this out.
1802+ # https://forum.snapcraft.io/t/docker-load-fails-with-permission-denied/1227/3
1803+ sudo chown root.root foo.ovpn
1804+
1805+ # run openvpn client as daemon to connect server
1806+ sudo easy-openvpn.connect-server foo.ovpn --daemon
1807+
1808+ # wait bit for client to initialize
1809+ sleep 10
1810+ sudo tail -n 10 /var/log/syslog | MATCH 'localhost openvpn.* Initialization Sequence Completed'
1811diff --git a/spread/main/hooks/task.yaml b/spread/main/hooks/task.yaml
1812new file mode 100644
1813index 0000000..53c3fe1
1814--- /dev/null
1815+++ b/spread/main/hooks/task.yaml
1816@@ -0,0 +1,13 @@
1817+summary: Test configure hooks.
1818+
1819+execute: |
1820+ sudo easy-openvpn.help | MATCH ".*'debug', using default value: '0'"
1821+ sudo easy-openvpn.help | MATCH "'nopasswd', using default value: '0'"
1822+
1823+ # set 'debug' to 1 and check the value in help command
1824+ sudo snap set easy-openvpn debug=1
1825+ sudo easy-openvpn.help | MATCH "'debug' current value set to: '1'.*"
1826+
1827+ # set 'nopasswd' to 1 and check the value in help command
1828+ sudo snap set easy-openvpn nopasswd=1
1829+ sudo easy-openvpn.help | MATCH "'nopasswd' current value set to: '1'.*"
1830diff --git a/spread/main/installation/task.yaml b/spread/main/installation/task.yaml
1831new file mode 100644
1832index 0000000..9193e8a
1833--- /dev/null
1834+++ b/spread/main/installation/task.yaml
1835@@ -0,0 +1,8 @@
1836+summary: Test all necessary plugs/slots are connected upon installation
1837+
1838+execute: |
1839+ snap interfaces | MATCH ":network +[a-z,-]*easy-openvpn"
1840+ snap interfaces | MATCH ":network-bind +[a-z,-]*easy-openvpn"
1841+ snap interfaces | MATCH ":network-control +[a-z,-]*easy-openvpn"
1842+ snap interfaces | MATCH ":firewall-control +[a-z,-]*easy-openvpn"
1843+ snap interfaces | MATCH ":home +[a-z,-]*easy-openvpn"
1844diff --git a/spread/main/launch_server/task.yaml b/spread/main/launch_server/task.yaml
1845new file mode 100644
1846index 0000000..9d04aa5
1847--- /dev/null
1848+++ b/spread/main/launch_server/task.yaml
1849@@ -0,0 +1,16 @@
1850+summary: Test launch openvpn server.
1851+
1852+execute: |
1853+ . $TESTSLIB/utilities.sh
1854+ # so enable to setup server in non-interactive mode
1855+ sudo snap set easy-openvpn nopasswd=1
1856+
1857+ # setup openvpn server
1858+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1859+
1860+ # launch openvpn server
1861+ sudo service ${SERVICE_UNIT} start
1862+
1863+ # wait openvpn server to launch
1864+ wait_for_systemd_service ${SERVICE_UNIT}
1865+ sudo journalctl -n 10 --no-pager -u ${SERVICE_UNIT} | MATCH 'Initialization Sequence Completed'
1866diff --git a/spread/main/monitor_status/task.yaml b/spread/main/monitor_status/task.yaml
1867new file mode 100644
1868index 0000000..d73a647
1869--- /dev/null
1870+++ b/spread/main/monitor_status/task.yaml
1871@@ -0,0 +1,43 @@
1872+summary: Test monitor check connection status.
1873+
1874+execute: |
1875+ . $TESTSLIB/utilities.sh
1876+ # so enable to setup server in non-interactive mode
1877+ sudo snap set easy-openvpn nopasswd=1
1878+
1879+ # setup openvpn server
1880+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1881+
1882+ # launch openvpn server
1883+ sudo service ${SERVICE_UNIT} start
1884+
1885+ # wait openvpn server to launch
1886+ wait_for_systemd_service ${SERVICE_UNIT}
1887+ sudo journalctl -n 10 --no-pager -u ${SERVICE_UNIT} | MATCH 'Initialization Sequence Completed'
1888+
1889+ # add a client
1890+ sudo easy-openvpn.add-client foo > foo.ovpn
1891+
1892+ # change foo.ovpn owner to avoid dac_override denied in snappy world.
1893+ sudo chown root.root foo.ovpn
1894+
1895+ # run openvpn client as daemon to connect server
1896+ sudo easy-openvpn.connect-server foo.ovpn --daemon
1897+
1898+ # check currrent client connection status
1899+ # status command is 'tail -F'running under the hood which output appended data as the file grows
1900+ # on the other hand, there's a delay on openvpn client connections detection even if client is connected.
1901+ # so we wait a reasonable amount of time and ran status command with no hang up.
1902+ sleep 90
1903+ sudo nohup easy-openvpn.status &>status_log &
1904+
1905+ sleep 1
1906+ cat status_log
1907+ client_info=$(sed '/^Common/,/^ROUTING/{//!b};d;//d' status_log)
1908+ echo $client_info
1909+ name=$(echo "${client_info}" | awk -F',' '{print $1}')
1910+ rx=$(echo "${client_info}" | awk -F',' '{print $3}')
1911+ tx=$(echo "${client_info}" | awk -F',' '{print $4}')
1912+ [ "${name}" = "foo" ] || exit 1
1913+ [ "${rx}" -gt "0" ] || exit 1
1914+ [ "${tx}" -gt "0" ] || exit 1
1915diff --git a/spread/main/revoke_after_connection/task.yaml b/spread/main/revoke_after_connection/task.yaml
1916new file mode 100644
1917index 0000000..3272fa9
1918--- /dev/null
1919+++ b/spread/main/revoke_after_connection/task.yaml
1920@@ -0,0 +1,51 @@
1921+summary: Test revoke a client after connection.
1922+
1923+execute: |
1924+ . $TESTSLIB/utilities.sh
1925+ # so enable to setup server in non-interactive mode
1926+ sudo snap set easy-openvpn nopasswd=1
1927+
1928+ # setup openvpn server
1929+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1930+
1931+ # launch openvpn server
1932+ sudo service ${SERVICE_UNIT} start
1933+
1934+ # wait openvpn server to launch
1935+ wait_for_systemd_service ${SERVICE_UNIT}
1936+ sudo journalctl -n 10 --no-pager -u ${SERVICE_UNIT} | MATCH 'Initialization Sequence Completed'
1937+
1938+ # add a client
1939+ sudo easy-openvpn.add-client foo > foo.ovpn
1940+
1941+ # check if foo exists in the client list
1942+ sudo easy-openvpn.clients | MATCH "foo.*VALID"
1943+
1944+ # change foo.ovpn owner to avoid dac_override denied in snappy world.
1945+ sudo chown root.root foo.ovpn
1946+
1947+ # run openvpn client as daemon to connect server
1948+ sudo easy-openvpn.connect-server foo.ovpn --daemon
1949+
1950+ # wait bit for client to initialize
1951+ sleep 10
1952+ sudo tail -n 10 /var/log/syslog | MATCH 'localhost openvpn.* Initialization Sequence Completed'
1953+
1954+ # revoke the client
1955+ sudo easy-openvpn.revoke-client foo
1956+
1957+ # check if it's revoked
1958+ sudo easy-openvpn.clients | MATCH "foo.*REVOKED"
1959+
1960+ # kill openvpn client
1961+ pid=$(ps aux | grep -P '[o]penvpn.* foo.ovpn.*' | awk '{print $2}')
1962+ sudo kill -9 $pid
1963+
1964+ # The OpenVPN server will read this change every time a client connects
1965+ # (no need to restart server) and deny clients access using revoked certificates.
1966+ # so we try to connect server again.
1967+ sudo easy-openvpn.connect-server foo.ovpn --daemon
1968+
1969+ sleep 10
1970+ sudo tail -n 10 /var/log/syslog | MATCH 'TLS Error: TLS handshake failed'
1971+ sudo tail -n 10 /var/log/syslog | MATCH 'CRL CHECK FAILED: CN=foo.*is REVOKED'
1972diff --git a/spread/main/revoke_client/task.yaml b/spread/main/revoke_client/task.yaml
1973new file mode 100644
1974index 0000000..48d97db
1975--- /dev/null
1976+++ b/spread/main/revoke_client/task.yaml
1977@@ -0,0 +1,22 @@
1978+summary: Test revoke a client configuration.
1979+
1980+execute: |
1981+ . $TESTSLIB/utilities.sh
1982+
1983+ # so enable to setup server in non-interactive mode
1984+ sudo snap set easy-openvpn nopasswd=1
1985+
1986+ # setup openvpn server
1987+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
1988+
1989+ # add a client
1990+ sudo easy-openvpn.add-client foo > foo.ovpn
1991+
1992+ # check if foo exists in the client list
1993+ sudo easy-openvpn.clients | MATCH "foo.*VALID"
1994+
1995+ # revoke the client
1996+ sudo easy-openvpn.revoke-client foo
1997+
1998+ # check if it's revoked
1999+ sudo easy-openvpn.clients | MATCH "foo.*REVOKED"
2000diff --git a/spread/main/setup_server/task.yaml b/spread/main/setup_server/task.yaml
2001new file mode 100644
2002index 0000000..77bf55b
2003--- /dev/null
2004+++ b/spread/main/setup_server/task.yaml
2005@@ -0,0 +1,18 @@
2006+summary: Test setup openvpn server.
2007+
2008+execute: |
2009+ . $TESTSLIB/utilities.sh
2010+
2011+ # set 'nopasswd' to 1 and check the value in help command
2012+ # so that we can execute spread test in non-interactive mode
2013+ # without user attention on password input for private key generation.
2014+ sudo snap set easy-openvpn nopasswd=1
2015+ sudo easy-openvpn.help | MATCH "'nopasswd' current value set to: '1'.*"
2016+
2017+ # setup openvpn server
2018+ sudo easy-openvpn.setup -u "udp://${SERVER_IP}"
2019+
2020+ # to check if ca keypairs are generated successfully
2021+ SNAP_DATA="/var/snap/easy-openvpn/current"
2022+ [ -f "${SNAP_DATA}/openvpn/pki/private/${SERVER_IP}.key" ] || exit 1
2023+ [ -f "${SNAP_DATA}/openvpn/pki/private/ca.key" ] || exit 1

Subscribers

People subscribed via source and target branches

to all changes: