Created daemon python script.
This commit is contained in:
commit
5d9cd3c207
7 changed files with 651 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
293
Cargo.lock
generated
Normal file
293
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.20.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32069d97bb81e38fa67eab65e3393bf804bb85969f2bc06bf13f64aef5aba248"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipban"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rusqlite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.38.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1d20bef17f513b9b3004532233187769cd072d790971f4e4da0e346eb6401e8"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rsqlite-vfs"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.16.1",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusqlite"
|
||||||
|
version = "0.40.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23f2a97da3e3873c73cb2a2e71b35c40ff95e0b1eefa8d72d8499a6928c3b5b3"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"smallvec",
|
||||||
|
"sqlite-wasm-rs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlite-wasm-rs"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"js-sys",
|
||||||
|
"rsqlite-vfs",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.119"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "3.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.127"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "ipban"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rusqlite = "0.40.0"
|
||||||
110
install.zsh
Executable file
110
install.zsh
Executable file
|
|
@ -0,0 +1,110 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# synapsys:
|
||||||
|
# cout "output_type" "message"
|
||||||
|
# supported output types:
|
||||||
|
# inf war err
|
||||||
|
cout() {
|
||||||
|
local msg="$2"
|
||||||
|
local lead="[=]"
|
||||||
|
if [[ "$1" == "war" ]]; then
|
||||||
|
lead="[?]"
|
||||||
|
fi
|
||||||
|
if [[ "$1" == "inf" ]]; then
|
||||||
|
lead="[=]"
|
||||||
|
fi
|
||||||
|
if [[ "$1" == "err" ]]; then
|
||||||
|
lead="[!]"
|
||||||
|
fi
|
||||||
|
print -P "$lead" "$msg"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# synapsys:
|
||||||
|
# ask "default_ans" "message"
|
||||||
|
#
|
||||||
|
# if user answers YES ask returns 0
|
||||||
|
# if NO, returns 1
|
||||||
|
#
|
||||||
|
# ex: ask "y" "overwrite?"
|
||||||
|
# out: overwrite? [Y/n]:
|
||||||
|
ask() {
|
||||||
|
local def_ans="$1"
|
||||||
|
local promt
|
||||||
|
if [[ "$def_ans" == "y" ]]; then
|
||||||
|
promt="[Y/n]"
|
||||||
|
elif [[ "$def_ans" == "n" ]]; then
|
||||||
|
promt="[y/N]"
|
||||||
|
else
|
||||||
|
cout "err" "ask() got \$default_ans as $1"
|
||||||
|
exit 10
|
||||||
|
fi
|
||||||
|
|
||||||
|
local msg="$2"
|
||||||
|
while [[ true ]]; do
|
||||||
|
local ans=''
|
||||||
|
read -r "ans?$msg $promt: "
|
||||||
|
local ans="${ans:l}"
|
||||||
|
|
||||||
|
if [[ "$def_ans" == "y" ]]; then
|
||||||
|
if [[ -z "$ans" || "$ans" == "y" || "$ans" == "yes" ]]; then
|
||||||
|
return 0
|
||||||
|
elif [[ "$ans" == "n" || "$ans" == "no" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
elif [[ "$def_ans" == "n" ]]; then
|
||||||
|
if [[ -z "$ans" || "$ans" == "n" || "$ans" == "no" ]]; then
|
||||||
|
return 1
|
||||||
|
elif [[ "$ans" == "y" || "$ans" == "YES" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# synapsys:
|
||||||
|
# abort_install "reason"
|
||||||
|
abort_install() {
|
||||||
|
cout "err" "%F{red}Install aborted:%f\t$1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ! $(id -g ipban) ]]; then
|
||||||
|
sudo groupadd --system ipban
|
||||||
|
else
|
||||||
|
abort_install "Group %Bipban%b already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! $(id -u ipban) ]]; then
|
||||||
|
sudo useradd \
|
||||||
|
--system \
|
||||||
|
--gid ipban \
|
||||||
|
--no-create-home \
|
||||||
|
--comment "ipban service" \
|
||||||
|
--home-dir / \
|
||||||
|
--shell /sbin/nologin \
|
||||||
|
ipban
|
||||||
|
else
|
||||||
|
abort_install "User %Bipban%b already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
db_dir="/var/lib/ipban"
|
||||||
|
if [[ ! -d $db_dir ]]; then
|
||||||
|
sudo mkdir $db_dir
|
||||||
|
sudo chmod 775 $db_dir
|
||||||
|
sudo chown ipban:ipban $db_dir
|
||||||
|
else
|
||||||
|
if ask "n" "directory $db_dir already exists. rewrite?"; then
|
||||||
|
sudo rm -rf $db_dir
|
||||||
|
|
||||||
|
sudo mkdir $db_dir
|
||||||
|
sudo chmod 775 $db_dir
|
||||||
|
sudo chown ipban:ipban $db_dir
|
||||||
|
else
|
||||||
|
abort_install "User decided not to overwrite \'$db_dir\'. Which is requred to store banned ip\'s"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#TODO: create systemd service
|
||||||
171
py/daemon.py
Executable file
171
py/daemon.py
Executable file
|
|
@ -0,0 +1,171 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import ipaddress
|
||||||
|
from datetime import date, datetime, timezone
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import socket
|
||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
from nftables import Nftables
|
||||||
|
from collections.abc import Iterable
|
||||||
|
|
||||||
|
#create table and its internal content
|
||||||
|
def create_nft_table():
|
||||||
|
nft = Nftables()
|
||||||
|
|
||||||
|
#rc, output, error = nft.cmd("add table inet ipban { flags owner; }")
|
||||||
|
rc, output, error = nft.cmd("add table inet ipban")
|
||||||
|
rc, output, error = nft.cmd(f"add set inet ipban banned_ipv4 {{ type ipv4_addr; }}")
|
||||||
|
rc, output, error = nft.cmd(f"add set inet ipban banned_ipv6 {{ type ipv6_addr; }}")
|
||||||
|
|
||||||
|
rc, output, error = nft.cmd("add chain inet ipban in_ban { type filter hook input priority filter; }")
|
||||||
|
|
||||||
|
rc, output, error = nft.cmd("add rule inet ipban in_ban ip saddr @banned_ipv4 drop")
|
||||||
|
rc, output, error = nft.cmd("add rule inet ipban in_ban ip6 saddr @banned_ipv6 drop")
|
||||||
|
|
||||||
|
def destroy_nft_table():
|
||||||
|
nft = Nftables()
|
||||||
|
rc, output, error = nft.cmd("destroy table inet ipban")
|
||||||
|
|
||||||
|
#delete old table, create new, and fill with ip's
|
||||||
|
def flush_nft(ips : Iterable[ipaddress.IPv4Address]):
|
||||||
|
nft = Nftables()
|
||||||
|
ips_str = ""
|
||||||
|
for ip in ips:
|
||||||
|
ips_str += f"{str(ip)}, "
|
||||||
|
ips_str = ips_str[:-2]
|
||||||
|
if ips_str == "":
|
||||||
|
return
|
||||||
|
rc, output, error = nft.cmd("destroy set inet ipban banned_ipv4")
|
||||||
|
rc, output, error = nft.cmd(f"""add set inet ipban banned_ipv4 {{type ipv4_addr;
|
||||||
|
elements = {{ {ips_str} }}; }}""")
|
||||||
|
|
||||||
|
#add list of ips to set in nft
|
||||||
|
def add_to_end_nft(ips: Iterable[ipaddress.IPv4Address]):
|
||||||
|
nft = Nftables()
|
||||||
|
ips_str = ""
|
||||||
|
for ip in ips:
|
||||||
|
ips_str += f"{str(ip)}, "
|
||||||
|
ips_str = ips_str[:-2]
|
||||||
|
if ips_str == "":
|
||||||
|
return
|
||||||
|
rc, output, error = nft.cmd(f"add element inet ipban banned_ipv4 {{ {ips_str} }}")
|
||||||
|
|
||||||
|
def init_nft(sql_conn: sqlite3.Connection):
|
||||||
|
rows = sql_conn.execute("""SELECT ip FROM banned
|
||||||
|
""").fetchall()
|
||||||
|
flush_nft([row[0] for row in rows])
|
||||||
|
|
||||||
|
#add selected ip to db table banned
|
||||||
|
def make_ban(sql_conn: sqlite3.Connection, ip: ipaddress.IPv4Address, remark = "", reason = "") -> bool:
|
||||||
|
#checking if ip is already banned
|
||||||
|
row = sql_conn.execute(f"""SELECT id FROM {ban_t_name}
|
||||||
|
WHERE ip = ? LIMIT 1""", (str(ip),)).fetchone()
|
||||||
|
print(row)
|
||||||
|
|
||||||
|
if row is not None:
|
||||||
|
return False #already banned
|
||||||
|
|
||||||
|
ban_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
sql_conn.execute(f"""INSERT INTO {ban_t_name} (ban_time,ip,remark,reason) VALUES (?, ?, ?, ?)""",
|
||||||
|
(str(ban_time), str(ip), remark, reason))
|
||||||
|
sql_conn.commit()
|
||||||
|
return True
|
||||||
|
|
||||||
|
#what to do in case of req_type=="action"
|
||||||
|
#TODO: protect from situation: ban "1.1.1.1", uban "1.1.1.1"
|
||||||
|
def action(sql_conn: sqlite3.Connection, conn: socket.socket, data: str):
|
||||||
|
data = data[data.find('\n')+1:] #strip req_type
|
||||||
|
data_json = json.loads(data)
|
||||||
|
|
||||||
|
ips_to_ban = list()
|
||||||
|
for ip,creds in data_json["ban"].items():
|
||||||
|
ip_addr = ipaddress.IPv4Address(ip)
|
||||||
|
remark = creds["remark"]
|
||||||
|
reason = creds["reason"]
|
||||||
|
make_ban(sql_conn, ip_addr, remark, reason)
|
||||||
|
ips_to_ban.append(ip)
|
||||||
|
|
||||||
|
for ip, creds in data_json["uban"].items():
|
||||||
|
print("Not implemented yet")
|
||||||
|
break
|
||||||
|
add_to_end_nft(ips_to_ban)
|
||||||
|
|
||||||
|
def list_ips(sql_conn: sqlite3.Connection, conn: socket.socket, data: str):
|
||||||
|
data = data[data.find('\n')+1:] #strip req_type
|
||||||
|
|
||||||
|
|
||||||
|
def recv_all(conn: socket.socket) -> bytes:
|
||||||
|
chunks = []
|
||||||
|
|
||||||
|
while True:
|
||||||
|
data = conn.recv(4096)
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
chunks.append(data)
|
||||||
|
return b"".join(chunks)
|
||||||
|
|
||||||
|
|
||||||
|
#initilise UNIX socket and do someting like http handler
|
||||||
|
def run_server(socket_path: Path, sql_conn: sqlite3.Connection):
|
||||||
|
if os.path.exists(socket_path):
|
||||||
|
os.unlink(socket_path)
|
||||||
|
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
|
||||||
|
server.bind(socket_path.as_posix())
|
||||||
|
server.listen()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
conn,_ = server.accept()
|
||||||
|
|
||||||
|
try:
|
||||||
|
data=recv_all(conn)
|
||||||
|
if not data:
|
||||||
|
continue
|
||||||
|
|
||||||
|
data = data.decode()
|
||||||
|
req_type = data.split('\n')[0]
|
||||||
|
|
||||||
|
match req_type:
|
||||||
|
case "action":
|
||||||
|
action(sql_conn, conn, data)
|
||||||
|
case "list":
|
||||||
|
list_ips(sql_conn, conn, data)
|
||||||
|
|
||||||
|
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
finally:
|
||||||
|
server.close()
|
||||||
|
if os.path.exists(socket_path):
|
||||||
|
os.unlink(socket_path)
|
||||||
|
|
||||||
|
|
||||||
|
def stop_handler(sugnum, frame):
|
||||||
|
destroy_nft_table()
|
||||||
|
os._exit(0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
signal.signal(signal.SIGINT, stop_handler)
|
||||||
|
signal.signal(signal.SIGTERM, stop_handler)
|
||||||
|
sql_conn = sqlite3.connect("/var/lib/ipban/db.file")
|
||||||
|
ban_t_name="banned"
|
||||||
|
sql_conn.execute(f"""CREATE TABLE IF NOT EXISTS {ban_t_name}
|
||||||
|
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
ban_time TEXT NOT NULL,
|
||||||
|
ip TEXT NOT NULL,
|
||||||
|
remark TEXT,
|
||||||
|
reason TEXT)""")
|
||||||
|
|
||||||
|
create_nft_table()
|
||||||
|
init_nft(sql_conn)
|
||||||
|
#flush_nft([ ipaddress.IPv4Address("123.134.124.1"), ipaddress.IPv4Address("8.8.8.8")])
|
||||||
|
|
||||||
|
sock_path = Path("/run/ipban/ipban.sock")
|
||||||
|
sock_path.parent.mkdir(parents=True,exist_ok=True)
|
||||||
|
run_server(sock_path, sql_conn)
|
||||||
|
destroy_nft_table()
|
||||||
48
src/main.rs
Normal file
48
src/main.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
use rusqlite;
|
||||||
|
use std::{path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
struct SqliteWrapper {
|
||||||
|
pub file: PathBuf,
|
||||||
|
connection: rusqlite::Connection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqliteWrapper {
|
||||||
|
pub fn new(&mut self){
|
||||||
|
self.file = PathBuf::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialize(&mut self){
|
||||||
|
self.connection = rusqlite::Connection::open(self.file.to_str().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let conn = rusqlite::Connection::open_in_memory().unwrap();
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE person (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
data BLOB)",
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO person (name, data) VALUES (?1, ?2)",
|
||||||
|
(&me.name, &me.data),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut stmt = conn.prepare("SELECT id, name, data FROM person").unwrap();
|
||||||
|
let person_iterator = stmt.query_map([], |row| {
|
||||||
|
Ok(Person {
|
||||||
|
id: row.get(0).unwrap(),
|
||||||
|
name: row.get(1).unwrap(),
|
||||||
|
data: row.get(2).unwrap(),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
for person in person_iterator.unwrap() {
|
||||||
|
println!("Found person {}", person.unwrap().to_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
21
test.json
Normal file
21
test.json
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
action
|
||||||
|
{
|
||||||
|
"ban": {
|
||||||
|
"1.2.3.4": {
|
||||||
|
"remark": "Cloudflare's web",
|
||||||
|
"reason": "bot"
|
||||||
|
},
|
||||||
|
"8.8.8.8": {
|
||||||
|
"remark": "",
|
||||||
|
"reason": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uban": {
|
||||||
|
"1.3.3.7": {
|
||||||
|
"reason": "Misstake"
|
||||||
|
},
|
||||||
|
"1.0.0.1": {
|
||||||
|
"reason": "DNS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue