#!/bin/bash time_in=$(date +%s%N) . /etc/sysconfig/rx3-net . /etc/sysconfig/rx3-vpn CGI_NAME="vpn-admin_board.cgi" VPN_TYPE[0]="IPSec" VPN_TYPE[1]="OpenVPN" VPN_TYPE[2]="L2TP" VPN_TYPE[3]="PPTP" VPN_TYPE[4]="NoVPN" #-------------------------------------------------------------------------------------------------------------------------- # Lookup Source IP () #-------------------------------------------------------------------------------------------------------------------------- Lookup_Src_IP () { lo_id=0 for lo_blk in ${IP_SRC_SN} do OIFS=${IFS} IFS=: set ${lo_blk} lo_ip=$1 lo_table=$2 lo_owner=$3 lo_type=$4 IFS=${OIFS} echo "${lo_ip}:${lo_table}:${lo_owner}:${lo_type}:${lo_type}:sn:${lo_id}" lo_id=$((${lo_id}+1)) done for lo_blk in ${IP_SRC_PTP} do OIFS=${IFS} IFS=: set ${lo_blk} lo_id=$1 lo_table=$2 lo_owner=$3 lo_forward=$4 IFS=${OIFS} for lo_type in 1 2 3 do echo "${IP_PREFIX}.${lo_type}.${lo_id}:${lo_table}:${lo_owner}:${lo_type}:${lo_forward}:ptp:${lo_id}" done done } #-------------------------------------------------------------------------------------------------------------------------- # Lookup Owner () #-------------------------------------------------------------------------------------------------------------------------- Lookup_Owner () { for lo_blk in $(Lookup_Src_IP) do OIFS=${IFS} IFS=: set ${lo_blk} lo_ip=$1 lo_table=$2 lo_owner=$3 lo_type=$4 IFS=${OIFS} if [[ "${ip}" == "${lo_ip}" ]] then echo ${lo_owner} fi done } #-------------------------------------------------------------------------------------------------------------------------- # Header Print #-------------------------------------------------------------------------------------------------------------------------- Header_Print () { case "${format}" in "html") echo "Content-type: text/html" echo "" echo "" echo "" echo " " echo " " echo " " echo " " echo " " echo " " if [[ "${cmd_status}" == "" ]] then echo " Rx3 VPN Admin Board" else echo " Rx3 VPN Admin Board: ${cmd_status}" fi if [[ "${redirect}" != "" ]] then echo " " fi echo " " echo " " ;; "csv") echo "Content-type: text/csv" echo "" echo "SOF" if [[ "${redirect}" != "" ]] then echo "CMD: ${cmd_status}" fi ;; "txt") echo "Content-disposition: attachment; filename=${file_name}" echo "Content-type: text/plain" echo "" ;; esac } #-------------------------------------------------------------------------------------------------------------------------- # Tailer #-------------------------------------------------------------------------------------------------------------------------- Footer_Print () { case "${format}" in "html") echo " " echo "" echo "" ;; "csv") echo "" echo "EOF" ;; esac } #-------------------------------------------------------------------------------------------------------------------------- # External VPN Status Board #-------------------------------------------------------------------------------------------------------------------------- External_VPN_Status_Board () { if [[ "${format}" == "html" ]] then echo "

" echo "
" echo "

" echo "" echo "

External VPN Status Board

