Network Analysis shell script (real-time traffic + connection statistics)
This article introduces a powerful Analysis Network shell script, which is split from EZHTTP and I think it is necessary to introduce it separately.
Script running effect:
This script provides the following functions:
- 1. monitor traffic of any network card in real time
- 2. Average traffic within 10 seconds
- 3. Calculate the average traffic of each port within 10 seconds based on the statistics of the client and server ports. We can see which ports account for a large amount of traffic. For web servers, port 80 is generally used. When other ports are under attack, the traffic on other ports may be large. Therefore, this function helps us determine whether the port traffic is normal.
- 4. Count the top 10 ip addresses that occupy the maximum bandwidth within 10 s. This feature helps us identify whether there are ip addresses that maliciously occupy bandwidth.
- 5. collect statistics on the connection status. This feature allows us to see which connections are in relatively large states. If the SYN-RECV is in many States, it may be vulnerable to semi-connection attacks. If ESTABLISED is very large, but there are not so many requests through logs, or if tcpdump finds that a large number of ip addresses only establish connections and do not request data, it may be a full connection attack, in this case, if you are using the nginx server, you can add listen 80 deferred in the configuration file to prevent it.
- 6. Check the connection status of each port. This feature helps us find out which port is under attack when it may be attacked.
- 7. The first 10 IP addresses with the maximum number of ESTAB connections in port 80. This feature helps us find out the Ip addresses with too many connections and block them.
- 8. The first 10 IP addresses with the maximum number of SYN-RECV connections in the status of port 80. This function helps us find malicious ip addresses when we are under semi-connected attacks.
Network Analysis tools used:
- 1. tcpdump: This script uses tcpdump to count traffic based on ip addresses or ports.
- 2. ss: This script uses ss commands to calculate the connection status. In actual use, it is much more efficient than netstat.
- 3./proc/net/dev is used to count the traffic of the specified Nic.
Script: https://www.centos.bz/wp-content/uploads/2014/06/network-analysis.sh
The following is a complete script:
- #! /Bin/bash
- # Write by zhumaohai (admin # centos. bz)
- # Author blog: www. centos. bz
- # Display menu (single choice)
- Display_menu (){
- Local soft = $1
- Local prompt = "which $ {soft} you 'd select :"
- Eval local arr = (\$ {soft {soft} _ arr [@]})
- While true
- Do
- Echo-e "#####################$ {soft} setting ########### ######### \ n"
- For (I = 1; I <=$ {# arr [@]}; I ++); do echo-e "$ I) $ {arr [$ I-1]} "; done
- Echo
- Read-p "$ {prompt}" $ soft
- Eval local select =\$ soft
- If ["$ select" = ""] | ["$ {arr [$ soft-1]}" = ""]; then
- Prompt = "input errors, please input a number :"
- Else
- Eval $ soft =$ {arr [$ soft-1]}
- Eval echo "your selection: \ $ soft"
- Break
- Fi
- Done
- }
- # Converting bandwidth bit units to human readable units
- Bit_to_human_readable (){
- # Input bit value
- Local trafficValue = $1
- If [[$ {trafficValue %. *}-gt 922]; then
- # Conv to Kb
- TrafficValue = 'awk-v value = $ trafficValue 'BEGIN {printf "% 0.1f", value/1024 }''
- If [[$ {trafficValue %. *}-gt 922]; then
- # Conv to Mb
- TrafficValue = 'awk-v value = $ trafficValue 'BEGIN {printf "% 0.1f", value/1024 }''
- Echo "$ {trafficValue} Mb"
- Else
- Echo "$ {trafficValue} Kb"
- Fi
- Else
- Echo "$ {trafficValue} B"
- Fi
- }
- # Determine the package management tool
- Check_package_manager (){
- Local manager = $1
- Local systemPackage =''
- If cat/etc/issue | grep-q-E-I "ubuntu | debian"; then
- SystemPackage = 'apt'
- Elif cat/etc/issue | grep-q-E-I "centos | red hat | redhat"; then
- SystemPackage = 'yum'
- Elif cat/proc/version | grep-q-E-I "ubuntu | debian"; then
- SystemPackage = 'apt'
- Elif cat/proc/version | grep-q-E-I "centos | red hat | redhat"; then
- SystemPackage = 'yum'
- Else
- Echo "unkonw"
- Fi
- If ["$ manager" = "$ systemPackage"]; then
- Return 0
- Else
- Return 1
- Fi
- }
- # Real-time traffic
- RealTimeTraffic (){
- Local eth = ""
- Local nic_arr = ('ifconfig | grep-E-o "^ [a-z0-9] +" | grep-v "lo" | uniq ')
- Local nicLen =$ {# nic_arr [@]}
- If [[$ nicLen-eq 0]; then
- Echo "sorry, I can not detect any network device, please report this issue to author ."
- Exit 1
- Elif [[$ nicLen-eq 1]; then
- Eth = $ nic_arr
- Else
- Display_menu nic
- Eth = $ nic
- Fi
- Local clear = true
- Local eth_in_peak = 0
- Local eth_out_peak = 0
- Local eth_in = 0
- Local eth_out = 0
- While true; do
- # Move the cursor to 0: 0
- Printf "\ 033 [0; 0 H"
- # Clear the screen and print Now Peak
- [[$ Clear = true] & printf "\ 033 [2J" & echo "$ eth -------- Now -------- Peak -----------"
- Traffic_be = ('awk-v eth = $ eth-F' [:] + ''{if ($0 ~ Eth) {print $3, $11} '/proc/net/dev ')
- Sleep 2
- Traffic_af = ('awk-v eth = $ eth-F' [:] + ''{if ($0 ~ Eth) {print $3, $11} '/proc/net/dev ')
- # Computing Rate
- Eth_in = $ ($ {traffic_af [0]}-$ {traffic_be [0]}) * 8/2 ))
- Eth_out = $ ($ {traffic_af [1]}-$ {traffic_be [1]}) * 8/2 ))
- # Calculating traffic peaks
- [[$ Eth_in-gt $ eth_in_peak] & eth_in_peak = $ eth_in
- [[$ Eth_out-gt $ eth_out_peak] & eth_out_peak = $ eth_out
- # Move the cursor
- Printf "\ 033 [2; 1 H"
- # Clearing the current row
- Printf "\ 033 [K"
- Printf "%-20 s %-20s \ n" "Receive: $ (bit_to_human_readable $ eth_in)" $ (bit_to_human_readable $ eth_in_peak )"
- # Clearing the current row
- Printf "\ 033 [K"
- Printf "%-20 s %-20s \ n" "Transmit: $ (bit_to_human_readable $ eth_out)" $ (bit_to_human_readable $ eth_out_peak )"
- [[$ Clear = true] & clear = false
- Done
- }
- # Traffic and connection Overview
- TrafficAndConnectionOverview (){
- If! Which tcpdump>/dev/null; then
- Echo "tcpdump not found, going to install it ."
- If check_package_manager apt; then
- Apt-get-y install tcpdump
- Elif check_package_manager yum; then
- Yum-y install tcpdump
- Fi
- Fi
- Local reg = ""
- Local eth = ""
- Local nic_arr = ('ifconfig | grep-E-o "^ [a-z0-9] +" | grep-v "lo" | uniq ')
- Local nicLen =$ {# nic_arr [@]}
- If [[$ nicLen-eq 0]; then
- Echo "sorry, I can not detect any network device, please report this issue to author ."
- Exit 1
- Elif [[$ nicLen-eq 1]; then
- Eth = $ nic_arr
- Else
- Display_menu nic
- Eth = $ nic
- Fi
- Echo "please wait for 10 s to generate network data ..."
- Echo
- # Current Traffic Value
- Local traffic_be = ('awk-v eth = $ eth-F' [:] + ''{if ($0 ~ Eth) {print $3, $11} '/proc/net/dev ')
- # Tcpdump listening Network
- Tcpdump-v-I $ eth-tnn>/tmp/tcpdump_temp 2> & 1 &
- Sleep 10
- Clear
- Kill 'ps aux | grep tcpdump | grep-v grep | awk '{print $2 }''
- # Traffic value after 10 s
- Local traffic_af = ('awk-v eth = $ eth-F' [:] + ''{if ($0 ~ Eth) {print $3, $11} '/proc/net/dev ')
- # Print the average rate of 10 s
- Local eth_in =$ ($ {traffic_af [0]}-$ {traffic_be [0]}) * 8/10 ))
- Local eth_out = $ ($ {traffic_af [1]}-$ {traffic_be [1]}) * 8/10 ))
- Echo-e "\ 033 [32 mnetwork device $ eth average traffic in 10 s: \ 033 [0 m"
- Echo "$ eth Receive: $ (bit_to_human_readable $ eth_in)/s"
- Echo "$ eth Transmit: $ (bit_to_human_readable $ eth_out)/s"
- Echo
- Local regTcpdump = $ (ifconfig | grep-A 1 $ eth | awk-F' [:] + ''$0 ~ /Inet addr: /{printf $4 "|"} '| sed-e's/| $ //'-e's/^/(/'-e's/$ /) \\\\\. [0-9] + :/')
- # The output formats of the new and old versions of tcpdump are different.
- If awk '/^ IP/{print; exit}'/tmp/tcpdump_temp | grep-q ") $"; then
- # Process tcpdump files
- Awk '/^ IP/{print; getline; print}'/tmp/tcpdump_temp>/tmp/tcpdump_temp2
- Else
- # Process tcpdump files
- Awk '/^ IP/{print}'/tmp/tcpdump_temp>/tmp/tcpdump_temp2
- Sed-I-r's # (. *: [0-9] + \) (. *) # \ 1 \ n \ 2 #'/tmp/tcpdump_temp2
- Fi
-
- Awk '{len = $ NF; sub (/\)/, "", len); getline; print $0, len}'/tmp/tcpdump_temp2>/tmp/tcpdump
- # Count the average traffic of each port within 10 s
- Echo-e "\ 033 [32 maverage traffic in 10 s base on server port: \ 033 [0 m"
- Awk-F' [.:] + '-v regTcpdump = $ regTcpdump' {if ($0 ~ RegTcpdump) {line = "clients>" $8 ". "$9 ". "$10 ". "$11": "$12} else {line = $2 ". "$3 ". "$4 ". "$5": "$6"> clients "}; sum [line] + = $ NF * 8/10} END {for (line in sum) {printf "% s % d \ n", line, sum [line]} '/tmp/tcpdump | \
- Sort-k 4-nr | head-n 10 | while read a B c d; do
- Echo "$ a $ B $ c $ (bit_to_human_readable $ d)/s"
- Done
- Echo-ne "\ 033 [11A"
- Echo-ne "\ 033 [50C"
- Echo-e "\ 033 [32 maverage traffic in 10 s base on client port: \ 033 [0 m"
- Awk-F' [.:] + '-v regTcpdump = $ regTcpdump' {if ($0 ~ RegTcpdump) {line = $2 ". "$3 ". "$4 ". "$5": "$6"> server "} else {line =" server> "$8 ". "$9 ". "$10 ". "$11": "$12}; sum [line] + = $ NF * 8/10} END {for (line in sum) {printf" % s % d \ n ", line, sum [line]} '/tmp/tcpdump | \
- Sort-k 4-nr | head-n 10 | while read a B c d; do
- Echo-ne "\ 033 [50C"
- Echo "$ a $ B $ c $ (bit_to_human_readable $ d)/s"
- Done
-
- Echo
- # Count the top 10 ip addresses with the largest bandwidth in 10 s
- Echo-e "\ 033 [32 mtop 10 ip average traffic in 10 s base on server: \ 033 [0 m"
- Awk-F' [.:] + '-v regTcpdump = $ regTcpdump' {if ($0 ~ RegTcpdump) {line = $2 ". "$3 ". "$4 ". "$5"> "$8 ". "$9 ". "$10 ". "$11": "$12} else {line = $2 ". "$3 ". "$4 ". "$5": "$6"> "$8 ". "$9 ". "$10 ". "$11}; sum [line] + = $ NF * 8/10} END {for (line in sum) {printf" % s % d \ n ", line, sum [line]} '/tmp/tcpdump | \
- Sort-k 4-nr | head-n 10 | while read a B c d; do
- Echo "$ a $ B $ c $ (bit_to_human_readable $ d)/s"
- Done
- Echo-ne "\ 033 [11A"
- Echo-ne "\ 033 [50C"
- Echo-e "\ 033 [32 mtop 10 ip average traffic in 10 s base on client: \ 033 [0 m"
- Awk-F' [.:] + '-v regTcpdump = $ regTcpdump' {if ($0 ~ RegTcpdump) {line = $2 ". "$3 ". "$4 ". "$5": "$6"> "$8 ". "$9 ". "$10 ". "$11} else {line = $2 ". "$3 ". "$4 ". "$5"> "$8 ". "$9 ". "$10 ". "$11": "$12}; sum [line] + = $ NF * 8/10} END {for (line in sum) {printf" % s % d \ n ", line, sum [line]} '/tmp/tcpdump | \
- Sort-k 4-nr | head-n 10 | while read a B c d; do
- Echo-ne "\ 033 [50C"
- Echo "$ a $ B $ c $ (bit_to_human_readable $ d)/s"
- Done
- Echo
- # Statistical connection status
- Local regSS =$ (ifconfig | grep-A 1 $ eth | awk-F' [:] + ''$0 ~ /Inet addr:/{printf $4 "|"} '| sed-e's/| $ //')
- Ss-an | grep-v-E "LISTEN | UNCONN" | grep-E "$ regSS">/tmp/ss
- Echo-e "\ 033 [32 mconnection state count: \ 033 [0 m"
- Awk 'nr> 1 {sum [$ (NF-4)] + = 1} END {for (state in sum) {print state, sum [state]} '/tmp/ss | sort-k 2-nr
- Echo
- # Count the connection status of each port
- Echo-e "\ 033 [32 mconnection state count by port base on server: \ 033 [0 m"
- Awk 'nr> 1 {sum [$ (NF-4), $ (NF-1)] + = 1} END {for (key in sum) {split (key, subkey, SUBSEP ); print subkey [1], subkey [2], sum [subkey [1], subkey [2]} '/tmp/ss | sort-k 3-nr | head-n 10
- Echo-ne "\ 033 [11A"
- Echo-ne "\ 033 [50C"
- Echo-e "\ 033 [32 mconnection state count by port base on client: \ 033 [0 m"
- Awk 'nr> 1 {sum [$ (NF-4), $ (NF)] + = 1} END {for (key in sum) {split (key, subkey, SUBSEP ); print subkey [1], subkey [2], sum [subkey [1], subkey [2]} '/tmp/ss | sort-k 3-nr | head-n 10 | awk' {print "\ 033 [50C" $0 }'
- Echo
- # Top 10 IP addresses with the maximum number of ESTAB connections in port 80
- Echo-e "\ 033 [32 mtop 10 ip ESTAB state count at port 80: \ 033 [0 m"
- Cat/tmp/ss | grep ESTAB | awk-F' [:] + ''{sum [$ (NF-2)] + = 1} END {for (ip in sum) {print ip, sum [ip]} '| sort-k 2-nr | head-n 10
- Echo
- # The first 10 IP addresses with the maximum number of SYN-RECV connections in port 80
- Echo-e "\ 033 [32 mtop 10 ip SYN-RECV state count at port 80: \ 033 [0 m"
- Cat/tmp/ss | grep-E "$ regSS" | grep SYN-RECV | awk-F '[:] + ''{sum [$ (NF-2)] + = 1} END {for (ip in sum) {print ip, sum [ip]} '| sort-k 2-nr | head-n 10
- }
- Main (){
- While true; do
- Echo-e "1) real time traffic. \ n2) traffic and connection overview. \ n"
- Read-p "please input your select (ie 1):" select
- Case $ select in
- 1) realTimeTraffic; break ;;
- 2) trafficAndConnectionOverview; break ;;
- *) Echo "input error, please input a number .";;
- Esac
- Done
- }
- Main
If you do not understand the script, leave a message for consultation.
For more information, see https://www.centos.bz/2014/06/shell-script-for-network-analysis/.