Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5550bb2
Add a failover handler to register slips service in systemd, create a…
AlyaGomaa Nov 14, 2025
5cea1d8
add a template slips service
AlyaGomaa Nov 14, 2025
ffa90d1
add a .sh script for slips runner to run via the systemd service
AlyaGomaa Nov 14, 2025
76c9d07
dockerfile: use apt_dependencies instead of duplicate hardcoding of d…
AlyaGomaa Nov 14, 2025
9ddc7f4
Fix Unable to start slips with -ap
AlyaGomaa Nov 14, 2025
4e6a2f2
failover_handler.sh: tell the user what slips does with the created o…
AlyaGomaa Nov 14, 2025
d260989
slips-runner: increase cpu shares and add NET_ADMIN capabilities to t…
AlyaGomaa Nov 14, 2025
f4b898b
Add a systemd .path and a .service for auto save on any iptables rule…
AlyaGomaa Nov 14, 2025
c2a83ab
failover_handler.sh: setup systemd persistence units
AlyaGomaa Nov 14, 2025
b320235
User a service that monitors rule changes every 10s for iptables rule…
AlyaGomaa Nov 14, 2025
7287e4d
add a .sh script to save the iptables rule whenever a change in the r…
AlyaGomaa Nov 14, 2025
b100fe6
failover_handler.sh: register the timer and iptables-watcher.service …
AlyaGomaa Nov 14, 2025
a8e4e3f
better logging of killing th eAP process when slips fails
AlyaGomaa Nov 19, 2025
6de6454
reorder apt dependencies with important libs first
AlyaGomaa Nov 24, 2025
0cd441d
increase timeouts for slips runner to start and cleanup
AlyaGomaa Nov 24, 2025
7530f5b
Don't rm the docker container when it's killed, or when the runner fi…
AlyaGomaa Nov 24, 2025
67df833
slips-runner: kill the container when slips stops
AlyaGomaa Nov 24, 2025
d89e627
more verbose prints about whats happening
AlyaGomaa Nov 24, 2025
52aaff7
Dockerfile: when doing apt update: retry on timeout, enforce https an…
AlyaGomaa Nov 24, 2025
e330ead
Add failover mechanisms docs
AlyaGomaa Nov 25, 2025
c1ba616
don't start docker with rm to be able to debug the failing container …
AlyaGomaa Nov 25, 2025
8159bab
Add a failover handler to register slips service in systemd, create a…
AlyaGomaa Nov 14, 2025
dfd871f
add a template slips service
AlyaGomaa Nov 14, 2025
72e5e0d
add a .sh script for slips runner to run via the systemd service
AlyaGomaa Nov 14, 2025
90a8d5b
dockerfile: use apt_dependencies instead of duplicate hardcoding of d…
AlyaGomaa Nov 14, 2025
f4da6d9
Fix Unable to start slips with -ap
AlyaGomaa Nov 14, 2025
d57d93b
failover_handler.sh: tell the user what slips does with the created o…
AlyaGomaa Nov 14, 2025
bb7a4dc
slips-runner: increase cpu shares and add NET_ADMIN capabilities to t…
AlyaGomaa Nov 14, 2025
70a67e3
Add a systemd .path and a .service for auto save on any iptables rule…
AlyaGomaa Nov 14, 2025
4d6bf36
failover_handler.sh: setup systemd persistence units
AlyaGomaa Nov 14, 2025
e73b10b
User a service that monitors rule changes every 10s for iptables rule…
AlyaGomaa Nov 14, 2025
8890603
add a .sh script to save the iptables rule whenever a change in the r…
AlyaGomaa Nov 14, 2025
47cdc13
failover_handler.sh: register the timer and iptables-watcher.service …
AlyaGomaa Nov 14, 2025
bb728db
better logging of killing th eAP process when slips fails
AlyaGomaa Nov 19, 2025
9499f50
reorder apt dependencies with important libs first
AlyaGomaa Nov 24, 2025
aa6427f
increase timeouts for slips runner to start and cleanup
AlyaGomaa Nov 24, 2025
9725122
Don't rm the docker container when it's killed, or when the runner fi…
AlyaGomaa Nov 24, 2025
4bfefae
slips-runner: kill the container when slips stops
AlyaGomaa Nov 24, 2025
c3ace1e
more verbose prints about whats happening
AlyaGomaa Nov 24, 2025
c8a4f0f
Dockerfile: when doing apt update: retry on timeout, enforce https an…
AlyaGomaa Nov 24, 2025
9229299
Add failover mechanisms docs
AlyaGomaa Nov 25, 2025
13c0b8c
don't start docker with rm to be able to debug the failing container …
AlyaGomaa Nov 25, 2025
0409d8c
Merge remote-tracking branch 'origin/alya/immune/failover_mechanisms'…
AlyaGomaa Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 15 additions & 27 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,26 @@ ENV NVM_DIR=/root/.nvm
# use bash instead of sh
SHELL ["/bin/bash", "-c"]

