Overview
Comment: | add vpn tool |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
75223838e1bae48168201470b2857ed2 |
User & Date: | lexi on 2019-05-03 15:21:43 |
Other Links: | manifest | tags |
Context
2019-05-04
| ||
02:38 | updates check-in: 05feae3cd3 user: lexi tags: trunk | |
2019-05-03
| ||
15:21 | add vpn tool check-in: 75223838e1 user: lexi tags: trunk | |
2019-05-01
| ||
01:03 | refactor tenki check-in: 70991b55c3 user: lexi tags: trunk | |
Changes
Added vpn/conf version [d086ba0334].
> > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# [ʞ] vpn/conf # ~ lexi hale <lexi@hale.su> # © public domain / CC0 # this is the master configuration file for # openvpn used by the `vpn` utility. these should # be sane-enough defaults for almost all cases. # server-specific config should be placed in # $server/conf in this directory client pull group nobody resolv-retry infinite nobind persist-key persist-tun log log mute-replay-warnings verb 3 mute 10 |
Added vpn/vpn version [8e3b5d4148].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
#!/usr/bin/env bash # [ʞ] vpn # ~ lexi hale <lexi@hale.su> # ® affero general public license # $ vpn (join | part | info | clean | key) <name> # : vim:ft=bash # vpn is a simple wrapper around openvpn to make it suitable # for everyday use. it takes two arguments: the vpn, and # what to do with it. # - vpn join <vpn>: opens a connection to vpn <name> # - vpn part <vpn>: closes an active connection to <name> # - vpn info <vpn>: reports the status of of a vpn # - vpn key <host>: automatically provisions the client # with RSA keys from <host> and creates # a configuration file if one does not # already exist # - vpn part <vpn>: closes an active connection to <vpn> # - vpn help: display this text # # a number of environment variables affect the behavior of # vpn. these are listed in the source with their defaults # and an explantion of their function. if you do not wish # users to be able to change the behavior of vpn with # setenv, you must change the param invokation to a simple # assignment. # # note that you may want to add a visudo line allowing # %wheel or perhaps even all users to execute openvpn # without a password; otherwise, only sudoers will be able # to use vpn and the root password will be required for # every state change. __=$LINENO param(){ eval $1=\${$1:-$2}; } param vpn_basedir ~/opt/vpn # the directory in which vpn's logfiles are stored, # and possibly the script itself param vpn_confdir $vpn_basedir # the directory that contains the individual vpn # directories param vpn_global $vpn_basedir/conf # a configuration file that is applied to all vpns param vpn_srv_keydir /srv/vpn/ca # the directory on the server where vpn client keys # are stored param vpn_cn $(uname -n) # the name of the device / user / resource connecting # `vpn key` will use this value to determine which # client keys to download. i recommend a one-key-per- # device setup with the certificate CN used to assign # a name in the tunnel's DNS server, but one-key-per- # user or one-key-period setups are also possible. param TMPDIR /tmp # a directory for temporary files, preferably one that # does not persist across boots (e.g. a tmpfs) param USER $(whoami) # the user who should own all files and processes # created and destroyed by vpn param vpn_pidbox $TMPDIR/pid.$USER # a directory for storing pids in. this should be chmod # 700 and owned by the user invoking vpn, ideally param vpn_script $0 # a path to the executable param vpn_scrname $(basename $vpn_script) # the name of the executable # thus ends the admin-configurable portion of this script. # abandon all hope, ye who enter here err(){ echo -e "\e[1;31merror:\e[m" $* ; exit 1; } assert(){ msg=$1; shift; test ! $@ && err $msg; } test "$1" == help || assert "incorrect number of arguments" $# -eq 2 act=$1; target=$2 vpnd=$vpn_confdir/$target conf=$vpnd/conf test "$act" == key && { mkdir -p $vpnd test -e $conf || { echo dev tun > $conf echo proto udp >> $conf echo remote $target 1194 >> $conf } } assert "target \e[1m$target\e[m does not exist!" -e $vpn_confdir/$target assert "target \e[1m$target\e[m has no configuration file" -e $conf pidfile="$vpn_pidbox/openvpn.$target" stale() { ((clean == 1)) && { echo " → deleting stale pidfile" rm -f $pidfile } || { echo -e " - run \e[1m$vpn_scrname clean\e[m to clean up" } } goodpid(){ test -e $pidfile || return 1 local proc=$(ps ho fname $(cat $pidfile)) || return 2 test "$proc" == openvpn || return 2 return 0 } case $act in # automatically provision machine ( key | setup | provision | download | dl | k ) scp $target:$vpn_srv_keydir/pki/{ca.crt,{issued,private}/$vpn_cn.\*} $vpnd/ || err "could not retrieve keys for \e[1m$target\e[m; ensure ssh is properly configured and machine keys are assigned to the correct user" ;; # connect to the openvpn server ( join | up | connect | con | start | j | u ) # don't clobber an existing connection goodpid && err "\e[1m$target\e[m is already up!" # make sure a private pid directory exists test ! -e $vpn_pidbox && mkdir -p $vpn_pidbox chmod 700 $vpn_pidbox # check and see if we're using automatic # host certificates; tell openvpn if so test -e $vpnd/ca.crt && { hostcert=$vpnd/$vpn_cn cmd=( --askpass --ca $vpnd/ca.crt --cert $hostcert.crt --key $hostcert.key ) } touch $pidfile # make sure invoker owns it chmod 600 $pidfile # bc fuck you, that's why sudo openvpn --daemon --config $vpn_global \ --config $conf \ --user $USER \ ${cmd[@]} \ --writepid $pidfile || rm $pidfile;; # kill an existing connection ( part | down | disc* | stop | p | d ) test -e $pidfile && { goodpid && { kill $(cat $pidfile) && rm -f $pidfile } || { echo -e "\e[1;33mwarn:\e[m pidfile exists but does not name an openvpn process" echo " → removing pidfile for safety" rm -f $pidfile } } || { echo -ne "\e[1mvpn $target\e[m is not up" } ;; # clean up dirty pidfiles ( clean | wipe | clear | fix | tidy ) clean=1 ;& # return profile status ( info | stat* | detail* | i ) echo -ne "\e[1mvpn $target:\e[m " test ! -e $pidfile && { echo -ne "\e[31mno\e[m current connection" pids=($(pidof openvpn)) let pidc=${#pids} ((pidc > 0)) && { echo ", but $pidc vpn instances are running" exit 2 } || { echo; exit 0; } } || { echo -n "pidfile exists" proc=$(ps ho fname $(cat $pidfile)) (($? != 0)) && { echo ", but there are no processes with that pid" stale; exit 1 } || test "$proc" == "openvpn" && { echo -e " and openvpn is \e[32mrunning\e[m" exit 0 } || { echo -e " but named process is \e[31mnot a vpn instance!\e[m" stale; exit 1 } } ;; ( help ) head -n $(expr $__ - 1) $vpn_script | tail -n $(expr $__ - 2); exit 255;; ( * ) err "action must be one of: join | part | info | clean" ;; esac |