# ngrep: grep for Network Packets in Real Time

LLMS index: [llms.txt](/en/llms.txt)

---

Ngrep applies grep-style pattern matching to network packets. When you need to see exactly what two services are exchanging over the wire and tcpdump drowns you in noise, ngrep isolates the payload content you care about.

## Installation

Ngrep ships in the standard repositories of most distributions.

```bash
# Debian/Ubuntu
apt install ngrep

# RHEL/CentOS/Alma
yum install ngrep

# macOS
brew install ngrep
```

Running ngrep requires root privileges or the `CAP_NET_RAW` and `CAP_NET_ADMIN` capabilities.

## Basic Syntax

```bash
ngrep [options] [pattern] [BPF filters]
```

Minimal invocation catches all packets on a port:

```bash
ngrep -i 'password' port 80
```

Breaking it down:

- `-i` — case-insensitive search
- `'password'` — regex pattern matched against payload
- `port 80` — BPF filter: traffic on port 80 only

Output resembles tcpdump with decoded payload:

```
T 10.0.1.15:54321 -> 10.0.2.10:80 [AP]
GET /api/v1/users HTTP/1.1..
Host: api.example.com....
```

## Common Flags

| Flag | Description |
|------|-------------|
| `-i` | Case-insensitive search |
| `-W byline` | Line-wrap output, strip escape sequences |
| `-q` | Quiet: show matches only, suppress metadata |
| `-t` | Prefix each packet with timestamp |
| `-d eth0` | Listen on a specific interface |
| `-n 1` | Exit after first match |
| `-c N` | Limit output to N characters per line |
| `-x` | Show hexdump instead of ASCII |

Practical example with timestamps:

```bash
ngrep -i -t 'POST' port 8080
```

## Port and Protocol Filtering

Ngrep accepts standard tcpdump BPF filters. Common patterns:

```bash
# Specific port
ngrep 'GET' port 80

# Port range
ngrep 'error' portrange 8000-9000

# By host
ngrep 'token' host 10.0.1.50

# Combined filter
ngrep -i 'auth' host 10.0.1.50 and port 443

# Outbound traffic only
ngrep 'response' dst port 8080
```

> [!NOTE]
> Ngrep parses BPF filters identically to tcpdump. The `port`, `host`, `and`, and `or` syntax works the same way in both tools.

## HTTP Requests in Docker Containers

A frequent task is tracking HTTP traffic between containers. Two approaches work.

**First: run ngrep inside the container**

Works if the container is Alpine or Debian-based and you have access:

```bash
docker exec -it <container_id> sh -c "apt-get update && apt-get install -y ngrep"
docker exec -it <container_id> ngrep -i 'Content-Type' port 80
```

**Second: listen on docker0**

When containers communicate over the host's bridge network:

```bash
# Find the docker network interface
ip addr show docker0

# Listen on it
ngrep -W byline 'HTTP' host 172.17.0.2 and port 80 -d docker0
```

Check a container's IP:

```bash
docker inspect -f '{{.NetworkSettings.IPAddress}}' <container_name>
```

## Limitations and Alternatives

Ngrep only works with plaintext traffic. It cannot decrypt TLS/HTTPS — you will see binary garbage instead of content.

Other limitations:

- Does not understand HTTP/2 or HTTP/3 — these protocols are binary
- No built-in JSON or XML parsing, only text-based matching
- Performance lags behind tcpdump under high load

**Alternatives by use case:**

| Task | Tool |
|------|------|
| Quick pcap capture | `tcpdump -i eth0 -A port 80` |
| Detailed protocol analysis | `tshark -Y http -i eth0` |
| HTTPS monitoring (key required) | Wireshark with decryption |
| gRPC tracing | `grpcurl` or Wireshark with Protobuf dissector |

For most debugging tasks, `ngrep` plus `tcpdump` covers the bases. If you need to parse a specific protocol in depth, tshark with filters gives more control — but requires learning Wireshark's syntax.
