Skip to content

Commit

Permalink
Update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
containerscrew committed Dec 7, 2024
1 parent 9f29bbc commit 2e71f95
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 174 deletions.
140 changes: 19 additions & 121 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
> [!WARNING]
> Ignore this README. It may change as I develop and adjust configurations.
> The entire tool is under development, while I am learning Rust and eBPF.
> I am not a Rust developer, so I am learning as I go. I am open to any suggestions or improvements.
> Code is not optimized, and I am not following best practices. I am learning and improving as I go.
<p align="center">
<h3 align="center">nflux</h3>
Expand All @@ -10,21 +12,15 @@

<!-- START OF TOC !DO NOT EDIT THIS CONTENT MANUALLY-->
**Table of Contents** *generated with [mtoc](https://github.com/containerscrew/mtoc)*
- [Intro](#intro)
- [Nflux architecture](#nflux-architecture)
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Debian/Ubuntu installation](#debianubuntu-installation)
- [Configuration file](#configuration-file)
- [Logging](#logging)
- [Testing firewall](#testing-firewall)
- [Debugging](#debugging)
- [Contribution](#contribution)
- [License](#license)
<!-- END OF TOC -->


# Intro
# Nflux architecture

Look at what level it works XDP:

Expand All @@ -34,134 +30,36 @@ Powerful, right? Same for traffic control (TC).

![tc](./tc.png)

> [!NOTE]
> nflux uses XDP for incoming packet processing (only works with physical interfaces). For outgoing packets, it uses TC. If you want to use it with a virtual interface, you need to use the `tc` mode which is not implemented yet.
# Features

Basic XDP firewall:

* Block TCP SYN incoming packets
* Allow incoming SYN-ACK incoming packets (for example, you are using your browser)
* Block ICMP incoming packets
* User can allow traffic for specific incoming ports
* User can allow traffic for specific IP addresses


# Requirements

`nflux` is not available in any package manager yet. You need to build it from source.

1. Install rust:
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

2. Install nightly toolchain:
```
rustup install stable && rustup toolchain install nightly --component rust-src
```

3. Optional, if using mac or other linux:
```bash
LLVM_SYS_180_PREFIX=$(brew --prefix llvm) cargo install --no-default-features bpf-linker
```

3. **MANDATORY:**
```bash
cargo install bpf-linker
```

> [!CAUTION]
> nflux uses XDP for packet processing. Only works with physical interfaces. If you want to use it with a virtual interface, you need to use the `tc` mode which is not implemented yet.
> For example, you want to monitor incoming traffic using a virtual interface like `tun0` (VPN), you need to use the `tc` mode.
* Block incoming ipv4/ipv6-tcp/udp packets.
* Allow incoming ipv4/ipv6-tcp/udp packets.
* Block incoming ICMP packets.
* Filter outgoing packets.

# Installation

By the moment, I only have the setup for `dpkg` (Debian/Ubuntu).

```shell
git clone https://github.com/containerscrew/nflux.git
```

## Debian/Ubuntu installation

```shell
make install-dpkg
```

# Configuration file

Edit the main configuration [`nflux.toml`](./nflux.toml) file if needed:

```shell
sudo nvim /etc/nflux/nflux.toml
sudo systemctl restart nflux.service
```

# Logging

```shell
make journal-logs
```

# Testing firewall

Now you can try to map some services using docker. For example, let's expose an nginx server (tcp) and bind9 (udp):

```shell
make compose-up
```

Test the exposed services works. (Recommended) test the services from other device in the same network:

* Nginx server:
By the moment, the quickest way to install **`nflux`** is using containers. Let's see how to run `nflux` with `docker-compose`.

```bash
curl http://ip:8081 # Welcome to nginx!
git clone https://github.com/containerscrew/nflux.git
make compose-build
```

* Bind9 server:
Before running the container, you need to edit the configuration file [`nflux.toml`](./nflux.toml). The most important configuration is the `interface` name.

```bash
dig @ip -p 5053 mycompany.org A
```

> Change `ip` to the ip of the machine where you are running the docker-compose and where you will run the firewall.
Now, since the exposed port of `nginx` for example is `8081`, let's run the firewall without any allowed port:

For example, in `nflux.toml`:

```toml
[log]
log_level = "info" # trace, debug, info, warn or error. Defaults to info if not set
log_type = "text" # text or json. Defaults to text if not set

[nflux]
interface_name = "wlp2s0"

[firewall]
# All incoming connections will be blocked by default
# You can specify allowed IP addresses and ports
# This will allow both, udp and tcp connections

# Specify IP addresses you want to allow. Will be able to access full ports tcp/udp
allowed_ipv4 = ["192.168.0.30"]
# Specify ports you want to allow. Everyone will be able to access these ports. No ip filtering
allowed_ports = ["8080"]
# Allow ICMP packets (ping)
allow_icmp = false
ip link show # get the name of your PHISICAL interface
# Once is changes in the conf file, lets run nflux
make compose-up
```

Try again `curl http://ip:8081` and you will see that the connection is blocked.

Change the `interface_name` to your physical interface name, also you can play changing the `allowed_ipv4` and `allowed_ports` to allow some traffic.

# Debugging

```bash
sudo bpftool prog list # show ebpf running programs
ip link show dev wlo1 # xdp attached to your interface
```
> By default, nflux will allow SSH (22) connections from any IP. Avoid blocking your SSH connection if testing in remote servers (VPS).
# Contribution

Expand Down
4 changes: 4 additions & 0 deletions docker/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ services:
restart: unless-stopped
network_mode: host
cap_add:
# Required caps:
# - CAP_NET_ADMIN
# - CAP_BPF
# - CAP_PERFMON
# Insecure, by the moment give all capabilities
- ALL
container_name: nflux
Expand Down
38 changes: 38 additions & 0 deletions docs/local_dev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- START OF TOC !DO NOT EDIT THIS CONTENT MANUALLY-->
**Table of Contents** *generated with [mtoc](https://github.com/containerscrew/mtoc)*
- [Local development](#local-development)
- [Requirements](#requirements)
- [Debugging](#debugging)
<!-- END OF TOC -->
# Local development

For more information, please visit [official documentation](https://aya-rs.dev/book/).

## Requirements

1. Install rust:
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

2. Install nightly toolchain:
```
rustup install stable && rustup toolchain install nightly --component rust-src
```

3. Optional, if using mac or other linux:
```bash
LLVM_SYS_180_PREFIX=$(brew --prefix llvm) cargo install --no-default-features bpf-linker
```

3. **MANDATORY:**
```bash
cargo install bpf-linker
```

# Debugging

```bash
sudo bpftool prog list # show ebpf running programs
ip link show dev wlo1 # xdp attached to your interface
```
5 changes: 3 additions & 2 deletions nflux.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ log_type = "text" # text or json. Defaults to text if not set

[ip_rules]
# The /32 CIDR block is used to represent a single IP address rather than a range
"192.168.0.0/24" = { priority = 1, action = "allow", ports = [22, 8000, 80], protocol = "tcp", log = false, description = "Allow SSH for entire local net" }
"0.0.0.0/0" = { priority = 1, action = "allow", ports = [22], protocol = "tcp", log = true, description = "Allow SSH from anywhere" }
"192.168.0.0/24" = { priority = 2, action = "allow", ports = [8000, 80], protocol = "tcp", log = false, description = "Allow SSH for entire local net" }

# curl -6 -v http://\[::ffff:192.168.0.26\]:80
"fe80::5bc2:662b:ac2f:7e8b/128" = { priority = 2, action = "allow", ports = [80], protocol = "tcp", log = false, description = "Deny HTTP for specific IPv6 address" }
"fe80::5bc2:662b:ac2f:7e8b/128" = { priority = 3, action = "allow", ports = [80], protocol = "tcp", log = false, description = "Deny HTTP for specific IPv6 address" }

#[mac_rules]
# todo: MAC address filtering
Expand Down
51 changes: 0 additions & 51 deletions stuff/test.rs

This file was deleted.

0 comments on commit 2e71f95

Please sign in to comment.