Last active
May 28, 2025 14:00
-
-
Save r3go/b1ecf0dcedff0135e4b45d183a50a1b1 to your computer and use it in GitHub Desktop.
vpn client
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
#!/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