Files
network_tools/lib/rx3/network.bash
Arnaud G. GIBERT bcf1c09fa0 - Add sudoers config file,
- Bug fixies,
- Change rx3-base to rx3-base-libs dependency.
2026-05-03 13:30:57 +02:00

1659 lines
49 KiB
Bash

#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------------------
#
# Rx3 Network Library
#
# Copyright (C) 2025-2026 Arnaud G. GIBERT
# mailto:arnaud@rx3.net
#
# This is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; If not, see
# <https://www.gnu.org/licenses/>.
#
#-----------------------------------------------------------------------------------------------------------------------------------
if [[ "${RX3_NETWORK_LIB}" != "" ]]
then
return
else
declare -g RX3_NETWORK_LIB=1
fi
#-----------------------------------------------------------------------------------------------------------------------------------
# Includes
#-----------------------------------------------------------------------------------------------------------------------------------
: "${RX3_LIB_DIR:=/usr/lib/rx3}"
. "${RX3_LIB_DIR}/dns.bash"
#-----------------------------------------------------------------------------------------------------------------------------------
# Global Variable
#-----------------------------------------------------------------------------------------------------------------------------------
declare -g NETWORK_OPENVPN_STATUS
declare -Ag NETWORK_IP_ROUTE_TAB=()
declare -g NETWORK_IP_ROUTE_ID_LIST=""
declare -Ag NETWORK_IP_ROUTE_IP_IDX=()
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 -Ag NETWORK_DST_NAME_IDX=()
declare -Ag NETWORK_DST_DEV_IDX=()
declare -g NETWORK_CONFIG_FILE="/etc/sysconfig/rx3-network"
declare -g NETWORK_CONFIG_LOCK="/var/lock/network/config"
#declare -g NETWORK_CONFIG_LOCK="${NETWORK_CONFIG_FILE}"
declare -g NETWORK_LOG_FILE
declare -g NETWORK_LOG_LOCK
#declare -g NETWORK_LOG_LOCK="${NETWORK_LOG_FILE}"
declare -g NETWORK_LOG_TRACE="DISABLE"
declare -g NETWORK_NC_TIMEOUT
#--------------------------------------------------------------------------------------------------------------------------
# Network Common Load
#--------------------------------------------------------------------------------------------------------------------------
network_common_load()
{
log_trace "Network" "Loading common..."
NETWORK_OPENVPN_STATUS="$( sudo 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 Common Openvpn Stats Get
#--------------------------------------------------------------------------------------------------------------------------
network_common_openvpn_stats_get()
{
local device="$1"
local client="$2"
if [[ "${client}" == "" ]]
then
client=".*"
else
if [[ "${device}" == "" ]]
then
tmp="$( echo "${NETWORK_OPENVPN_STATUS}" | grep "CLIENT_LIST,${client},")" || true
tmp="${tmp/*\//}"
device="${tmp/.status*/}"
fi
fi
if [[ "${device}" != "" ]]
then
if [[ "${NETWORK_OPENVPN_STATUS}" =~ ("${device}.status: TITLE") ]]
then
# OpenVPN Server Mode
OIFS="${IFS}"
IFS=","
set XXX/$( echo "${NETWORK_OPENVPN_STATUS}" | grep "${device}\.status: CLIENT_LIST,${client},") &>/dev/null || true
IFS="${OIFS}"
tmp="${1/XXX*\//}"
ovpn_stat_device="${tmp/.status*/}"
ovpn_stat_client_name="$2"
ovpn_stat_address_ext="$3"
ovpn_stat_address_int="$4"
ovpn_stat_address_int6="$5"
ovpn_stat_bytes_received="$6"
ovpn_stat_bytes_sent="$7"
ovpn_stat_connected_date="$8"
ovpn_stat_connected_time_t="$9"
ovpn_stat_user_name="$10"
ovpn_stat_client_id="$11"
ovpn_stat_peer_id="$12"
ovpn_stat_cipher="$13"
else
# OpenVPN Client Mode
set XXX/$( echo "${NETWORK_OPENVPN_STATUS}" | grep "${device}\.status:") &>/dev/null || true
tmp="${1:-""}"
tmp="${tmp/XXX*\//}"
ovpn_stat_device="${tmp/.status*/}"
tmp="${18:-0}"
ovpn_stat_bytes_received="${tmp/bytes,/}"
tmp="${22:-0}"
ovpn_stat_bytes_sent="${tmp/bytes,/}"
fi
else
ovpn_stat_device=""
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Ip Route Tab Load
#--------------------------------------------------------------------------------------------------------------------------
network_ip_route_tab_load()
{
nirtl_id=0
log_trace "Network" "Loading IP Route tab..."
while IFS= read -r line
do
line=${line%%#*}
if [[ ! -z "$line" ]]
then
set ${line}
nirtl_ip="$1"
nirtl_mask="$2"
nirtl_device="$3"
var_assign NETWORK_IP_ROUTE_ID_LIST "${nirtl_id}" INC
tab_assign NETWORK_IP_ROUTE_TAB "${nirtl_id},IP" "${nirtl_ip}"
tab_assign NETWORK_IP_ROUTE_TAB "${nirtl_id},Mask" "${nirtl_mask}"
tab_assign NETWORK_IP_ROUTE_TAB "${nirtl_id},Device" "${nirtl_device}"
tab_assign NETWORK_IP_ROUTE_IP_IDX "${nirtl_ip}" "${nirtl_id}"
nirtl_id=$(( ${nirtl_id} + 1))
fi
done <<< ${NETWORK_IP_ROUTE_CONFIG}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Ip Route Tab Get
#--------------------------------------------------------------------------------------------------------------------------
network_ip_route_tab_get()
{
ip_route_id="$1"
ip_route_ip=${NETWORK_IP_ROUTE_TAB["${ip_route_id},IP"]}
ip_route_mask=${NETWORK_IP_ROUTE_TAB["${ip_route_id},Mask"]}
ip_route_device=${NETWORK_IP_ROUTE_TAB["${ip_route_id},Device"]}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Ip Route Tab Dump
#--------------------------------------------------------------------------------------------------------------------------
network_ip_route_tab_dump()
{
echo "NETWORK_IP_ROUTE_ID_LIST: [${NETWORK_IP_ROUTE_ID_LIST}]"
echo
echo "NETWORK_IP_ROUTE_IP_IDX:"
for key in "${!NETWORK_IP_ROUTE_IP_IDX[@]}"
do
echo "[${key}]: [${NETWORK_IP_ROUTE_IP_IDX[${key}]}]"
done | sort -n
echo
echo "NETWORK_IP_ROUTE_TAB:"
for key in "${!NETWORK_IP_ROUTE_TAB[@]}"
do
echo "[${key}]: [${NETWORK_IP_ROUTE_TAB[${key}]}]"
done | sort -n
echo
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Tab Load
#--------------------------------------------------------------------------------------------------------------------------
network_dst_tab_load()
{
ndtl_id=0
vpn_id=0
log_trace "Network" "Loading Dst tab..."
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
ndtl_status="$( ip link show dev ${ndtl_device} 2>/dev/null | grep -q ",UP," && echo "1" || echo "0")" || true
if [[ "${ndtl_type}" == "5" ]]
then
ndtl_host_name=""
dns_value=""
else
ndtl_host_name="vpn${vpn_id}.${NETWORK_DST_NAME}"
dns_lookup "A" "${ndtl_host_name}" "NOCACHE"
vpn_id=$((${vpn_id} + 1))
fi
tab_assign NETWORK_DST_TAB "${ndtl_id},Host_Name" "${ndtl_host_name}"
tab_assign NETWORK_DST_TAB "${ndtl_id},IP" "${dns_value}"
case "${ndtl_type}"
in
"0")
ndtl_bytes_received="$( cat /sys/class/net/${ndtl_device}/statistics/rx_bytes 2>/dev/null | numfmt --to=iec-i --suffix=B)" || true
ndtl_bytes_sent="$( cat /sys/class/net/${ndtl_device}/statistics/tx_bytes 2>/dev/null | numfmt --to=iec-i --suffix=B)" || true
;;
"1"|"2")
network_common_openvpn_stats_get "${ndtl_device}" ""
if [[ ( "${ndtl_type}" == "1") && ( "${ndtl_status}" == "1") && ( "${ovpn_stat_client_name}" == "") ]]
then
ndtl_status="2"
ndtl_bytes_received=""
ndtl_bytes_sent=""
else
ndtl_bytes_received="$( echo ${ovpn_stat_bytes_received} | numfmt --to=iec-i --suffix=B)" || true
ndtl_bytes_sent="$( echo ${ovpn_stat_bytes_sent} | numfmt --to=iec-i --suffix=B)" || true
fi
;;
esac
tab_assign NETWORK_DST_TAB "${ndtl_id},Status" "${ndtl_status}"
if [[ "${ndtl_status}" == "1" ]]
then
if [[ "${ndtl_type}" == "1" ]]
then
ndtl_start_date="${ovpn_stat_connected_date}"
ndtl_uptime="$( echo $(( $(date +%s) - ${ovpn_stat_connected_time_t})) | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}')" || true
else
ndtl_start_date="$( stat -c %Z /sys/class/net/${ndtl_device})" || true
ndtl_uptime="$( echo $(( $(date +%s) - ${ndtl_start_date})) | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}')" || true
fi
else
ndtl_start_date=""
ndtl_uptime=""
fi
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},Start_Date" "${ndtl_start_date}"
tab_assign NETWORK_DST_TAB "${ndtl_id},Uptime" "${ndtl_uptime}"
tab_assign NETWORK_DST_NAME_IDX "${ndtl_name}" "${ndtl_id}"
tab_assign NETWORK_DST_DEV_IDX "${ndtl_device}" "${ndtl_id}"
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_host_name=${NETWORK_DST_TAB["${dst_id},Host_Name"]}
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_TYPE:"
for key in "${!NETWORK_DST_TYPE[@]}"
do
echo "[${key}]: [${NETWORK_DST_TYPE[${key}]}]"
done | sort -n
echo
echo "NETWORK_DST_ID_LIST: [${NETWORK_DST_ID_LIST}]"
echo
echo "NETWORK_DST_NAME_IDX:"
for key in "${!NETWORK_DST_NAME_IDX[@]}"
do
echo "[${key}]: [${NETWORK_DST_NAME_IDX[${key}]}]"
done | sort -n
echo
echo "NETWORK_DST_DEV_IDX:"
for key in "${!NETWORK_DST_DEV_IDX[@]}"
do
echo "[${key}]: [${NETWORK_DST_DEV_IDX[${key}]}]"
done | sort -n
echo
echo "NETWORK_DST_TAB:"
for key in "${!NETWORK_DST_TAB[@]}"
do
echo "[${key}]: [${NETWORK_DST_TAB[${key}]}]"
done | sort -n
echo
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Tab Name Lookup
#--------------------------------------------------------------------------------------------------------------------------
network_dst_tab_name_lookup()
{
dst_name="$1"
dst_id=${NETWORK_DST_NAME_IDX["${dst_name}"]}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Tab Dev Lookup
#--------------------------------------------------------------------------------------------------------------------------
network_dst_tab_dev_lookup()
{
dst_device="$1"
dst_id=${NETWORK_DST_DEV_IDX["${dst_device}"]}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Ip Update
#--------------------------------------------------------------------------------------------------------------------------
network_dst_ip_update()
{
local dst_ip_new="$1"
if [[ "${dst_ip}" != "${dst_ip_new}" ]]
then
log_info "Network" "Update [${dst_host_name}]: Old: [${dst_ip}] New: [${dst_ip_new}]"
${DEBUG} /usr/local/sbin/ip_host_update "${dst_host_name/.*}" "${dst_host_name#*.}" "${dst_ip_new}" 60
tab_assign NETWORK_DST_TAB "${dst_id},IP" "${dst_ip_new}"
else
log_trace "Network" "Skiping [${dst_host_name}]: IP: [${dst_ip}]"
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Ip Update
#--------------------------------------------------------------------------------------------------------------------------
network_dst_ip_update()
{
local dst_ip_new="$1"
if [[ "${dst_ip}" != "${dst_ip_new}" ]]
then
log_info "Network" "Update [${dst_host_name}]: Old: [${dst_ip}] New: [${dst_ip_new}]"
dns_host_update "${dst_host_name/.*}" "${dst_host_name#*.}" "${dst_ip_new}" 60
tab_assign NETWORK_DST_TAB "${dst_id},IP" "${dst_ip_new}"
else
log_trace "Network" "Skiping [${dst_host_name}]: IP: [${dst_ip}]"
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Name Ip Update
#--------------------------------------------------------------------------------------------------------------------------
network_dst_name_ip_update()
{
local dst_name="$1"
local dst_ip_new="$2"
network_dst_tab_name_lookup "${job_name}"
if [[ "${dst_id}" != "" ]]
then
network_dst_tab_get "${dst_id}"
network_dst_ip_update "${dst_ip_new}"
else
log_error "Network" "dst name not found: [${dst_name}]"
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Src Tab Load
#--------------------------------------------------------------------------------------------------------------------------
network_src_tab_load()
{
nstl_id=0
nstl_local_id=0
nstl_port_default=3000
log_trace "Network" "Loading Src tab..."
ip_base=$( ip_ip_to_num ${NETWORK_SRC_LOCAL_ADDRESS}) || true
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_host_name="${dns_value}"
case "${nstl_type}"
in
"0") # Local
# nstl_device="${NETWORK_SRC_DEVICE}-${nstl_local_id}"
# ((nstl_local_id++))
# [[ $nstl_host_name =~ ([0-9]+) ]]
# nstl_device="${NETWORK_SRC_LOCAL_DEVICE}-${BASH_REMATCH[1]}"
ip_num=$(ip_ip_to_num ${nstl_ip})
device_num="$(( ( ${ip_num} - ${ip_base}) / 4))"
nstl_device="${NETWORK_SRC_LOCAL_DEVICE}-${device_num}"
nstl_status="$( ip link show dev ${nstl_device} 2>/dev/null | grep -q ",UP," && echo "1" || echo "0")" || true
if [[ "${nstl_status}" == 1 ]]
then
nstl_bytes_received="$( cat /sys/class/net/${nstl_device}/statistics/rx_bytes 2>/dev/null | numfmt --to=iec-i --suffix=B)" || true
nstl_bytes_sent="$( cat /sys/class/net/${nstl_device}/statistics/tx_bytes 2>/dev/null | numfmt --to=iec-i --suffix=B)" || true
nstl_start_date="$( stat -c %Z /sys/class/net/${nstl_device})" || true
nstl_uptime="$( echo $(( $(date +%s) - ${nstl_start_date})) | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}')" || true
else
nstl_bytes_received=""
nstl_bytes_sent=""
nstl_uptime=""
nstl_last_seen=""
fi
;;
"1") # Routed
nstl_device=""
nstl_status="2"
nstl_bytes_received=""
nstl_bytes_sent=""
nstl_start_date=""
nstl_uptime=""
nstl_last_seen=""
;;
"2") # OpenVPN
network_common_openvpn_stats_get "" "${nstl_host_name}"
if [[ "${ovpn_stat_device}" == "" ]]
then
nstl_device=""
nstl_status="0"
nstl_bytes_received=""
nstl_bytes_sent=""
nstl_start_date=""
nstl_uptime=""
nstl_last_seen="$( stat -c "%x" /etc/openvpn/status/${nstl_host_name}.status 2>/dev/null | sed -e 's/\..*//')" || true
else
nstl_device="${ovpn_stat_device}"
nstl_status="1"
nstl_bytes_received=$( echo ${ovpn_stat_bytes_sent} | numfmt --to=iec-i --suffix=B) || true
nstl_bytes_sent=$( echo ${ovpn_stat_bytes_sent} | numfmt --to=iec-i --suffix=B) || true
nstl_start_date=${ovpn_stat_connected_date}
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)}') || true
nstl_last_seen="$(stat -c "%x" /etc/openvpn/status/${nstl_host_name}.status 2>/dev/null | sed -e 's/\..*//')" || true
fi
;;
esac
if [[ " ${NETWORK_TABLE_LIST} " != *" ${nstl_table} "* ]]
then
echo_error "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},Host_Name" "${nstl_host_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},Start_Date" "${nstl_start_date}"
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_host_name=${NETWORK_SRC_TAB["${src_id},Host_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_TYPE:"
for key in "${!NETWORK_SRC_TYPE[@]}"
do
echo "[${key}]: [${NETWORK_SRC_TYPE[${key}]}]"
done | sort -n
echo
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()
{
log_trace "Network" "Loading config..."
dns_tab_load
network_common_load
network_ip_route_tab_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_ip_route_tab_dump
network_dst_tab_dump
network_src_tab_dump
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Route Dst Init
#--------------------------------------------------------------------------------------------------------------------------
network_route_dst_init()
{
local dst_id="$1"
network_dst_tab_get "${dst_id}"
if [[ ${dst_type} == "0" ]]
then
log_trace "Network" "Copy main default route into table ${dst_table} (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 ${dst_table}
fi
else
log_trace "Network" "Define default route to device: [${dst_device}] into table: [${dst_table}]"
if [[ "$(ip link show ${dst_device})" != "" ]]
then
${DEBUG} ip route add default dev ${dst_device} table ${dst_table}
fi
fi
# network_route_rx3_init ${dst_device}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Route Rx3 Init
#--------------------------------------------------------------------------------------------------------------------------
network_route_rx3_init()
{
local target_device="$1"
log_trace "Network" "Add [${target_device}] Rx3 routes in VPN tables"
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_dst_tab_get ${dst_id}
for ip_route_id in ${NETWORK_IP_ROUTE_ID_LIST}
do
network_ip_route_tab_get ${ip_route_id}
if [[ "${ip_route_device}" == "${target_device}" ]]
then
${DEBUG} ip route add ${ip_route_ip}/${ip_route_mask} dev ${ip_route_device} table ${dst_table}
fi
done
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Route Other Init
#--------------------------------------------------------------------------------------------------------------------------
network_route_other_init()
{
local dst_id="$1"
network_dst_tab_get ${dst_id}
log_trace "Network" "Add other routes in Rx3 VPN table: [${dst_table}]"
for ip_route_id in ${NETWORK_IP_ROUTE_ID_LIST}
do
network_ip_route_tab_get ${ip_route_id}
network_dst_tab_dev_lookup ${ip_route_device}
if [[ "${dst_id}" == "" ]]
then
${DEBUG} ip route add ${ip_route_ip}/${ip_route_mask} table ${dst_table} dev ${ip_route_device}
fi
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Device Init
#--------------------------------------------------------------------------------------------------------------------------
network_device_init()
{
local dst_id="$1"
local device_name="$2"
log_trace "Network" "Init dst_id: [${dst_id}] device_name: [${device_name}]"
if [[ "${dst_id}" == "" ]]
then
network_dst_tab_dev_lookup "${device_name}"
fi
if [[ "${dst_id}" != "" ]]
then
network_route_dst_init "${dst_id}"
device_name="${dst_device}"
fi
network_route_rx3_init "${device_name}"
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Device Deinit
#--------------------------------------------------------------------------------------------------------------------------
network_device_deinit()
{
local dst_id="$1"
local device_name="$2"
log_trace "Network" "DeInit dst_id: [${dst_id}] device_name: [${device_name}]"
if [[ "${dst_id}" == "" ]]
then
network_dst_tab_dev_lookup "${device_name}"
fi
if [[ "${dst_id}" != "" ]]
then
network_dst_tab_get "${dst_id}"
network_dst_ip_update "0.0.0.0"
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Route Init
#--------------------------------------------------------------------------------------------------------------------------
network_route_init()
{
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_device_init "${dst_id}" ""
network_route_other_init "${dst_id}"
done
# for dst_id in ${NETWORK_DST_ID_LIST}
# do
# network_route_dst_init ${dst_id}
# network_route_other_init ${dst_id}
# done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Route Deinit
#--------------------------------------------------------------------------------------------------------------------------
network_route_deinit()
{
log_trace "Network" "Remove Rx3 routes in VPN tables"
for table in ${NETWORK_TABLE_LIST}
do
for ip_route_id in ${NETWORK_IP_ROUTE_ID_LIST}
do
network_ip_route_tab_get ${ip_route_id}
${DEBUG} ip route del ${ip_route_ip}/${ip_route_mask} table ${table} dev ${ip_route_device} 2>/dev/null
done
done
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_dst_tab_get ${dst_id}
log_trace "Network" "Remove default route in table: [${dst_table}]"
${DEBUG} ip route del default table ${dst_table} 2>/dev/null
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Table Set
#--------------------------------------------------------------------------------------------------------------------------
network_table_set()
{
nts_ip=$1
nts_table=$2
network_src_tab_ip_lookup "${nts_ip}"
if [[ "${src_id}" == "" ]]
then
echo_error "IP not found: [${nts_ip}]!"
return 1
fi
if [[ " ${NETWORK_TABLE_LIST} " != *" ${nts_table} "* ]]
then
echo_error "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 Dst Address Init All
#--------------------------------------------------------------------------------------------------------------------------
network_dst_address_init_all()
{
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_dst_tab_get "${dst_id}"
network_dst_ip_update "0.0.0.0"
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Address Refresh
#--------------------------------------------------------------------------------------------------------------------------
network_dst_address_refresh()
{
local dst_id="$1"
local dst_ip_new
local proxy_host
local proxy_port=8080
network_dst_tab_get "${dst_id}"
if [[ ( "${dst_host_name}" != "" )]]
then
if [[ ${dst_host_name} =~ ([0-9]+) ]]
then
proxy_host="proxy${BASH_REMATCH[1]}.${NETWORK_DST_PROXY_NAME}"
if [[ ( "${dst_status}" == 1) || ( ( "${dst_status}" != 1) && ( "${dst_ip}" != "0.0.0.0")) ]]
then
if [[ ( ( "${dst_ip}" != "0.0.0.0") && ( "${dst_status}" != 1)) ]]
then
log_info "Network" "Reseting IP: [${dst_host_name}]: IP: [${dst_ip_new}] Status: (${dst_status})"
dst_ip_new="0.0.0.0"
else
dst_ip_new="$( nc -w "${NETWORK_NC_TIMEOUT}" "${proxy_host}" "${proxy_port}" 2>/dev/null)" || true
fi
if ip_is_valid_ip "${dst_ip_new}"
then
if [[ "${dst_ip}" != "${dst_ip_new}" ]]
then
network_dst_ip_update "${dst_ip_new}"
else
log_trace "Network" "Skiping: [${dst_host_name}]: No changes..."
fi
else
log_info "Network" "Skiping: [${dst_host_name}]: Invalid IP: [${dst_ip_new}]"
fi
else
log_trace "Network" "Skiping: [${dst_host_name}]: Device not Up..."
fi
else
log_info "Network" "Skiping: dst_id: [${dst_id}]: Invalid host_name: [${dst_host_name}]"
fi
fi
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Dst Address Refresh All
#--------------------------------------------------------------------------------------------------------------------------
network_dst_address_refresh_all()
{
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_dst_address_refresh "${dst_id}"
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Bridge Up
#--------------------------------------------------------------------------------------------------------------------------
function bridge_up
{
# set -x
bu_bridge_device=$1
bu_bridge_network=$2
bu_bridge_mask=$3
bu_bridge_address=$4
bu_peer_address=$5
bu_table=$6
log_trace "Network" "Create bridge [${bu_bridge_device}]..."
${DEBUG} ip link add name ${bu_bridge_device} type bridge
log_trace "Network" "Configure host side [${bu_bridge_device}:${bu_bridge_address}/${bu_bridge_mask}]..."
${DEBUG} ip link set ${bu_bridge_device} up
${DEBUG} ip addr add ${bu_bridge_address}/${bu_bridge_mask} dev ${bu_bridge_device}
log_trace "Network" "Configure IP rule and routing [${bu_bridge_device}]..."
${DEBUG} ip rule del from ${bu_peer_address} 2>/dev/null
${DEBUG} ip rule add from ${bu_peer_address} table ${bu_table}
for bu_tab in ${NETWORK_TABLE_LIST}
do
${DEBUG} ip route add ${bu_bridge_network}/${bu_bridge_mask} dev ${bu_bridge_device} table ${bu_tab}
done
# set +x
}
#--------------------------------------------------------------------------------------------------------------------------
# Bridge Down
#--------------------------------------------------------------------------------------------------------------------------
function bridge_down
{
bd_bridge_device=$1
bd_bridge_network=$2
bd_bridge_mask=$3
bd_bridge_address=$4
bd_peer_address=$5
bd_table=$6
log_trace "Network" "Remove IP routing and rule [${bd_bridge_device}]..."
for bd_tab in ${NETWORK_TABLE_LIST}
do
${DEBUG} ip route del ${bd_bridge_network}/${bd_bridge_mask} dev ${bd_bridge_device} table ${bd_tab} 2>/dev/null || true
done
${DEBUG} ip rule del from ${bd_peer_address} table ${bd_table} 2>/dev/null
log_trace "Network" "Remove bridge [${bd_bridge_device}]..."
${DEBUG} ip link show ${bd_bridge_device} &>/dev/null && ${DEBUG} ip link del ${bd_bridge_device}
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Bridge Init
#--------------------------------------------------------------------------------------------------------------------------
network_bridge_init()
{
log_trace "Network" "Add all Bridges"
for src_id in ${NETWORK_SRC_ID_LIST}
do
network_src_tab_get ${src_id}
if [[ "${src_type}" == "0" ]]
then
nbi_bridge_device="${src_device}"
nbi_bridge_network="${src_ip%.*}.$(( ${src_ip/*./} - 1))"
nbi_bridge_mask="30"
nbi_bridge_address="${src_ip%.*}.$(( ${src_ip/*./} + 1))"
nbi_peer_address="${src_ip}"
bridge_up "${nbi_bridge_device}" "${nbi_bridge_network}" "${nbi_bridge_mask}" "${nbi_bridge_address}" "${nbi_peer_address}" "${src_table}"
fi
done
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Bridge Deinit
#--------------------------------------------------------------------------------------------------------------------------
network_bridge_deinit()
{
log_trace "Network" "Remove all Bridge"
for src_id in ${NETWORK_SRC_ID_LIST}
do
network_src_tab_get ${src_id}
if [[ "${src_type}" == "0" ]]
then
nbi_bridge_device="${src_device}"
nbi_bridge_network="${src_ip%.*}.$(( ${src_ip/*./} - 1))"
nbi_bridge_mask="30"
nbi_bridge_address="${src_ip%.*}.$(( ${src_ip/*./} + 1))"
nbi_peer_address="${src_ip}"
bridge_down "${nbi_bridge_device}" "${nbi_bridge_network}" "${nbi_bridge_mask}" "${nbi_bridge_address}" "${nbi_peer_address}" "${src_table}"
fi
done
}
#--------------------------------------------------------------------------------------------------------------------------
# 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_trace "Network" "Create VPN forward chain"
${DEBUG} iptables -t nat -N PREROUTING-VPN
log_trace "Network" "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_trace "Network" "Add VPN client addresse rules"
for src_id in ${NETWORK_SRC_ID_LIST}
do
network_src_tab_get ${src_id}
if [[ "${src_type}" != "0" ]]
then
${DEBUG} ip rule del from ${src_ip} 2>/dev/null
${DEBUG} ip rule add from ${src_ip} table ${src_table}
fi
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_trace "Network" "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_trace "Network" "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 2>/dev/null
fi
done
log_trace "Network" "Delete VPN forward chain"
${DEBUG} iptables -t nat -X PREROUTING-VPN 2>/dev/null
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Init
#--------------------------------------------------------------------------------------------------------------------------
network_init()
{
# By default Loggin is enabled
# export LOG="" to disable it
if [ -v LOG ] && [[ "${LOG}" == "" ]]
then
export NETWORK_LOG_FILE=""
export NETWORK_LOG_LOCK=""
fi
# By default Echoing is disabled
# export LOG="echo" to enable it
if [ ! -v ECHO ] || [[ "${ECHO}" == "" ]]
then
export ECHO=":"
fi
file_dir_init ${NETWORK_CONFIG_LOCK} root apache
file_lock ${NETWORK_CONFIG_LOCK} READ 9
[ -e "${NETWORK_CONFIG_FILE}" ] && . "${NETWORK_CONFIG_FILE}"
file_unlock 9
log_set "${NETWORK_LOG_FILE}" "${NETWORK_LOG_LOCK}" "${ECHO}" "${NETWORK_LOG_TRACE}"
dns_init
file_dir_init ${NETWORK_LOG_FILE} root apache
file_dir_init ${NETWORK_LOG_LOCK} root apache
network_tab_load
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Deinit
#--------------------------------------------------------------------------------------------------------------------------
network_deinit()
{
NETWORK_OPENVPN_STATUS=""
NETWORK_IP_ROUTE_TAB=()
NETWORK_IP_ROUTE_ID_LIST=""
NETWORK_IP_ROUTE_IP_IDX=()
NETWORK_SRC_TYPE=""
NETWORK_SRC_TAB=()
NETWORK_SRC_ID_LIST=""
NETWORK_SRC_IP_IDX=()
NETWORK_DST_TYPE=""
NETWORK_DST_TAB=()
NETWORK_DST_ID_LIST=""
NETWORK_DST_NAME_IDX=()
NETWORK_DST_DEV_IDX=()
dns_deinit
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Reinit
#--------------------------------------------------------------------------------------------------------------------------
network_reinit()
{
network_deinit
network_init
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Start
#--------------------------------------------------------------------------------------------------------------------------
network_start()
{
log_info "Network" "Starting network..."
network_route_init
network_bridge_init
network_forward_start
network_dst_address_init_all
log_info "Network" "Network started!"
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Stop
#--------------------------------------------------------------------------------------------------------------------------
network_stop()
{
log_info "Network" "Stoping network..."
network_forward_stop
network_bridge_deinit
network_route_deinit
log_info "Network" "Network stoped!"
return 0
}
#--------------------------------------------------------------------------------------------------------------------------
# Network Status
#--------------------------------------------------------------------------------------------------------------------------
network_status()
{
echo "Number of Network IP Route entries: ${#NETWORK_IP_ROUTE_IP_IDX[@]}"
echo "Number of Network Src entries: ${#NETWORK_SRC_IP_IDX[@]}"
echo "Number of Network Dst entries: ${#NETWORK_DST_DEV_IDX[@]}"
echo "Number of DNS cache A entries: ${#DNS_A_TAB[@]}"
echo "Number of DNS cache PTR entries: ${#DNS_PTR_TAB[@]}"
(
echo "SRC"
for src_id in ${NETWORK_SRC_ID_LIST}
do
network_src_tab_get ${src_id}
if [[ "${src_device}" != "" ]]
then
echo ${src_device}
fi
done | sort -Vu
echo "DST"
for dst_id in ${NETWORK_DST_ID_LIST}
do
network_dst_tab_get ${dst_id}
if [[ "${dst_device}" != "" ]]
then
echo ${dst_device}
fi
done | sort -Vu
) | while read entry
do
case ${entry}
in
"SRC")
echo
echo "Src Devices:"
;;
"DST")
echo
echo "Dst Devices:"
;;
*)
ip address show $entry | sed -e 's/^[^:]*: //' || true
;;
esac
done
echo
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} || true
echo
done
fi
echo "Forward:"
iptables -t nat -L PREROUTING -v -n || true
echo
iptables -t nat -L PREROUTING-VPN -v -n || true
}