diff options
-rwxr-xr-x | network-topology-scanner | 134 |
1 files changed, 74 insertions, 60 deletions
diff --git a/network-topology-scanner b/network-topology-scanner index d2929be..a7c4f9a 100755 --- a/network-topology-scanner +++ b/network-topology-scanner @@ -8,49 +8,66 @@ hosts=( tmp_dir=$(mktemp -d) trap 'rm -rf --one-file-system "${tmp_dir:?}"' EXIT -for host in "${hosts[@]}"; do - name="${host% *}" - addr="${host##* }" - printf '"%s" [fontcolor="#800000"];\n' "${name}" >> "${tmp_dir}/print-content" - ssh "${addr}" ip -o addr | \ - sed -n ' - s/\s*\\.*$// - s/\s\+/ /g - / scope link/d - s/^[0-9]\+: // - /^lo /d - h - s/^\(\S\+\) .*$/'"${name}"' \1/ - w '"${tmp_dir}"'/interfaces - s/^\(.\+\) \(\S\+\)$/"\0" [label = "\2", fontcolor="#00ff00"];/ - w '"${tmp_dir}/print-content"' - g - s/^\(\S\+\) .*$/"'"${name}"'" -> "'"${name}"' \1";/ - w '"${tmp_dir}/print-content"' - g - s/^\(\S\+\) \S\+ \(\S\+\) .*$/"'"${name}"' \1" -> "\2";/ - w '"${tmp_dir}/print-content"' - g - s/^\S\+ \(\S\+\) \(\S\+\) .*$/\1 \2/ - w '"${tmp_dir}"'/ips - ' - for file in ips interfaces print-content; do - cat "${tmp_dir}/${file}" >> "${tmp_dir}/all-${file}" +if [ -f "infos" ]; then + cp "infos" "${tmp_dir}/infos" +else + for host in "${hosts[@]}"; do + name="${host% *}" + addr="${host##* }" + printf '"%s" [fontcolor="#800000"];\n' "${name}" >> "${tmp_dir}/print-content" + ssh "${addr}" ' + ip -o addr | sed "s/^/ip /" + sudo iptables-save | sed "s/^/ip4tables /" + sudo ip6tables-save | sed "s/^/ip6tables /" + ' 2>/dev/null \ + | sed ' + s/^\S\+ /\0'"${name}"' / + ' \ + >> "${tmp_dir}/infos" done - ssh "${addr}" 'sudo iptables-save | sed "s/^/4 /"; sudo ip6tables-save | sed "s/^/6 /"' 2>/dev/null | \ - sed ' - s/^/'"${name}"' / - ' >> \ - "${tmp_dir}/iptables" -done +fi + +sed ' + s/^ip // + t ip + s/^ip\([64]\)tables /\1 / + t iptables + s/^/>> unknown: >>/ + w /dev/stderr + d + :iptables + w '"${tmp_dir}"'/iptables + d + :ip + s/\s*\\.*$// + s/\s\+/ /g + / scope link/d + s/^\(\S\+ \)[0-9]\+: /\1/ + /^\S\+ lo /d + h + s/^\(\S\+ \S\+\) .*$/\1/ + w '"${tmp_dir}"'/interfaces + s/^\(\S\+\) \(\S\+\)$/"\0" [label = "\2", fontcolor="#00ff00"];/ + w '"${tmp_dir}/print-content"' + g + s/^\(\S\+\)\( \S\+\) .*$/"\1" -> "\1\2";/ + w '"${tmp_dir}/print-content"' + g + s/^\(\S\+ \S\+\) \S\+ \(\S\+\) .*$/"\1" -> "\2";/ + w '"${tmp_dir}/print-content"' + g + s/^\S\+ \S\+ \(\S\+\) \(\S\+\) .*$/\1 \2/ + w '"${tmp_dir}"'/ips + d +' "${tmp_dir}/infos" while read -r version address; do case ${version} in inet) - printf '"%s" [fontcolor="#000080"];\n' "${address}" >> "${tmp_dir}/adress-types" + printf '"%s" [fontcolor="#000080"];\n' "${address}" >> "${tmp_dir}/print-content" ;; inet6) - printf '"%s" [fontcolor="#0000ff"];\n' "${address}" >> "${tmp_dir}/adress-types" + printf '"%s" [fontcolor="#0000ff"];\n' "${address}" >> "${tmp_dir}/print-content" ;; esac subnet_mask=${address##*/} @@ -59,7 +76,7 @@ while read -r version address; do fi case ${version} in inet) - printf '"%s" [fontcolor="#000080"];\n' "${address}" >> "${tmp_dir}/adress-types" + printf '"%s" [fontcolor="#000080"];\n' "${address}" >> "${tmp_dir}/print-content" if [ "${subnet_mask}" = 32 ]; then continue fi @@ -100,14 +117,14 @@ while read -r version address; do "${address}" \ "${base_address}" done \ - < "${tmp_dir}/all-ips" \ + < "${tmp_dir}/ips" \ | sort -u \ | sort -k2,2 -k1,1 \ | uniq -Df1 \ | sed ' s/^\(\S\+\) \(\S\+\)$/"\1" -> "\2";\n/ ' \ - | tee -a "${tmp_dir}/all-print-content" \ + | tee -a "${tmp_dir}/print-content" \ | sed -n ' s/^".*" -> "\(\S\+\)";$/\1/ T @@ -120,29 +137,27 @@ done \ p } ' \ - >> "${tmp_dir}/adress-types" - -cat "${tmp_dir}/adress-types" >> "${tmp_dir}/all-print-content" + >> "${tmp_dir}/print-content" -grep '\S\+ [46] :FORWARD ACCEPT ' "${tmp_dir}/iptables" | \ - while read -r host ipver _; do - grep "^${host} " "${tmp_dir}/all-interfaces" +grep '[46] \S\+ :FORWARD ACCEPT ' "${tmp_dir}/iptables" | \ + while read -r ipver host _; do + grep "^${host} " "${tmp_dir}/interfaces" done | \ sort -u > \ "${tmp_dir}/ifs-routed" join -j1 "${tmp_dir}/ifs-routed" "${tmp_dir}/ifs-routed" \ | grep -v ' \(\S\+\) \1$' \ | sed ' - s/^\(\S\+\)\( .*\)$/\1 4\2\n\1 6\2/ + s/^.*$/4 \0\n6 \0/ ' \ > "${tmp_dir}/routes" grep -vwF "$( grep -vwF -- '-m conntrack' "${tmp_dir}/iptables" | \ - grep -v '^\S\+ 4 .*/32 ' | \ - grep -v '^\S\+ 6 .*/128 ' | \ + grep -v '^4 .*/32 ' | \ + grep -v '^6 .*/128 ' | \ sed -n ' - s/^\(\S\+\) \([46]\) \(.* \)\?-A FORWARD \(.* \)\?-i \(\S\+\) \(.* \)\?-j DROP/\1 \2 \5/ + s/^\([46]\) \(\S\+\) \(.* \)\?-A FORWARD \(.* \)\?-i \(\S\+\) \(.* \)\?-j DROP/\1 \2 \5/ T p ' @@ -151,12 +166,12 @@ grep -vwF "$( mv "${tmp_dir}/routes.new" "${tmp_dir}/routes" grep -vwF -- '-m conntrack' "${tmp_dir}/iptables" | \ - grep -v '^\S\+ 4 .*/32 ' | \ - grep -v '^\S\+ 6 .*/128 ' | \ + grep -v '^4 \S\+ .*/32 ' | \ + grep -v '^6 \S\+ .*/128 ' | \ sed ' - s/^\(\S\+\) \([46]\) \(.* \)\?-A FORWARD \(.* \)\?-i \(\S\+\) \(.* \)\?-o \(\S\+\) \(.* \)\?-j ACCEPT/\1 \2 \5 \7/ + s/^\([46]\) \(\S\+\) \(.* \)\?-A FORWARD \(.* \)\?-i \(\S\+\) \(.* \)\?-o \(\S\+\) \(.* \)\?-j ACCEPT/\1 \2 \5 \7/ t - s/^\(\S\+\) \([46]\) \(.* \)\?-A FORWARD \(.* \)\?-o \(\S\+\) \(.* \)\?-i \(\S\+\) \(.* \)\?-j ACCEPT/\1 \2 \7 \5/ + s/^\([46]\) \(\S\+\) \(.* \)\?-A FORWARD \(.* \)\?-o \(\S\+\) \(.* \)\?-i \(\S\+\) \(.* \)\?-j ACCEPT/\1 \2 \7 \5/ t d ' \ @@ -165,7 +180,7 @@ grep -vwF -- '-m conntrack' "${tmp_dir}/iptables" | \ sed ' s/^\(\S\+ \S\+\) \(\S\+\) \(\S\+\)$/f \1 \2 \3\nr \1 \3 \2/ ' "${tmp_dir}/routes" \ - | while read -r dir host ip from to; do + | while read -r dir ip host from to; do printf '%s %s %s %s %s %s\n' \ "${dir}" \ "${from}" \ @@ -175,14 +190,13 @@ sed ' "$( printf '%s\n' "${from}" "${to}" | \ sort | \ - sha512sum | \ - awk '{print $1}' + tr -d '\n' )" done \ | sort -k2,6 -k1,1 \ > "${tmp_dir}/routes.new" -uniq -uf1 "${tmp_dir}/routes.new" | tee /dev/stderr \ +uniq -uf1 "${tmp_dir}/routes.new" \ | grep '^f ' \ > "${tmp_dir}/routes" @@ -204,14 +218,14 @@ sed ' t d ' "${tmp_dir}/routes" \ - >> "${tmp_dir}/all-print-content" + >> "${tmp_dir}/print-content" -sort -u "${tmp_dir}/all-print-content" | cat -n +sort -u "${tmp_dir}/print-content" | cat -n { echo 'digraph network {' echo 'rankdir=LR;' - sort -u "${tmp_dir}/all-print-content" + sort -u "${tmp_dir}/print-content" echo '}' } | \ dot -Tpng -onetwork.png |