" echo "" echo " " echo " " else echo "TABLE: External_VPN_Status_Board" echo "#;Name;Type;Device;Address;Config;Table;Status;Bytes In;Bytes Out;UpTime" fi idx=0 for blk in ${VPN_EXT_LIST} do OIFS=${IFS} IFS=: set $blk dev=$1 conf=$2 table=$3 name=$4 IFS=${OIFS} case "${dev}" in "eth"*) type="Local" ;; "tun"*) type="OpenVPN" ;; "ppp"*) type="PPTP" ;; esac /sbin/ifconfig ${dev} 2>/dev/null | grep UP >/dev/null if [[ "$?" == 0 ]] then status=1 else status=0 fi if [[ ${status} == 0 ]] then address="-" else case "${type}" in "Local"|"PPTP") address="$(ip addr show dev ${dev} | grep "inet " | grep -v "${dev}:" | awk '{print $2;}' | sed -e 's/\/.*//')" ;; "OpenVPN") # address="$(sudo /usr/local/sbin/ns-launch 3 ${table} /usr/local/bin/my_address_get)" address="$(host vpn${idx}.vpn.rx3 | sed -e 's/.*address //')" ;; esac fi if [[ "${conf}" == "" ]] then conf="-" bytes_received="-" bytes_sent="-" uptime="-" else if [[ "${status}" == "1" ]] then if [[ "$type" == "OpenVPN" ]] then bytes_received=$(sudo /usr/local/sbin/openvpn-status ${dev} | grep -e "TCP/UDP read bytes" | sed -e "s/.*,//" | numfmt --to=iec-i --suffix=B) bytes_sent=$(sudo /usr/local/sbin/openvpn-status ${dev} | grep -e "TCP/UDP write bytes" | sed -e "s/.*,//" | numfmt --to=iec-i --suffix=B) start_date=$(grep "ext-client-${dev}.conf" /var/log/rx3-vpn.status 2>/dev/null | sed -e "s/.*Date: \[//" -e "s/\].*//") uptime=$(echo "$(($(date +%s) - $(date -d "${start_date}" +%s)))" | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}') else bytes_received="-" bytes_sent="-" start_date="-" uptime="-" fi else bytes_received="-" bytes_sent="-" uptime="-" fi fi if [[ "${format}" == "html" ]] then echo -n "" else echo -n "\"Down\"" fi echo "" else echo "${idx};${name};${type};${dev};${conf};${table};${status};${bytes_received};${bytes_sent};${uptime}" fi idx=$((idx+1)) done if [[ "${format}" == "html" ]] then echo "
#NameTypeDeviceAddressConfigTableStatusBytes InBytes OutUpTime
${idx}${name}${type}${dev}${address}${conf}${table}" if [[ "${status}" == 1 ]] then echo -n "\"Up\"${bytes_received}${bytes_sent}${uptime}
" echo "

" echo "
" echo "

