#!/bin/bash if [[ "${NETWORK_BASH}" != "" ]] then return fi # Includes #----------------------------------------------------------------------------------------------------------------------------------- . /usr/global/lib/default.bash . /usr/global/lib/dns.bash # Global Variable #----------------------------------------------------------------------------------------------------------------------------------- declare -g NETWORK_BASH=1 declare -g NETWORK_OPENVPN_STATUS declare -g NETWORK_SRC_TYPE declare -Ag NETWORK_SRC_TAB declare -g NETWORK_SRC_ID_LIST declare -Ag NETWORK_SRC_IP_IDX declare -g NETWORK_DST_TYPE declare -Ag NETWORK_DST_TAB declare -g NETWORK_DST_ID_LIST declare -g NETWORK_CONFIG_FILE="/etc/sysconfig/rx3-network" declare -g NETWORK_CONFIG_LOCK="/var/lock/network/rx3-network" #declare -g NETWORK_CONFIG_LOCK="${NETWORK_CONFIG_FILE}" file_lock ${NETWORK_CONFIG_LOCK} READ 9 [ -e "${NETWORK_CONFIG_FILE}" ] && . "${NETWORK_CONFIG_FILE}" file_unlock 9 if [ ! -v LOG ] then LOG=":" fi #-------------------------------------------------------------------------------------------------------------------------- # network_common_load #-------------------------------------------------------------------------------------------------------------------------- network_common_load() { NETWORK_OPENVPN_STATUS="$( sudo /usr/local/sbin/openvpn-status)" NETWORK_TABLE_LIST="" } #-------------------------------------------------------------------------------------------------------------------------- # network_common_dump #-------------------------------------------------------------------------------------------------------------------------- network_common_dump() { echo "NETWORK_OPENVPN_STATUS: [${NETWORK_OPENVPN_STATUS}]" echo echo "NETWORK_TABLE_LIST: [${NETWORK_TABLE_LIST}]" echo } #-------------------------------------------------------------------------------------------------------------------------- # network_dst_tab_load #-------------------------------------------------------------------------------------------------------------------------- network_dst_tab_load() { ndtl_id=0 while IFS= read -r line do line=${line%%#*} if [[ ! -z "$line" ]] then set ${line} ndtl_name="$1" ndtl_type="$2" ndtl_device="$3" ndtl_config="$4" ndtl_table="$5" var_assign NETWORK_DST_ID_LIST "${ndtl_id}" INC tab_assign NETWORK_DST_TAB "${ndtl_id},Name" "${ndtl_name}" tab_assign NETWORK_DST_TAB "${ndtl_id},Type" "${ndtl_type}" tab_assign NETWORK_DST_TAB "${ndtl_id},Device" "${ndtl_device}" tab_assign NETWORK_DST_TAB "${ndtl_id},Config" "${ndtl_config}" tab_assign NETWORK_DST_TAB "${ndtl_id},Table" "${ndtl_table}" var_assign NETWORK_TABLE_LIST "${ndtl_table}" INC tab_assign NETWORK_DST_TAB "${ndtl_id},Status" "$( ip link show dev ${ndtl_device} 2>/dev/null | grep -q ",UP," && echo 1 || echo 0)" dns_lookup A vpn${ndtl_id}.vpn.rx3 "NOCACHE" tab_assign NETWORK_DST_TAB "${ndtl_id},IP" "${dns_value}" case "${ndtl_type}" in "0") set $(ip -s link show ${ndtl_device} 2>/dev/null ) &>/dev/null ndtl_bytes_received="$( echo ${27} | numfmt --to=iec-i --suffix=B)" ndtl_bytes_sent="$( echo ${40} | numfmt --to=iec-i --suffix=B)" ndtl_uptime="" ;; "1") set $( echo "${NETWORK_OPENVPN_STATUS}" | grep ${ndtl_device}) &>/dev/null # i=1; while [[ $i -lt 50 ]]; do eval "val=\${$i}"; echo "($i):[${val}]" 1>&2; i=$(( $i + 1)); done ndtl_bytes_received="$( echo ${18/bytes,} | numfmt --to=iec-i --suffix=B)" ndtl_bytes_sent="$( echo ${22/bytes,} | numfmt --to=iec-i --suffix=B)" ndtl_start_date="$( grep "ext-client-${ndtl_device}.conf" /var/log/rx3-vpn.status 2>/dev/null | sed -e "s/.*Date: \[//" -e "s/\].*//")" if [[ "${ndtl_start_date}" == "" ]] then ndtl_uptime="" else ndtl_uptime=$( echo "$(($(date +%s) - $(date -d "${ndtl_start_date}" +%s)))" | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}') fi ;; esac tab_assign NETWORK_DST_TAB "${ndtl_id},Bytes_Received" "${ndtl_bytes_received}" tab_assign NETWORK_DST_TAB "${ndtl_id},Bytes_Sent" "${ndtl_bytes_sent}" tab_assign NETWORK_DST_TAB "${ndtl_id},Uptime" "${ndtl_uptime}" ndtl_id=$(( ${ndtl_id} + 1)) fi done <<< ${NETWORK_DST_CONFIG} } #-------------------------------------------------------------------------------------------------------------------------- # network_dst_tab_get #-------------------------------------------------------------------------------------------------------------------------- network_dst_tab_get() { dst_id="$1" dst_name=${NETWORK_DST_TAB["${dst_id},Name"]} dst_type=${NETWORK_DST_TAB["${dst_id},Type"]} dst_device=${NETWORK_DST_TAB["${dst_id},Device"]} dst_config=${NETWORK_DST_TAB["${dst_id},Config"]} dst_table=${NETWORK_DST_TAB["${dst_id},Table"]} dst_status=${NETWORK_DST_TAB["${dst_id},Status"]} dst_ip=${NETWORK_DST_TAB["${dst_id},IP"]} dst_bytes_received=${NETWORK_DST_TAB["${dst_id},Bytes_Received"]} dst_bytes_sent=${NETWORK_DST_TAB["${dst_id},Bytes_Sent"]} dst_start_date=${NETWORK_DST_TAB["${dst_id},Start_Date"]} dst_uptime=${NETWORK_DST_TAB["${dst_id},Uptime"]} } #-------------------------------------------------------------------------------------------------------------------------- # network_dst_tab_dump #-------------------------------------------------------------------------------------------------------------------------- network_dst_tab_dump() { echo "NETWORK_DST_ID_LIST: [${NETWORK_DST_ID_LIST}]" echo echo "NETWORK_DST_TAB:" for key in "${!NETWORK_DST_TAB[@]}" do echo "[${key}]: [${NETWORK_DST_TAB[${key}]}]" done | sort -n echo } #-------------------------------------------------------------------------------------------------------------------------- # network_src_tab_load #-------------------------------------------------------------------------------------------------------------------------- network_src_tab_load() { nstl_id=0 nstl_port_default=3000 while IFS= read -r line do line=${line%%#*} if [[ ! -z "$line" ]] then set ${line} nstl_ip="$1" nstl_type="$2" nstl_owner="$3" nstl_table="$4" nstl_port_start="$5" nstl_port_range="$6" if [[ "${nstl_port_start}" == "-" ]] then nstl_port_start=${nstl_port_default} fi dns_lookup PTR ${nstl_ip} nstl_name="${dns_value}" case "${nstl_type}" in "0"|"1") # Local + Routed nstl_device="" nstl_status="2" nstl_bytes_received="" nstl_bytes_sent="" nstl_uptime="" nstl_last_seen="" ;; "2") # OpenVPN nstl_device="tun0" nstl_status_line="$( echo "${NETWORK_OPENVPN_STATUS}" | grep "${nstl_device}.log: CLIENT_LIST.*${nstl_ip},")" if [[ "${nstl_status_line}" == "" ]] then nstl_status="0" nstl_bytes_received="" nstl_bytes_sent="" nstl_start_date="" nstl_uptime="" nstl_last_seen="$( stat -c "%x" /etc/openvpn/status/${nstl_name}.status 2>/dev/null | sed -e 's/\..*//')" else nstl_status="1" IFS=, set ${nstl_status_line} &>/dev/null unset IFS nstl_bytes_received=$( echo ${6} | numfmt --to=iec-i --suffix=B) nstl_bytes_sent=$( echo ${7} | numfmt --to=iec-i --suffix=B) nstl_start_date=${8} nstl_uptime=$( echo "$(($(date +%s) - $(date -d "${nstl_start_date}" +%s)))" | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}') nstl_last_seen="$(stat -c "%x" /etc/openvpn/status/${nstl_name}.status 2>/dev/null | sed -e 's/\..*//')" fi ;; esac if [[ " ${NETWORK_TABLE_LIST} " != *" ${nstl_table} "* ]] then err_echo "Invalid table number: [${nstl_table}] in network src entry: [${nstl_id}]!" exit 1 fi var_assign NETWORK_SRC_ID_LIST "${nstl_id}" INC tab_assign NETWORK_SRC_TAB "${nstl_id},IP" "${nstl_ip}" tab_assign NETWORK_SRC_TAB "${nstl_id},Name" "${nstl_name}" tab_assign NETWORK_SRC_TAB "${nstl_id},Type" "${nstl_type}" tab_assign NETWORK_SRC_TAB "${nstl_id},Owner" "${nstl_owner}" tab_assign NETWORK_SRC_TAB "${nstl_id},Table" "${nstl_table}" tab_assign NETWORK_SRC_TAB "${nstl_id},Port_Start" "${nstl_port_start}" tab_assign NETWORK_SRC_TAB "${nstl_id},Port_Range" "${nstl_port_range}" tab_assign NETWORK_SRC_TAB "${nstl_id},Device" "${nstl_device}" tab_assign NETWORK_SRC_TAB "${nstl_id},Status" "${nstl_status}" tab_assign NETWORK_SRC_TAB "${nstl_id},Bytes_Received" "${nstl_bytes_received}" tab_assign NETWORK_SRC_TAB "${nstl_id},Bytes_Sent" "${nstl_bytes_sent}" tab_assign NETWORK_SRC_TAB "${nstl_id},Uptime" "${nstl_uptime}" tab_assign NETWORK_SRC_TAB "${nstl_id},Last_Seen" "${nstl_last_seen}" tab_assign NETWORK_SRC_IP_IDX "${nstl_ip}" "${nstl_id}" nstl_id=$(( ${nstl_id} + 1)) nstl_port_default=$(( ${nstl_port_start} + ${nstl_port_range})) fi done <<< ${NETWORK_SRC_CONFIG} } #-------------------------------------------------------------------------------------------------------------------------- # network_src_tab_get #-------------------------------------------------------------------------------------------------------------------------- network_src_tab_get() { src_id="$1" src_ip=${NETWORK_SRC_TAB["${src_id},IP"]} src_name=${NETWORK_SRC_TAB["${src_id},Name"]} src_type=${NETWORK_SRC_TAB["${src_id},Type"]} src_owner=${NETWORK_SRC_TAB["${src_id},Owner"]} src_table=${NETWORK_SRC_TAB["${src_id},Table"]} src_port_start=${NETWORK_SRC_TAB["${src_id},Port_Start"]} src_port_range=${NETWORK_SRC_TAB["${src_id},Port_Range"]} if [[ "${src_port_range}" != "0" ]] then src_port_end=$(( ${src_port_start} + ${src_port_range} - 1)) else src_port_start="" src_port_end="" fi src_device=${NETWORK_SRC_TAB["${src_id},Device"]} src_status=${NETWORK_SRC_TAB["${src_id},Status"]} src_bytes_received=${NETWORK_SRC_TAB["${src_id},Bytes_Received"]} src_bytes_sent=${NETWORK_SRC_TAB["${src_id},Bytes_Sent"]} src_start_date=${NETWORK_SRC_TAB["${src_id},Start_Date"]} src_uptime=${NETWORK_SRC_TAB["${src_id},Uptime"]} src_last_seen=${NETWORK_SRC_TAB["${src_id},Last_Seen"]} } #-------------------------------------------------------------------------------------------------------------------------- # network_src_tab_dump #-------------------------------------------------------------------------------------------------------------------------- network_src_tab_dump() { echo "NETWORK_SRC_ID_LIST: [${NETWORK_SRC_ID_LIST}]" echo echo "NETWORK_SRC_IP_IDX:" for key in "${!NETWORK_SRC_IP_IDX[@]}" do echo "[${key}]: [${NETWORK_SRC_IP_IDX[${key}]}]" done | sort -n echo echo "NETWORK_SRC_TAB:" for key in "${!NETWORK_SRC_TAB[@]}" do echo "[${key}]: [${NETWORK_SRC_TAB[${key}]}]" done | sort -n echo } #-------------------------------------------------------------------------------------------------------------------------- # network_src_tab_ip_lookup #-------------------------------------------------------------------------------------------------------------------------- network_src_tab_ip_lookup() { src_ip="$1" src_id=${NETWORK_SRC_IP_IDX["${src_ip}"]} } #-------------------------------------------------------------------------------------------------------------------------- # network_tab_load #-------------------------------------------------------------------------------------------------------------------------- network_tab_load() { dns_tab_load network_common_load network_dst_tab_load network_src_tab_load dns_tab_save } #-------------------------------------------------------------------------------------------------------------------------- # network_tab_dump #-------------------------------------------------------------------------------------------------------------------------- network_tab_dump() { dns_tab_dump network_common_dump network_dst_tab_dump network_src_tab_dump } #-------------------------------------------------------------------------------------------------------------------------- # network_table_init #-------------------------------------------------------------------------------------------------------------------------- network_table_init() { ${LOG} "Add Rx3 routes in VPN tables" for table in ${TABLE_LIST} do for route in ${IP_ROUTE} do ${DEBUG} ip route add ${route/:*/} table ${table} dev ${route/*:/} done done ${LOG} "Copy main default rule into table 3 (VPN Local routing table)" if [[ "$(ip route list match 0.0.0.0 table main)" != "" ]] then ${DEBUG} ip route add $(ip route list match 0.0.0.0 table main) table 3 fi } #-------------------------------------------------------------------------------------------------------------------------- # network_table_deinit #-------------------------------------------------------------------------------------------------------------------------- network_table_deinit() { ${LOG} "Remove default route in table 3" ${DEBUG} ip route del default table 3 ${LOG} "Remove Rx3 routes in VPN tables" for table in ${TABLE_LIST} do for route in ${IP_ROUTE} do ${DEBUG} ip route del ${route/:*/} table ${table} dev ${route/*:/} 2>/dev/null done done } #-------------------------------------------------------------------------------------------------------------------------- # network_table_set #-------------------------------------------------------------------------------------------------------------------------- network_table_set() { nts_ip=$1 nts_table=$2 network_src_tab_ip_lookup "${nts_ip}" if [[ "${src_id}" == "" ]] then err_echo "IP not found: [${nts_ip}]!" return 1 fi if [[ " ${NETWORK_TABLE_LIST} " != *" ${nts_table} "* ]] then err_echo "Table not found: [${nts_table}]!" return 1 fi tab_assign NETWORK_SRC_TAB "${src_id},Table" "${ts_table}" ${DEBUG} sed "/^NETWORK_SRC_CONFIG=\"/,/^\"/ { s/^\(${nts_ip//./\\.}[[:space:]]\+\([^\t ]\+[[:space:]]\+\)\{2\}\)[^[:space:]]\+/\1${nts_table}/ }" -i ${NETWORK_CONFIG_FILE} ${DEBUG} ip rule del from ${nts_ip} 2>/dev/null ${DEBUG} ip rule add from ${nts_ip} table ${nts_table} } #-------------------------------------------------------------------------------------------------------------------------- # network_forward_add #-------------------------------------------------------------------------------------------------------------------------- network_forward_add() { nfa_ip=$1 nfa_port_start=$2 nfa_port_end=$3 ${DEBUG} iptables -t nat -A PREROUTING-VPN -p tcp -m tcp --dport ${nfa_port_start}:${nfa_port_end} -j DNAT --to ${nfa_ip} ${DEBUG} iptables -t nat -A PREROUTING-VPN -p udp -m udp --dport ${nfa_port_start}:${nfa_port_end} -j DNAT --to ${nfa_ip} } #-------------------------------------------------------------------------------------------------------------------------- # network_forward_remove #-------------------------------------------------------------------------------------------------------------------------- network_forward_remove() { nfr_ip=$1 nfr_port_start=$2 nfr_port_end=$3 ${DEBUG} iptables -t nat -D PREROUTING-VPN -p tcp -m tcp --dport ${nfr_port_start}:${nfr_port_end} -j DNAT --to ${nfr_ip} ${DEBUG} iptables -t nat -D PREROUTING-VPN -p udp -m udp --dport ${nfr_port_start}:${nfr_port_end} -j DNAT --to ${nfr_ip} } #-------------------------------------------------------------------------------------------------------------------------- # network_forward_start #-------------------------------------------------------------------------------------------------------------------------- network_forward_start() { ${LOG} "Create VPN forward chain" ${DEBUG} iptables -t nat -N PREROUTING-VPN ${LOG} "Add jump rule for VPN" for dst_id in ${NETWORK_DST_ID_LIST} do network_dst_tab_get ${dst_id} if [[ "${dst_type}" != "0" ]] then ${DEBUG} iptables -t nat -A PREROUTING -i ${dst_device} -j PREROUTING-VPN fi done ${LOG} "Add VPN client addresse rules" for src_id in ${NETWORK_SRC_ID_LIST} do network_src_tab_get ${src_id} ${DEBUG} ip rule add from ${src_ip} table ${src_table} if [[ "${src_port_range}" != "0" ]] then network_forward_add "${src_ip}" "${src_port_start}" "${src_port_end}" fi done } #-------------------------------------------------------------------------------------------------------------------------- # network_forward_stop #-------------------------------------------------------------------------------------------------------------------------- network_forward_stop() { ${LOG} "Remove VPN client addresse rules" for src_id in ${NETWORK_SRC_ID_LIST} do network_src_tab_get ${src_id} ${DEBUG} ip rule del from ${src_ip} 2>/dev/null if [[ "${src_port_range}" != "0" ]] then network_forward_remove "${src_ip}" "${src_port_start}" "${src_port_end}" fi done ${LOG} "Remove Jump rule for VPN" for dst_id in ${NETWORK_DST_ID_LIST} do network_dst_tab_get ${dst_id} if [[ "${dst_type}" != "0" ]] then ${DEBUG} iptables -t nat -D PREROUTING -i ${dst_device} -j PREROUTING-VPN fi done ${LOG} "Delete VPN forward chain" ${DEBUG} iptables -t nat -X PREROUTING-VPN } #-------------------------------------------------------------------------------------------------------------------------- # network_status #-------------------------------------------------------------------------------------------------------------------------- network_status() { echo "Rules:" ip rule show echo if [[ "${NETWORK_TABLE_LIST}" == "" ]] then echo "Network table list empty" echo else for table in ${NETWORK_TABLE_LIST} do echo "Table ${table}:" ip route list table ${table} echo done fi echo "Forward:" iptables -t nat -L PREROUTING -v -n echo iptables -t nat -L PREROUTING-VPN -v -n }