# Switch to Slips installation dir on login.
WORKDIR ${SLIPS_DIR}

COPY . $SLIPS_DIR

RUN apt update && apt install -y --no-install-recommends \
wget \
ca-certificates \
git \
curl \
gnupg \
RUN apt-get update -o Acquire::Retries=5 -o Acquire::https::No-Cache=True \
&& apt-get install -y --no-install-recommends --fix-broken --fix-missing \
$(cat install/apt_dependencies.txt) \
lsb-release \
software-properties-common \
build-essential \
file \
lsof \
iptables \
iproute2 \
nfdump \
tshark \
whois \
yara \
net-tools \
vim \
less \
unzip \
golang \
python3-certifi \
python3-dev \
python3-tzlocal \
python3-pip \
nano \
tree \
tmux \
arp-scan \
&& echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' | tee /etc/apt/sources.list.d/security:zeek.list \
&& curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_22.04/Release.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null \
&& apt update \
&& apt install -y --no-install-recommends --fix-missing \
&& apt-get install -y --no-install-recommends --fix-missing \
zeek-8.0 \
npm \
&& ln -s /opt/zeek/bin/zeek /usr/local/bin/bro \
Expand All @@ -72,11 +57,15 @@ RUN apt update && apt install -y --no-install-recommends \
&& curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - \
&& export NVM_DIR="$HOME/.nvm" \
&& [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
&& nvm install 22
&& nvm install 22 \
&& apt purge -y redis-server redis # we'll be compiling it manually



# why are we compiling redis instead od just using apt?
# to support running slips on the rpi (arm64). the rpi uses jemmalloc by default, which expects a different page size
# than the default on x86_64
WORKDIR /
RUN pip3 install --no-cache-dir --upgrade pip \
&& curl -O https://download.redis.io/redis-stable.tar.gz \
&& tar xzf redis-stable.tar.gz \
Expand All @@ -87,11 +76,9 @@ RUN pip3 install --no-cache-dir --upgrade pip \
ENV PATH="$PATH:/redis-stable/src"


# Switch to Slips installation dir on login.
WORKDIR ${SLIPS_DIR}

COPY . $SLIPS_DIR

WORKDIR ${SLIPS_DIR}
# Retrieve Iris
COPY --from=build /iris/iris ./modules/irisModule

Expand All @@ -110,4 +97,5 @@ ENV PATH="$PATH:/StratosphereLinuxIPS/p2p4slips/"

WORKDIR ${SLIPS_DIR}


CMD /bin/bash
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions docs/immune/failover_mechanisms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Failover Mechanisms

The project has a few failure points listed below that we explicitly want to control instead and try to recover from.

Our goal if something breaks, is to try to recover automatically where possible, but if recovery is not possible or the failure is critical, the user must lose internet so they are forced to debug and restart Slips manually instead of staying connected without Slips protection.


All failure points are handled by the ```failover_handler.sh``` script located in ```StratosphereLinuxIPS/rpi_scripts/```.

## Prerequisites

- Raspberry Pi with docker installed
- StratosphereLinuxIPS cloned. (or just the rpi_scripts/ directory)
- Root access to the Raspberry Pi.
- A [running access point](https://stratospherelinuxips.readthedocs.io/en/develop/immune/installing_slips_in_the_rpi.html#protect-your-local-network-with-slips-on-the-rpi).


## How to use

Run the following command from Slips main directory as root:

```bash
sudo ./rpi_scripts/failover_handler.sh <wifi_interface>,<ethernet_interface>
```

**Where**

- ```<wifi_interface>``` is the name of the wifi interface used by the access point (e.g. ```wlan0```, etc).

- ```<ethernet_interface>``` is the name of the ethernet interface connected to the router (e.g. ```eth0```, etc).

**You should see output similar to the image below:**

![](../images/immune/a8/failovers_script_output.jpg)


**Output:**

The script will
- Log Slips docker container status, used command, and any errors to ```slips_container.log``` for debugging purposes. This file should be checked in case you notice any issues with the AP or Slips.
- Start Slips and iptables watcher services through systemd so they start automatically on reboot and on failure.
- Start slips inside a docker container monitring your ethernet and wifi interfaces.
- Mount your local ```StratosphereLinuxIPS/output``` to ```/StratosphereLinuxIPS/output``` inside the started Slips container so any output generated by Slips will be available on the host machine.



## How Failovers are Handled

Slips in the Raspberry Pi has 3 main failure points that we want to handle:
1. The access point dies
2. Slips dies
3. The Raspberry Pi reboots

### The access point dies

If the AP dies, clients get disconnected. There's nothing to handle here. Slips keeps monitoring the ethernet interface and when the AP is back up, clients can reconnect and Slips continues protecting them.


### Slips dies

Failovers when Slips dies consist of:

* **Iptables firewall rules persistence**: The iptables firewall rules are saved periodically by the systemd unit that watches for iptables changes and saves them using ```netfilter-persistent``` whenever a change is detected.
* **Shutting down the AP process**: If Slips crashes we do not want the AP to keep running without Slips protection so we intentionally shut down the access point for the user to notice, debug and restart Slips manually instead of staying connected without Slips protection.
* **Restarting Slips automatically through systemd:** Slips restarts automatically through systemd on failure and on reboot.
* **Logging Slips container status to a file for debugging**: Slips container logs are places in ```slips_container.log``` for debugging purposes.



### The Raspberry Pi reboots

Failovers consist of:

* **Iptables firewall rules persistence**
* **Automatic start of Slips service through systemd**


When the Pi reboots, we want Slips to start automatically, and we want the iptables rules added by Slips to persist. The automatic restart is handled by systemd through the generated ```slips.service``` file, and firewall persistence is handled using the custom iptables watcher through the generated ```iptables-watcher.service```.


Both units are generated and started and added to the user's ```/etc/systemd/system``` by the ```failover_handler.sh``` script.

---

## File Descriptions

All the files involved in failover mechanisms are placed in ```StratosphereLinuxIPS/rpi_scripts/``` and are described in the table below:


| File | What it does |
|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| failover_handler.sh | The central orchestrator that checks AP status, ensures root access, prepares directories, sets up iptables persistence, builds the Slips runner script, generates the systemd unit, and enforces all failover behavior. This is the piece that links every component together and decides how the system should react when something breaks. |
| iptables_autosave/check-iptables-hash.sh | Keeps track of the hash of the current iptables rules and triggers a save when change is detected. |
| iptables_autosave/iptables-watcher.service | The systemd service that runs check-iptables-hash.sh (because we can't run the script directly by the timer), this is triggered by the iptables-watcher.timer every 10s to check for iptables changes. |
| iptables_autosave/iptables-watcher.timer | A systemd timer that periodically runs iptables-watcher.service so iptables rule changes are captured and saved automatically. |
| slips_container.log | A runtime log collecting Docker container output, commands, and status. useful for investigating restarts, failures, or unexpected behavior. |
| slips-runner-template.sh | The script that launches Slips container and launches slips inside of it in a tmux. This runner keeps the container up as long as Slips is running. |
| slips.service.template | The systemd unit that starts slips on reboot and on failure, it runs the slips-runner-template.sh. |


---
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ Docker can run amd64 images on arm devices using emulation, but this method come

So we decided to go for an ARM docker image specifically for ARM devices and the RPI. This is doable without maintaining 2 different Dockerfiles one for each architechture thanks to docker buildx multiplatform support.

**Commands for building the ARM image**

**Commands for building one multi-architecture image (supporting AMD and ARM)**
```
docker buildx create --name slips\_builder

docker buildx use slips\_builder

export BUILDKIT\_CONTAINERD=1

docker buildx build --platform linux/amd64,linux/arm64 -t stratosphereips/slips:latest -f docker/Dockerfile --push .
```

Our goal is to maintain one Dockerfile that is able to run on both ARM and AMD architectures.

Expand Down
18 changes: 9 additions & 9 deletions install/apt_dependencies.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
curl
gnupg
ca-certificates
python3
redis-server
python3-pip
python3-certifi
python3-dev
python3-watchdog
python3-tzlocal
wget
npm
iw
build-essential
file
lsof
net-tools
iproute2
iptables
python3-tzlocal
nfdump
tshark
git
Expand All @@ -21,11 +27,5 @@ yara
libnotify-bin
wireless-tools
arp-scan
python3-watchdog
curl
gnupg
ca-certificates
redis-server
redis
wget
npm
iw
2 changes: 1 addition & 1 deletion managers/ap_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def store_ap_interfaces(self, input_information):
"""
stores the interfaces given with -ap to slips in the db
"""
self.wifi_interface, self.eth_interface = input_information.split(",")
self.wifi_interface, self.eth_interface = input_information.split("_")
interfaces = {
"wifi_interface": self.wifi_interface,
"ethernet_interface": self.eth_interface,
Expand Down
Loading
Loading