" echo "" else echo "" fi } #-------------------------------------------------------------------------------------------------------------------------- # VPN Routing Board Line #-------------------------------------------------------------------------------------------------------------------------- VPN_Routing_Board_Line() { if [[ ( "${filter}" == "") || ( "${filter}" == "owner") || ( "${filter}" == "${owner}") ]] then if [[ "${REMOTE_USER}" == "${owner}" ]] then class="default" else if [[ "${filter}" == "owner" ]] then class="skip" else class="dark" fi fi else class="skip" fi if [[ "${class}" != "skip" ]] then host_name=$(host ${ip} | sed -e 's/.*domain name pointer //' -e 's/.$//') case "${vpn_type}" in "0") /sbin/ifconfig ipsec0 2>/dev/null | grep UP >/dev/null if [[ "$?" == 0 ]] then dev=ipsec0 status=1 else dev="-" status=0 fi ;; "1") dev="tun0" status_line="$(sudo /usr/local/sbin/openvpn-status ${dev} | grep "CLIENT_LIST.*${ip},")" if [[ "${status_line}" == "" ]] then bytes_received="-" bytes_sent="-" uptime="-" status=0 last_seen="$(stat -c "%x" /etc/openvpn/status/${host_name}.status | sed -e 's/\..*//')" else status=1 OIFS=${IFS} IFS=, set ${status_line} header=$1 h_name=$2 h_ip=$3 v_ip=$4 v_ip6=$5 v_bytes_received=$6 v_bytes_sent=$7 v_date=$8 v_uptime=$9 IFS=${OIFS} bytes_received="$(echo ${v_bytes_received} | numfmt --to=iec-i --suffix=B)" bytes_sent="$(echo ${v_bytes_sent} | numfmt --to=iec-i --suffix=B)" uptime=$(echo "$(($(date +%s) - $(date -d "${v_date}" +%s)))" | awk '{days = int($1/86400); print days " day" (( days > 1 ) ? "s" : "") strftime(" %H:%M:%S", $1,1)}') last_seen="$(date +"%Y/%m/%d %H:%M:%S")" fi ;; "2" | "3") /sbin/ifconfig 2>/dev/null | grep "P-t-P:${ip} " >/dev/null if [[ "$?" == 0 ]] then dev=$(/sbin/route -n 2>/dev/null | grep "^${ip}" | awk '{print $8}') bytes_received="-" bytes_sent="-" uptime="-" lastseen="-" status=1 else dev="-" bytes_received="-" bytes_sent="-" uptime="-" last_seen="-" status=0 fi ;; *) dev="-" bytes_received="-" bytes_sent="-" uptime="-" last_seen="-" status=2 ;; esac if [[ "${forward}" == "${vpn_type}" ]] then if [[ "${net_type}" == "sn" ]] then port_start=$((3000+${vpn_id}*100)) else port_start=$((33000+${vpn_id}*100)) fi port_end=$((${port_start}+99)) else port_start="" port_end="" fi if [[ "${format}" == "html" ]] then echo -n "${idx}" echo "${VPN_TYPE[${vpn_type}]}${ip}${host_name}" case "${status}" in "0") echo -n "\"Down\"" ;; "1") echo -n "\"Up\"" ;; "2") echo -n "-" ;; esac echo -n "${dev}" else echo -n "${idx};${VPN_TYPE[${vpn_type}]};${ip};${host_name};${status};${dev};" fi i=0 for blk in ${VPN_EXT_LIST} do if [[ "${format}" == "html" ]] then echo -n "
" if [[ $i == $id ]] then echo -n "\"Up\" " else echo -n "\"Down\"" if [[ "${REMOTE_USER}" == "${owner}" ]] then echo -n "\"Activate\"" else echo -n " " fi fi echo -n "
" else if [[ $i == $id ]] then echo -n "1;" else echo -n "0;" fi fi i=$((i + 1)) done if [[ "${format}" == "html" ]] then if [[ "${forward}" == "${vpn_type}" ]] then echo -n "\"Up\"" echo -n "${port_start}${port_end}" else if [[ "${REMOTE_USER}" == "${owner}" ]] then echo -n "\"Activate\"" else echo -n " " fi echo -n "  " fi echo "${owner}${bytes_received}${bytes_sent}${uptime}${last_seen}" else if [[ "${forward}" == "${vpn_type}" ]] then echo -n "1;" else echo -n "0;" fi echo "${port_start};${port_end};${owner};${bytes_received};${bytes_sent};${uptime};${last_seen}" fi fi } #-------------------------------------------------------------------------------------------------------------------------- # VPN Routing Board #-------------------------------------------------------------------------------------------------------------------------- VPN_Routing_Board() { if [[ "${format}" == "html" ]] then echo "

" echo "
" echo "

" echo "" echo "

VPN Routing Board

" echo "" echo " " echo -n " " else echo "TABLE: VPN_Routing_Board" echo -n "#;Type;IP;Host Name;Status;Device;" fi for blk in ${VPN_EXT_LIST} do OIFS=${IFS} IFS=: set $blk dev=$1 conf=$2 table=$3 name=$4 IFS=${OIFS} if [[ "${format}" == "html" ]] then echo -n "" else echo -n "${name};" fi done if [[ "${format}" == "html" ]] then echo "" else echo "Forward;From Port;To Port;Owner;Bytes In;Bytes Out;UpTime;Last Seen" fi idx=0 for blk in $(Lookup_Src_IP) do OIFS=${IFS} IFS=: set $blk ip=$1 table=$2 owner=$3 vpn_type=$4 forward=$5 net_type=$6 vpn_id=$7 IFS=${OIFS} id=$((table - 3)) idx=$((idx+1)) VPN_Routing_Board_Line done if [[ "${format}" == "html" ]] then echo "
#TypeIPHost NameStatusDevice${name}ForwardFrom PortTo PortOwnerBytes InBytes OutUpTimeLast Seen
" echo "

" echo "
" echo "

" else echo "" fi } #-------------------------------------------------------------------------------------------------------------------------- # OpenVPN Board #-------------------------------------------------------------------------------------------------------------------------- VPN_OpenVPN_Board() { if [[ "${format}" == "html" ]] then echo "

" echo "
" echo "

" echo "" echo "

OpenVPN Board

