#!/bin/bash #TryHackMe VPN Troubleshooting #Jan, 2021 #V1.5 #MuirlandOracle #Define Colours colour(){ if [ $# -lt 2 ]; then exit 1 fi case "$1" in "green") printf "\033[01;32m$2\033[0m\n" ;; "red") printf "\033[01;31m$2\033[0m\n" ;; "yellow") printf "\033[01;93m$2\033[0m\n" ;; "header") printf "\033[0;1;4m$2\033[0m\n" ;; "code") printf "\033[01;31;47m$2\033[0m\n" ;; "warning") printf "\033[01;93m[Warning!]\033[0m $2\n" ;; "process") printf "\033[01;94m$2\033[0m\n" ;; *) return 1 ;; esac if [ $# -eq 3 ]; then sleep $3s fi } fin(){ printf "\n\n" exit 1 } connect(){ testSuccess() ( if grep -qio "Initialization Sequence Completed" $ovpnoutput;then return 0; else return 1;fi ) testCert() ( if grep -qioE "Cannot load inline certificate file|certificate verify failed|cannot load CA" $ovpnoutput;then return 0; else return 1;fi ) testCipher() ( if grep -qioE "cipher AES-256-CBC" $ovpn;then return 0; else return 1;fi ) ovpnoutput=$(mktemp) openvpn $ovpn $ovpnoutput & colour process "[+] Connecting...." 10 for i in {1..2};do if testSuccess; then colour green "[+] Connection Process completed successfully!" 1 return 1 elif testCert; then killall -9 openvpn &>/dev/null 2>/dev/null colour red "[-] Fatal Error: Inline Certificate is invalid" 1 printf "Please regenerate your VPN config on the access page (https://tryhackme.com/access)\nIf errors persist, change server then regenerate the config.\nIf all else fails, ask for further assistance on the TryHackMe Discord server, subreddit or forums.\n" colour red "[-] Exiting" 2 return 0 elif testCipher; then colour red "[-] Using outdated switch for ciper negotiations. Attempting to update..." 1 sed -i 's/cipher AES-256-CBC/data-ciphers AES-256-CBC/' $ovpn colour green "[+] Successfully updated cipher switch! Please connect to the vpn using the following command: " colour code "sudo openvpn $ovpn" 2 return 0 fi if [ $i -le 1 ]; then colour warning "Connection process is taking longer than expected to complete" 30 else colour red "[-] Failed to connect" 1 printf "Failure to connect to the VPN can usually be solved by one of the following options:\n" printf " -Regenerating your OpenVPN config on the TryHackMe access page (https://tryhackme.com/access)\n" printf " -Switching servers, then regenerating your OpenVPN config\n" printf " -Checking your system time. If your system time is incorrect then this can cause issues with the authentication process\n" printf "If none of these methods work, please ask for further assistance in the TryHackMe Discord server, subreddit or forums.\n" colour red "[-] Exiting" 2 return 0 fi done } distro_call=$("lsb_release" "-is") distro="${distro_call[*]}" #Title title(){ printf "\n\n\033[0;1;32m" cat << "EOF" _____ _ _ _ __ __ |_ _| __ _ _| | | | __ _ ___| | _| \/ | ___ | || '__| | | | |_| |/ _` |/ __| |/ / |\/| |/ _ \ | || | | |_| | _ | (_| | (__| <| | | | __/ |_||_| \__, |_| |_|\__,_|\___|_|\_\_| |_|\___| |___/ EOF if [[ -n $distro ]]; then printf "\033[38;2;216;1;81mLooks like you're running %s \033[0m" "$distro" else printf "\033[38;2;216;1;81mLinux distro not recognized \033[0m" fi printf "\033[0;35m @MuirlandOracle\033[0m\n\n\n" } if [ ! -f /tmp/thm-title ]; then title else colour green "[+] Re-running with root permissions" 1 rm /tmp/thm-title fi sleep 1s #Check that the script is being run with sudo if [[ $EUID -ne 0 ]]; then colour red "[-] Script is being run as a low-privileged user" 1 read -p "Would you like to run this script with higher privileges automatically (Y/n)? " choice case "$choice" in n|N) printf "\n\nPlease run the script with the following command:\n" colour code "sudo $0" 1 colour red "[-] Exiting" 2 fin ;; *) touch /tmp/thm-title sudo -E $0 ;; esac fin fi # TODO add a check for network vpn files and/or other vpn configs - how to differentiate main THM VPN config from others? #Find the VPN Config ovpn=$(find . -maxdepth 1 -name "*.ovpn" -print -quit) if [ ${#ovpn} -eq 0 ]; then colour red "[-] Config not found in current directory" 1 read -ep "Please enter the path to your config: " ovpn ovpn=${ovpn/\~/$HOME} if [ ${#ovpn} -lt 5 ]; then colour red "[-] Invalid File -- Config should be .ovpn" 1 colour red "[-] Exiting" 2 fin elif [ -f $ovpn ] && [ ${ovpn: -5} == ".ovpn" ]; then colour green "[+] Config Located successfully" 1 else colour red "[-] Config not located" 1 colour red "[-] Exiting" 2 fin fi fi #Check Internet connectivity if [ $(ping -c 1 -q 1.1.1.1 >&/dev/null; echo $?) -gt 0 ]; then colour red "[-] You are not connected to the internet" 1 colour red "[-] Exiting" 2 fin else colour green "[+] Stable internet connection" 1 fi # Determine package manager being used to create variables if pacman -V &>/dev/null; then pkg_manager_status=("pacman" "-V"); is_openvpn_installed=("pacman" "-Qs" "openvpn"); pkg_manager_update=("pacman" "-Syy"); install_openvpn=("pacman" "-S" "openvpn" "--noconfirm"); fi if dpkg-query -W -f='${Status}' apt &>/dev/null; then pkg_manager_status=("dpkg-query" "-W" "-f='${Status}'" "apt") is_openvpn_installed=("dpkg-query" "-W" "-f='${Status}'" "openvpn") pkg_manager_update=("apt" "update") install_openvpn=("apt" "install" "openvpn" "-y") fi #Ensure that Openvpn is installed if ! "${is_openvpn_installed[@]}" &>/dev/null; then colour red "[-] OpenVPN is not installed" 1 read -p "Would you like to install OpenVPN automatically (Y/n)? " choice case "$choice" in n|N) printf "\n\nPlease install OpenVPN manually\n" colour red "[-] Exiting" 2 fin ;; *) if ! "${pkg_manager_status[@]}" &>/dev/null; then colour red "[-] System doesn't use apt or pacman -- please install OpenVPN manually" 1 colour red "[-] Exiting" 2 fin else "${pkg_manager_update[@]}" &>/dev/null && "${install_openvpn[@]}" &>/dev/null & pid=$! colour process "[+] Installing OpenVPN..." while :; do running=$(ps aux | grep $pid | wc -l) if [ $running -eq 1 ]; then break fi done if "${is_openvpn_installed[@]}" &>/dev/null; then colour green "[+] Installation Process Completed" 1 else colour red "[-] Installation failed. Please try installing OpenVPN manually -- otherwise ask for further assistance in the TryHackMe Discord server, subreddit or forum" 1 colour red "[-] Exiting" 2 fin fi fi ;; esac else colour green "[+] OpenVPN is installed" 1 fi #Check that a tun0 exists if ! ip a | grep -q tun0; then colour red "[-] tun0 interface does not exist" 1 printf "Would you like the script to attempt a connection automatically (Y/n)? " read -p "" choice case "$choice" in n|N) printf "\n\nPlease connect to the vpn using the following command:\n" colour code "sudo openvpn $ovpn" printf "\n" colour red "[-] Exiting" 2 fin ;; *) if connect; then exit 0 fi ;; esac else colour green "[+] tun0 exists" 1 fi #Check that the tun0 IP is in the right range if ! ip a show tun0 | grep -qoE "10\.(2|4|6|8|9|11|13|14|17|50)\.[0-9]{1,3}\.[0-9]{1,3}" | head -1; then colour red "[-] tun0 ip is in the wrong range: $(ip addr show tun0 | grep "inet " | awk '{print $2}')" 1 read -p "Would you like the script to attempt to fix this (Y/n)? " choice case "$choice" in n|N) printf "\n\nIf you're using another VPN, please check that it isn't operating on tun0\nOtherwise please regenerate your TryHackMe VPN config pack, or try another server.\n" colour red "[-] Exiting" 2 fin ;; *) colour green "[+] Resetting tun0 interface" 1 ip link delete tun0 if connect; then exit 0 elif ! ip a | grep -qoE "10\.(2|4|6|8|9|11|13|14|17|50)\.[0-9]{1,3}\.[0-9]{1,3}" | head -1; then colour red "[-] Fatal Error: tun0 IP still in the wrong range: $(ip addr show tun0 | grep "inet " | awk '{print $2}')" 1 printf "Please try switching servers and/or regenerating your VPN config\n" colour red "[-] Exiting" 2 fin fi ;; esac else colour green "[+] tun0 IP is in the correct range" 1 fi #Check for multivpn connections=$(ps aux | grep -v "sudo\|grep" | grep -Eo "openvpn .*\.ovpn" | wc -l) if [ $connections -gt 1 ]; then colour red "[-] More than one connection running" 1 read -p "Would you like the script to attempt to fix this (Y/n)? " choice case $choice in n|N) printf "\n\nPlease run the following command, then reconnect manually:\n" colour code "sudo killall -9 openvpn" fin ;; *) killall -9 openvpn colour green "[+] Killed duplicate processes" if connect; then exit 0 fi esac else colour green "[+] Only one instance of OpenVPN is running" 1 fi #Check MTU value # default mtu is 1500, but get value from the actual tun interface origin_mtu=$(cat /sys/class/net/tun0/mtu) # Usually 30 bytes are needed for the vpn additions in the packet mtu=$((origin_mtu-30)) colour process "[+] Confirming connectivity" 2 while true; do # ping THM machine without breaking the packet into fragments. If fails, packet too big # -M do disables packet fragmentation # -s sets packet size # -W sets timeout (1 second) (second fractions not working in Ubuntu ping, wtf?) # -c only send 1 ping if [ $(ping -M do -s $mtu -W 1 -c 1 10.10.10.10 >&/dev/null; echo $?) -gt 0 ]; then # A very rare case would be an MTU value below 1000 not working. If that happens, something else is probably wrong - break the MTU check if [[ $mtu -lt 1000 ]]; then colour red "[-] MTU value failed at 1000, aborting MTU check" break fi # decrease MTU until it goes through mtu=$((mtu-30)) # if ping goes through, that's a working MTU value else # Add the 30 bytes back mtu=$((mtu+30)) # if working with the original value, nothing needs to be done if [[ $mtu -eq $origin_mtu ]]; then colour green "[+] MTU value OK" 1 break else colour red "[-] MTU not working with the value of $origin_mtu" # Fix the MTU in the interface sudo ip link set dev tun0 mtu $mtu colour green "[+] MTU set at $mtu in tun0" colour yellow "[!] Note that a working MTU value might change depending on your network condition" # fix the ovpn file read -p "Would you like the script to set the MTU value permanently in your .ovpn file (Y/n)? " choice case $choice in n|N) colour green "[+] You can set the value manually in your .ovpn file with the following line:" colour code "tun-mtu $mtu" ;; *) if [ $(grep "thm-troubleshoot" $ovpn >&/dev/null; echo $?) -eq 0 ]; then sed -i "s/tun-mtu.*/tun-mtu $mtu/g" $ovpn colour green "[+] .ovpn file MTU value changed" else sed -i "1i# Added by the thm-troubleshoot script\n# The MTU value might need to be changed depending on your network. Default is 1500\ntun-mtu $mtu\n" $ovpn colour green "[+] .ovpn file MTU value and comment added" fi ;; esac break fi fi done #Final Check if [ $(ping -c 1 -q 10\.10\.10\.10 >&/dev/null; echo $?) -eq 0 ];then colour green "[+] Connectivity checks completed!" 2 colour green "[+] You are connected to the TryHackMe Network" 2 printf "Your TryHackMe IP address is: $(curl -s http://10.10.10.10/whoami)\n\n" colour green "Happy Hacking!" 3 else colour red "[-] Something went wrong -- please ask for further assistance in the TryHackMe Discord server, subreddit, or forum" 3 fi printf "\n"