#!/bin/bash #=================== Environment =============================================== # ScriptName=$(basename "$0") SshUser=ansible #SshKey="/home/wireguard/.ssh/ansible_evoq_rsa" SshKey="/home/boig01/.ssh/ansible_evoq_rsa" #BaseDir="/home/wireguard" BaseDir="/dev/shm" CCR1=10.1.8.11 CCR2=10.1.8.12 Version=240222_1842 CORP="EVOQ" TmpUserList=$(mktemp -p /dev/shm) # Wireguard For Routers RtrCCR1Int=WG-Routers RtrCCR1PubKey="9au45IDNJhHDNtN+LIpJDyMFTEYdN9WOSSHEJS8WRmw=" RtrCCR1Prefix="10.1.32" RtrCCR1Address="10.1.32.254/24" RtrCCR1Port=13232 WgRtrDir="${BaseDir}/routers" # Wireguard For Users UsrCCR1Int=WG-Users UsrCCR1PubKey="EsxauwYNBotyfDJzy9yCUXDci2gHbtZLhUWnMgMP0AY=" UsrCCR1Prefix="10.1.33" UsrCCR1Address="10.1.33.254/24" UsrCCR1Port=13233 WgUsrDir="${BaseDir}/users" YELLOW='\033[0;33m' GREEN='\033[0;32m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Create paths if not there [ ! -d "$WgRtrDir" ] && mkdir -p "${WgRtrDir}" [ ! -d "$WgUsrDir" ] && mkdir -p "${WgUsrDir}" #=================== function Info ============================================= # # Avec date / time prefix # Info() { printf "${GREEN} %s ${NC} %s\n" "$( date +%F_%T )" "$*" >&2; } # send to stderr #=================== function Message ========================================== # Message() { printf "${GREEN}%s ${NC}\n" "$*" ;} # send to stderr #=================== function Help ============================================= # function Help () { echo -e " usage: $ScriptName [options] -l List WireGuard clients on CCR1 -h This help " } #=================== function addCCR1 ========================================== # function addCCR1() { local Router="$1" echo -e "\nAdding ${Router} Wireguard account to CCR1..." ssh -i ${SSHKey} ansible@${CCR1} "/ppp secret add local-address=10.1.31.254 name=${Router} password=${L2TPPass} remote-address=${CCRSideIP} routes=\"${ip_Subnet} $CCRSideIP 1\" service=l2tp" if [ $? = 0 ] then echo "${Router} Wireguard account successfully added to CCR1" else echo "Failed to add ${Router} Wireguard account to CCR1" fi } #=================== function newClient ======================================= # function newClient() { ENDPOINT="${SERVER_PUB_IP}:${SERVER_PORT}" echo "" echo "Tell me a name for the client." echo "The name must consist of alphanumeric character. It may also include an underscore or a dash and can't exceed 15 chars." until [[ ${CLIENT_NAME} =~ ^[a-zA-Z0-9_-]+$ && ${CLIENT_EXISTS} == '0' && ${#CLIENT_NAME} -lt 16 ]]; do read -rp "Client name: " -e CLIENT_NAME CLIENT_EXISTS=$(grep -c -E "^### Client ${CLIENT_NAME}\$" "$(pwd)/wireguard/${SERVER_WG_NIC}/${SERVER_WG_NIC}.conf") if [[ ${CLIENT_EXISTS} == '1' ]]; then echo "" echo "A client with the specified name was already created, please choose another name." echo "" fi done for DOT_IP in {2..254}; do DOT_EXISTS=$(grep -c "${SERVER_WG_IPV4::-1}${DOT_IP}" "$(pwd)/wireguard/${SERVER_WG_NIC}/${SERVER_WG_NIC}.conf") if [[ ${DOT_EXISTS} == '0' ]]; then break fi done if [[ ${DOT_EXISTS} == '1' ]]; then echo "" echo "The subnet configured supports only 253 clients." exit 99 fi BASE_IP=$(echo "$SERVER_WG_IPV4" | awk -F '.' '{ print $1"."$2"."$3 }') until [[ ${IPV4_EXISTS} == '0' ]]; do read -rp "Client's WireGuard IPv4: ${BASE_IP}." -e -i "${DOT_IP}" DOT_IP CLIENT_WG_IPV4="${BASE_IP}.${DOT_IP}" IPV4_EXISTS=$(grep -c "$CLIENT_WG_IPV4/24" "$(pwd)/wireguard/${SERVER_WG_NIC}/${SERVER_WG_NIC}.conf") if [[ ${IPV4_EXISTS} == '1' ]]; then echo "" echo "A client with the specified IPv4 was already created, please choose another IPv4." echo "" fi done BASE_IP=$(echo "$SERVER_WG_IPV6" | awk -F '::' '{ print $1 }') until [[ ${IPV6_EXISTS} == '0' ]]; do read -rp "Client's WireGuard IPv6: ${BASE_IP}::" -e -i "${DOT_IP}" DOT_IP CLIENT_WG_IPV6="${BASE_IP}::${DOT_IP}" IPV6_EXISTS=$(grep -c "${CLIENT_WG_IPV6}/64" "$(pwd)/wireguard/${SERVER_WG_NIC}/${SERVER_WG_NIC}.conf") if [[ ${IPV6_EXISTS} == '1' ]]; then echo "" echo "A client with the specified IPv6 was already created, please choose another IPv6." echo "" fi done # Generate key pair for the client CLIENT_PRIV_KEY=$(wg genkey) CLIENT_PUB_KEY=$(echo "${CLIENT_PRIV_KEY}" | wg pubkey) CLIENT_PRE_SHARED_KEY=$(wg genpsk) mkdir -p "$(pwd)/wireguard/${SERVER_WG_NIC}/client/${CLIENT_NAME}" >/dev/null 2>&1 HOME_DIR="$(pwd)/wireguard/${SERVER_WG_NIC}/client/${CLIENT_NAME}" # Create client file and add the server as a peer echo "[Interface] PrivateKey = ${CLIENT_PRIV_KEY} Address = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128 DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2} [Peer] PublicKey = ${SERVER_PUB_KEY} PresharedKey = ${CLIENT_PRE_SHARED_KEY} Endpoint = ${ENDPOINT} AllowedIPs = 0.0.0.0/0,::/0" >>"${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf" # Add the client as a peer to the MikroTik (to client folder) echo "# WireGuard client peer configure /interface wireguard peers add allowed-address=${CLIENT_WG_IPV4}/32 comment=\\ ${SERVER_WG_NIC}-client-${CLIENT_NAME} interface=${SERVER_WG_NIC} \\ preshared-key=\"${CLIENT_PRE_SHARED_KEY}\" public-key=\\ \"${CLIENT_PUB_KEY}\" " >"${HOME_DIR}/mikrotik-peer-${SERVER_WG_NIC}-client-${CLIENT_NAME}.rsc" # Add the client as a peer to the MikroTik echo "# WireGuard client peer configure /interface wireguard peers add allowed-address=${CLIENT_WG_IPV4}/32 comment=\\ ${SERVER_WG_NIC}-client-${CLIENT_NAME} interface=${SERVER_WG_NIC} \\ preshared-key=\"${CLIENT_PRE_SHARED_KEY}\" public-key=\\ \"${CLIENT_PUB_KEY}\" " >> "$(pwd)/wireguard/${SERVER_WG_NIC}/mikrotik/${SERVER_WG_NIC}.rsc" # Add the client as a peer to the server echo -e "\n### Client ${CLIENT_NAME} [Peer] PublicKey = ${CLIENT_PUB_KEY} PresharedKey = ${CLIENT_PRE_SHARED_KEY} AllowedIPs = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128" >>"$(pwd)/wireguard/${SERVER_WG_NIC}/${SERVER_WG_NIC}.conf" echo -e "\nHere is your client config file as a QR Code:" qrencode -t ansiutf8 -l L <"${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf" qrencode -l L -s 6 -d 225 -o "${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.png" <"${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf" echo -e "${INFO} Config available in ${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf" echo -e "${INFO} QR is also available in ${HOME_DIR}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.png" echo -e "${INFO} MikroTik peer config available in ${HOME_DIR}/mikrotik-${SERVER_WG_NIC}-client-${CLIENT_NAME}.rsc" } #=================== function manageMenu ====================================== # function manageMenu() { echo "" echo "It looks like this WireGuard interface is already." echo "" echo "What do you want to do?" echo " 1) Add a new client" echo " 2) Exit" until [[ ${MENU_OPTION} =~ ^[1-4]$ ]]; do read -rp "Select an option [1-2]: " MENU_OPTION done case "${MENU_OPTION}" in 1) newClient ;; 2) exit 0 ;; esac } #=================== function listConfs ======================================= # function listConfs() { local directory directory="$(pwd)/wireguard" if [ -d "${directory}" ]; then echo "List of existing configurations:" i=1 for folder in "${directory}"/*/; do local users count folder_name users="${folder}/client/" count=$(find "$users" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | wc -l) folder_name=$(basename "${folder}") echo "${i}. ${folder_name} [${count} user(s)]" ((i++)) done fi echo "" } #=================== function listCCR1 ========================================= # # Filter 1: enlever les ";" et remplacer ^m par LF # Filter 2: Grouper 2 lignes consecutives # Filter 3: Print field #4 et #3 # function ListCCR() { Message "User List" ssh -i $SshKey ${SshUser}@${CCR1} "/interface/wireguard/peers/print proplist=comment,interface" \ | grep User | tr -d ";" | sed -e "s/\r//g" \ | awk 'NR%2 {printf("%s ", $0); next} {print $0}' \ | awk '{print $4, $3}' | tee ${TmpUserList} LastEntry=$(cat ${TmpUserList} | sort -r | head -1 | awk '{ print $1 }') NextEntry=$(($LastEntry+1)) echo -e " Last Entry = $LastEntry Next Entry = $NextEntry " } #=================== MAIN ===================================================== # echo -e "\nWireGuard-MikroTik ${BLUE}${CORP}${NC} configurator\n" ((!$#)) && Help && exit while getopts cfhl option do case "${option}" in c) BoolCreate=1 ;; f) VarFileLog=1;; h) Help exit 0;; l) ListCCR ;; *) Help exit 1;; esac done rm -f ${TmpUserList} exit #? Check for root, OS, WireGuard installCheck listConfs #? Check server exist serverName #? Check if WireGuard is already installed and load params if [[ -e $(pwd)/wireguard/${SERVER_WG_NIC}/params ]]; then # shellcheck source=/dev/null source "$(pwd)/wireguard/${SERVER_WG_NIC}/params" manageMenu else newInterface fi