Skip to content

Instantly share code, notes, and snippets.

@r3go
Last active May 28, 2025 14:00
Show Gist options
  • Save r3go/b1ecf0dcedff0135e4b45d183a50a1b1 to your computer and use it in GitHub Desktop.
Save r3go/b1ecf0dcedff0135e4b45d183a50a1b1 to your computer and use it in GitHub Desktop.
vpn client
#!/bin/bash
# ==============================================================================================
#
# Sobre: Client para conexão de VPN (OpenVPN) sem necessidade de programas externos.
# Dependências: openvpn, gpg (as dependências serão instaladas automaticamente)
#
# Author: Diego Rego
# Created: 2025-04-09
# Version: 1.0
# Usage: ./vpn.sh
#
# ===============================================================================================
## 1. Crie uma pasta vpn para abrigar este script e outras credenciais.
# mkdir vpn
# Coloque na pasta acima esse script, e também seu arquivo .ovpn
## 2. Na nova pasta vpn, execute o abaixo
# echo "sua senha" > partial-password.txt
# Na próxima etapa removeremos este arquivo. Fique tranquilo.
# Salve nesse arquivo só o início da senha da vpn. O final da senha vc irá informar na hora da conexão
# (útil se vc utiliza um método que combina senha + mfa)
## 3. Criptografe o arquivo de senha
# gpg --symmetric --cipher-algo AES256 partial-password.txt
# Isto irá gerar um arquivo .gpg no mesmo diretorio, é a senha criptografada.
# Agora, APAGUE o arquivo .txt com a senha pura antes de seguir para o próximo passo.
## 4. Certifique-se que tenha apagado o arquivo da senha pura .txt
# rm partial-password.txt
## 5. Crie o arquivo email-auth.txt contendo apenas o usuário da vpn (ex: email)
# echo "email aqui" > email-auth.txt
## 6. De permissão de execução no script
# chmod +x vpn.sh
# 7. Neste mesmo arquivo, altere a variável $VPN_DIR
# Altere o caminho para conter a o path até sua pasta vpn (sem barra no final)
# Para obter o path completo, navegue via terminal até a pasta vpn, e rode um pwd
## 8. Pronto! Rode o script com o comando abaixo
# ./vpn.sh
# As opções vão ser apresentadas, para adicionar um alias, rode: ./vpn.sh alias-add
# Adicionando o alias, as próximas vezes será possível executar apenas com "vpn".
#
VPN_DIR="/home/rego/Documents/vpn"
OVPN_FILE="$VPN_DIR/vpn.ovpn"
AUTH_FILE="$VPN_DIR/email-auth.txt"
ENCRYPTED_PASSWORD_FILE="$VPN_DIR/partial-password.txt.gpg"
#
DECRYPTED_PASSWORD_FILE="/tmp/partial-password-decrypted.txt"
LOG_FILE="$VPN_DIR/connect.log"
TEMP_AUTH_FILE="/tmp/vpn-auth-temp.txt"
# Nome da interface VPN (geralmente tun0 para OpenVPN)
VPN_INTERFACE="tun0"
handle_interrupt() {
echo -e "\nSafely terminating vpn script..."
cleanup
exit 1
}
trap handle_interrupt SIGINT
cleanup() {
rm -f "$TEMP_AUTH_FILE"
rm -f "$DECRYPTED_PASSWORD_FILE"
kill_process_openvpn
}
# Função para verificar se a VPN está ativa
check_vpn() {
if ip addr show "$VPN_INTERFACE" >/dev/null 2>&1; then
return 0 # VPN está ativa
else
return 1 # VPN não está ativa
fi
}
install_dependencies(){
check_or_install_package gpg
check_or_install_package openvpn
}
# Função para descriptografar a parte inicial da senha
decrypt_partial_password() {
# Verifica se o arquivo criptografado existe
if [ ! -f "$ENCRYPTED_PASSWORD_FILE" ]; then
echo "❌ Error: Encrypted file $ENCRYPTED_PASSWORD_FILE was not found! Ensure you followed the instructions in the README file."
exit 1
fi
# Descriptografa o arquivo (pedirá a senha do usuário)
gpg --decrypt --output "$DECRYPTED_PASSWORD_FILE" "$ENCRYPTED_PASSWORD_FILE"
if [ $? -ne 0 ]; then
echo "❌ Error: Fail to descrypt the pass file. Ensure you encrypted the correct vpn password."
exit 1
fi
# Ajusta as permissões do arquivo descriptografado
chmod 600 "$DECRYPTED_PASSWORD_FILE"
}
change_vpn_password() {
read -sp "Type the first part of your VPN Password 👉 " PARTIAL_PASSWORD
echo
if [ -z "$PARTIAL_PASSWORD" ]; then
echo "❌ Error: Password cannot be empty!"
exit 1
fi
echo "$PARTIAL_PASSWORD" > "$VPN_DIR/partial-password.txt"
gpg --yes --symmetric --cipher-algo AES256 "$VPN_DIR/partial-password.txt"
if [ $? -ne 0 ]; then
echo "❌ Error: Fail to encrypt the partial password. Ensure you have gpg installed and configured."
exit 1
fi
rm -f "$VPN_DIR/partial-password.txt"
echo "✅ VPN Password changed!"
}
create_temp_auth_file() {
if [ ! -f "$AUTH_FILE" ]; then
echo "❌ Error: File $AUTH_FILE was not found!"
exit 1
fi
# Descriptografa a parte inicial da senha
decrypt_partial_password
USERNAME=$(head -n 1 "$AUTH_FILE")
PARTIAL_PASSWORD=$(cat "$DECRYPTED_PASSWORD_FILE")
read -sp "Type the last part of your VPN Password 👉 " FINAL_PASSWORD
echo
FULL_PASSWORD="$PARTIAL_PASSWORD$FINAL_PASSWORD"
echo "$USERNAME" > "$TEMP_AUTH_FILE"
echo "$FULL_PASSWORD" >> "$TEMP_AUTH_FILE"
chmod 600 "$TEMP_AUTH_FILE"
rm -f "$DECRYPTED_PASSWORD_FILE"
}
prepare_log_file(){
echo "" > "$LOG_FILE"
chmod +w "$LOG_FILE"
}
check_or_install_package() {
local pkg="$1"
if ! command -v "$pkg" >/dev/null 2>&1; then
echo "[INFO] $pkg not found. Installing..."
sudo apt update && sudo apt install -y "$pkg"
if [ $? -ne 0 ]; then
echo "[ERROR] Failed to install $pkg." >&2
exit 1
fi
fi
}
connect_vpn() {
if [ ! -f "$OVPN_FILE" ]; then
echo "❌ Error: Your vpn file $OVPN_FILE was not found!"
exit 1
fi
# Pré-autentica o sudo para evitar múltiplas solicitações de senha
sudo -v
if [ $? -ne 0 ]; then
echo "Error: Fail to authenticate as sudo! Check the password and try again."
exit 1
fi
install_dependencies
create_temp_auth_file
prepare_log_file
MSG_CONNECTING="Connecting..."
# Executa o OpenVPN em background, usando o arquivo temporário de autenticação
sudo openvpn --config "$OVPN_FILE" --auth-user-pass "$TEMP_AUTH_FILE" --daemon --log "$LOG_FILE"
MAX_ATTEMPTS=5
WAIT_TIME=1
MSG_CONNECTING="Connecting"
PROGRESS_CHAR="🍒"
for ((i = 1; i <= MAX_ATTEMPTS; i++)); do
if check_vpn; then
break
fi
PROGRESS_BAR=$(printf "%${i}s" ' ' "$PROGRESS_CHAR")
EMPTY_BAR=$(printf "%$((MAX_ATTEMPTS - i))s")
echo -ne "\r$MSG_CONNECTING $PROGRESS_BAR"
sleep "$WAIT_TIME"
done
if ! check_vpn; then
echo -e "\n❌ Failed to connect to VPN! 🤔 Check your user and vpn password and try again! You can also check the logs in the $LOG_FILE."
cleanup
exit 1
else
show_status
fi
# Remove o arquivo temporário após a conexão bem-sucedida
rm -f "$TEMP_AUTH_FILE"
}
disconnect_vpn() {
echo "Disconnecting..."
kill_process_openvpn
if ! check_vpn; then
show_status
else
echo "❌ Failed to disconnect to VPN. Try again."
exit 1
fi
}
kill_process_openvpn() {
# Usa pgrep para encontrar o PID do processo OpenVPN que está usando o arquivo .ovpn
PIDS=$(pgrep -f "openvpn.*$(basename "$OVPN_FILE")")
if [ -n "$PIDS" ]; then
echo "Interrupting OpenVPN process (PIDs: $PIDS)..."
# Encerra os processos encontrados
echo "$PIDS" | xargs sudo kill -TERM
# Aguarda um momento para garantir que o processo seja encerrado
sleep 2
fi
}
show_interface() {
ip addr show "$VPN_INTERFACE" | cat
}
show_status() {
echo -e "\n"
if check_vpn; then
echo "🔒 VPN is CONNECTED! 😎 "
return 1
else
echo "🔓 VPN IS DISCONNECTED! 😴"
return 0
fi
}
add_alias() {
# Caminho do script atual (resolve o caminho absoluto)
SCRIPT_PATH="$(realpath "$0")"
# Verifica se o arquivo de configuração do shell existe (.bashrc ou .zshrc)
SHELL_CONFIG_FILE=""
if [ -f "$HOME/.zshrc" ]; then
SHELL_CONFIG_FILE="$HOME/.zshrc"
elif [ -f "$HOME/.bashrc" ]; then
SHELL_CONFIG_FILE="$HOME/.bashrc"
else
echo -e "Neither .bashrc and .zshrc not found in $HOME"
fi
# If a configuration file was found, checks and creates the alias
if [ -n "$SHELL_CONFIG_FILE" ]; then
# Checks if the alias 'vpn' already exists
if ! grep -q "alias vpn=" "$SHELL_CONFIG_FILE"; then
echo "alias vpn='$SCRIPT_PATH'" >> "$SHELL_CONFIG_FILE"
echo "✅ Alias created!"
echo "To use it, run 'vpn' in a new terminal instance."
echo "Or run 'source $SHELL_CONFIG_FILE' to use the new alias here!"
else
echo "The alias 'vpn' already exists!"
fi
fi
}
case "$1" in
status)
if ! show_status; then
show_interface
fi
;;
readme)
batcat README.md
;;
log)
vim $LOG_FILE
;;
alias-add)
add_alias
;;
connect)
if check_vpn; then
show_status
else
connect_vpn
fi
;;
disconnect)
if check_vpn; then
disconnect_vpn
else
show_status
fi
;;
change-pass)
change_vpn_password
;;
*)
show_status
echo -e "\n\nUsage: vpn COMMAND"
echo -e "\nCommands:"
echo -e " connect Connect to the VPN"
echo -e " disconnect Disconnect from the VPN"
echo -e " status Display the connection status with the VPN"
echo -e " log Open log file in vim"
echo -e " readme Show the README.me file with configuration instructions"
echo -e " change-pass Change the VPN password"
echo -e " alias-add Add an alias 'vpn' for this script to your .bashrc or .zshrc"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment