Skip to content

Commit

Permalink
Format script, add CI, add tests, update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaosCypher committed Sep 14, 2024
1 parent dc2268f commit a46e4b2
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 34 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: CI

on:
pull_request:
branches:
- main
types: [opened, synchronize, edited]

permissions: {}

jobs:
lint:
name: Lint
runs-on: ubuntu-latest

permissions:
contents: read
packages: read
statuses: write

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Super-linter
uses: super-linter/super-linter/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

test:
needs: lint
name: Test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run tests
shell: bash
run: |
chmod +x bidir-traffic-check.sh \
test-bidir-traffic-check.sh
sudo ./test-bidir-traffic-check.sh
87 changes: 85 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,85 @@
# bidir-traffic-check
This repo contains a health script that looks for bi-directional TCP communications using tcpdump.
# Bi-Directional Traffic Check

This project provides a script to check for bi-directional network traffic on specified interfaces.

## Table of Contents

- [Description](#description)
- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)

## Description

The Bi-Directional Traffic Check script is designed to monitor network interfaces for bi-directional TCP traffic. It's useful for network administrators and security professionals who need to verify active two-way communications on their networks.

## Features

- Automatic detection of active network interfaces
- Configurable interface ignore list
- Customizable packet capture count

## Installation

1. Clone this repository:
```bash
git clone https://github.com/yourusername/bidir-traffic-check.git
```
2. Navigate to the project directory:
```bash
cd bidir-traffic-check
```
3. Ensure the script has execute permissions:
```bash
chmod +x bidir-traffic-check.sh
```

## Usage

Run the script with root privileges:

```bash
sudo ./bidir-traffic-check.sh
```

The script will output whether bi-directional communication was found on each active interface.

## Configuration

You can configure the script by editing the following variables:

- `TCPDUMP_PATH`: Set the path to tcpdump if it's not in your system PATH
- `INTERFACES`: Specify network interfaces to check (empty array checks all interfaces)
- `IGNORE_INTERFACES`: List interfaces to ignore
- `PACKETS`: Number of packets to capture when checking for bi-directional traffic
## Testing
To run the test suite:
1. Ensure the test script has execute permissions:
```bash
chmod +x test-bidir-traffic-check.sh
```
2. Run the test script with root privileges:
```bash
sudo ./test-bidir-traffic-check.sh
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## License
This project is licensed under the GNU General Public License v3.0. See the [LICENSE](LICENSE) file for details.
78 changes: 46 additions & 32 deletions bidir-traffic-check.sh
Original file line number Diff line number Diff line change
@@ -1,73 +1,87 @@
#!/usr/bin/env bash

set -x

# Path to tcpdump (defaults to $PATH if empty)
TCPDUMP_PATH=
TCPDUMP_PATH=${TCPDUMP_PATH:-tcpdump}

# Automatically found network interfaces in 'up' status
AUTO_INTERFACES=()

# Network interfaces to check (defaults to all interfaces if empty)
INTERFACES=()

# Network interface ignore list (useful when defaulting to all interfaces)
IGNORE_INTERFACES=("lo" "docker0" "virbr0")

# Number of packets to capture when checking for bi-directional traffic
PACKETS=50

# Return codes
OK=0
ERROR=1
WARNING=2
UNKNOWN=3

# Check for root privileges
function checkSudo() {
if (( $(id -u) != 0 )); then
echo "ERROR - This script must be run with root privileges!"
return $ERROR
fi
if (($(id -u) != 0)); then
echo "ERROR - This script must be run with root privileges!"
return $ERROR
fi
}

# Populate the network interfaces array
function getInterfaces() {
if (( ${#INTERFACES[@]} == 0 )); then
for iface in /sys/class/net/*; do
INTERFACES+=("${iface}")
done
fi
if ((${#INTERFACES[@]} == 0)); then
for iface in /sys/class/net/*; do
INTERFACES+=("${iface}")
done
fi
}

# Remove ignored interfaces from the interfaces array
function ignoreInterfaces() {
for ignored_iface in "${IGNORE_INTERFACES[@]}"; do
INTERFACES=("${INTERFACES[@]/$ignored_iface}")
done
for ignored_iface in "${IGNORE_INTERFACES[@]}"; do
INTERFACES=("${INTERFACES[@]/$ignored_iface/}")
done
}

# Remove interfaces marked as 'down'
function removeDownInterfaces() {
for iface in "${INTERFACES[@]}"; do
if [[ -n "$iface" && -f "/sys/class/net/$iface/operstate" ]]; then
if grep -q 'up' "/sys/class/net/$iface/operstate"; then
AUTO_INTERFACES+=("$iface")
fi
fi
done
for iface in "${INTERFACES[@]}"; do
if [[ -n "$iface" && -f "/sys/class/net/$iface/operstate" ]]; then
if grep -q 'up' "/sys/class/net/$iface/operstate"; then
AUTO_INTERFACES+=("$iface")
fi
fi
done
}

# Check for bi-directional traffic on interfaces
function checkTraffic() {
for iface in "${AUTO_INTERFACES[@]}"; do
tcpdump -n -i "$iface" tcp -c 50 2> /dev/null | awk '{
src[NR]=$3;
dst[NR]=substr($5, 1, length($5)-1)
for iface in "${AUTO_INTERFACES[@]}"; do
tcpdump -n -i "$iface" tcp -c "$PACKETS" 2>/dev/null | awk '
{
src[NR] = $3
dst[NR] = substr($5, 1, length($5) - 1)
}
END {
for (i=1; i<=NR; i++) {
for (j=1; j<=NR; j++) {
for (i = 1; i <= NR; i++) {
for (j = 1; j <= NR; j++) {
if (src[i] == dst[j] && src[i] != "") {
if (dst[i] == src[j]) {
print "Bi-Directional communication found on '"$iface"'\n" src[i]" -> "dst[i]"\n"src[j]" -> "dst[j];
exit
print "Bi-Directional communication found on '"$iface"'"
print src[i] " -> " dst[i]
print src[j] " -> " dst[j]
return '"$OK"'
}
}
}
}
print "Bi-Directional communication not found on '"$iface"'"
return '"$WARNING"'
}'
done
done
}

# Main script execution
checkSudo
getInterfaces
Expand Down
62 changes: 62 additions & 0 deletions test-bidir-traffic-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash

# Set up test environment
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_TO_TEST="$SCRIPT_DIR/bidir-traffic-check.sh"
FAILED_TESTS=0

# Function to run the script and capture output
run_test() {
local description="$1"
local expected_exit_code="$2"
local expected_output="$3"

echo "Running test: $description"
output=$(sudo "$SCRIPT_TO_TEST" 2>&1)
exit_code=$?

if [ $exit_code -eq "$expected_exit_code" ]; then
echo "Exit code test passed"
else
echo "Exit code test failed. Expected: $expected_exit_code, Got: $exit_code"
FAILED_TESTS=$((FAILED_TESTS + 1))
fi

if echo "$output" | grep -q "$expected_output"; then
echo "Output test passed"
else
echo "Output test failed. Expected to contain: $expected_output"
echo "Got: $output"
FAILED_TESTS=$((FAILED_TESTS + 1))
fi

echo "---"
}

# Test 1: Check if script runs without errors
run_test "Basic execution" 0 "Bi-Directional communication"

# Test 2: Check if script detects lack of root privileges
if [ "$EUID" -eq 0 ]; then
echo "Skipping root privilege test (already running as root)"
else
run_test "Non-root execution" 3 "This script must be run with root privileges"
fi

# Test 3: Check if script handles non-existent interface
NONEXISTENT_INTERFACE="eth999"
sudo sed -i "s/^INTERFACES=(.*)/INTERFACES=($NONEXISTENT_INTERFACE)/" "$SCRIPT_TO_TEST"
run_test "Non-existent interface" 1 "Bi-Directional communication not found"

# Restore original INTERFACES setting
sudo sed -i "s/^INTERFACES=(.*)/INTERFACES=()/" "$SCRIPT_TO_TEST"

echo "All tests completed."

if [ $FAILED_TESTS -gt 0 ]; then
echo "Test suite failed with $FAILED_TESTS error(s)."
exit 1
else
echo "All tests passed successfully."
exit 0
fi

0 comments on commit a46e4b2

Please sign in to comment.