Добавь установщик Lemana VPN
This commit is contained in:
346
install.sh
Executable file
346
install.sh
Executable file
@@ -0,0 +1,346 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
APP_NAME="lemana-vpn"
|
||||
DEFAULT_RAW_BASE_URL="http://192.168.50.109/dokril/lemana-vpn/raw/branch/main"
|
||||
|
||||
RAW_BASE_URL="${LEMANA_VPN_RAW_BASE_URL:-$DEFAULT_RAW_BASE_URL}"
|
||||
INSTALL_BIN_DIR="${LEMANA_VPN_BIN_DIR:-$HOME/bin}"
|
||||
CONFIG_DIR="${LEMANA_VPN_CONFIG_DIR:-$HOME/.config/lemana-vpn}"
|
||||
OC_CONFIG_DIR="${OPENCONNECT_LITE_CONFIG_DIR:-$HOME/.config/openconnect-lite}"
|
||||
DNS_CLEANUP="/usr/local/sbin/lemana-vpn-dns-cleanup"
|
||||
USERNAME="${LEMANA_VPN_USERNAME:-60103293}"
|
||||
BW_ITEM="${LEMANA_VPN_BW_ITEM:-LM LDAP}"
|
||||
USE_BITWARDEN=1
|
||||
USE_TOUCHID=1
|
||||
INSTALL_SUDOERS=1
|
||||
INSTALL_ALIASES=1
|
||||
CONFIGURE_KEYCHAIN=0
|
||||
DRY_RUN=0
|
||||
FORCE=0
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
sh install.sh [options]
|
||||
|
||||
Options:
|
||||
--with-bitwarden Install/use Bitwarden CLI module (default)
|
||||
--without-bitwarden Do not install/use Bitwarden CLI; use Keychain credentials
|
||||
--with-touchid Install/use keychain-fingerprint Touch ID helper (default)
|
||||
--without-touchid Do not install/use Touch ID helper
|
||||
--configure-keychain Prompt for LDAP password/TOTP after install
|
||||
--username VALUE Corporate LDAP username (default: 60103293)
|
||||
--bw-item VALUE Bitwarden item name (default: LM LDAP)
|
||||
--raw-base-url URL Raw file base URL for curl installs
|
||||
--no-sudoers Do not install sudoers rules
|
||||
--no-shell Do not update ~/.zshrc aliases
|
||||
--minimal Same as --without-bitwarden --without-touchid
|
||||
--dry-run Print actions without changing files
|
||||
--force Reinstall files even when present
|
||||
-h, --help Show this help
|
||||
|
||||
Examples:
|
||||
sh install.sh
|
||||
sh install.sh --minimal --configure-keychain
|
||||
sh install.sh --without-touchid
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--with-bitwarden) USE_BITWARDEN=1 ;;
|
||||
--without-bitwarden) USE_BITWARDEN=0 ;;
|
||||
--with-touchid) USE_TOUCHID=1 ;;
|
||||
--without-touchid) USE_TOUCHID=0 ;;
|
||||
--configure-keychain) CONFIGURE_KEYCHAIN=1 ;;
|
||||
--username)
|
||||
shift
|
||||
[ "$#" -gt 0 ] || { echo "--username requires a value" >&2; exit 1; }
|
||||
USERNAME="$1"
|
||||
;;
|
||||
--bw-item)
|
||||
shift
|
||||
[ "$#" -gt 0 ] || { echo "--bw-item requires a value" >&2; exit 1; }
|
||||
BW_ITEM="$1"
|
||||
;;
|
||||
--raw-base-url)
|
||||
shift
|
||||
[ "$#" -gt 0 ] || { echo "--raw-base-url requires a value" >&2; exit 1; }
|
||||
RAW_BASE_URL="${1%/}"
|
||||
;;
|
||||
--no-sudoers) INSTALL_SUDOERS=0 ;;
|
||||
--no-shell) INSTALL_ALIASES=0 ;;
|
||||
--minimal)
|
||||
USE_BITWARDEN=0
|
||||
USE_TOUCHID=0
|
||||
;;
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--force) FORCE=1 ;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
log() {
|
||||
printf '%s\n' "$*"
|
||||
}
|
||||
|
||||
die() {
|
||||
printf 'ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
run() {
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
printf '+'
|
||||
for arg in "$@"; do
|
||||
printf ' %s' "$arg"
|
||||
done
|
||||
printf '\n'
|
||||
return 0
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "Command not found: $1"
|
||||
}
|
||||
|
||||
script_dir() {
|
||||
case "$0" in
|
||||
*/*) cd "$(dirname "$0")" 2>/dev/null && pwd ;;
|
||||
*) pwd ;;
|
||||
esac
|
||||
}
|
||||
|
||||
download_file() {
|
||||
src="$1"
|
||||
dst="$2"
|
||||
local_dir="$(script_dir)"
|
||||
|
||||
if [ -f "$local_dir/$src" ]; then
|
||||
run cp "$local_dir/$src" "$dst"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -f "$PWD/$src" ]; then
|
||||
run cp "$PWD/$src" "$dst"
|
||||
return 0
|
||||
fi
|
||||
|
||||
need_cmd curl
|
||||
run curl -fsSL "$RAW_BASE_URL/$src" -o "$dst"
|
||||
}
|
||||
|
||||
write_file() {
|
||||
dst="$1"
|
||||
content="$2"
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
printf '+ write %s\n' "$dst"
|
||||
return 0
|
||||
fi
|
||||
printf '%s\n' "$content" > "$dst"
|
||||
}
|
||||
|
||||
install_homebrew_packages() {
|
||||
need_cmd brew
|
||||
|
||||
for pkg in openconnect pipx; do
|
||||
if brew list "$pkg" >/dev/null 2>&1; then
|
||||
log "Homebrew package already installed: $pkg"
|
||||
else
|
||||
log "Installing Homebrew package: $pkg"
|
||||
run brew install "$pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$USE_BITWARDEN" -eq 1 ]; then
|
||||
if brew list bitwarden-cli >/dev/null 2>&1; then
|
||||
log "Homebrew package already installed: bitwarden-cli"
|
||||
else
|
||||
log "Installing Homebrew package: bitwarden-cli"
|
||||
run brew install bitwarden-cli
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
install_openconnect_lite() {
|
||||
need_cmd pipx
|
||||
|
||||
if [ -x "$HOME/.local/bin/openconnect-lite" ] && [ "$FORCE" -eq 0 ]; then
|
||||
log "openconnect-lite already installed"
|
||||
else
|
||||
log "Installing openconnect-lite via pipx"
|
||||
run pipx install openconnect-lite
|
||||
fi
|
||||
|
||||
if pipx --help 2>/dev/null | grep -q ' pin '; then
|
||||
run pipx pin openconnect-lite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
install_cli() {
|
||||
tmp="$1"
|
||||
run mkdir -p "$INSTALL_BIN_DIR"
|
||||
|
||||
download_file "bin/vpn-lemanapro.sh" "$tmp/vpn-lemanapro.sh"
|
||||
run install -m 755 "$tmp/vpn-lemanapro.sh" "$INSTALL_BIN_DIR/vpn-lemanapro.sh"
|
||||
}
|
||||
|
||||
install_config() {
|
||||
tmp="$1"
|
||||
run mkdir -p "$CONFIG_DIR" "$OC_CONFIG_DIR"
|
||||
|
||||
download_file "templates/openconnect-lite-config.toml" "$tmp/openconnect-lite-config.toml"
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
printf '+ render %s/config.toml\n' "$OC_CONFIG_DIR"
|
||||
else
|
||||
sed "s/{{USERNAME}}/$USERNAME/g" "$tmp/openconnect-lite-config.toml" > "$OC_CONFIG_DIR/config.toml"
|
||||
chmod 600 "$OC_CONFIG_DIR/config.toml"
|
||||
fi
|
||||
|
||||
env_content="LEMANA_VPN_USERNAME=\"$USERNAME\"
|
||||
LEMANA_VPN_BW_ITEM=\"$BW_ITEM\"
|
||||
LEMANA_VPN_USE_BITWARDEN=\"$USE_BITWARDEN\"
|
||||
LEMANA_VPN_USE_TOUCHID=\"$USE_TOUCHID\"
|
||||
LEMANA_VPN_DNS_CLEANUP=\"$DNS_CLEANUP\""
|
||||
write_file "$tmp/env" "$env_content"
|
||||
run install -m 600 "$tmp/env" "$CONFIG_DIR/env"
|
||||
}
|
||||
|
||||
install_dns_cleanup() {
|
||||
tmp="$1"
|
||||
|
||||
download_file "libexec/lemana-vpn-dns-cleanup" "$tmp/lemana-vpn-dns-cleanup"
|
||||
log "Installing DNS cleanup wrapper: $DNS_CLEANUP"
|
||||
run sudo install -m 755 -o root -g wheel "$tmp/lemana-vpn-dns-cleanup" "$DNS_CLEANUP"
|
||||
}
|
||||
|
||||
install_sudoers() {
|
||||
[ "$INSTALL_SUDOERS" -eq 1 ] || return 0
|
||||
|
||||
openconnect_bin="$(brew --prefix)/bin/openconnect"
|
||||
[ -x "$openconnect_bin" ] || openconnect_bin="$(command -v openconnect || true)"
|
||||
[ -n "$openconnect_bin" ] || die "openconnect binary not found"
|
||||
|
||||
tmp="$1"
|
||||
current_user="$(id -un)"
|
||||
|
||||
write_file "$tmp/sudoers-openconnect" "$current_user ALL=(ALL) NOPASSWD: $openconnect_bin"
|
||||
run sudo install -m 440 -o root -g wheel "$tmp/sudoers-openconnect" /etc/sudoers.d/lemana-vpn-openconnect
|
||||
run sudo visudo -c -f /etc/sudoers.d/lemana-vpn-openconnect
|
||||
|
||||
write_file "$tmp/sudoers-dns" "$current_user ALL=(ALL) NOPASSWD: $DNS_CLEANUP"
|
||||
run sudo install -m 440 -o root -g wheel "$tmp/sudoers-dns" /etc/sudoers.d/lemana-vpn-dns
|
||||
run sudo visudo -c -f /etc/sudoers.d/lemana-vpn-dns
|
||||
}
|
||||
|
||||
install_touchid_helper() {
|
||||
[ "$USE_TOUCHID" -eq 1 ] || return 0
|
||||
|
||||
if [ -x "$INSTALL_BIN_DIR/keychain-fingerprint" ] && [ "$FORCE" -eq 0 ]; then
|
||||
log "Touch ID helper already installed: $INSTALL_BIN_DIR/keychain-fingerprint"
|
||||
return 0
|
||||
fi
|
||||
|
||||
need_cmd git
|
||||
need_cmd swiftc
|
||||
|
||||
tmp="$1"
|
||||
log "Building keychain-fingerprint helper"
|
||||
run git clone --depth 1 https://github.com/dss99911/keychain-fingerprint.git "$tmp/keychain-fingerprint"
|
||||
run swiftc -o "$tmp/keychain-fingerprint-bin" "$tmp/keychain-fingerprint/main.swift" -framework LocalAuthentication -framework Security
|
||||
run install -m 700 "$tmp/keychain-fingerprint-bin" "$INSTALL_BIN_DIR/keychain-fingerprint"
|
||||
}
|
||||
|
||||
install_shell_aliases() {
|
||||
[ "$INSTALL_ALIASES" -eq 1 ] || return 0
|
||||
|
||||
zshrc="$HOME/.zshrc"
|
||||
tmp="$1"
|
||||
[ -f "$zshrc" ] || run touch "$zshrc"
|
||||
|
||||
block="$tmp/zshrc-block"
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
printf '+ update %s aliases\n' "$zshrc"
|
||||
return 0
|
||||
fi
|
||||
|
||||
cat > "$block" <<EOF
|
||||
# >>> lemana-vpn
|
||||
vpn() { "$INSTALL_BIN_DIR/vpn-lemanapro.sh" "\$@"; }
|
||||
vpn-debug() { "$INSTALL_BIN_DIR/vpn-lemanapro.sh" --debug "\$@"; }
|
||||
vpn-fix-dns() { sudo "$DNS_CLEANUP"; }
|
||||
# <<< lemana-vpn
|
||||
EOF
|
||||
|
||||
awk '
|
||||
/^# >>> lemana-vpn$/ { skip=1; next }
|
||||
/^# <<< lemana-vpn$/ { skip=0; next }
|
||||
skip != 1 { print }
|
||||
' "$zshrc" > "$tmp/zshrc"
|
||||
|
||||
{
|
||||
cat "$tmp/zshrc"
|
||||
printf '\n'
|
||||
cat "$block"
|
||||
} > "$tmp/zshrc.new"
|
||||
|
||||
mv "$tmp/zshrc.new" "$zshrc"
|
||||
}
|
||||
|
||||
maybe_login_bitwarden() {
|
||||
[ "$USE_BITWARDEN" -eq 1 ] || return 0
|
||||
command -v bw >/dev/null 2>&1 || return 0
|
||||
|
||||
status="$(bw status 2>/dev/null || true)"
|
||||
if printf '%s\n' "$status" | grep -q '"status":"unauthenticated"'; then
|
||||
log "Bitwarden CLI is not logged in. Run later: bw login"
|
||||
elif printf '%s\n' "$status" | grep -q '"status":"locked"'; then
|
||||
log "Bitwarden CLI is logged in but locked. First vpn run will ask for master password."
|
||||
else
|
||||
log "Bitwarden CLI is available."
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
[ "$(uname -s)" = "Darwin" ] || die "This installer supports macOS only"
|
||||
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT INT TERM
|
||||
|
||||
log "Installing Lemana VPN"
|
||||
log "Modules: bitwarden=$USE_BITWARDEN touchid=$USE_TOUCHID sudoers=$INSTALL_SUDOERS shell=$INSTALL_ALIASES"
|
||||
|
||||
install_homebrew_packages
|
||||
install_openconnect_lite
|
||||
install_cli "$tmp"
|
||||
install_config "$tmp"
|
||||
install_dns_cleanup "$tmp"
|
||||
install_sudoers "$tmp"
|
||||
install_touchid_helper "$tmp"
|
||||
install_shell_aliases "$tmp"
|
||||
maybe_login_bitwarden
|
||||
|
||||
if [ "$CONFIGURE_KEYCHAIN" -eq 1 ]; then
|
||||
run "$INSTALL_BIN_DIR/vpn-lemanapro.sh" --configure-keychain
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "Done."
|
||||
log "Open a new shell or run: exec zsh"
|
||||
log "Connect: vpn"
|
||||
log "Status: vpn --status"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user