" echo "" echo " " echo -n " " else echo "TABLE: OpenVPN_Board" echo "#;IP;Host Name;Certificate" fi idx=0 for blk in $(Lookup_Src_IP) do OIFS=${IFS} IFS=: set $blk ip=$1 table=$2 owner=$3 type=$4 IFS=${OIFS} if [[ "${type}" == 1 ]] then idx=$((idx+1)) if [[ ( "${filter}" == "") || ( "${filter}" == "owner") || ( "${filter}" == "${owner}") ]] then if [[ "${REMOTE_USER}" == "${owner}" ]] then class="default" else if [[ "${filter}" == "owner" ]] then class="skip" else class="dark" fi fi else class="skip" fi if [[ "${class}" != "skip" ]] then host_name=$(host ${ip} | sed -e 's/.*domain name pointer //' -e 's/.$//') if [[ "${format}" == "html" ]] then echo -n "" echo -n "" if [[ "${REMOTE_USER}" == "${owner}" ]] then echo -n "" else echo -n "" fi echo -n "" if [[ "${REMOTE_USER}" == "${owner}" ]] then echo -n "" else echo -n "" fi else echo -n "${idx};${ip};${host_name}" fi if [[ "${format}" == "html" ]] then echo -n "" if [[ "${REMOTE_USER}" == "${owner}" ]] then echo -n "" if [[ -f /etc/openvpn/tls/certs/${host_name}.crt ]] then echo -n "" echo -n "" echo -n "" else echo -n "" echo -n "" echo -n "" fi else echo -n "" if [[ -f /etc/openvpn/tls/certs/${host_name}.crt ]] then echo -n "" echo -n "" echo -n "" else echo -n "" echo -n "" echo -n "" fi fi else if [[ -f /etc/openvpn/tls/certs/${host_name}.crt ]] then echo ";1" else echo ";0" fi fi fi fi done if [[ "${format}" == "html" ]] then echo "
#IPHost NameConfigurationCertificates
Default Route VPNNo Default Route VPNCA Certificate (.crt)TC Certificate (.key)Private Key (.key)Cerificate Signing Request (.csr)Public Certificate (.crt)
External CrtInline CrtExternal CrtInline Crt
${idx}${ip}${host_name}\"Configuration\"Configuration\"Configuration\"Configuration\"Configuration\"Configuration\"CA\"TC\"Private\"Certificat\"Public
\"Private\"Certificat\"Public
\"TC\"Private\"Certificat\"Public
\"Private\"Certificat\"Public
" echo "

" echo "
" echo "

" fi } #-------------------------------------------------------------------------------------------------------------------------- # Main Board Print #-------------------------------------------------------------------------------------------------------------------------- Main_Board_Print () { if [[ "${format}" == "html" ]] then echo "" if [[ "${filter}" == "owner" ]] then echo "

VPN Admin Board - My VPN

" else echo "

VPN Admin Board - All VPN

" fi echo "

" echo "
" echo "" echo " Date: $(/bin/date)
" echo "

" echo "
" echo "" fi External_VPN_Status_Board VPN_Routing_Board VPN_OpenVPN_Board if [[ "${format}" == "html" ]] then time_out=$(date +%s%N) elaps=$((${time_out} - ${time_in})) elaps_sec=$((${elaps} / 1000000000)) elaps_mili=$(( ( ${elaps} / 1000000) - ( ${elaps_sec} * 1000))) echo "

" echo "
" echo "
" printf "Page generated in %d.%03d seconds" ${elaps_sec} ${elaps_mili} echo "

" echo "" echo "
" echo "" echo "

" echo " Rx3 Admin" echo "

" echo "" echo "
" echo "" echo "

" echo " \"Best" echo " \"Valid" echo " \"Valid" echo "

