#!/bin/bash Version=241231-1054 debug=0 CORP="ingtegration-rb5009" # default value ScriptName=$(basename "$0") ScriptDir=$(dirname "0") IniFile=${ScriptDir}/${ScriptName}.ini BaseDir="/home/boig01/temp/wireguard" ((debug)) && echo -e " ScriptDir = $ScriptDir IniFile = $IniFile " NumUser=0 NameUser="" NumRouter=0 NameRouter="" Mode=0 BOLD=$( tput bold) NORMAL=$( tput sgr0) RESET=$( tput sgr0) NC=$( tput sgr0) # No color BOLD=$( tput bold) BLACK=$( tput setaf 0) RED=$( tput setaf 1) GREEN=$( tput setaf 2) YELLOW=$( tput setaf 3) BLUE=$( tput setaf 4) MAGENTA=$( tput setaf 5) CYAN=$( tput setaf 6) WHITE=$( tput setaf 7) DEFAULT=$( tput setaf 9) #---ini file parameters unset PARAMS; PARAMS=( Endpoint_Rtr_Addr_Public Endpoint_Rtr_Addr_Private Endpoint_Rrt_Port Endpoint_Rtr_PUB_KEY Endpoint_Usr_Addr Endpoint_Usr_Port Endpoint_Usr_PUB_KEY ) #========== INTERNAL FUNCTIONS ================================================ #---------- function Info ----------------------------------------------------- # # With date / time prefix # Info() { printf "${GREEN}%s ${NC} %s\n" "$( date +%F_%T )" "$*" } #---------- function Message -------------------------------------------------- # # Send to STDOUT # function Message() { printf "\n${GREEN}[i] ${BLUE}%s${NC}\n" "$*" } #---------- ip2int ------------------------------------------------------------ # function ip2int() { local a b c d { IFS=. read a b c d; } <<< $1 echo $(((((((a << 8) | b) << 8) | c) << 8) | d)) } #---------- int2ip ------------------------------------------------------------ # function int2ip() { local ui32=$1; shift local ip n for n in 1 2 3 4; do ip=$((ui32 & 0xff))${ip:+.}$ip ui32=$((ui32 >> 8)) done echo $ip } #---------- CreateUser -------------------------------------------------------- # function CreateUser() { local debug=0 local ClientName="$1" local Corp="$2" #local CLIENT_NUM=$(printf "%03d" $3) local WgUsrDir="${BaseDir}/${Corp}/users" # BaseDir global variable #---Create paths if not there [ ! -d "$WgUsrDir" ] && mkdir -p "${WgUsrDir}" CLIENT_PRIV_KEY=$(wg genkey) CLIENT_PUB_KEY=$(echo "${CLIENT_PRIV_KEY}" | wg pubkey) CLIENT_PRE_SHARED_KEY=$(wg genpsk) #CLIENT_FILE_PREFIX="${CLIENT_NUM}-${ClientName}" CLIENT_FILE_PREFIX="${ClientName}" CLIENT_FILE_WIN="${WgUsrDir}/${CLIENT_FILE_PREFIX}.conf" CLIENT_FILE_RTR="${WgUsrDir}/${CLIENT_FILE_PREFIX}.Endpoint.rsc" ((debug)) && echo -e " Corp = $Corp ClientName = $ClientName CLIENT_FILE_WIN = $CLIENT_FILE_WIN CLIENT_FILE_RTR = $CLIENT_FILE_RTR " && exit echo -e "Client: ${GREEN}---------------------------------------------------------${NC}" echo -e "[Interface] PrivateKey = ${CLIENT_PRIV_KEY} ListenPort = 51821 Address = 10.8.38.${ClientNum}/32 DNS = 1.1.1.1,8.8.8.8 [Peer] PublicKey = ${Endpoint_Usr_PUB_KEY} PresharedKey = ${CLIENT_PRE_SHARED_KEY} AllowedIPs = 10.8.0.0/16 Endpoint = ${Endpoint_Usr_Addr}:${Endpoint_Usr_Port} PersistentKeepalive = 25 " | tee "${CLIENT_FILE_WIN}" echo -e "\${CORP} Router: ${GREEN}---------------------------------------------------------${NC}" echo -e "/interface wireguard peers add allowed-address=10.8.38.${ClientNum}/32 disabled=no comment=\"User ${ClientName}\" interface=wg1 \\ preshared-key=\"${CLIENT_PRE_SHARED_KEY}\" public-key=\"${CLIENT_PUB_KEY}\""| tee "${CLIENT_FILE_RTR}" Message "QR Code:" qrencode -t ansiutf8 -l L < "${CLIENT_FILE_WIN}" qrencode -l L -s 6 -d 225 -o "${CLIENT_FILE_WIN}.png" < "${CLIENT_FILE_WIN}" } #---------- CreateRouter ------------------------------------------------------ # function CreateRouter() { local debug=1 local RouterNum="$1" local RouterSubnet="$2" local Corp="$3" local BaseDir="${BaseDir}/${Corp}" # BaseDir global variable local WgRtrDir="${BaseDir}/routers" #---Create paths if not there [ ! -d "$WgRtrDir" ] && mkdir -p "${WgRtrDir}" RTR_PRIV_KEY=$(wg genkey) Endpoint_Rtr_PUB_KEY=$(echo "${RTR_PRIV_KEY}" | wg pubkey) RTR_PRE_SHARED_KEY=$(wg genpsk) RTR_NUM=$(printf "%03d" $1) RTR_FILE_PREFIX="${RTR_NUM}-Router" RTR_FILE_RTR="${WgRtrDir}/${RTR_FILE_PREFIX}_Client.rsc" RTR_FILE_RTR_ENDPOINT="${WgRtrDir}/${RTR_FILE_PREFIX}_Endpoint.rsc" ((debug)) && echo -e " Corp = $Corp RTR_NUM = $RTR_NUM CLIENT_FILE_RTR = $RTR_FILE_RTR BaseDir = $BaseDir PreShared Key = $RTR_PRE_SHARED_KEY " && exit [ -d "${BaseDir}" ] && Message "Creating dir ${BaseDir}" && mkdir -p "${BaseDir}" Message "Generated output files:" echo -e "${GREEN}---------------------------------------------------------${NC} ${RTR_FILE_RTR} ${RTR_FILE_RTR_ENDPOINT} " Message "Client Router Config:" echo -e "${GREEN}---------------------------------------------------------${NC}" echo -e "/interface wireguard add listen-port=13239 mtu=1420 name=wg01 private-key=\"${RTR_PRIV_KEY}\" /ip address add address=172.18.1.${RouterNum}/32 comment=wg-wg01 interface=wg01 /interface wireguard peers add allowed-address=172.16.18.254 client-keepalive=10 disabled=no comment=\"CCR1 Montreal\" interface=wg01 \\ endpoint-address=${Endpoint_Rtr_Addr_Public} endpoint-port=${Endpoint_Rrt_Port} preshared-key=\"${RTR_PRE_SHARED_KEY}\" public-key=\"${Endpoint_Rtr_PUB_KEY}\" /system script add dont-require-permissions=no name=ping-CCR1 owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\\ \"/ping interval=10 10.1.8.11 count=61\" /system/scheduler add interval=10m name=Ping-CCR1 on-event=\"/system/script/run ping-CCR1\" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=apr/02/2022 start-time=12:00:00 " \ | tee "${RTR_FILE_RTR}" #echo -e "\n" Message "${EndpointID} endpoint Config:" echo -e "${GREEN}---------------------------------------------------------${NC}" echo -e "/interface wireguard peers add allowed-address=10.1.41.${RouterNum}/32,${RouterSubnet} disabled=no comment=\"Router ${RouterNum} ${NameRouter}\" \\ interface=WG-Routers preshared-key=\"${RTR_PRE_SHARED_KEY}\" public-key=\"${Endpoint_Rtr_PUB_KEY}\" /ip route add dst-address=${RouterSubnet} gateway=10.1.41.${RouterNum}" \ | tee "${RTR_FILE_RTR_ENDPOINT}" } #---------- function RrtSubnet ------------------------------------------------ # RtrSubnet() { local RtrNum=$1 BaseNum=$(ip2int $Start_Subnet) # Subnet de depart en format integer Nth=$((RtrNum-1)) # Le router #1 est "0" dans la séquence de subnet, #2 est 1, etc Nth=$((Nth*NAPS)) # Decimal a aditionner en fonction pour le Nth router Subnet=$((BaseNum+Nth)) # Nth subnet calculé # Subnet="${Subnet}/$(Bits_Subnet=3})" echo -e "$(int2ip $Subnet)/${Subnet_Bits}" } #---------- function Interactive ---------------------------------------------- # function Interactive() { echo -e "\nInteractive function" } #---------- function Help ----------------------------------------------------- # function Help() { echo -e " MikroTik WireGuard configurator usage: ${ScriptName} [Options] -c Corp name -i Interactive (will ask for all needed infos) -l List endpoints in config -n User mode: # ot the new user (Unique user number between 1 and 253) -u User name (example: AdrianSmith, don't use space or accentuated chars) -r Router mode: # of the new client router (EVOQ router #, like 1 or 11) -s Router Name (example: Montreal-1 , will appear as comment in endpoint router ) When in user mode, you must provide name & unique user number between 2 and 253. This user number will be assigned an ip address 10.1.40.[user #]. " && exit } #================ MAIN ======================================================== # ((!$#)) && Help && exit # If no command parameters passed, help and bail out echo -e "\n${GREEN}${ScriptName} ${BLUE}configurator version ${YELLOW}$Version${NC}" while getopts c:dhiln:r:s:u: option do case "${option}" in c) CORP=${OPTARG} ;; d) debug=1 ;; h) Help exit ;; i) Interactive exit ;; l) Message "Listing endpoints in ${IniFile}" grep '\[' ${IniFile} exit ;; n) NumUser=${OPTARG} Mode="User" ;; r) NumRouter=${OPTARG} Mode="Router" ;; s) NameRouter="${OPTARG}" ;; u) NameUser="${OPTARG}" ;; *) echo -e "Usage (bad argument: $OPTARG) \n" exit 1;; esac done ((debug)) && echo -e " NumRouter = ${NumRouter} NumUser = ${NumUser} RtrSubnet = $(RtrSubnet ${NumRouter}) " if [[ "${NumRouter}" -ne "0" && "${NumUser}" -ne "0" ]] then echo "** Error, can't use user and router # simulteaneously" exit 1 fi #---Endpoint Router Config EndpointID=RB5009 for PARAM in "${PARAMS[@]}" do eval ${PARAM}=$(sed -nr "/^\[${CORP}\]/ { :l /^${PARAM}[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ${IniFile}) done #Endpoint_Rtr_Addr_Public=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Rtr_Addr_Public[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Rtr_Addr_Private=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Rtr_Addr_Private[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Rrt_Port=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Rrt_Port[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Rtr_PUB_KEY=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Rtr_PUB_KEY[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Usr_Addr=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Usr_Addr[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Usr_Port=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Usr_Port[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) #Endpoint_Usr_PUB_KEY=$(sed -nr "/^\[${CORP}\]/ { :l /^Endpoint_Usr_PUB_KEY[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" ./genconfig.ini) echo -e " CORP = $CORP Endpoint_Rtr_Addr_Public = $Endpoint_Rtr_Addr_Public Endpoint_Rtr_Addr_Private = $Endpoint_Rtr_Addr_Private Endpoint_Rrt_Port = $Endpoint_Rrt_Port Endpoint_Rtr_PUB_KEY = $Endpoint_Rtr_PUB_KEY Endpoint_Usr_Addr = $Endpoint_Usr_Addr Endpoint_Usr_Port = $Endpoint_Usr_Port Endpoint_Usr_PUB_KEY = $Endpoint_Usr_PUB_KEY " ((debug)) && printf "Parameters : %s\n" "${PARAMS[@]}" #exit #---Client Router Subnets Start_Subnet=10.1.41.0 Bits_Subnet=8 Subnet_Bits=$((32-Bits_Subnet)) # Router address subnet bits NAPS=$((2**Bits_Subnet)) # Nombre d'Adresses Par Subnet case "$Mode" in User) Message "Creating User" CreateUser ${NameUser} ${CORP} exit ;; Router) Message "Creating Router with $(RtrSubnet ${NumRouter})" CreateRouter $NumRouter $(RtrSubnet ${NumRouter}) ${CORP} exit ;; *) echo -e "\n** ERROR : User # was not provided" Help ;; esac