RaspberryPi 5BにSuricata7.0.3をインストール

## この記事について

[Bookwormではラズパイにsnortをインストールできない](https://forums.raspberrypi.com/viewtopic.php?t=364523)為、Suricata7.0.3をインストールしました。

とりあえず自分用手順としてUPしますが、ご入用の方は過不足修正して利用いただければ幸いです。  

## 環境  

### RaspberryPi  

```sh: cat /proc/cpuinfo
Revision        : c04170
Serial          : xxxxxxxxxxxxxxxx
Model           : Raspberry Pi 5 Model B Rev 1.0
```
### RaspberryPi OS Imager

* Device：RASPBERRY PI 5  
* OS：RASPBERRY PI OS(64-BIT)  
* Storage：microSDカード32GB  
* Wi-Fi使用  
* 公開鍵認証のみ使用  

初回起動後に以下を確認
```sh: cat /proc/version
Linux version 6.1.0-rpi8-rpi-2712 
(debian-kernel@lists.debian.org) 
(gcc-12 (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) 
#1 SMP PREEMPT Debian 1:6.1.73-1+rpt1 (2024-01-25)
```

### Suricata  
```sh: suricata -V
Suricata version 7.0.3 RELEASE
```

## 基本環境構築  

ラズパイのuser directoryに/envとenv_prov.shをコピーします。
(Suricataインストール用のshも/envに入れて一緒にコピーします)

```
user
 ┣ env
 ┃ ┣ ap_prov.conf
 ┃ ┣ environment.sh
 ┃ ┣ set_nft.sh
 ┃ ┣ set_nm.sh
 ┃ ┣ set_postfix.sh
 ┃ ┣ set_ssh.sh
 ┃ ┣ set_suricata.sh
 ┃ ┗ set_suricata_bin.sh
 ┗ env_prov.sh
```

env_prov.shを実行します。

```sh
#/envとenv_prov.shをコピーした後に実行
sudo chmod u+x *.sh
./env_prov.sh
```

夫々のsh、confの詳細は以下です。

### アップデート/パッケージインストール    

```sh: environment.sh
#!/bin/bash

sudo apt update  
sudo apt -y full-upgrade  

mkdir ~/.pip
echo "[global]" | tee -a ~/.pip/pip.conf
echo "break-system-packages = true" | tee -a ~/.pip/pip.conf
sudo apt install -y python3-dev python3-pip git unzip
sudo python3 -m pip install --upgrade pip setuptools wheel typing-extensions

sudo pip3 install paho-mqtt boto3 --upgrade

echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean false | sudo debconf-set-selections
sudo apt install -y iptables iptables-persistent

./set_postfix.sh

curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --update
curl -L https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip -o aws-sam-cli-linux-arm64.zip
unzip aws-sam-cli-linux-arm64.zip -d sam-installation
sudo ./sam-installation/install

cd /usr/bin
sudo rm python
sudo ln -s python3 python
cd
```

cron実行用にenvironment.shの中でpostfixをlocal設定でインストールします。

```sh: set_postfix.sh
#!/bin/sh

debian_install_postfix()
{
  cat <<EOF | sudo debconf-set-selections
postfix postfix/main_mailer_type select No configuration
EOF
  sudo apt install -y postfix

  cat <<EOF | sudo tee /etc/postfix/main.cf
myhostname = ${1}
mydomain = ${2}
myorigin = \$myhostname.\$mydomain
mydestination = localhost, localhost.\$mydomain, \$myhostname, \$mydomain, \$myorigin
compatibility_level = 2
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix
inet_interfaces = all
local_recipient_maps = unix:passwd.byname \$alias_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
mynetworks = 127.0.0.0/8
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
smtpd_banner = \$myhostname ESMTP \$mail_name (Debian/GNU)
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd \$daemon_directory/\$process_name \$process_id & sleep 5
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
inet_protocols = ipv4
EOF
  sudo newaliases
  sudo systemctl restart postfix
  sudo apt install -y mutt
}

debian_main()
{
  debian_install_postfix $(uname -n) localdomain             # localhost only.
}

debian_main
```


### Network Manager設定

```sh: set_nm.sh
#!/bin/bash

#wlan0 IP固定
CON_NAME="w0-s"
SSID=$(cat ~/ap_prov.conf | grep SSID | awk -F'=' '{print echo $2}' | sed -e "s/[\r\n]\+//g")
PSK=$(cat ~/ap_prov.conf | grep PW | awk -F'=' '{print echo $2}' | sed -e "s/[\r\n]\+//g")
STATIC_IP=$(cat ~/ap_prov.conf | grep MYIP_WLAN0 | awk -F'=' '{print echo $2}' | sed -e "s/[\r\n]\+//g")/24
STATIC_ROUTE=$(cat ~/ap_prov.conf | grep WLAN0_ROUTER | awk -F'=' '{print echo $2}' | sed -e "s/[\r\n]\+//g")
STATIC_DNS=$(cat ~/ap_prov.conf | grep MY_NAME_SERVER | awk -F'=' '{print echo $2}' | sed -e "s/[\r\n]\+//g")

sudo nmcli connection add con-name $CON_NAME \
type wifi \
ifname wlan0 \
connection.autoconnect yes \
wifi.mode infrastructure \
wifi.ssid $SSID \
802-11-wireless-security.auth-alg open \
802-11-wireless-security.key-mgmt wpa-psk \
802-11-wireless-security.psk $PSK \
ipv4.addresses $STATIC_IP \
ipv4.gateway $STATIC_ROUTE \
ipv4.method manual \
ipv4.dns $STATIC_DNS \
ipv4.never-default no \
ipv6.method disabled

#eth0 リンクローカル接続時のIP固定
CON_NAME="e0-lo-s"
STATIC_IP="169.254.1.11/16"
sudo nmcli connection add con-name $CON_NAME \
type ethernet \
ifname eth0 \
connection.autoconnect yes \
ipv4.addresses $STATIC_IP \
ipv4.method manual \
ipv4.never-default no \
ipv6.method disabled

#eth0 動的
CON_NAME="e0-d"
sudo nmcli connection add con-name $CON_NAME \
type ethernet \
ifname eth0 \
connection.autoconnect yes \
ipv4.method auto \
ipv4.never-default no \
ipv6.method disabled

#設定反映と初期設定削除
sudo nmcli c reload
sudo nmcli c up w0-s
sudo nmcli c up e0-d
sudo nmcli c delete preconfigured
sudo nmcli c delete Wired\ connection\ 1
```

今回の設定ではSSID/pskとstatic IPをconfから読ませています。

```sh: ap_prov.conf
MYIP_WLAN0=192.168.1.10
WLAN0_ROUTER=192.168.1.1
MY_NAME_SERVER=192.168.1.1
WLAN0_CIDR=192.168.1.0
SSID=MySSID
PW=HasedMyPsk
```

### ssh設定  

```sh: ./set_ssh.sh
#!/bin/bash

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo sed -i "s/#Port 22/Port 62000/g" /etc/ssh/sshd_config
sudo sed -i "s/#PubkeyAuthentication yes/PubkeyAuthentication yes/g" /etc/ssh/sshd_config
```

### iptables設定  

```sh: set_nft.sh
#!/bin/bash

sudo cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.bak
sudo rm /etc/iptables/rules.v4

sudo iptables -F
sudo iptables -X
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -A INPUT -j NFQUEUE
sudo iptables -A OUTPUT -j NFQUEUE
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -d 127.0.0.0/8 ! -i lo -j REJECT --reject-with icmp-port-unreachable
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 8883 -j ACCEPT
sudo iptables -A INPUT -s 127.0.0.0/8 -p tcp -m tcp --dport 1883 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -s 169.254.0.0/16 -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.1/24 -p udp -m udp --dport 123 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 5353 -j ACCEPT
sudo iptables -A INPUT -s 169.254.0.0/16 -p udp -m udp --dport 5353 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 5900 -j ACCEPT
sudo iptables -A INPUT -s 169.254.0.0/16 -p tcp -m tcp --dport 5900 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 5900 -j ACCEPT
sudo iptables -A INPUT -s 169.254.0.0/16 -p udp -m udp --dport 5900 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m tcp --dport 62000 --tcp-flags FIN,SYN,RST,ACK SYN -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name t_sshd --hashlimit-htable-expire 120000 -j ACCEPT
sudo iptables -A INPUT -s 169.254.0.0/16 -p tcp -m state --state NEW -m tcp --dport 62000 --tcp-flags FIN,SYN,RST,ACK SYN -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-name t_sshd --hashlimit-htable-expire 120000 -j ACCEPT
sudo iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
sudo iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable

sudo service netfilter-persistent reload
sudo service netfilter-persistent save
sudo sh -c "iptables-save >/etc/iptables.ipv4.filter"
sudo iptables -L
```

## Suricata構築  

[(apt-getによる)Binary packagesのインストール](https://docs.suricata.io/en/latest/install.html#debian)と[Sourceからのインストール](https://docs.suricata.io/en/latest/install.html#source)の2パターンを検証しました。  

### Binary packagesのインストール  

user ディレクトリーからset_suricata_bin.shを実行します。  

```sh
./set_suricata_bin.sh
```

記事作成時点(2024.03.03)ではapt-getでインストール可能な[suricata(安定版)](https://forums.raspberrypi.com/viewtopic.php?t=359196)は6.0.10でした。

apt-get install後にDebian backportsから最新版suricataをsources.listに追加して7.0.3をインストールしました。

```sh: set_suricata_bin.sh
sudo apt-get -y install suricata

#最新版suricataをsources.listに追加
echo "deb http://deb.debian.org/debian bookworm-backports main" | sudo tee a /etc/apt/sources.list.d/backports.list
sudo apt-get update
sudo apt-get -y install suricata -t bookworm-backports

#起動設定
sudo systemctl enable suricata
sudo systemctl start suricata
```

**(20240304追記)** suricata.rulesを/var/lib/suricata/rulesにダウンロードします。

```sh
sudo suricata-update
```


### Sourceからのインストール 

#### build/make install

user ディレクトリーからset_suricata.shを実行します。  

```sh
./set_suricata.sh
```

こちらは直接7.0.3を指定してインストールしました。

```sh:set_suricata.sh
#!/bin/bash

#依存関係のインストール
sudo apt install autoconf automake build-essential ccache clang curl git \
                gosu jq libbpf-dev libcap-ng0 libcap-ng-dev libelf-dev \
                libevent-dev libgeoip-dev libhiredis-dev libjansson-dev \
                liblua5.1-dev libmagic-dev libnet1-dev libpcap-dev \
                libpcre2-dev libtool libyaml-0-2 libyaml-dev m4 make \
                pkg-config python3 python3-dev python3-yaml sudo zlib1g \
                zlib1g-dev

sudo apt update

sudo apt-get install -y libnuma-dev dpdk-dev liblz4-dev

#rustインストール
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env

#iptablesとの統合(ここでイイのか？)
sudo apt install libnetfilter-queue-dev libnetfilter-queue1  \
                libnetfilter-log-dev libnetfilter-log1      \
                libnfnetlink-dev libnfnetlink0

#suricataインストール
wget https://www.openinfosecfoundation.org/download/suricata-7.0.3.tar.gz
tar -xvf suricata-7.0.3.tar.gz suricata-7.0.3
cd suricata-7.0.3/

./configure -prefix=/usr -sysconfdir=/etc -localstatedir=/var -enable-nfqueue -enable-lua  -enable-dpdk
#To build and install run 'make' and 'make install'.
#
#You can run 'make install-conf' if you want to install initial configuration
#files to /etc/suricata/. Running 'make install-full' will install configuration
#and rules and provide you a ready-to-run suricata.
#
#To install Suricata into /usr/bin/suricata, have the config in
#/etc/suricata and use /var/log/suricata as log dir, use:
#./configure --prefix=/usr/ --sysconfdir=/etc/ --localstatedir=/var/

make
sudo make install-full
#You can now start suricata by running as root something like:
#  /usr/bin/suricata -c /etc/suricata/suricata.yaml -i eth0
#
#If a library like libhtp.so is not found, you can run suricata with:
#  LD_LIBRARY_PATH=/usr/lib /usr/bin/suricata -c /etc/suricata/suricata.yaml -i eth0
#
#The Emerging Threats Open rules are now installed. Rules can be
#updated and managed with the suricata-update tool.
#
#For more information please see:
#  https://docs.suricata.io/en/latest/rule-management/index.html
#
```

serviceの登録は説明を省略します。

コマンドラインより実行して動作確認しました。

```sh
suricata -c /etc/suricata/suricata.yaml -i eth0
```

別窓を開いてtailで確認します。

```sh
sudo tail -f /var/log/suricata/eve.json
```

#### iptables統合
[Sourceからインストールした場合iptablesと統合する](https://docs.suricata.io/en/latest/setting-up-ipsinline-for-linux.html#setting-up-ips-with-netfilter)には以下の操作が必要です。~~apt-getでインストールした場合は不要でした。~~(20240304訂正：apt-getでインストールした場合もINSERTしないとiptablesのルールに反映されませんでした。併せて確認訂正します)  

suricata起動時に-qオプションをつけます。
```sh
sudo suricata -c /etc/suricata/suricata.yaml -q 0
```

基本環境構築時に設定したiptablesにルールをINSERTします。

```sh
sudo iptables -I INPUT -j NFQUEUE
sudo iptables -I OUTPUT -j NFQUEUE
```

## 今後の予定

暫定記事UPとなりましたので
* ルールファイルのカスタム設定
* Sourceからインストールした場合の起動設定  
* eth0とwlan0のlogを同時取得するためのyaml変更用のshの追加  

等の追記を予定します。

公式Docの記載順に実行しましたが、Sourceからインストールする場合のaptでパッケージのiptables統合は順番が違う気もしますので後日併せて確認したいと思います。