" fi } #-------------------------------------------------------------------------------------------------------------------------- # Main #-------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------- # Args #-------------------------------------------------------------------------------------------------------------------------- cmd="" format="" filter="" ip="" vpn="" type="" redirect="" cmd_status="" if [[ "${QUERY_STRING}" != "" ]] then OIFS=${IFS} IFS="\&" set ${QUERY_STRING} IFS=${OIFS} i=$# while [[ "${i}" != 0 ]] do var=${1/=*/} arg=${1/*=/} case "${var}" in "cmd") cmd=${arg} ;; "format") format=${arg} ;; "filter") filter=${arg} ;; "ip") ip=${arg} ;; "vpn") vpn=${arg} ;; "type") type=${arg} ;; "filename") filename=${arg} ;; "defroute") defroute=${arg} ;; esac shift i=$((i - 1)) done fi if [[ "${format}" == "" ]] then format="html" fi #-------------------------------------------------------------------------------------------------------------------------- # Command Handler #-------------------------------------------------------------------------------------------------------------------------- case "${cmd}" in "") Header_Print Main_Board_Print Footer_Print ;; "route_set") owner=$(Lookup_Owner) if [[ "${REMOTE_USER}" == "${owner}" ]] then sudo /etc/init.d/rx3-net table_set $ip $((${vpn} + 3)) 2>&1 >/dev/null if [[ "$?" == 0 ]] then cmd_status="route_set: OK" else cmd_status="route_set: KO" fi else cmd_status="route_set: NOT_AUTHORIZED" fi redirect="${CGI_NAME}?filter=${filter}" Header_Print Footer_Print ;; "forward_set") owner=$(Lookup_Owner) if [[ "${REMOTE_USER}" == "${owner}" ]] then sudo /etc/init.d/rx3-net forward_set $ip 2>&1 >/dev/null if [[ "$?" == 0 ]] then cmd_status="forward_set: OK " else cmd_status="forward_set: KO" fi else cmd_status="forward_set: NOT_AUTHORIZED" fi redirect="${CGI_NAME}?filter=${filter}" Header_Print Footer_Print ;; "cert_download") owner=$(Lookup_Owner) if [[ "${type}" == "ca" ]] || [[ "${type}" == "crt" ]] || [[ "${REMOTE_USER}" == "${owner}" ]] then cmd_status="cert_download: OK" format="txt" case "${type}" in "ca") file_name="ca.crt" host_name="" ;; "tc") file_name="tc.key" host_name="" ;; *) host_name=$(host ${ip} | sed -e 's/.*domain name pointer //' -e 's/.$//') file_name="${host_name}.${type}" ;; esac Header_Print sudo /usr/local/sbin/cert_dump ${type} ${host_name} else cmd_status="cert_download: NOT_AUTHORIZED" redirect="${CGI_NAME}?filter=${filter}" format="html" Header_Print Footer_Print fi ;; "config_download") owner=$(Lookup_Owner) if [[ ( "${type}" == "ext") || ( ( "${type}" == "inline") && ( "${REMOTE_USER}" == "${owner}")) ]] then cmd_status="config_download: OK" host_name=$(host ${ip} | sed -e 's/.*domain name pointer //' -e 's/.$//') template_name="rx3-client.ovpn" if [[ "${defroute}" == "false" ]] then defroute_pipe="sed s/#pull-filter/pull-filter/" route_type="nodefroute" else defroute_pipe="cat" route_type="defroute" fi format="txt" if [[ "${type}" == "ext" ]] then file_name="${host_name}-${route_type}-external.ovpn" Header_Print sed \"; sudo \/usr\/local\/sbin\/cert_dump ca; echo \"<\/ca>\")/" -e "s/cert tls\/certs\/CLIENT_FQDN.crt/\$(echo \"\"; sudo \/usr\/local\/sbin\/cert_dump crt CLIENT_FQDN; echo \"<\/cert>\")/" -e "s/key tls\/private\/CLIENT_FQDN.key/\$(echo \"\"; sudo \/usr\/local\/sbin\/cert_dump key CLIENT_FQDN; echo \"<\/key>\")/" -e "s/tls-crypt tls\/private\/tc.key/\$(echo \"\"; sudo \/usr\/local\/sbin\/cert_dump tc; echo \"<\/tls-crypt>\")/" -e "s/CLIENT_FQDN/${host_name}/g")\"" | ${defroute_pipe} fi else cmd_status="config_download: NOT_AUTHORIZED" redirect="${CGI_NAME}?filter=${filter}" format="html" Header_Print Footer_Print fi ;; *) cmd_status="${cmd}: UNKNOWN_CMD" Header_Print Footer_Print ;; esac