parent
e2fd60a5eb
commit
a27ccc28a1
42
.drone.yml
42
.drone.yml
@ -13,11 +13,11 @@ steps:
|
|||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y libnftnl-dev libmnl-dev
|
- apt-get install -y libnftnl-dev libmnl-dev libclang-dev
|
||||||
- curl -o /usr/bin/sccache https://assets.paulbsd.com/sccache_linux_amd64
|
- curl -o $${RUSTC_WRAPPER} https://assets.paulbsd.com/sccache_linux_${DRONE_STAGE_ARCH}
|
||||||
- chmod +x /usr/bin/sccache
|
- chmod +x $${RUSTC_WRAPPER}
|
||||||
- cargo build --verbose --all
|
- cargo b -v
|
||||||
- cargo test --verbose --all
|
- cargo t -v
|
||||||
environment:
|
environment:
|
||||||
RUSTC_WRAPPER: /usr/bin/sccache
|
RUSTC_WRAPPER: /usr/bin/sccache
|
||||||
SCCACHE_WEBDAV_ENDPOINT: https://sccache.paulbsd.com
|
SCCACHE_WEBDAV_ENDPOINT: https://sccache.paulbsd.com
|
||||||
@ -36,10 +36,10 @@ steps:
|
|||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y libnftnl-dev libmnl-dev
|
- apt-get install -y libnftnl-dev libmnl-dev libclang-dev
|
||||||
- curl -o /usr/bin/sccache https://assets.paulbsd.com/sccache_linux_amd64
|
- curl -o $${RUSTC_WRAPPER} https://assets.paulbsd.com/sccache_linux_${DRONE_STAGE_ARCH}
|
||||||
- chmod +x /usr/bin/sccache
|
- chmod +x $${RUSTC_WRAPPER}
|
||||||
- cargo build --release --verbose --all
|
- cargo b -r -v
|
||||||
- cd target/release
|
- cd target/release
|
||||||
- tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc
|
- tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc
|
||||||
environment:
|
environment:
|
||||||
@ -61,9 +61,6 @@ steps:
|
|||||||
api_key:
|
api_key:
|
||||||
from_secret: gitea_token
|
from_secret: gitea_token
|
||||||
files: "target/release/*.tar.gz"
|
files: "target/release/*.tar.gz"
|
||||||
#checksum:
|
|
||||||
# - sha256
|
|
||||||
# - sha512
|
|
||||||
environment:
|
environment:
|
||||||
PLUGIN_TITLE: ""
|
PLUGIN_TITLE: ""
|
||||||
when:
|
when:
|
||||||
@ -92,11 +89,11 @@ steps:
|
|||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y libnftnl-dev libmnl-dev
|
- apt-get install -y libnftnl-dev libmnl-dev libclang-dev
|
||||||
- curl -o /usr/bin/sccache https://assets.paulbsd.com/sccache_linux_arm64
|
- curl -o $${RUSTC_WRAPPER} https://assets.paulbsd.com/sccache_linux_${DRONE_STAGE_ARCH}
|
||||||
- chmod +x /usr/bin/sccache
|
- chmod +x $${RUSTC_WRAPPER}
|
||||||
- cargo build --verbose --all
|
- cargo b -v
|
||||||
- cargo test --verbose --all
|
- cargo t -v
|
||||||
environment:
|
environment:
|
||||||
RUSTC_WRAPPER: /usr/bin/sccache
|
RUSTC_WRAPPER: /usr/bin/sccache
|
||||||
SCCACHE_WEBDAV_ENDPOINT: https://sccache.paulbsd.com
|
SCCACHE_WEBDAV_ENDPOINT: https://sccache.paulbsd.com
|
||||||
@ -115,10 +112,10 @@ steps:
|
|||||||
pull: always
|
pull: always
|
||||||
commands:
|
commands:
|
||||||
- apt-get update -y
|
- apt-get update -y
|
||||||
- apt-get install -y libnftnl-dev libmnl-dev
|
- apt-get install -y libnftnl-dev libmnl-dev libclang-dev
|
||||||
- curl -o /usr/bin/sccache https://assets.paulbsd.com/sccache_linux_arm64
|
- curl -o $${RUSTC_WRAPPER} https://assets.paulbsd.com/sccache_linux_${DRONE_STAGE_ARCH}
|
||||||
- chmod +x /usr/bin/sccache
|
- chmod +x $${RUSTC_WRAPPER}
|
||||||
- cargo build --release --verbose --all
|
- cargo b -r -v
|
||||||
- cd target/release
|
- cd target/release
|
||||||
- tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc
|
- tar -czvf ipblc-${DRONE_TAG}-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}.tar.gz ipblc
|
||||||
environment:
|
environment:
|
||||||
@ -140,9 +137,6 @@ steps:
|
|||||||
api_key:
|
api_key:
|
||||||
from_secret: gitea_token
|
from_secret: gitea_token
|
||||||
files: "target/release/*.tar.gz"
|
files: "target/release/*.tar.gz"
|
||||||
#checksum:
|
|
||||||
# - sha256
|
|
||||||
# - sha512
|
|
||||||
environment:
|
environment:
|
||||||
PLUGIN_TITLE: ""
|
PLUGIN_TITLE: ""
|
||||||
when:
|
when:
|
||||||
|
297
Cargo.lock
generated
297
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@ -117,6 +117,35 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.68.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"peeking_take_while",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash 1.1.0",
|
||||||
|
"shlex",
|
||||||
|
"syn",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
@ -159,6 +188,15 @@ dependencies = [
|
|||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -186,6 +224,17 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.21"
|
version = "4.5.21"
|
||||||
@ -281,6 +330,22 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -378,12 +443,27 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "home"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -644,18 +724,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipblc"
|
name = "ipblc"
|
||||||
version = "1.7.1"
|
version = "1.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"git-version",
|
"git-version",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"mnl",
|
"nix 0.29.0",
|
||||||
"nftnl",
|
|
||||||
"nix",
|
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rustables",
|
||||||
|
"rustables-macros",
|
||||||
"sd-notify",
|
"sd-notify",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -669,6 +749,12 @@ version = "2.10.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
|
checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnetwork"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
@ -696,12 +782,34 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.164"
|
version = "0.2.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@ -730,12 +838,27 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -758,46 +881,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mnl"
|
name = "nix"
|
||||||
version = "0.2.2"
|
version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d1a5469630da93e1813bb257964c0ccee3b26b6879dd858039ddec35cc8681ed"
|
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"mnl-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mnl-sys"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9750685b201e1ecfaaf7aa5d0387829170fa565989cc481b49080aa155f70457"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nftnl"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "06a7491dd91b71643f65546389f25506da70723d1f1ec8c8d6d20444d1c23f27"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"log",
|
|
||||||
"nftnl-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nftnl-sys"
|
|
||||||
version = "0.6.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b193f2c2a70e6421534c3f3b75eaaed4e4b9df45281b3d94f5bc8c32fb346cbb"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"pkg-config",
|
"memoffset",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -806,12 +899,22 @@ version = "0.29.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
@ -865,6 +968,12 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peeking_take_while"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
@ -883,12 +992,6 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.31"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
@ -898,6 +1001,16 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.92"
|
version = "1.0.92"
|
||||||
@ -907,6 +1020,19 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2-diagnostics"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quinn"
|
name = "quinn"
|
||||||
version = "0.11.6"
|
version = "0.11.6"
|
||||||
@ -917,7 +1043,7 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"quinn-proto",
|
"quinn-proto",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
"rustc-hash",
|
"rustc-hash 2.0.0",
|
||||||
"rustls",
|
"rustls",
|
||||||
"socket2",
|
"socket2",
|
||||||
"thiserror 2.0.3",
|
"thiserror 2.0.3",
|
||||||
@ -935,7 +1061,7 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
"rand",
|
"rand",
|
||||||
"ring",
|
"ring",
|
||||||
"rustc-hash",
|
"rustc-hash 2.0.0",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"slab",
|
"slab",
|
||||||
@ -1004,7 +1130,7 @@ version = "0.5.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1093,18 +1219,67 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustables"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "177fda7beae62153f2ee2d0d3f2c7cf37da4b31a7240483fa1e06f7ccc25fb1c"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"ipnetwork",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"nix 0.23.2",
|
||||||
|
"regex",
|
||||||
|
"rustables-macros",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustables-macros"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "698b79177cbf57522a1dcc118ac31393dc2a7ccc9bdb3625a6601ff5c27a3085"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"proc-macro2-diagnostics",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.18"
|
version = "0.23.18"
|
||||||
@ -1194,7 +1369,7 @@ version = "2.11.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.6.0",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1688,6 +1863,18 @@ dependencies = [
|
|||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"home",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
@ -1821,6 +2008,12 @@ version = "0.5.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ipblc"
|
name = "ipblc"
|
||||||
version = "1.7.1"
|
version = "1.8.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["PaulBSD <paul@paulbsd.com>"]
|
authors = ["PaulBSD <paul@paulbsd.com>"]
|
||||||
description = "ipblc is a tool that search and send attacking ip addresses to ipbl"
|
description = "ipblc is a tool that search and send attacking ip addresses to ipbl"
|
||||||
@ -14,11 +14,11 @@ clap = { version = "4.5", features = ["string"] }
|
|||||||
git-version = "0.3"
|
git-version = "0.3"
|
||||||
ipnet = "2.10"
|
ipnet = "2.10"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
mnl = "0.2"
|
|
||||||
nftnl = "0.7"
|
|
||||||
nix = { version = "0.29", features = ["hostname", "inotify"] }
|
nix = { version = "0.29", features = ["hostname", "inotify"] }
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||||
|
rustables = "0.8.5"
|
||||||
|
rustables-macros = "0.1.2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sd-notify = { version = "0.4" }
|
sd-notify = { version = "0.4" }
|
||||||
|
143
examples/fw_with_rustables.rs
Normal file
143
examples/fw_with_rustables.rs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
use rustables::*;
|
||||||
|
use rustables::{expr::*, Chain, Rule, Table};
|
||||||
|
use std::{io::*, net::*};
|
||||||
|
|
||||||
|
const TABLE_NAME: &str = "ipblc4";
|
||||||
|
const CHAIN_NAME: &str = "ipblc";
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
/*let name = "blabla";
|
||||||
|
let mut batch = Batch::new();
|
||||||
|
let table = Table::new(ProtocolFamily::Ipv4).with_name(name);
|
||||||
|
batch.add(&table, MsgType::Add);
|
||||||
|
let mut chain = Chain::new(&table).with_name(name);
|
||||||
|
batch.add(&chain, MsgType::Add);
|
||||||
|
|
||||||
|
let toadd1: Ipv4Addr = "9.9.9.8".parse().unwrap();
|
||||||
|
let toadd2: Ipv4Addr = "9.9.9.1".parse().unwrap();
|
||||||
|
|
||||||
|
let mut setbuilder: SetBuilder<Ipv4Addr> = SetBuilder::new("s1", &table).unwrap();
|
||||||
|
setbuilder.add(&toadd1);
|
||||||
|
setbuilder.add(&toadd2);
|
||||||
|
let (mut set, setelem) = setbuilder.finish();
|
||||||
|
batch.add(&setelem, MsgType::Add);
|
||||||
|
//batch.add(&set, MsgType::Add);
|
||||||
|
set.family = ProtocolFamily::Ipv4;
|
||||||
|
set.id = Some(5);
|
||||||
|
set.flags = Some(0);
|
||||||
|
set.userdata = Some("test".into());
|
||||||
|
println!("{:?}", setelem);*/
|
||||||
|
|
||||||
|
let get_table = || -> Result<Option<Table>> {
|
||||||
|
let tables = list_tables().unwrap();
|
||||||
|
for table in tables {
|
||||||
|
if let Some(name) = table.get_name() {
|
||||||
|
println!("Found table {}", name);
|
||||||
|
|
||||||
|
if name == TABLE_NAME {
|
||||||
|
return Ok(Some(table));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let get_chain = |table: &Table| -> Result<Option<Chain>> {
|
||||||
|
let chains = list_chains_for_table(table).unwrap();
|
||||||
|
for chain in chains {
|
||||||
|
if let Some(name) = chain.get_name() {
|
||||||
|
println!("Found chain {}", name);
|
||||||
|
|
||||||
|
if name == CHAIN_NAME {
|
||||||
|
return Ok(Some(chain));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let table = get_table().unwrap().expect("no table?");
|
||||||
|
let chain = get_chain(&table).unwrap().expect("no chain?");
|
||||||
|
|
||||||
|
let ip: IpAddr = "184.73.167.217".parse().unwrap();
|
||||||
|
|
||||||
|
let cmprule = Rule::new(&chain).unwrap().saddr(ip).drop();
|
||||||
|
println!("{:?}", cmprule);
|
||||||
|
|
||||||
|
let mut gexpr = RawExpression::default();
|
||||||
|
for e in cmprule.get_expressions().unwrap().iter() {
|
||||||
|
if let Some(ExpressionVariant::Cmp(_)) = e.get_data() {
|
||||||
|
gexpr = e.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let rules = list_rules_for_chain(&chain).unwrap();
|
||||||
|
for rule in rules {
|
||||||
|
let handle = rule.get_handle().unwrap();
|
||||||
|
println!("handle {}", handle);
|
||||||
|
let exprs = rule.get_expressions().unwrap();
|
||||||
|
for expr in exprs.iter() {
|
||||||
|
if let Some(ExpressionVariant::Cmp(_)) = expr.get_data() {
|
||||||
|
if expr.clone() == gexpr {
|
||||||
|
println!("{:?}", expr.get_data());
|
||||||
|
println!("test");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if expr.get_data()
|
||||||
|
//if expr.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//let mut set: Set<Ipv4Addr> = nft_set!(
|
||||||
|
// &CString::new("blabla").unwrap(),
|
||||||
|
// 32,
|
||||||
|
// &table,
|
||||||
|
// ProtoFamily::Ipv4 //ProtoFamily::Ipv4;
|
||||||
|
// //[&toadd1,&toadd2,]
|
||||||
|
//);
|
||||||
|
////println!("{:?}", set.0);
|
||||||
|
//set.add(&toadd1);
|
||||||
|
//set.add(&toadd2);
|
||||||
|
//batch.add(&set, MsgType::Add);
|
||||||
|
|
||||||
|
//let mut rule = Rule::new(&chain)
|
||||||
|
// .unwrap()
|
||||||
|
// .with_expr(
|
||||||
|
// HighLevelPayload::Network(NetworkHeaderField::IPv4(IPv4HeaderField::Saddr)).build(),
|
||||||
|
// )
|
||||||
|
// .with_expr(Lookup::new(&set).unwrap())
|
||||||
|
// .with_expr(Immediate::new_verdict(VerdictKind::Accept));
|
||||||
|
//println!("{:?}", rule);
|
||||||
|
//batch.add(&rule, rustables::MsgType::Add);
|
||||||
|
|
||||||
|
//match batch.send() {
|
||||||
|
// Ok(o) => {}
|
||||||
|
// Err(e) => {
|
||||||
|
// println!("{e}");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//rule.add_expr(&nft_expr!(payload ipv4 saddr));
|
||||||
|
//#[rustfmt::skip]
|
||||||
|
//rule.add_expr(&nft_expr!(lookup &set));
|
||||||
|
//rule.add_expr(&nft_expr!(ct state));
|
||||||
|
//rule.add_expr(&nft_expr!(verdict drop));
|
||||||
|
//batch.add(&rule, MsgType::Add);
|
||||||
|
//let finalized_batch = batch.finalize();
|
||||||
|
//send_and_process(&finalized_batch)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Error(String);
|
||||||
|
|
||||||
|
impl<T: std::error::Error> From<T> for Error {
|
||||||
|
fn from(error: T) -> Self {
|
||||||
|
Error(error.to_string())
|
||||||
|
}
|
||||||
|
}
|
65
old/fw.rs
Normal file
65
old/fw.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use nftnl::{nft_expr, set::Set, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table};
|
||||||
|
use std::{ffi::CString, io::*, net::Ipv4Addr};
|
||||||
|
|
||||||
|
fn main() -> std::result::Result<(), Error> {
|
||||||
|
let table_name = format!("ipblc4");
|
||||||
|
let table = Table::new(
|
||||||
|
&CString::new(format!("{table_name}")).unwrap(),
|
||||||
|
ProtoFamily::Ipv4,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut batch = Batch::new();
|
||||||
|
|
||||||
|
batch.add(&table, nftnl::MsgType::Add);
|
||||||
|
batch.add(&table, nftnl::MsgType::Del);
|
||||||
|
|
||||||
|
batch.add(&table, nftnl::MsgType::Add);
|
||||||
|
|
||||||
|
let mut chain = Chain::new(&CString::new("test").unwrap(), &table);
|
||||||
|
chain.set_hook(nftnl::Hook::In, 1);
|
||||||
|
chain.set_policy(nftnl::Policy::Accept);
|
||||||
|
|
||||||
|
batch.add(&chain, nftnl::MsgType::Add);
|
||||||
|
batch.add(&Rule::new(&chain), nftnl::MsgType::Del);
|
||||||
|
|
||||||
|
let mut rule = Rule::new(&chain);
|
||||||
|
|
||||||
|
rule.add_expr(&nft_expr!(ct state));
|
||||||
|
rule.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32));
|
||||||
|
rule.add_expr(&nft_expr!(cmp != 0u32));
|
||||||
|
rule.add_expr(&nft_expr!(counter));
|
||||||
|
rule.add_expr(&nft_expr!(verdict accept));
|
||||||
|
|
||||||
|
batch.add(&rule, nftnl::MsgType::Add);
|
||||||
|
let finalized_batch = batch.finalize();
|
||||||
|
send_and_process(&finalized_batch)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_and_process(batch: &FinalizedBatch) -> std::result::Result<(), Error> {
|
||||||
|
let seq: u32 = 2;
|
||||||
|
let socket = mnl::Socket::new(mnl::Bus::Netfilter)?;
|
||||||
|
socket.send_all(batch)?;
|
||||||
|
let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize];
|
||||||
|
while let Some(message) = socket_recv(&socket, &mut buffer[..])? {
|
||||||
|
match mnl::cb_run(message, seq, socket.portid())? {
|
||||||
|
mnl::CbResult::Stop => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mnl::CbResult::Ok => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn socket_recv<'a>(
|
||||||
|
socket: &mnl::Socket,
|
||||||
|
buf: &'a mut [u8],
|
||||||
|
) -> std::result::Result<Option<&'a [u8]>, Error> {
|
||||||
|
let ret = socket.recv(buf)?;
|
||||||
|
if ret > 0 {
|
||||||
|
Ok(Some(&buf[..ret]))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,12 @@
|
|||||||
use crate::ip::{BlockIpData, IpData, IpEvent};
|
use crate::ip::{BlockIpData, IpData, IpEvent};
|
||||||
use crate::utils::{gethostname, sleep_s};
|
use crate::utils::{gethostname, sleep_s};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
@ -10,11 +16,9 @@ use nix::sys::inotify::{AddWatchFlags, Inotify, WatchDescriptor};
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::{Client, Error as ReqError, Response};
|
use reqwest::{Client, Error as ReqError, Response};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub const GIT_VERSION: &str = git_version!(args = ["--always", "--dirty="]);
|
pub const GIT_VERSION: &str = git_version!(args = ["--always", "--dirty="]);
|
||||||
|
|
||||||
const MASTERSERVER: &str = "ipbl.paulbsd.com";
|
const MASTERSERVER: &str = "ipbl.paulbsd.com";
|
||||||
const WSSUBSCRIPTION: &str = "ipbl";
|
const WSSUBSCRIPTION: &str = "ipbl";
|
||||||
const CONFIG_RETRY_INTERVAL: u64 = 2;
|
const CONFIG_RETRY_INTERVAL: u64 = 2;
|
||||||
@ -28,7 +32,7 @@ pub struct Context {
|
|||||||
pub flags: Flags,
|
pub flags: Flags,
|
||||||
pub sas: HashMap<String, SetMap>,
|
pub sas: HashMap<String, SetMap>,
|
||||||
pub hashwd: HashMap<String, WatchDescriptor>,
|
pub hashwd: HashMap<String, WatchDescriptor>,
|
||||||
pub reloadinterval: isize,
|
pub reloadinterval: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -43,6 +47,7 @@ pub struct SetMap {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Flags {
|
pub struct Flags {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub server: String,
|
pub server: String,
|
||||||
}
|
}
|
||||||
@ -134,6 +139,25 @@ impl Context {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut last_in_err = false;
|
||||||
|
loop {
|
||||||
|
let res = self.discovery().await;
|
||||||
|
match res {
|
||||||
|
Ok(o) => {
|
||||||
|
self.discovery = o;
|
||||||
|
if last_in_err {
|
||||||
|
println!("loaded discovery");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("error loading disvoery: {e}, retrying in {CONFIG_RETRY_INTERVAL}s");
|
||||||
|
last_in_err = true;
|
||||||
|
sleep_s(CONFIG_RETRY_INTERVAL).await;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
if last_in_err {
|
if last_in_err {
|
||||||
println!("creating sas");
|
println!("creating sas");
|
||||||
}
|
}
|
||||||
@ -145,21 +169,21 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub async fn get_blocklist_pending(&self) -> Vec<IpData> {
|
pub async fn get_blocklist_pending(&self) -> Vec<BlockIpData> {
|
||||||
let mut res: Vec<IpData> = vec![];
|
let mut res: Vec<BlockIpData> = vec![];
|
||||||
for (_, v) in self.blocklist.iter() {
|
for (_, ipblock) in self.blocklist.iter() {
|
||||||
res.push(v.ipdata.clone());
|
res.push(ipblock.clone());
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_blocklist_toblock(&self) -> Vec<IpData> {
|
pub async fn get_blocklist_toblock(&self, all: bool) -> Vec<BlockIpData> {
|
||||||
let mut res: Vec<IpData> = vec![];
|
let mut res: Vec<BlockIpData> = vec![];
|
||||||
for (_, block) in self.blocklist.iter() {
|
for (_, ipblock) in self.blocklist.iter() {
|
||||||
match self.cfg.sets.get(&block.ipdata.src) {
|
match self.cfg.sets.get(&ipblock.ipdata.src) {
|
||||||
Some(set) => {
|
Some(set) => {
|
||||||
if block.tryfail >= set.tryfail {
|
if ipblock.tryfail >= set.tryfail && (!ipblock.blocked || all) {
|
||||||
res.push(block.ipdata.clone());
|
res.push(ipblock.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@ -176,6 +200,8 @@ impl Context {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.with_timezone(&chrono::Local);
|
.with_timezone(&chrono::Local);
|
||||||
let blocktime = set.blocktime;
|
let blocktime = set.blocktime;
|
||||||
|
let blocked = false;
|
||||||
|
let handle = u64::MIN;
|
||||||
if ipevent.mode == "file".to_string() && gethostname(true) == ipevent.hostname {
|
if ipevent.mode == "file".to_string() && gethostname(true) == ipevent.hostname {
|
||||||
let block =
|
let block =
|
||||||
self.blocklist
|
self.blocklist
|
||||||
@ -185,6 +211,8 @@ impl Context {
|
|||||||
tryfail: 0,
|
tryfail: 0,
|
||||||
starttime,
|
starttime,
|
||||||
blocktime,
|
blocktime,
|
||||||
|
blocked,
|
||||||
|
handle,
|
||||||
});
|
});
|
||||||
block.tryfail += 1;
|
block.tryfail += 1;
|
||||||
block.blocktime = blocktime;
|
block.blocktime = blocktime;
|
||||||
@ -199,6 +227,8 @@ impl Context {
|
|||||||
tryfail: set.tryfail,
|
tryfail: set.tryfail,
|
||||||
starttime,
|
starttime,
|
||||||
blocktime,
|
blocktime,
|
||||||
|
blocked,
|
||||||
|
handle,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,8 +239,8 @@ impl Context {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn gc_blocklist(&mut self) -> Vec<IpData> {
|
pub async fn gc_blocklist(&mut self) -> Vec<BlockIpData> {
|
||||||
let mut removed: Vec<IpData> = vec![];
|
let mut removed: Vec<BlockIpData> = vec![];
|
||||||
let now: DateTime<Local> = Local::now().trunc_subsecs(0);
|
let now: DateTime<Local> = Local::now().trunc_subsecs(0);
|
||||||
// nightly, future use
|
// nightly, future use
|
||||||
// let drained: HashMap<String,IpData> = ctx.blocklist.drain_filter(|k,v| v.parse_date() < mindate)
|
// let drained: HashMap<String,IpData> = ctx.blocklist.drain_filter(|k,v| v.parse_date() < mindate)
|
||||||
@ -225,7 +255,7 @@ impl Context {
|
|||||||
let mindate = now - Duration::minutes(blocked.blocktime);
|
let mindate = now - Duration::minutes(blocked.blocktime);
|
||||||
if blocked.starttime < mindate {
|
if blocked.starttime < mindate {
|
||||||
self.blocklist.remove(&ip.clone()).unwrap();
|
self.blocklist.remove(&ip.clone()).unwrap();
|
||||||
removed.push(blocked.ipdata.clone());
|
removed.push(blocked.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removed
|
removed
|
||||||
@ -637,7 +667,7 @@ mod test {
|
|||||||
pub async fn test_blocklist_toblock() {
|
pub async fn test_blocklist_toblock() {
|
||||||
let mut ctx = prepare_test_data().await;
|
let mut ctx = prepare_test_data().await;
|
||||||
ctx.gc_blocklist().await;
|
ctx.gc_blocklist().await;
|
||||||
let toblock = ctx.get_blocklist_toblock().await;
|
let toblock = ctx.get_blocklist_toblock(false).await;
|
||||||
assert_eq!(toblock.len(), 3);
|
assert_eq!(toblock.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
265
src/fw.rs
265
src/fw.rs
@ -1,171 +1,208 @@
|
|||||||
use crate::ip::IpData;
|
use crate::{config::Context, ip::BlockIpData, ipblc::PKG_NAME};
|
||||||
use crate::ipblc::PKG_NAME;
|
|
||||||
|
|
||||||
use nftnl::{nft_expr, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table};
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::CString,
|
|
||||||
io::Error,
|
io::Error,
|
||||||
net::{Ipv4Addr, Ipv6Addr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use rustables::{expr::*, *};
|
||||||
|
|
||||||
pub enum FwTableType {
|
pub enum FwTableType {
|
||||||
IPv4,
|
IPv4,
|
||||||
IPv6,
|
IPv6,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fwglobalinit<'a>() -> ((Batch, Table), (Batch, Table)) {
|
#[allow(dead_code)]
|
||||||
let (batch4, table4) = fwinit(FwTableType::IPv4);
|
pub enum FwAction {
|
||||||
let (batch6, table6) = fwinit(FwTableType::IPv6);
|
Add,
|
||||||
((batch4, table4), (batch6, table6))
|
Delete,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! initrules {
|
macro_rules! initrules {
|
||||||
($batch:expr, $table:expr, $chain:ident) => {
|
($batch:expr, $table:expr, $chain:ident, $reset:expr) => {
|
||||||
$chain.set_hook(nftnl::Hook::In, 1);
|
$chain.set_hook(Hook::new(HookClass::In, 1));
|
||||||
$chain.set_policy(nftnl::Policy::Accept);
|
|
||||||
|
|
||||||
$batch.add(&$chain, nftnl::MsgType::Add);
|
$batch.add(&$chain, MsgType::Add);
|
||||||
$batch.add(&Rule::new(&$chain), nftnl::MsgType::Del);
|
if $reset {
|
||||||
|
$batch.add(&Rule::new(&$chain).unwrap(), MsgType::Del);
|
||||||
let mut rule = Rule::new(&$chain);
|
}
|
||||||
rule.add_expr(&nft_expr!(ct state));
|
|
||||||
rule.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32));
|
|
||||||
rule.add_expr(&nft_expr!(cmp != 0u32));
|
|
||||||
rule.add_expr(&nft_expr!(counter));
|
|
||||||
rule.add_expr(&nft_expr!(verdict accept));
|
|
||||||
$batch.add(&rule, nftnl::MsgType::Add);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! createrules {
|
macro_rules! makerules {
|
||||||
($ipdata:ident, $chain:ident, $batch:ident, $t:ty, $ip_t:ident) => {
|
($ipdata:ident, $chain:ident, $batch:ident, $t:ty, $ip_t:ident,$action:ty) => {
|
||||||
let mut rule = Rule::new(&$chain);
|
let ip = $ipdata.ipdata.ip.parse::<$t>().unwrap();
|
||||||
let ip = $ipdata.ip.parse::<$t>().unwrap();
|
Rule::new(&$chain)
|
||||||
|
.unwrap()
|
||||||
rule.add_expr(&nft_expr!(payload $ip_t saddr));
|
.saddr(ip.into())
|
||||||
rule.add_expr(&nft_expr!(cmp == ip));
|
.drop()
|
||||||
rule.add_expr(&nft_expr!(ct state));
|
.add_to_batch(&mut $batch);
|
||||||
rule.add_expr(&nft_expr!(bitwise mask 10u32, xor 0u32));
|
};
|
||||||
rule.add_expr(&nft_expr!(cmp != 0u32));
|
|
||||||
rule.add_expr(&nft_expr!(counter));
|
|
||||||
rule.add_expr(&nft_expr!(verdict drop));
|
|
||||||
|
|
||||||
$batch.add(&rule, nftnl::MsgType::Add);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fwinit(t: FwTableType) -> (Batch, Table) {
|
pub fn fwglobalinit(t: FwTableType, reset: bool) -> (Batch, Chain) {
|
||||||
let table_name: String;
|
let table_name: String;
|
||||||
let table: Table;
|
let table: Table;
|
||||||
|
let mut chain: Chain;
|
||||||
match t {
|
match t {
|
||||||
FwTableType::IPv4 => {
|
FwTableType::IPv4 => {
|
||||||
table_name = format!("{PKG_NAME}4");
|
table_name = format!("{PKG_NAME}4");
|
||||||
table = Table::new(
|
table = Table::new(ProtocolFamily::Ipv4).with_name(table_name);
|
||||||
&CString::new(format!("{table_name}")).unwrap(),
|
chain = Chain::new(&table)
|
||||||
ProtoFamily::Ipv4,
|
.with_policy(ChainPolicy::Accept)
|
||||||
);
|
.with_name(PKG_NAME);
|
||||||
}
|
}
|
||||||
FwTableType::IPv6 => {
|
FwTableType::IPv6 => {
|
||||||
table_name = format!("{PKG_NAME}6");
|
table_name = format!("{PKG_NAME}6");
|
||||||
table = Table::new(
|
table = Table::new(ProtocolFamily::Ipv6).with_name(table_name);
|
||||||
&CString::new(format!("{table_name}")).unwrap(),
|
chain = Chain::new(&table)
|
||||||
ProtoFamily::Ipv6,
|
.with_policy(ChainPolicy::Accept)
|
||||||
);
|
.with_name(PKG_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut batch = Batch::new();
|
let mut batch = Batch::new();
|
||||||
|
|
||||||
batch.add(&table, nftnl::MsgType::Add);
|
batch.add(&table, MsgType::Add);
|
||||||
batch.add(&table, nftnl::MsgType::Del);
|
initrules!(batch, table, chain, reset);
|
||||||
|
|
||||||
batch.add(&table, nftnl::MsgType::Add);
|
(batch, chain)
|
||||||
(batch, table)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fwblock(
|
pub fn fwblock<'a>(ip_add: &BlockIpData) -> std::result::Result<&String, error::QueryError> {
|
||||||
ips_add_all: &Vec<IpData>,
|
let (mut batch4, chain4) = fwglobalinit(FwTableType::IPv4, false);
|
||||||
ret: &mut Vec<String>,
|
let (mut batch6, chain6) = fwglobalinit(FwTableType::IPv6, false);
|
||||||
fwlen: &mut usize,
|
|
||||||
) -> std::result::Result<(), Error> {
|
|
||||||
let ((mut batch4, table4), (mut batch6, table6)) = fwglobalinit();
|
|
||||||
|
|
||||||
let mut chain4 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table4);
|
match ip_add.ipdata.t {
|
||||||
let mut chain6 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table6);
|
|
||||||
|
|
||||||
initrules!(batch4, table4, chain4);
|
|
||||||
initrules!(batch6, table6, chain6);
|
|
||||||
|
|
||||||
let mut factor = 1;
|
|
||||||
if ips_add_all.len() > 100 {
|
|
||||||
factor = (ips_add_all.len() / 10) as usize
|
|
||||||
}
|
|
||||||
|
|
||||||
let ips_add_tmp: Vec<IpData> = ips_add_all.clone().iter().map(|x| x.clone()).collect();
|
|
||||||
let mut ips_add_iter = ips_add_tmp.chunks(factor);
|
|
||||||
let mut ips_add: Vec<&[IpData]> = vec![];
|
|
||||||
while let Some(x) = ips_add_iter.next() {
|
|
||||||
ips_add.push(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
// build and add rules
|
|
||||||
for ipdata_group in ips_add.clone() {
|
|
||||||
for ipdata in ipdata_group {
|
|
||||||
match ipdata.t {
|
|
||||||
4 => {
|
4 => {
|
||||||
createrules!(ipdata, chain4, batch4, Ipv4Addr, ipv4);
|
makerules!(ip_add, chain4, batch4, Ipv4Addr, ipv4, FwAction::Add);
|
||||||
|
match batch4.send() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("block not ok {e} {ip_add:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
createrules!(ipdata, chain6, batch6, Ipv6Addr, ipv6);
|
makerules!(ip_add, chain6, batch6, Ipv6Addr, ipv6, FwAction::Add);
|
||||||
|
match batch6.send() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("block not ok {e} {ip_add:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Ok(&ip_add.ipdata.ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate and send batch
|
pub fn fwunblock<'a>(ip_del: &BlockIpData) -> std::result::Result<&String, error::QueryError> {
|
||||||
for b in [batch4, batch6] {
|
let (mut batch4, chain4) = fwglobalinit(FwTableType::IPv4, false);
|
||||||
let bf = b.finalize();
|
let (mut batch6, chain6) = fwglobalinit(FwTableType::IPv6, false);
|
||||||
match send_and_process(&bf) {
|
|
||||||
|
match ip_del.ipdata.t {
|
||||||
|
4 => {
|
||||||
|
let r = Rule::new(&chain4).unwrap().with_handle(ip_del.handle);
|
||||||
|
batch4.add(&r, MsgType::Del);
|
||||||
|
match batch4.send() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("error sending batch: {e}");
|
println!("delete not ok {e} {ip_del:?}")
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if fwlen != &mut ips_add_all.len() {
|
|
||||||
ret.push(format!(
|
|
||||||
"{length} ip in firewall",
|
|
||||||
length = ips_add_all.len()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
*fwlen = ips_add_all.len();
|
6 => {
|
||||||
Ok(())
|
let r = Rule::new(&chain6).unwrap().with_handle(ip_del.handle);
|
||||||
|
batch6.add(&r, MsgType::Del);
|
||||||
|
match batch6.send() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("delete not ok {e} {ip_del:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
Ok(&ip_del.ipdata.ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_and_process(batch: &FinalizedBatch) -> std::result::Result<(), Error> {
|
pub async fn get_current_rules(
|
||||||
let seq: u32 = 2;
|
ctx: &Arc<RwLock<Context>>,
|
||||||
let socket = mnl::Socket::new(mnl::Bus::Netfilter)?;
|
ret: &mut Vec<String>,
|
||||||
socket.send_all(batch)?;
|
fwlen: &mut usize,
|
||||||
let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize];
|
) -> Result<(), Error> {
|
||||||
while let Some(message) = socket_recv(&socket, &mut buffer[..])? {
|
let mut ips_all_count = 0;
|
||||||
match mnl::cb_run(message, seq, socket.portid())? {
|
let tables = vec![format!("{PKG_NAME}4"), format!("{PKG_NAME}6")];
|
||||||
mnl::CbResult::Stop => {
|
for table_name in tables {
|
||||||
break;
|
let get_table = || -> Result<Option<Table>, Error> {
|
||||||
}
|
let tables = list_tables().unwrap();
|
||||||
mnl::CbResult::Ok => (),
|
for table in tables {
|
||||||
|
if let Some(name) = table.get_name() {
|
||||||
|
if *name == table_name {
|
||||||
|
return Ok(Some(table));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn socket_recv<'a>(
|
|
||||||
socket: &mnl::Socket,
|
|
||||||
buf: &'a mut [u8],
|
|
||||||
) -> std::result::Result<Option<&'a [u8]>, Error> {
|
|
||||||
let ret = socket.recv(buf)?;
|
|
||||||
if ret > 0 {
|
|
||||||
Ok(Some(&buf[..ret]))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let get_chain = |table: &Table| -> Result<Option<Chain>, Error> {
|
||||||
|
let chains = list_chains_for_table(table).unwrap();
|
||||||
|
for chain in chains {
|
||||||
|
if let Some(name) = chain.get_name() {
|
||||||
|
if *name == "ipblc" {
|
||||||
|
return Ok(Some(chain));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let table = get_table()?.expect("no table?");
|
||||||
|
let chain = get_chain(&table)?.expect("no chain?");
|
||||||
|
|
||||||
|
let mut ctx = { ctx.write().await };
|
||||||
|
let rules = list_rules_for_chain(&chain).unwrap().clone();
|
||||||
|
|
||||||
|
for (ip, c) in ctx.blocklist.iter_mut() {
|
||||||
|
let ip_parsed: IpAddr = ip.parse().unwrap();
|
||||||
|
|
||||||
|
let cmprule = Rule::new(&chain).unwrap().saddr(ip_parsed).drop();
|
||||||
|
let mut gexpr = RawExpression::default();
|
||||||
|
for e in cmprule.get_expressions().unwrap().iter() {
|
||||||
|
if let Some(ExpressionVariant::Cmp(_ip)) = e.get_data() {
|
||||||
|
gexpr = e.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for rule in rules.iter() {
|
||||||
|
for expr in rule.get_expressions().unwrap().iter() {
|
||||||
|
if let Some(expr::ExpressionVariant::Cmp(_)) = expr.get_data() {
|
||||||
|
if gexpr == expr.clone() {
|
||||||
|
ips_all_count += 1;
|
||||||
|
c.handle = *rule.get_handle().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if *fwlen != ips_all_count {
|
||||||
|
ret.push(format!("{length} ip in firewall", length = ips_all_count));
|
||||||
|
}
|
||||||
|
*fwlen = ips_all_count;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn fw_rules_count() -> i64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
13
src/ip.rs
13
src/ip.rs
@ -1,15 +1,18 @@
|
|||||||
use crate::utils::gethostname;
|
use crate::utils::gethostname;
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
|
fmt::{Display, Formatter},
|
||||||
|
io::{BufRead, BufReader, Read},
|
||||||
|
net::IpAddr,
|
||||||
|
};
|
||||||
|
|
||||||
use chrono::offset::LocalResult;
|
use chrono::offset::LocalResult;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use ipnet::IpNet;
|
use ipnet::IpNet;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cmp::Ordering;
|
|
||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use std::io::{BufRead, BufReader, Read};
|
|
||||||
use std::net::IpAddr;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref R_IPV4: Regex = Regex::new(include_str!("regexps/ipv4.txt")).unwrap();
|
static ref R_IPV4: Regex = Regex::new(include_str!("regexps/ipv4.txt")).unwrap();
|
||||||
@ -51,6 +54,8 @@ pub struct BlockIpData {
|
|||||||
pub tryfail: i64,
|
pub tryfail: i64,
|
||||||
pub blocktime: i64,
|
pub blocktime: i64,
|
||||||
pub starttime: DateTime<Local>,
|
pub starttime: DateTime<Local>,
|
||||||
|
pub blocked: bool,
|
||||||
|
pub handle: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq)]
|
||||||
|
91
src/ipblc.rs
91
src/ipblc.rs
@ -1,5 +1,5 @@
|
|||||||
use crate::config::{Context, GIT_VERSION};
|
use crate::config::{Context, GIT_VERSION};
|
||||||
use crate::fw::{fwblock, fwglobalinit};
|
use crate::fw::*;
|
||||||
use crate::ip::{filter, IpData, IpEvent};
|
use crate::ip::{filter, IpData, IpEvent};
|
||||||
use crate::ipevent;
|
use crate::ipevent;
|
||||||
use crate::monitoring::apiserver;
|
use crate::monitoring::apiserver;
|
||||||
@ -7,20 +7,19 @@ use crate::utils::{gethostname, read_lines, sleep_s};
|
|||||||
use crate::webservice::send_to_ipbl_api;
|
use crate::webservice::send_to_ipbl_api;
|
||||||
use crate::websocket::{send_to_ipbl_websocket, websocketpubsub, websocketreqrep};
|
use crate::websocket::{send_to_ipbl_websocket, websocketpubsub, websocketreqrep};
|
||||||
|
|
||||||
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use chrono::prelude::{DateTime, Local};
|
use chrono::prelude::{DateTime, Local};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent};
|
use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent};
|
||||||
use sd_notify::*;
|
use sd_notify::*;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
||||||
const BL_CHAN_SIZE: usize = 32;
|
const BL_CHAN_SIZE: usize = 32;
|
||||||
const WS_CHAN_SIZE: usize = 64;
|
const WS_CHAN_SIZE: usize = 64;
|
||||||
const LOOP_MAX_WAIT: u64 = 5;
|
|
||||||
|
|
||||||
macro_rules! log_with_systemd {
|
macro_rules! log_with_systemd {
|
||||||
($msg:expr) => {
|
($msg:expr) => {
|
||||||
@ -33,6 +32,10 @@ pub async fn run() {
|
|||||||
let inotify = Inotify::init(InitFlags::empty()).unwrap();
|
let inotify = Inotify::init(InitFlags::empty()).unwrap();
|
||||||
let globalctx = Context::new(&inotify).await;
|
let globalctx = Context::new(&inotify).await;
|
||||||
let ctxarc = Arc::new(RwLock::new(globalctx));
|
let ctxarc = Arc::new(RwLock::new(globalctx));
|
||||||
|
let (batch4, _) = fwglobalinit(FwTableType::IPv4, true);
|
||||||
|
let (batch6, _) = fwglobalinit(FwTableType::IPv6, true);
|
||||||
|
batch4.send().unwrap();
|
||||||
|
batch6.send().unwrap();
|
||||||
|
|
||||||
let mut fwlen: usize = 0;
|
let mut fwlen: usize = 0;
|
||||||
|
|
||||||
@ -40,7 +43,6 @@ pub async fn run() {
|
|||||||
|
|
||||||
let mut last_cfg_reload: DateTime<Local> = Local::now().trunc_subsecs(0);
|
let mut last_cfg_reload: DateTime<Local> = Local::now().trunc_subsecs(0);
|
||||||
log_with_systemd!(format!("Launching {}, version {}", PKG_NAME, pkgversion));
|
log_with_systemd!(format!("Launching {}, version {}", PKG_NAME, pkgversion));
|
||||||
fwglobalinit();
|
|
||||||
|
|
||||||
let ctxapi = Arc::clone(&ctxarc);
|
let ctxapi = Arc::clone(&ctxarc);
|
||||||
apiserver(&ctxapi).await.unwrap();
|
apiserver(&ctxapi).await.unwrap();
|
||||||
@ -72,21 +74,26 @@ pub async fn run() {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut ret: Vec<String> = Vec::new();
|
let mut ret: Vec<String> = Vec::new();
|
||||||
|
|
||||||
let ctxclone = Arc::clone(&ctxarc);
|
let ctxclone = Arc::clone(&ctxarc);
|
||||||
|
|
||||||
|
let reloadinterval;
|
||||||
|
{
|
||||||
|
let ctx = ctxclone.read().await;
|
||||||
|
reloadinterval = ctx.reloadinterval;
|
||||||
|
}
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
ipevent = ipeventrx.recv() => {
|
ipevent = ipeventrx.recv() => {
|
||||||
let received_ip = ipevent.unwrap();
|
let received_ip = ipevent.unwrap();
|
||||||
|
|
||||||
let (toblock,server) = {
|
let (toblock,server) = {
|
||||||
let ctx = ctxclone.read().await;
|
let ctx = ctxclone.read().await;
|
||||||
(ctx.get_blocklist_toblock().await,ctx.flags.server.clone())
|
(ctx.get_blocklist_toblock(true).await,ctx.flags.server.clone())
|
||||||
};
|
};
|
||||||
|
|
||||||
if received_ip.msgtype == "bootstrap".to_string() {
|
if received_ip.msgtype == "bootstrap".to_string() {
|
||||||
for ip_to_send in toblock {
|
for ip_to_send in toblock {
|
||||||
let ipe = ipevent!("init","ws",gethostname(true),Some(ip_to_send));
|
let ipe = ipevent!("init","ws",gethostname(true),Some(ip_to_send.ipdata));
|
||||||
if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await {
|
if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await {
|
||||||
wssocketrr.close(None).unwrap();
|
wssocketrr.close(None).unwrap();
|
||||||
wssocketrr = websocketreqrep(&ctxwsrr).await;
|
wssocketrr = websocketreqrep(&ctxwsrr).await;
|
||||||
@ -115,7 +122,7 @@ pub async fn run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_val = sleep_s(LOOP_MAX_WAIT) => {
|
_val = sleep_s(reloadinterval) => {
|
||||||
let ipe = ipevent!("ping", "ws", gethostname(true));
|
let ipe = ipevent!("ping", "ws", gethostname(true));
|
||||||
if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await {
|
if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await {
|
||||||
wssocketrr.close(None).unwrap();
|
wssocketrr.close(None).unwrap();
|
||||||
@ -125,7 +132,43 @@ pub async fn run() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let ctxclone = Arc::clone(&ctxarc);
|
let ctxclone = Arc::clone(&ctxarc);
|
||||||
handle_fwblock(ctxclone, &mut ret, &mut fwlen).await;
|
let ipstounblock = {
|
||||||
|
let mut ctx = ctxclone.write().await;
|
||||||
|
ctx.gc_blocklist().await
|
||||||
|
};
|
||||||
|
let ipstoblock = {
|
||||||
|
let ctx = ctxclone.read().await;
|
||||||
|
ctx.get_blocklist_toblock(false).await
|
||||||
|
};
|
||||||
|
|
||||||
|
get_current_rules(&ctxarc, &mut ret, &mut fwlen)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for ip in ipstoblock {
|
||||||
|
match fwblock(&ip) {
|
||||||
|
Ok(ip) => {
|
||||||
|
let mut ctx = ctxclone.write().await;
|
||||||
|
if let Some(x) = ctx.blocklist.get_mut(ip) {
|
||||||
|
x.blocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("err: {e}, unable to push firewall rules, use super user")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for ip in ipstounblock {
|
||||||
|
if ip.blocked {
|
||||||
|
match fwunblock(&ip) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("err: {e}, unable to push firewall rules, use super user")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// log lines
|
// log lines
|
||||||
if ret.len() > 0 {
|
if ret.len() > 0 {
|
||||||
@ -135,17 +178,18 @@ pub async fn run() {
|
|||||||
|
|
||||||
let ctxclone = Arc::clone(&ctxarc);
|
let ctxclone = Arc::clone(&ctxarc);
|
||||||
let inoclone = Arc::clone(&inoarc);
|
let inoclone = Arc::clone(&inoarc);
|
||||||
handle_cfg_reload(&ctxclone, &mut last_cfg_reload, inoclone).await;
|
handle_cfg_reload(&ctxclone, reloadinterval, &mut last_cfg_reload, inoclone).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_cfg_reload(
|
async fn handle_cfg_reload(
|
||||||
ctxclone: &Arc<RwLock<Context>>,
|
ctxclone: &Arc<RwLock<Context>>,
|
||||||
|
reloadinterval: u64,
|
||||||
last_cfg_reload: &mut DateTime<Local>,
|
last_cfg_reload: &mut DateTime<Local>,
|
||||||
inoarc: Arc<RwLock<Inotify>>,
|
inoarc: Arc<RwLock<Inotify>>,
|
||||||
) {
|
) {
|
||||||
let now_cfg_reload = Local::now().trunc_subsecs(0);
|
let now_cfg_reload = Local::now().trunc_subsecs(0);
|
||||||
if (now_cfg_reload - *last_cfg_reload) > Duration::seconds(LOOP_MAX_WAIT as i64) {
|
if (now_cfg_reload - *last_cfg_reload) > Duration::seconds(reloadinterval as i64) {
|
||||||
let inotify;
|
let inotify;
|
||||||
loop {
|
loop {
|
||||||
inotify = match inoarc.try_read() {
|
inotify = match inoarc.try_read() {
|
||||||
@ -158,14 +202,14 @@ async fn handle_cfg_reload(
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let mut ctxtest = match ctxclone.try_write() {
|
let mut ctx = match ctxclone.try_write() {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("{e}");
|
println!("{e}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match ctxtest.load(&inotify).await {
|
match ctx.load(&inotify).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
*last_cfg_reload = Local::now().trunc_subsecs(0);
|
*last_cfg_reload = Local::now().trunc_subsecs(0);
|
||||||
}
|
}
|
||||||
@ -176,25 +220,6 @@ async fn handle_cfg_reload(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_fwblock(ctxclone: Arc<RwLock<Context>>, ret: &mut Vec<String>, fwlen: &mut usize) {
|
|
||||||
{
|
|
||||||
let mut ctx = ctxclone.write().await;
|
|
||||||
ctx.gc_blocklist().await;
|
|
||||||
}
|
|
||||||
let toblock = {
|
|
||||||
let ctx = ctxclone.read().await;
|
|
||||||
ctx.get_blocklist_toblock().await
|
|
||||||
};
|
|
||||||
|
|
||||||
// apply firewall blocking
|
|
||||||
match fwblock(&toblock, ret, fwlen) {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
println!("err: {e}, unable to push firewall rules, use super user")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn watchfiles(inoarc: Arc<RwLock<Inotify>>) -> Receiver<FileEvent> {
|
async fn watchfiles(inoarc: Arc<RwLock<Inotify>>) -> Receiver<FileEvent> {
|
||||||
let (bltx, blrx): (Sender<FileEvent>, Receiver<FileEvent>) = channel(BL_CHAN_SIZE);
|
let (bltx, blrx): (Sender<FileEvent>, Receiver<FileEvent>) = channel(BL_CHAN_SIZE);
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::config::Context;
|
use crate::config::Context;
|
||||||
|
|
||||||
|
use std::{io, sync::Arc};
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::io;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
|
use std::{boxed::Box, fs::File, io::*};
|
||||||
|
|
||||||
use nix::unistd;
|
use nix::unistd;
|
||||||
use std::boxed::Box;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::*;
|
|
||||||
use tokio::time::{sleep, Duration};
|
use tokio::time::{sleep, Duration};
|
||||||
|
|
||||||
pub fn read_lines(filename: &String, offset: u64) -> Option<Box<dyn Read>> {
|
pub fn read_lines(filename: &String, offset: u64) -> Option<Box<dyn Read>> {
|
||||||
|
@ -2,10 +2,13 @@ use crate::config::{Context, WebSocketCfg};
|
|||||||
use crate::ip::IpEvent;
|
use crate::ip::IpEvent;
|
||||||
use crate::utils::{gethostname, sleep_s};
|
use crate::utils::{gethostname, sleep_s};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
io::{self, Write},
|
||||||
|
net::TcpStream,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::io::{self, Write};
|
|
||||||
use std::net::TcpStream;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tungstenite::stream::*;
|
use tungstenite::stream::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user