Skip to content

Commit 14946fb

Browse files
authored
Merge pull request #1737 from stratosphereips/alya/immune/failover_mechanisms
Add failover handler for running Slips in the RPI
2 parents abc8ee4 + 0409d8c commit 14946fb

File tree

12 files changed

+484
-39
lines changed

12 files changed

+484
-39
lines changed

docker/Dockerfile

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,41 +29,26 @@ ENV NVM_DIR=/root/.nvm
2929
# use bash instead of sh
3030
SHELL ["/bin/bash", "-c"]
3131

32+
# Switch to Slips installation dir on login.
33+
WORKDIR ${SLIPS_DIR}
34+
35+
COPY . $SLIPS_DIR
3236

33-
RUN apt update && apt install -y --no-install-recommends \
34-
wget \
35-
ca-certificates \
36-
git \
37-
curl \
38-
gnupg \
37+
RUN apt-get update -o Acquire::Retries=5 -o Acquire::https::No-Cache=True \
38+
&& apt-get install -y --no-install-recommends --fix-broken --fix-missing \
39+
$(cat install/apt_dependencies.txt) \
3940
lsb-release \
4041
software-properties-common \
41-
build-essential \
42-
file \
43-
lsof \
44-
iptables \
45-
iproute2 \
46-
nfdump \
47-
tshark \
48-
whois \
49-
yara \
50-
net-tools \
5142
vim \
5243
less \
5344
unzip \
54-
golang \
55-
python3-certifi \
56-
python3-dev \
57-
python3-tzlocal \
58-
python3-pip \
5945
nano \
6046
tree \
6147
tmux \
62-
arp-scan \
6348
&& echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' | tee /etc/apt/sources.list.d/security:zeek.list \
6449
&& 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 \
6550
&& apt update \
66-
&& apt install -y --no-install-recommends --fix-missing \
51+
&& apt-get install -y --no-install-recommends --fix-missing \
6752
zeek-8.0 \
6853
npm \
6954
&& ln -s /opt/zeek/bin/zeek /usr/local/bin/bro \
@@ -72,11 +57,15 @@ RUN apt update && apt install -y --no-install-recommends \
7257
&& curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash - \
7358
&& export NVM_DIR="$HOME/.nvm" \
7459
&& [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
75-
&& nvm install 22
60+
&& nvm install 22 \
61+
&& apt purge -y redis-server redis # we'll be compiling it manually
62+
63+
7664
7765
# why are we compiling redis instead od just using apt?
7866
# to support running slips on the rpi (arm64). the rpi uses jemmalloc by default, which expects a different page size
7967
# than the default on x86_64
68+
WORKDIR /
8069
RUN pip3 install --no-cache-dir --upgrade pip \
8170
&& curl -O https://download.redis.io/redis-stable.tar.gz \
8271
&& tar xzf redis-stable.tar.gz \
@@ -87,11 +76,9 @@ RUN pip3 install --no-cache-dir --upgrade pip \
8776
ENV PATH="$PATH:/redis-stable/src"
8877
8978
90-
# Switch to Slips installation dir on login.
91-
WORKDIR ${SLIPS_DIR}
9279
93-
COPY . $SLIPS_DIR
9480
81+
WORKDIR ${SLIPS_DIR}
9582
# Retrieve Iris
9683
COPY --from=build /iris/iris ./modules/irisModule
9784
@@ -110,4 +97,5 @@ ENV PATH="$PATH:/StratosphereLinuxIPS/p2p4slips/"
11097
11198
WORKDIR ${SLIPS_DIR}
11299
100+
113101
CMD /bin/bash
177 KB
Loading

docs/immune/failover_mechanisms.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Failover Mechanisms
2+
3+
The project has a few failure points listed below that we explicitly want to control instead and try to recover from.
4+
5+
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.
6+
7+
8+
All failure points are handled by the ```failover_handler.sh``` script located in ```StratosphereLinuxIPS/rpi_scripts/```.
9+
10+
## Prerequisites
11+
12+
- Raspberry Pi with docker installed
13+
- StratosphereLinuxIPS cloned. (or just the rpi_scripts/ directory)
14+
- Root access to the Raspberry Pi.
15+
- 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).
16+
17+
18+
## How to use
19+
20+
Run the following command from Slips main directory as root:
21+
22+
```bash
23+
sudo ./rpi_scripts/failover_handler.sh <wifi_interface>,<ethernet_interface>
24+
```
25+
26+
**Where**
27+
28+
- ```<wifi_interface>``` is the name of the wifi interface used by the access point (e.g. ```wlan0```, etc).
29+
30+
- ```<ethernet_interface>``` is the name of the ethernet interface connected to the router (e.g. ```eth0```, etc).
31+
32+
**You should see output similar to the image below:**
33+
34+
![](../images/immune/a8/failovers_script_output.jpg)
35+
36+
37+
**Output:**
38+
39+
The script will
40+
- 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.
41+
- Start Slips and iptables watcher services through systemd so they start automatically on reboot and on failure.
42+
- Start slips inside a docker container monitring your ethernet and wifi interfaces.
43+
- 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.
44+
45+
46+
47+
## How Failovers are Handled
48+
49+
Slips in the Raspberry Pi has 3 main failure points that we want to handle:
50+
1. The access point dies
51+
2. Slips dies
52+
3. The Raspberry Pi reboots
53+
54+
### The access point dies
55+
56+
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.
57+
58+
59+
### Slips dies
60+
61+
Failovers when Slips dies consist of:
62+
63+
* **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.
64+
* **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.
65+
* **Restarting Slips automatically through systemd:** Slips restarts automatically through systemd on failure and on reboot.
66+
* **Logging Slips container status to a file for debugging**: Slips container logs are places in ```slips_container.log``` for debugging purposes.
67+
68+
69+
70+
### The Raspberry Pi reboots
71+
72+
Failovers consist of:
73+
74+
* **Iptables firewall rules persistence**
75+
* **Automatic start of Slips service through systemd**
76+
77+
78+
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```.
79+
80+
81+
Both units are generated and started and added to the user's ```/etc/systemd/system``` by the ```failover_handler.sh``` script.
82+
83+
---
84+
85+
## File Descriptions
86+
87+
All the files involved in failover mechanisms are placed in ```StratosphereLinuxIPS/rpi_scripts/``` and are described in the table below:
88+
89+
90+
| File | What it does |
91+
|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
92+
| 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. |
93+
| iptables_autosave/check-iptables-hash.sh | Keeps track of the hash of the current iptables rules and triggers a save when change is detected. |
94+
| 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. |
95+
| iptables_autosave/iptables-watcher.timer | A systemd timer that periodically runs iptables-watcher.service so iptables rule changes are captured and saved automatically. |
96+
| slips_container.log | A runtime log collecting Docker container output, commands, and status. useful for investigating restarts, failures, or unexpected behavior. |
97+
| 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. |
98+
| slips.service.template | The systemd unit that starts slips on reboot and on failure, it runs the slips-runner-template.sh. |
99+
100+
101+
---

docs/immune/reimplement_slips_features_incompatible_with_the_rpi.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ Docker can run amd64 images on arm devices using emulation, but this method come
2424

2525
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.
2626

27-
**Commands for building the ARM image**
28-
27+
**Commands for building one multi-architecture image (supporting AMD and ARM)**
28+
```
2929
docker buildx create --name slips\_builder
3030
3131
docker buildx use slips\_builder
3232
3333
export BUILDKIT\_CONTAINERD=1
3434
3535
docker buildx build --platform linux/amd64,linux/arm64 -t stratosphereips/slips:latest -f docker/Dockerfile --push .
36+
```
3637

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

install/apt_dependencies.txt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1+
curl
2+
gnupg
3+
ca-certificates
14
python3
2-
redis-server
35
python3-pip
46
python3-certifi
57
python3-dev
8+
python3-watchdog
9+
python3-tzlocal
10+
wget
11+
npm
12+
iw
613
build-essential
714
file
815
lsof
916
net-tools
1017
iproute2
1118
iptables
12-
python3-tzlocal
1319
nfdump
1420
tshark
1521
git
@@ -21,11 +27,5 @@ yara
2127
libnotify-bin
2228
wireless-tools
2329
arp-scan
24-
python3-watchdog
25-
curl
26-
gnupg
27-
ca-certificates
30+
redis-server
2831
redis
29-
wget
30-
npm
31-
iw

managers/ap_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def store_ap_interfaces(self, input_information):
1414
"""
1515
stores the interfaces given with -ap to slips in the db
1616
"""
17-
self.wifi_interface, self.eth_interface = input_information.split(",")
17+
self.wifi_interface, self.eth_interface = input_information.split("_")
1818
interfaces = {
1919
"wifi_interface": self.wifi_interface,
2020
"ethernet_interface": self.eth_interface,

0 commit comments

Comments
 (0)