Compare commits
1 Commits
auth-daemo
...
manpages
| Author | SHA1 | Date | |
|---|---|---|---|
|
3f89eab11a
|
90
Cargo.lock
generated
90
Cargo.lock
generated
@@ -292,9 +292,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.54"
|
version = "4.5.53"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
|
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@@ -313,9 +313,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.54"
|
version = "4.5.53"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
|
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@@ -325,9 +325,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete"
|
name = "clap_complete"
|
||||||
version = "4.5.65"
|
version = "4.5.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "430b4dc2b5e3861848de79627b2bedc9f3342c7da5173a14eaa5d0f8dc18ae5d"
|
checksum = "004eef6b14ce34759aa7de4aea3217e368f463f46a3ed3764ca4b5a4404003b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
@@ -353,6 +353,16 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_mangen"
|
||||||
|
version = "0.2.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ea63a92086df93893164221ad4f24142086d535b3a0957b9b9bea2dc86301"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"roff",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color-print"
|
name = "color-print"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@@ -695,7 +705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1102,9 +1112,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.13.0"
|
version = "2.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.16.1",
|
"hashbrown 0.16.1",
|
||||||
@@ -1127,7 +1137,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1156,9 +1166,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.17"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
@@ -1202,9 +1212,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.180"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
@@ -1337,6 +1347,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"clap-verbosity-flag",
|
"clap-verbosity-flag",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
"clap_mangen",
|
||||||
"color-print",
|
"color-print",
|
||||||
"const_format",
|
"const_format",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
@@ -1616,18 +1627,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.105"
|
version = "1.0.103"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7"
|
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.43"
|
version = "1.0.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -1769,6 +1780,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roff"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.9"
|
version = "0.9.9"
|
||||||
@@ -1808,7 +1825,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1914,9 +1931,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.149"
|
version = "1.0.148"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
@@ -1992,11 +2009,10 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.8"
|
version = "1.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"errno",
|
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2275,9 +2291,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.114"
|
version = "2.0.111"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -2305,7 +2321,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2395,9 +2411,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.49.0"
|
version = "1.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -2437,9 +2453,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.18"
|
version = "0.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
|
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@@ -2448,9 +2464,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.18"
|
version = "0.7.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
|
checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -2462,9 +2478,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.9.11+spec-1.1.0"
|
version = "0.9.10+spec-1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46"
|
checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
@@ -3222,9 +3238,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zmij"
|
name = "zmij"
|
||||||
version = "1.0.10"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868"
|
checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
|
|||||||
15
Cargo.toml
15
Cargo.toml
@@ -22,9 +22,10 @@ autolib = false
|
|||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
async-bincode = "0.8.0"
|
async-bincode = "0.8.0"
|
||||||
bincode = "2.0.1"
|
bincode = "2.0.1"
|
||||||
clap = { version = "4.5.54", features = ["cargo", "derive"] }
|
clap = { version = "4.5.53", features = ["cargo", "derive"] }
|
||||||
clap-verbosity-flag = { version = "3.0.4", features = [ "tracing" ] }
|
clap-verbosity-flag = { version = "3.0.4", features = [ "tracing" ] }
|
||||||
clap_complete = { version = "4.5.65", features = ["unstable-dynamic"] }
|
clap_complete = { version = "4.5.62", features = ["unstable-dynamic"] }
|
||||||
|
clap_mangen = "0.2.31"
|
||||||
color-print = "0.3.7"
|
color-print = "0.3.7"
|
||||||
const_format = "0.2.35"
|
const_format = "0.2.35"
|
||||||
derive_more = { version = "2.1.1", features = ["display", "error"] }
|
derive_more = { version = "2.1.1", features = ["display", "error"] }
|
||||||
@@ -38,14 +39,14 @@ num_cpus = "1.17.0"
|
|||||||
prettytable = "0.10.0"
|
prettytable = "0.10.0"
|
||||||
rand = "0.9.2"
|
rand = "0.9.2"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_json = { version = "1.0.149", features = ["preserve_order"] }
|
serde_json = { version = "1.0.148", features = ["preserve_order"] }
|
||||||
sqlx = { version = "0.8.6", features = ["runtime-tokio", "mysql", "tls-rustls"] }
|
sqlx = { version = "0.8.6", features = ["runtime-tokio", "mysql", "tls-rustls"] }
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "signal"] }
|
tokio = { version = "1.48.0", features = ["rt-multi-thread", "macros", "signal"] }
|
||||||
tokio-serde = { version = "0.9.0", features = ["bincode"] }
|
tokio-serde = { version = "0.9.0", features = ["bincode"] }
|
||||||
tokio-stream = "0.1.18"
|
tokio-stream = "0.1.17"
|
||||||
tokio-util = { version = "0.7.18", features = ["codec", "rt"] }
|
tokio-util = { version = "0.7.17", features = ["codec", "rt"] }
|
||||||
toml = "0.9.11"
|
toml = "0.9.10"
|
||||||
tracing = { version = "0.1.44", features = ["log"] }
|
tracing = { version = "0.1.44", features = ["log"] }
|
||||||
tracing-subscriber = "0.3.22"
|
tracing-subscriber = "0.3.22"
|
||||||
uuid = { version = "1.19.0", features = ["v4"] }
|
uuid = { version = "1.19.0", features = ["v4"] }
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ over a IPC, which then performs the requested operations on behalf of the client
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [Installation and initial configuration](docs/installation.md)
|
- [Installation and configuration](docs/installation.md)
|
||||||
- [Administration and further configuration](docs/administration.md)
|
|
||||||
- [Development and testing](docs/development.md)
|
- [Development and testing](docs/development.md)
|
||||||
- [Compiling and packaging](docs/compiling.md)
|
- [Compiling and packaging](docs/compiling.md)
|
||||||
- [Compatibility mode with mysql-admutils](docs/mysql-admutils-compatibility.md)
|
- [Compatibility mode with mysql-admutils](docs/mysql-admutils-compatibility.md)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# These are the default system groups on debian.
|
# These are the default system groups on debian.
|
||||||
# You can also add groups by gid by prefixing the line with 'gid:'.
|
# You can alos add groups by gid by prefixing the line with 'gid:'.
|
||||||
|
|
||||||
group:_ssh
|
group:_ssh
|
||||||
group:adm
|
group:adm
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Type=notify
|
|||||||
ExecStart=/usr/bin/muscl-server --systemd --disable-landlock socket-activate
|
ExecStart=/usr/bin/muscl-server --systemd --disable-landlock socket-activate
|
||||||
ExecReload=/usr/bin/kill -HUP $MAINPID
|
ExecReload=/usr/bin/kill -HUP $MAINPID
|
||||||
|
|
||||||
WatchdogSec=3min
|
WatchdogSec=15
|
||||||
|
|
||||||
# Although this is a multi-instance unit, the constant `User` field is needed
|
# Although this is a multi-instance unit, the constant `User` field is needed
|
||||||
# for authentication via mysql's auth_socket plugin to work.
|
# for authentication via mysql's auth_socket plugin to work.
|
||||||
@@ -61,7 +61,3 @@ SystemCallFilter=@system-service
|
|||||||
SystemCallFilter=~@privileged @resources
|
SystemCallFilter=~@privileged @resources
|
||||||
|
|
||||||
UMask=0777
|
UMask=0777
|
||||||
|
|
||||||
[Install]
|
|
||||||
Also=muscl.socket
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
# Administration and further configuration
|
|
||||||
|
|
||||||
This page describes some additional configuration options and administration tasks for muscl.
|
|
||||||
|
|
||||||
## Configuring group denylists
|
|
||||||
|
|
||||||
In `/etc/muscl/muscl.conf`, you will find an option below `[authorization]` named `group_denylist_file`,
|
|
||||||
which points to `/etc/muscl/group_denylist.txt` by default.
|
|
||||||
|
|
||||||
In this file, you can add unix group names or GIDs to disallow the groups from being used as prefixes.
|
|
||||||
|
|
||||||
The deb package comes with a default denylist that disallows some common system groups.
|
|
||||||
|
|
||||||
The format of the file is one group name or GID per line. Lines starting with `#` and empty lines are ignored.
|
|
||||||
|
|
||||||
```
|
|
||||||
# Disallow using the 'root' group as a prefix
|
|
||||||
gid:0
|
|
||||||
|
|
||||||
# Disallow using the 'adm' group as a prefix
|
|
||||||
group:adm
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> If a user is named the same as a disallowed group, that user will still be able to use their username as a prefix.
|
|
||||||
|
|
||||||
## Configuring logging
|
|
||||||
|
|
||||||
By default, muscl logs to the systemd journal when run as a systemd service,
|
|
||||||
and also limits the log level to `info`. You can request more verbose logging
|
|
||||||
by appending `-v` flags to the `ExecStart=` line in the systemd service file.
|
|
||||||
|
|
||||||
To do this on a system where muscl was installed using a package, you can override
|
|
||||||
the service like this:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo systemctl edit muscl.service
|
|
||||||
```
|
|
||||||
|
|
||||||
This will open an editor where you can add the following lines:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=/usr/bin/muscl-server -v ...
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> The first `ExecStart=` line is necessary to clear the previous value, as systemd
|
|
||||||
> interprets multiple `ExecStart=` lines as a list of commands to run in sequence.
|
|
||||||
|
|
||||||
You set either `-v` or `-vv` for `debug` and `trace` logging, respectively.
|
|
||||||
|
|
||||||
> [!WARNING]
|
|
||||||
> Be careful when enabling trace logging on production systems, as it might log
|
|
||||||
> passwords and credentials in plaintext.
|
|
||||||
|
|
||||||
## Querying logs in the systemd journal
|
|
||||||
|
|
||||||
Although invisible if you just run `journalctl -u muscl.service`, muscl adds a set of so-called
|
|
||||||
"fields" to its log entries to make it easier to filter and search them.
|
|
||||||
|
|
||||||
Here are some examples of how you can filter logs using `journalctl`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Show only logs related to a specific user
|
|
||||||
journalctl -eu muscl F_USER="<username>"
|
|
||||||
journalctl -eu muscl F_USER=johndoe
|
|
||||||
|
|
||||||
# Show only logs for a specific command types
|
|
||||||
journalctl -eu muscl F_COMMAND="<operation>"
|
|
||||||
journalctl -eu muscl F_COMMAND=create-db
|
|
||||||
|
|
||||||
# Show logs emitted for a specific session id
|
|
||||||
journalctl -eu muscl F_SESSION_ID="<session-id>"
|
|
||||||
journalctl -eu muscl F_SESSION_ID=123
|
|
||||||
|
|
||||||
# Show all of these fields together with the log message in a json format
|
|
||||||
journalctl --output json-pretty --output-fields MESSAGE,F_USER,F_COMMAND,F_SESSION_ID -eu muscl
|
|
||||||
```
|
|
||||||
|
|
||||||
See [`journalctl(1)`][journalctl_1] and [`systemd.journal-fields(7)`][systemd_journal-fields_7] for more information.
|
|
||||||
|
|
||||||
> [!NOTE]
|
|
||||||
> Please note that the commands are not 1-1 mapped to muscl subcommands.
|
|
||||||
> Rather, they are the available requests in the protocol used between the muscl client and server.
|
|
||||||
> These requests will often have the same name as the subcommands, but this is not always the case.
|
|
||||||
|
|
||||||
[journalctl_1]: https://man7.org/linux/man-pages/man1/journalctl.1.html
|
|
||||||
[systemd_journal-fields_7]: https://man7.org/linux/man-pages/man7/systemd.journal-fields.7.html
|
|
||||||
@@ -39,12 +39,7 @@ docker stop mariadb
|
|||||||
|
|
||||||
## Development using Nix
|
## Development using Nix
|
||||||
|
|
||||||
> [!NOTE]
|
If you have nix installed, you can easily test your changes in a NixOS vm by running:
|
||||||
> We have created some nix code to generate a QEMU VM with a setup similar to a production deployment
|
|
||||||
> There is not necessarily any VMs running in a production setup, and if so then at least not this VM.
|
|
||||||
> It is mainly there for easy access to interactive testing, as well as for testing the NixOS module.
|
|
||||||
|
|
||||||
If you have nix installed, you can easily test your changes in a NixOS test VM by running:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix run .#vm # Start a NixOS VM in QEMU with muscl and MariaDB installed
|
nix run .#vm # Start a NixOS VM in QEMU with muscl and MariaDB installed
|
||||||
@@ -52,3 +47,11 @@ nix run .#vm-mysql # Start a NixOS VM in QEMU with muscl and MySQL installed
|
|||||||
```
|
```
|
||||||
|
|
||||||
You can configure the vm in `flake.nix`
|
You can configure the vm in `flake.nix`
|
||||||
|
|
||||||
|
## Filter logs by user with journalctl
|
||||||
|
|
||||||
|
If you want to filter the server logs by user, you can use journalctl's built-in filtering capabilities.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
journalctl -eu muscl F_USER=<username>
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
# Installation and initial configuration
|
# Installation and configuration
|
||||||
|
|
||||||
This document contains instructions for the recommended way of installing and configuring muscl.
|
This document contains instructions for the recommended way of installing and configuring muscl.
|
||||||
|
|
||||||
Note that there are separate instructions for [installing on NixOS](nixos.md) and [installing with SUID/SGID mode](suid-sgid-mode.md).
|
Note that there are separate instructions for [installing on NixOS](nixos.md) and [installing with SUID/SGID mode](suid-sgid-mode.md).
|
||||||
|
|
||||||
After installation, you might want to look at the [Administration and further configuration](administration.md) page.
|
|
||||||
|
|
||||||
## Installing with deb on Debian
|
## Installing with deb on Debian
|
||||||
|
|
||||||
You can install muscl by adding the [PVV apt repository][pvv-apt-repository] and installing the package:
|
You can install muscl by adding the [PVV apt repository][pvv-apt-repository] and installing the package:
|
||||||
@@ -105,6 +103,28 @@ If you are using systemd, you should also create an override to unset the `Impor
|
|||||||
ImportCredential=
|
ImportCredential=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Configuring group denylists
|
||||||
|
|
||||||
|
In `/etc/muscl/muscl.conf`, you will find an option below `[authorization]` named `group_denylist_file`,
|
||||||
|
which points to `/etc/muscl/group_denylist.txt` by default.
|
||||||
|
|
||||||
|
In this file, you can add unix group names or GIDs to disallow the groups from being used as prefixes.
|
||||||
|
|
||||||
|
The deb package comes with a default denylist that disallows some common system groups.
|
||||||
|
|
||||||
|
The format of the file is one group name or GID per line. Lines starting with `#` and empty lines are ignored.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Disallow using the 'root' group as a prefix
|
||||||
|
gid:0
|
||||||
|
|
||||||
|
# Disallow using the 'adm' group as a prefix
|
||||||
|
group:adm
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If a user is named the same as a disallowed group, that user will still be able to use their username as a prefix.
|
||||||
|
|
||||||
## A note on minimum version requirements
|
## A note on minimum version requirements
|
||||||
|
|
||||||
The muscl server will work with older versions of systemd, but the recommended version is 254 or newer.
|
The muscl server will work with older versions of systemd, but the recommended version is 254 or newer.
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
> This will be deprecated in a future release, see https://git.pvv.ntnu.no/Projects/muscl/issues/101
|
> This will be deprecated in a future release, see https://git.pvv.ntnu.no/Projects/muscl/issues/101
|
||||||
>
|
>
|
||||||
> We do not recommend you use this mode unless you absolutely have to. The biggest reason why `muscl` was rewritten from scratch
|
> We do not recommend you use this mode unless you absolutely have to. The biggest reason why `muscl` was rewritten from scratch
|
||||||
> was to fix an architectural issue that easily caused vulnerabilities due to reliance on SUID/SGID. Although the architecture now
|
> was to fix an architectural issue that easily caused vulnerabilites due to reliance on SUID/SGID. Althought the architecture now
|
||||||
> is more resistant against such vulnerabilities, it is not failsafe.
|
> is more resistant against such vulnerabilites, it is not failsafe.
|
||||||
|
|
||||||
For backwards compatibility reasons, it is possible to run the program without a daemon by utilizing SUID/SGID.
|
For backwards compatibility reasons, it is possible to run the program without a daemon by utilizing SUID/SGID.
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Authorization daemon for Muscl
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=notify
|
|
||||||
ExecStart=/usr/local/bin/muscl_auth_daemon.py
|
|
||||||
|
|
||||||
# WatchdogSec=15
|
|
||||||
|
|
||||||
User=muscl
|
|
||||||
Group=muscl
|
|
||||||
DynamicUser=yes
|
|
||||||
|
|
||||||
; ConfigurationDirectory=muscl
|
|
||||||
; RuntimeDirectory=muscl
|
|
||||||
|
|
||||||
; # This is required to read unix user/group details.
|
|
||||||
; PrivateUsers=false
|
|
||||||
|
|
||||||
; # Needed to communicate with MySQL.
|
|
||||||
; PrivateNetwork=false
|
|
||||||
; PrivateIPC=false
|
|
||||||
|
|
||||||
; AmbientCapabilities=
|
|
||||||
; CapabilityBoundingSet=
|
|
||||||
; DeviceAllow=
|
|
||||||
; DevicePolicy=closed
|
|
||||||
; LockPersonality=true
|
|
||||||
; MemoryDenyWriteExecute=true
|
|
||||||
; NoNewPrivileges=true
|
|
||||||
; PrivateDevices=true
|
|
||||||
; PrivateMounts=true
|
|
||||||
; PrivateTmp=yes
|
|
||||||
; ProcSubset=pid
|
|
||||||
; ProtectClock=true
|
|
||||||
; ProtectControlGroups=strict
|
|
||||||
; ProtectHome=true
|
|
||||||
; ProtectHostname=true
|
|
||||||
; ProtectKernelLogs=true
|
|
||||||
; ProtectKernelModules=true
|
|
||||||
; ProtectKernelTunables=true
|
|
||||||
; ProtectProc=invisible
|
|
||||||
; ProtectSystem=strict
|
|
||||||
; RemoveIPC=true
|
|
||||||
; RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
|
||||||
; RestrictNamespaces=true
|
|
||||||
; RestrictRealtime=true
|
|
||||||
; RestrictSUIDSGID=true
|
|
||||||
; SocketBindDeny=any
|
|
||||||
; SystemCallArchitectures=native
|
|
||||||
; SystemCallFilter=@system-service
|
|
||||||
; SystemCallFilter=~@privileged @resources
|
|
||||||
; UMask=0777
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Authorization daemon for Muscl
|
|
||||||
WantedBy=sockets.target
|
|
||||||
|
|
||||||
[Socket]
|
|
||||||
ListenStream=/run/muscl/muscl-auth-daemon.socket
|
|
||||||
Accept=no
|
|
||||||
SocketMode=0660
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# TODO: create pool of workers to handle requests concurrently
|
|
||||||
# the socket should be a listener socket and each worker should accept connections from it
|
|
||||||
# the socket should accept requests as newline-separated JSON objects
|
|
||||||
# there should be a watchdog to monitor worker health and restart them if they die
|
|
||||||
# graceful shutdown should be implemented for the workers
|
|
||||||
# optional logging of requests and responses
|
|
||||||
# use systemd notify to signal readiness and amount of connections handled
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
from socket import AF_UNIX, SOCK_DGRAM, SOCK_STREAM, fromfd, socket
|
|
||||||
from multiprocessing import Pool
|
|
||||||
|
|
||||||
|
|
||||||
def get_listener_from_systemd() -> socket:
|
|
||||||
listen_fds = int(os.getenv("LISTEN_FDS", "0"))
|
|
||||||
listen_pid = int(os.getenv("LISTEN_PID", "0"))
|
|
||||||
if listen_fds != 1 or listen_pid != os.getpid():
|
|
||||||
raise RuntimeError("No socket passed from systemd")
|
|
||||||
assert listen_fds == 1
|
|
||||||
sock = fromfd(3, AF_UNIX, SOCK_STREAM)
|
|
||||||
sock.setblocking(False)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
|
|
||||||
def get_notify_socket_from_systemd() -> socket:
|
|
||||||
notify_socket_path = os.getenv("NOTIFY_SOCKET")
|
|
||||||
if not notify_socket_path:
|
|
||||||
raise RuntimeError("No notify socket path found in environment")
|
|
||||||
sock = socket(AF_UNIX, SOCK_DGRAM)
|
|
||||||
sock.connect(notify_socket_path)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
|
|
||||||
def run_auth_daemon(sock: socket):
|
|
||||||
sock.listen()
|
|
||||||
print("Auth daemon is running and listening for connections...")
|
|
||||||
with Pool() as worker_pool:
|
|
||||||
with get_notify_socket_from_systemd() as notify_socket:
|
|
||||||
notify_socket.sendall(b"READY=1\n")
|
|
||||||
while True:
|
|
||||||
conn, _ = sock.accept()
|
|
||||||
worker_pool.apply_async(session_handler, args=(conn,))
|
|
||||||
|
|
||||||
|
|
||||||
def session_handler(sock: socket):
|
|
||||||
buffer = ""
|
|
||||||
while True:
|
|
||||||
data = sock.recv(4096).decode("utf-8")
|
|
||||||
if not data:
|
|
||||||
print("Connection closed by client")
|
|
||||||
break
|
|
||||||
buffer += data
|
|
||||||
if buffer.endswith("\n"):
|
|
||||||
requests = buffer.strip().split("\n")
|
|
||||||
buffer = ""
|
|
||||||
for request in requests:
|
|
||||||
try:
|
|
||||||
req_json = json.loads(request)
|
|
||||||
username = req_json.get("username", "")
|
|
||||||
groups = req_json.get("groups", [])
|
|
||||||
resource_type = req_json.get("resource_type", "")
|
|
||||||
resource = req_json.get("resource", "")
|
|
||||||
allowed = process_request(username, groups, resource_type, resource)
|
|
||||||
response = {"allowed": allowed}
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
response = {"error": "Invalid JSON"}
|
|
||||||
sock.sendall((json.dumps(response) + "\n").encode("utf-8"))
|
|
||||||
|
|
||||||
|
|
||||||
def process_request(
|
|
||||||
username: str,
|
|
||||||
groups: list[str],
|
|
||||||
resource_type: str,
|
|
||||||
resource: str,
|
|
||||||
) -> bool:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
listener_socket = get_listener_from_systemd()
|
|
||||||
run_auth_daemon(listener_socket)
|
|
||||||
18
flake.lock
generated
18
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"crane": {
|
"crane": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767744144,
|
"lastModified": 1766774972,
|
||||||
"narHash": "sha256-9/9ntI0D+HbN4G0TrK3KmHbTvwgswz7p8IEJsWyef8Q=",
|
"narHash": "sha256-8qxEFpj4dVmIuPn9j9z6NTbU+hrcGjBOvaxTzre5HmM=",
|
||||||
"owner": "ipetkov",
|
"owner": "ipetkov",
|
||||||
"repo": "crane",
|
"repo": "crane",
|
||||||
"rev": "2fb033290bf6b23f226d4c8b32f7f7a16b043d7e",
|
"rev": "01bc1d404a51a0a07e9d8759cd50a7903e218c82",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768127708,
|
"lastModified": 1766902085,
|
||||||
"narHash": "sha256-1Sm77VfZh3mU0F5OqKABNLWxOuDeHIlcFjsXeeiPazs=",
|
"narHash": "sha256-coBu0ONtFzlwwVBzmjacUQwj3G+lybcZ1oeNSQkgC0M=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ffbc9f8cbaacfb331b6017d5a5abb21a492c9a38",
|
"rev": "c0b0e0fddf73fd517c3471e546c0df87a42d53f4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1768186348,
|
"lastModified": 1766976750,
|
||||||
"narHash": "sha256-nkpIe3zkpeoFuOl8xBpexulECsHLQ9Ljg1gW3bPCjSI=",
|
"narHash": "sha256-w+o3AIBI56tzfMJRqRXg9tSXnpQRN5hAT15o2t9rxYw=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "af69e497567a5945a64057717bc9b17c8478097e",
|
"rev": "9fe44e7f05b734a64a01f92fc51ad064fb0a884f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -105,7 +105,6 @@
|
|||||||
fileset = lib.fileset.unions [
|
fileset = lib.fileset.unions [
|
||||||
(craneLib.fileset.commonCargoSources ./.)
|
(craneLib.fileset.commonCargoSources ./.)
|
||||||
./assets
|
./assets
|
||||||
./examples
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|||||||
@@ -85,9 +85,6 @@ buildFunction ({
|
|||||||
install -Dm644 assets/systemd/muscl.service -t "$out/lib/systemd/system"
|
install -Dm644 assets/systemd/muscl.service -t "$out/lib/systemd/system"
|
||||||
substituteInPlace "$out/lib/systemd/system/muscl.service" \
|
substituteInPlace "$out/lib/systemd/system/muscl.service" \
|
||||||
--replace-fail '/usr/bin/muscl-server' "$out/bin/muscl-server"
|
--replace-fail '/usr/bin/muscl-server' "$out/bin/muscl-server"
|
||||||
|
|
||||||
mkdir -p "$out/share/muscl"
|
|
||||||
cp -r examples "$out/share/muscl"
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
|||||||
@@ -27,31 +27,6 @@ in
|
|||||||
}.${level};
|
}.${level};
|
||||||
};
|
};
|
||||||
|
|
||||||
authHandler = lib.mkOption {
|
|
||||||
type = with lib.types; nullOr lines;
|
|
||||||
default = null;
|
|
||||||
description = "Custom authentication handler, written in python";
|
|
||||||
example = ''
|
|
||||||
def process_request(
|
|
||||||
username: str,
|
|
||||||
groups: list[str],
|
|
||||||
resource_type: str,
|
|
||||||
resource: str,
|
|
||||||
) -> bool:
|
|
||||||
if resource_type == "database":
|
|
||||||
if resource.startswith(username) or any(
|
|
||||||
resource.startswith(group) for group in groups
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
elif resource_type == "user":
|
|
||||||
if resource.startswith(username) or any(
|
|
||||||
resource.startswith(group) for group in groups
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = lib.mkOption {
|
settings = lib.mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
type = lib.types.submodule {
|
type = lib.types.submodule {
|
||||||
@@ -180,14 +155,15 @@ in
|
|||||||
systemd.services."muscl" = {
|
systemd.services."muscl" = {
|
||||||
reloadTriggers = [ config.environment.etc."muscl/config.toml".source ];
|
reloadTriggers = [ config.environment.etc."muscl/config.toml".source ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "notify-reload";
|
|
||||||
ExecStart = [
|
ExecStart = [
|
||||||
""
|
""
|
||||||
"${lib.getExe' cfg.package "muscl-server"} ${cfg.logLevel} --systemd --disable-landlock socket-activate"
|
"${lib.getExe' cfg.package "muscl-server"} ${cfg.logLevel} --systemd --disable-landlock socket-activate"
|
||||||
];
|
];
|
||||||
|
|
||||||
ExecReload = "";
|
ExecReload = [
|
||||||
ReloadSignal = "SIGHUP";
|
""
|
||||||
|
"${lib.getExe' pkgs.coreutils "kill"} -HUP $MAINPID"
|
||||||
|
];
|
||||||
|
|
||||||
RuntimeDirectory = "muscl/root-mnt";
|
RuntimeDirectory = "muscl/root-mnt";
|
||||||
RuntimeDirectoryMode = "0700";
|
RuntimeDirectoryMode = "0700";
|
||||||
@@ -216,72 +192,5 @@ in
|
|||||||
++ (lib.optionals (cfg.settings.mysql.host != null) [ "AF_INET" "AF_INET6" ]);
|
++ (lib.optionals (cfg.settings.mysql.host != null) [ "AF_INET" "AF_INET6" ]);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.sockets."muscl-auth-daemon" = lib.mkIf (cfg.authHandler != null) {
|
|
||||||
description = "Authorization daemon for Muscl";
|
|
||||||
wantedBy = [ "sockets.target" ];
|
|
||||||
socketConfig = {
|
|
||||||
ListenStream = "/run/muscl/muscl-auth-daemon.sock";
|
|
||||||
Accept = "no";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services."muscl-auth-daemon" = lib.mkIf (cfg.authHandler != null) {
|
|
||||||
description = "Authorization daemon for Muscl";
|
|
||||||
requires = [ "muscl-auth-daemon.socket" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "notify";
|
|
||||||
ExecStart = let
|
|
||||||
authScript = lib.pipe ../examples/auth_daemon_python/muscl_auth_daemon.py [
|
|
||||||
lib.fileContents
|
|
||||||
(lib.replaceString ''
|
|
||||||
def process_request(
|
|
||||||
username: str,
|
|
||||||
groups: list[str],
|
|
||||||
resource_type: str,
|
|
||||||
resource: str,
|
|
||||||
) -> bool:
|
|
||||||
...
|
|
||||||
'' cfg.authHandler)
|
|
||||||
(pkgs.writers.writePyPy3Bin "muscl-auth-handler.py" { })
|
|
||||||
];
|
|
||||||
in lib.getExe authScript;
|
|
||||||
|
|
||||||
User = "muscl-auth-daemon";
|
|
||||||
Group = "muscl-auth-daemon";
|
|
||||||
DynamicUser = true;
|
|
||||||
|
|
||||||
AmbientCapabilities = [ "" ];
|
|
||||||
CapabilityBoundingSet = [ "" ];
|
|
||||||
DeviceAllow = [ "" ];
|
|
||||||
LockPersonality = true;
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
PrivateDevices = true;
|
|
||||||
PrivateMounts = true;
|
|
||||||
PrivateTmp = "yes";
|
|
||||||
ProcSubset = "pid";
|
|
||||||
ProtectClock = true;
|
|
||||||
ProtectControlGroups = "strict";
|
|
||||||
ProtectHome = true;
|
|
||||||
ProtectHostname = true;
|
|
||||||
ProtectKernelLogs = true;
|
|
||||||
ProtectKernelModules = true;
|
|
||||||
ProtectKernelTunables = true;
|
|
||||||
ProtectProc = "invisible";
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
RemoveIPC = true;
|
|
||||||
UMask = "0777";
|
|
||||||
RestrictNamespaces = true;
|
|
||||||
RestrictRealtime = true;
|
|
||||||
RestrictSUIDSGID = true;
|
|
||||||
SystemCallArchitectures = "native";
|
|
||||||
SocketBindDeny = [ "any" ];
|
|
||||||
SystemCallFilter = [
|
|
||||||
"@system-service"
|
|
||||||
"~@privileged"
|
|
||||||
"~@resources"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,25 +56,6 @@ nixpkgs.lib.nixosSystem {
|
|||||||
enable = true;
|
enable = true;
|
||||||
logLevel = "trace";
|
logLevel = "trace";
|
||||||
createLocalDatabaseUser = true;
|
createLocalDatabaseUser = true;
|
||||||
authHandler = ''
|
|
||||||
def process_request(
|
|
||||||
username: str,
|
|
||||||
groups: list[str],
|
|
||||||
resource_type: str,
|
|
||||||
resource: str,
|
|
||||||
) -> bool:
|
|
||||||
if resource_type == "database":
|
|
||||||
if resource.startswith(username) or any(
|
|
||||||
resource.startswith(group) for group in groups
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
elif resource_type == "user":
|
|
||||||
if resource.startswith(username) or any(
|
|
||||||
resource.startswith(group) for group in groups
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.vim = {
|
programs.vim = {
|
||||||
|
|||||||
@@ -305,6 +305,10 @@ fn main() -> anyhow::Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if handle_manpage_command()?.is_some() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mysql-admutils-compatibility")]
|
#[cfg(feature = "mysql-admutils-compatibility")]
|
||||||
if handle_mysql_admutils_command()?.is_some() {
|
if handle_mysql_admutils_command()?.is_some() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -361,6 +365,48 @@ fn handle_dynamic_completion() -> anyhow::Result<Option<()>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **WARNING:** This function may be run with elevated privileges.
|
||||||
|
fn handle_manpage_command() -> anyhow::Result<Option<()>> {
|
||||||
|
let argv1: Option<String> = std::env::args().nth(1);
|
||||||
|
|
||||||
|
match argv1.as_deref() {
|
||||||
|
Some("generate-manpages") => {
|
||||||
|
#[cfg(feature = "suid-sgid-mode")]
|
||||||
|
if executing_in_suid_sgid_mode()? {
|
||||||
|
use muscl_lib::core::bootstrap::drop_privs;
|
||||||
|
drop_privs()?
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_dir = std::env::args().nth(2).ok_or(anyhow::anyhow!(
|
||||||
|
"Output directory argument missing for manpage generation"
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let output_dir = PathBuf::from(&output_dir);
|
||||||
|
if !output_dir.is_dir() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"Output directory `{:?}` does not exist or is not a directory",
|
||||||
|
output_dir,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut roff = clap_mangen::roff::Roff::new();
|
||||||
|
let man = clap_mangen::Man::new(Args::command());
|
||||||
|
man.render_title(&mut std::io::stdout())?;
|
||||||
|
man.render_name_section(&mut std::io::stdout())?;
|
||||||
|
man.render_synopsis_section(&mut std::io::stdout())?;
|
||||||
|
man.render_subcommands_section(&mut std::io::stdout())?;
|
||||||
|
man.render_options_section(&mut std::io::stdout())?;
|
||||||
|
|
||||||
|
roff.control("SH", ["VERSION"]);
|
||||||
|
roff.text([clap_mangen::roff::roman(AFTER_LONG_HELP)]);
|
||||||
|
roff.to_writer(&mut std::io::stdout())?;
|
||||||
|
|
||||||
|
Ok(Some(()))
|
||||||
|
}
|
||||||
|
_ => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// **WARNING:** This function may be run with elevated privileges.
|
/// **WARNING:** This function may be run with elevated privileges.
|
||||||
fn handle_mysql_admutils_command() -> anyhow::Result<Option<()>> {
|
fn handle_mysql_admutils_command() -> anyhow::Result<Option<()>> {
|
||||||
let argv0 = std::env::args().next().and_then(|s| {
|
let argv0 = std::env::args().next().and_then(|s| {
|
||||||
@@ -376,7 +422,7 @@ fn handle_mysql_admutils_command() -> anyhow::Result<Option<()>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the given command (from the client side) using Tokio.
|
/// Run the given commmand (from the client side) using Tokio.
|
||||||
fn tokio_run_command(
|
fn tokio_run_command(
|
||||||
command: ClientCommand,
|
command: ClientCommand,
|
||||||
server_connection: StdUnixStream,
|
server_connection: StdUnixStream,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ spawn the editor stored in the $EDITOR environment variable.
|
|||||||
(pico will be used if the variable is unset)
|
(pico will be used if the variable is unset)
|
||||||
|
|
||||||
The file should contain one line per user, starting with the
|
The file should contain one line per user, starting with the
|
||||||
username and followed by ten Y/N-values separated by whitespace.
|
username and followed by ten Y/N-values seperated by whitespace.
|
||||||
Lines starting with # are ignored.
|
Lines starting with # are ignored.
|
||||||
|
|
||||||
The Y/N-values corresponds to the following mysql privileges:
|
The Y/N-values corresponds to the following mysql privileges:
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl UnixUser {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn from_environment() -> anyhow::Result<Self> {
|
// pub fn from_enviroment() -> anyhow::Result<Self> {
|
||||||
// let libc_uid = nix::unistd::getuid();
|
// let libc_uid = nix::unistd::getuid();
|
||||||
// UnixUser::from_uid(libc_uid.as_raw())
|
// UnixUser::from_uid(libc_uid.as_raw())
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ impl Supervisor {
|
|||||||
|
|
||||||
let (tx, rx) = broadcast::channel(1);
|
let (tx, rx) = broadcast::channel(1);
|
||||||
|
|
||||||
// TODO: try to detect systemd socket before using the provided socket path
|
// TODO: try to detech systemd socket before using the provided socket path
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
let listener = Arc::new(RwLock::new(match config.socket_path {
|
let listener = Arc::new(RwLock::new(match config.socket_path {
|
||||||
Some(ref path) => create_unix_listener_with_socket_path(path.clone()).await?,
|
Some(ref path) => create_unix_listener_with_socket_path(path.clone()).await?,
|
||||||
@@ -295,15 +295,7 @@ impl Supervisor {
|
|||||||
|
|
||||||
pub async fn reload(&self) -> anyhow::Result<()> {
|
pub async fn reload(&self) -> anyhow::Result<()> {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
sd_notify::notify(
|
sd_notify::notify(false, &[sd_notify::NotifyState::Reloading])?;
|
||||||
false,
|
|
||||||
&[
|
|
||||||
sd_notify::NotifyState::Reloading,
|
|
||||||
sd_notify::NotifyState::monotonic_usec_now()
|
|
||||||
.expect("Failed to get monotonic time to send to systemd while reloading"),
|
|
||||||
sd_notify::NotifyState::Status("Reloading configuration"),
|
|
||||||
],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let previous_config = self.config.lock().await.clone();
|
let previous_config = self.config.lock().await.clone();
|
||||||
self.reload_config().await?;
|
self.reload_config().await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user