-
-
Save the-eater/8248c8056a21892d29f0c9fcfe6e6480 to your computer and use it in GitHub Desktop.
vpnm - Bash Openvpn manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -e; | |
VPNM_CONF="${VPNM_CONF:-$HOME/.vpnm}"; | |
VPNM_SUDO="${VPNM_SUDO:-sudo}"; | |
VPNM_GPG="${VPNM_GPG:-gpp2}"; | |
VPNM_CREDS="${VPNM_CREDS:-keyring}"; | |
main() { | |
local action="$1"; | |
shift; | |
case "$action" in | |
enable) | |
enable_vpn "$1"; | |
return; | |
;; | |
disable) | |
disable_vpn "$1"; | |
return; | |
;; | |
start) | |
start_vpn "$1"; | |
return; | |
;; | |
stop) | |
stop_vpn "$1"; | |
return; | |
;; | |
status) | |
status_vpn "$1"; | |
return; | |
;; | |
add) | |
add_vpn $@; | |
return; | |
;; | |
edit) | |
edit_vpn $@; | |
return; | |
;; | |
list) | |
list_vpn; | |
return; | |
;; | |
list-enabled) | |
list_enabled_vpn; | |
return; | |
;; | |
set-private-pass) | |
set_private_pass "$1"; | |
return; | |
;; | |
set-auth) | |
set_auth "$1"; | |
return; | |
;; | |
boot) | |
boot; | |
return; | |
;; | |
help) | |
print_man; | |
return; | |
;; | |
*) | |
echo "Action ${action} doesn't exist" | |
echo; | |
print_man; | |
exit 1; | |
;; | |
esac | |
} | |
print_man () { | |
cat <<MAN | |
vpnm - A Bash vpn manager | |
Commands: | |
- enable {vpn name} enables and starts the vpn | |
- disable {vpn name} disable and doesnt stop the vpn | |
- start {vpn name} starts vpn without enabling it | |
- stop {vpn name} stop vpn without disabling it | |
- add {vpn name} {openvpn config} [additionial files] add a vpn to the manager | |
- edit {vpn name} [file] edit the openvpn config or given file of vpn | |
- list list all vpns in config manager | |
- list-enabled list all enabled vpns | |
- set-private-pass {vpn name} save the private key pass in a gpg encrypted file or your keyring | |
- set-auth {vpn name} save the auth user combo in a gpg encrypted file or your keyring | |
MAN | |
} | |
add_vpn () { | |
local name="$1"; shift; | |
local config="$1"; shift; | |
ensure_not_empty "name" "${name}"; | |
ensure_not_empty "config" "${config}"; | |
if check_vpn_exists "${name}"; then | |
echo "Vpn with the name '${name}' already exists"; | |
exit 1; | |
fi | |
local vpndir="$(get_vpn_dir "${name}")"; | |
mkdir -p "${vpndir}/config"; | |
cp "${config}" "${vpndir}/config/server.conf"; | |
cp -a $@ "${vpndir}/config/"; | |
echo "Succesfully created vpn ${name}"; | |
} | |
enable_vpn () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
if grep -q "^${name}$" "${VPNM_CONF}/enabled"; then | |
echo "${name} is already enabled"; | |
exit 1; | |
fi | |
echo "${name}" >> "${VPNM_CONF}/enabled"; | |
start_vpn "${name}"; | |
} | |
disable_vpn () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
grep -v "^${name}$" "${VPNM_CONF}/enabled" > "${VPNM_CONF}/enabled.new" || true; | |
rm "${VPNM_CONF}/enabled"; | |
mv "${VPNM_CONF}/enabled.new" "${VPNM_CONF}/enabled"; | |
} | |
boot () { | |
echo "Booting vpns"; | |
while read -r vpn; | |
do | |
start_vpn "${vpn}"; | |
done < "${VPNM_CONF}/enabled"; | |
} | |
list_enabled_vpn () { | |
cat "${VPNM_CONF}/enabled"; | |
} | |
edit_vpn () { | |
local name="$1"; | |
local config="$2"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
"$EDITOR" "$(get_vpn_dir "${name}")/config/${config:-server.conf}"; | |
} | |
list_vpn () { | |
ls -1 "${VPNM_CONF}/vpn"; | |
} | |
status_vpn () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
local vpndir="$(get_vpn_dir "${name}")"; | |
if [ -f "${vpndir}/pid" ] && $VPNM_SUDO kill -0 "$(cat "${vpndir}/pid")" 2>/dev/null; then | |
echo "Vpn ${name} is running..."; | |
exit 0; | |
fi; | |
echo "Vpn ${name} is not running..."; | |
exit 1; | |
} | |
start_vpn () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
local vpndir="$(get_vpn_dir "${name}")"; | |
if [ -f "${vpndir}/pid" ] && $VPNM_SUDO kill -0 "$(cat "${vpndir}/pid")" 2>/dev/null; then | |
echo "Vpn ${name} is already running..." | |
exit 0; | |
fi; | |
local args=""; | |
if [ -f "${vpndir}/auth" ]; then | |
local user="$(cat "${vpndir}/auth")"; | |
local pass="$(lookup_pass "${name}" "auth")"; | |
[ -f "${vpndir}/.pw" ] && rm "${vpndir}/.pw"; | |
echo "$user" > "${vpndir}/.pw"; | |
echo "$pass" >> "${vpndir}/.pw"; | |
args="$args --auth-user-pass ${vpndir}/.pw"; | |
fi | |
if [ -f "${vpndir}/privkeypass" ]; then | |
args="$args --askpass ${vpndir}/.pk"; | |
lookup_pass "${name}" "private" > "${vpndir}/.pk"; | |
fi; | |
cd "${vpndir}/config"; | |
local ret=0; | |
$VPNM_SUDO openvpn --writepid "${vpndir}/pid" --daemon --log-append "${vpndir}/log" --config "${vpndir}/config/server.conf" $args || ret=$?; | |
sleep .5; | |
[ -f "${vpndir}/.pk" ] && rm "${vpndir}/.pk"; | |
[ -f "${vpndir}/.pw" ] && rm "${vpndir}/.pw"; | |
if [ $ret != 0 ]; then | |
echo "Failed to start openvpn"; | |
exit $ret; | |
fi; | |
$VPNM_SUDO chmod a+r "${vpndir}/log"; | |
echo "Started vpn ${name}"; | |
} | |
stop_vpn () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
local vpndir="$(get_vpn_dir "${name}")"; | |
local pid="$(cat "${vpndir}/pid")"; | |
if [ ! -f "${vpndir}/pid" ] || ! $VPNM_SUDO kill -0 "${pid}" 2>/dev/null; then | |
echo "Vpn ${name} is not running..." | |
exit 0; | |
fi; | |
$VPNM_SUDO kill "${pid}"; | |
$VPNM_SUDO rm "${vpndir}/pid"; | |
while $VPNM_SUDO kill -0 "${pid}" 2>/dev/null; do | |
sleep 0.2; | |
done; | |
echo "Stopped vpn ${name}"; | |
} | |
set_private_pass () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
read -rsp "Please enter the private key password: " pass; | |
echo; | |
store_pass "$name" "private" "$pass"; | |
touch "$(get_vpn_dir "$name")/privkeypass"; | |
} | |
set_auth () { | |
local name="$1"; | |
ensure_not_empty "name" "${name}"; | |
ensure_vpn_exists "${name}"; | |
read -rp "Please enter the user for ${name}: " user; | |
read -rsp "Please enter the password for ${name}: " pass; | |
echo; | |
store_pass "$name" "auth" "$pass"; | |
echo "${user}" > "$(get_vpn_dir "$name")/auth"; | |
} | |
get_vpn_dir () { | |
local name="$1"; | |
echo "${VPNM_CONF}/vpn/${name}"; | |
} | |
check_vpn_exists () { | |
local name="$1"; | |
test -d "$(get_vpn_dir "${name}")"; | |
return $? | |
} | |
ensure_not_empty () { | |
local name="$1"; | |
local value="$2"; | |
if [ -z "${value}" ]; then | |
echo "${name} is empty"; | |
exit 1; | |
fi | |
} | |
ensure_vpn_exists () { | |
local name="$1"; | |
if ! check_vpn_exists "${name}"; then | |
echo "Vpn ${name} doesn't exist"; | |
exit 1; | |
fi | |
} | |
lookup_pass () { | |
local name="$1"; | |
local what="$2"; | |
case "${VPNM_CREDS}" in | |
keyring) | |
secret-tool lookup "vpnm/vpn/${name}" "${what}"; | |
;; | |
gpg) | |
$VPNM_GPG --decrypt "$(get_vpn_dir "${name}")/pass/${what}.gpg"; | |
;; | |
pass) | |
pass show "vpnm/vpn/${name}/${what}"; | |
;; | |
*) | |
echo "Secret storage engine ${VPNM_CREDS}, not available"; | |
exit 1; | |
esac | |
} | |
store_pass () { | |
local name="$1"; | |
local what="$2"; | |
local pass="$3"; | |
case "${VPNM_CREDS}" in | |
keyring) | |
echo "${pass}" | secret-tool store --label "${what} password for ${name} vpn" "vpnm/vpn/${name}" "${what}"; | |
;; | |
gpg) | |
if [ -z "${VPNM_GPGKEY}" ]; then | |
echo "No GPG key given to encrypt passwords with"; | |
fi | |
local vpnpassdir="$(get_vpn_dir "${name}")/pass"; | |
[ ! -d "${vpnpassdir}" ] && mkdir "${vpnpassdir}" | |
echo "${pass}" | $VPNM_GPG --encrypt --armor -r "$VPNM_GPGKEY" | "${vpnpassdir}/${what}.gpg"; | |
;; | |
pass) | |
echo "${pass}" | pass insert -e "vpnm/vpn/${name}/${what}"; | |
;; | |
*) | |
echo "Secret storage engine ${VPNM_CREDS}, not available"; | |
exit 1; | |
esac | |
} | |
main $@; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment