merge
This commit is contained in:
commit
3bdf4bc1e1
|
@ -14,7 +14,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -52,7 +52,7 @@ dependencies = [
|
|||
"actix-utils",
|
||||
"ahash 0.8.3",
|
||||
"base64 0.21.0",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"brotli",
|
||||
"bytes",
|
||||
"bytestring",
|
||||
|
@ -609,41 +609,12 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.66.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
|
||||
dependencies = [
|
||||
"bitflags 2.3.2",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.16",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
|
@ -804,15 +775,6 @@ dependencies = [
|
|||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -851,24 +813,13 @@ dependencies = [
|
|||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"clap_derive 3.2.25",
|
||||
"clap_lex 0.2.4",
|
||||
"indexmap",
|
||||
|
@ -895,7 +846,7 @@ checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd"
|
|||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"clap_lex 0.4.1",
|
||||
"strsim",
|
||||
]
|
||||
|
@ -1054,7 +1005,7 @@ version = "0.25.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
|
@ -1560,12 +1511,6 @@ dependencies = [
|
|||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "gloo-timers"
|
||||
version = "0.2.6"
|
||||
|
@ -1578,15 +1523,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobuild"
|
||||
version = "0.1.0-alpha.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e156a4ddbf3deb5e8116946c111413bd9a5679bdc1536c78a60618a7a9ac9e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.19"
|
||||
|
@ -1924,28 +1860,12 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.1.4"
|
||||
|
@ -2071,21 +1991,13 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nebula-ffi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"gobuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"static_assertions",
|
||||
|
@ -2168,7 +2080,7 @@ version = "0.10.52"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
|
@ -2321,12 +2233,6 @@ version = "1.0.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "1.1.1"
|
||||
|
@ -2383,7 +2289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"libc",
|
||||
|
@ -2410,16 +2316,6 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
|
@ -2561,7 +2457,7 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2570,7 +2466,7 @@ version = "0.3.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2723,12 +2619,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
|
@ -2744,7 +2634,7 @@ version = "0.37.19"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
|
@ -2985,7 +2875,7 @@ version = "2.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
@ -3132,12 +3022,6 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.15"
|
||||
|
@ -3265,7 +3149,7 @@ dependencies = [
|
|||
"atoi",
|
||||
"base64 0.13.1",
|
||||
"bigdecimal",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
|
@ -3431,7 +3315,7 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
|||
|
||||
[[package]]
|
||||
name = "tfcli"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"clap 4.2.7",
|
||||
"dirs 5.0.1",
|
||||
|
@ -3446,7 +3330,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tfclient"
|
||||
version = "0.2.0"
|
||||
version = "0.1.9"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"base64-serde",
|
||||
|
@ -3459,7 +3343,6 @@ dependencies = [
|
|||
"hex",
|
||||
"ipnet",
|
||||
"log",
|
||||
"nebula-ffi",
|
||||
"openssl-sys",
|
||||
"reqwest",
|
||||
"serde",
|
||||
|
@ -3750,7 +3633,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "trifid-api"
|
||||
version = "0.1.0"
|
||||
version = "0.1.3"
|
||||
dependencies = [
|
||||
"actix-cors",
|
||||
"actix-request-identifier",
|
||||
|
@ -4073,17 +3956,6 @@ dependencies = [
|
|||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.4.0"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
FROM rust:latest
|
||||
|
||||
COPY trifid-pki /trifid-pki
|
||||
COPY dnapi-rs /dnapi-rs
|
||||
COPY trifid-api /trifid-api
|
||||
|
||||
RUN cd /trifid-api && cargo build --release && cp target/release/trifid-api /bin/trifid-api
|
||||
|
||||
CMD ["/bin/trifid-api"]
|
|
@ -19,8 +19,9 @@ trifid-api feature table:
|
|||
| Feature | trifid-api | api.defined.net |
|
||||
|---------------------------------------------|--------------|-----------------|
|
||||
| Enroll in sites with dnclient | Yes | Yes |
|
||||
| Automatic config update polling by dnclient | Not yet | Yes |
|
||||
| Group-based firewalling | Not yet | Yes |
|
||||
| Automatic config update polling by dnclient | Yes | Yes |
|
||||
| Group-based firewalling | Yes | Yes |
|
||||
| All config features | Yes | Not officially |
|
||||
| SSO authentication | Not yet | Yes |
|
||||
| Open-source server | Yes | No |
|
||||
|
||||
|
@ -33,3 +34,6 @@ tfclient feature table:
|
|||
| Poll the API server for config updates | Yes | Yes |
|
||||
| Secure Ed25519 signing for API communication | Yes | Yes |
|
||||
|
||||
# Documentation
|
||||
|
||||
Documentation work is underway. You can find a link to all documentation on the main project page [here](https://hub.e3t.cc/~core/trifid).
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# tfclient - a Rust DNClient alternative
|
||||
|
||||
TODO
|
|
@ -0,0 +1,13 @@
|
|||
# Help us out - test tfclient on new platforms
|
||||
|
||||
There are [lots](index.md#where-does-trifid-work) of operating systems in which `tfclient` *should* work, but due to a lack of devices, it cannot be tested. If you have a system running one of these devices and want to help out the project, please test tfclient for functionality on your device!
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<strong>Notice</strong>: While tfclient is almost always perfectly safe, there are always risks to running untested software on production machines. Be careful out there!
|
||||
</div>
|
||||
|
||||
Any findings, positive or negative, can be posted straight to [trifid-devel](https://lists.e3t.cc/~core/trifid-devel).
|
||||
|
||||
Thanks!
|
||||
|
||||
[Return home](index.md)
|
|
@ -0,0 +1,9 @@
|
|||
# Why cant tfclient support XXXXX?
|
||||
|
||||
There are limits to what operating systems and architectures tfclient can support. As you may know, tfclient is based upon the [Nebula](https://github.com/slackhq/nebula) project, maintained by Slack. tfclient can only support architectures and operating systems that [Nebula itself supports](https://github.com/slackhq/nebula/releases/).
|
||||
|
||||
In addition, tfclient, being written in Rust, can only function in environments [where Rust compiles well](https://doc.rust-lang.org/nightly/rustc/platform-support.html). For example, this rules out MIPS - `rustc` currently does not function correctly on that architecture, and thus tfclient cannot, and likely never will support that architecture.
|
||||
|
||||
Did Nebula add a new architecture, and we missed it? Rust supports a new architecture in a new release? [Let us know!](https://lists.e3t.cc/~core/trifid-devel) We love adding support for new systems whenever we can.
|
||||
|
||||
Did we miss an architecture? If your architecture is supported by BOTH Nebula and Rust, but you still get `This architecture is not supported yet :(` when trying to build tfclient, we might have missed you - [get in touch](https://lists.e3t.cc/~core/trifid-devel) and we will work with you to get your system supported :D
|
27
index.md
27
index.md
|
@ -15,15 +15,42 @@ The API implementation is tested with the official dnclient implementation, and
|
|||
- [tfcli documentation](./docs/tfcli/index.md)
|
||||
- [tfclient documentation](./docs/tfclient/index.md)
|
||||
- [trifid-api documentation](./docs/trifid-api/index.md)
|
||||
|
||||
|
||||
- [dnapi-rs documentation](https://docs.rs/dnapi-rs)
|
||||
- [dnapi-rs on crates.io](https://crates.io/crates/dnapi-rs)
|
||||
|
||||
|
||||
- [trifid-pki documentation](https://docs.rs/trifid-pki)
|
||||
- [trifid-pki on crates.io](https://crates.io/crates/trifid-pki)
|
||||
|
||||
|
||||
- [trifid git repository](https://git.e3t.cc/~core/trifid)
|
||||
|
||||
|
||||
- [trifid announcements mailing list](https://lists.e3t.cc/~core/trifid-announce)
|
||||
- [trifid patch mailing list](https://lists.e3t.cc/~core/trifid-devel)
|
||||
- [trifid discussion mailing list](https://lists.e3t.cc/~core/trifid-discuss)
|
||||
|
||||
# Where does trifid work?
|
||||
|
||||
| Operating System | trifid-api? |
|
||||
|-------------------------|-----------------------------------------------------------------------------------------|
|
||||
| Windows amd64 | [Yes](docs/tfclient/index.md) [(untested - help wanted!)](docs/tfclient/untested_os.md) |
|
||||
| Windows arm64 | [Yes](docs/tfclient/index.md) [(untested - help wanted!)](docs/tfclient/untested_os.md) |
|
||||
| Darwin (macOS) | [Yes](docs/tfclient/index.md) [(untested - help wanted!)](docs/tfclient/untested_os.md) |
|
||||
| FreeBSD amd64 | [Yes](docs/tfclient/index.md) [(untested - help wanted!)](docs/tfclient/untested_os.md) |
|
||||
| Linux i386 | [Yes](docs/tfclient/index.md) |
|
||||
| Linux amd64 | [Yes](docs/tfclient/index.md) |
|
||||
| Linux armv5 | [Yes](docs/tfclient/index.md) |
|
||||
| Linux armv6 | [Yes](docs/tfclient/index.md) |
|
||||
| Linux armv7 | [Yes](docs/tfclient/index.md) |
|
||||
| Linux aarch64 | [Yes](docs/tfclient/index.md) |
|
||||
| Android | Almost [(help wanted!)](docs/trifid_mobile/help.md) |
|
||||
| iOS | Almost [(help wanted!)](docs/trifid_mobile/help.md) |
|
||||
| Other operating systems | No, and [likely never will be](docs/tfclient/why_not_this_os.md) |
|
||||
|
||||
|
||||
# Get in touch
|
||||
|
||||
Have a question about trifid? Check out the [discussion mailing list](https://lists.e3t.cc/~core/trifid-discuss)! `trifid-discuss` is a mailing list for end-user discussion and questions related to the trifid project.
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
[package]
|
||||
name = "tfcli"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
description = "Command-line client for managing trifid-api"
|
||||
license = "GPL-3.0-or-later"
|
||||
documentation = "https://git.e3t.cc/~core/trifid"
|
||||
homepage = "https://git.e3t.cc/~core/trifid"
|
||||
repository = "https://git.e3t.cc/~core/trifid"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
@ -14,4 +19,4 @@ tokio = { version = "1", features = ["full"] }
|
|||
dirs = "5.0.1"
|
||||
qr2term = "0.3.1"
|
||||
ipnet = "2.7.2"
|
||||
serde_json = "1.0.96"
|
||||
serde_json = "1.0.96"
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::net::{Ipv4Addr, SocketAddrV4};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::{Url};
|
||||
use crate::api::APIErrorResponse;
|
||||
use crate::{HostCommands};
|
||||
use crate::{HostCommands, HostOverrideCommands};
|
||||
|
||||
pub async fn host_main(command: HostCommands, server: Url) -> Result<(), Box<dyn Error>> {
|
||||
match command {
|
||||
|
@ -14,7 +14,12 @@ pub async fn host_main(command: HostCommands, server: Url) -> Result<(), Box<dyn
|
|||
HostCommands::Delete { id } => delete_host(id, server).await,
|
||||
HostCommands::Update { id, listen_port, static_address, name, ip, role } => update_host(id, listen_port, static_address, name, ip, role, server).await,
|
||||
HostCommands::Block { id } => block_host(id, server).await,
|
||||
HostCommands::Enroll { id } => enroll_host(id, server).await
|
||||
HostCommands::Enroll { id } => enroll_host(id, server).await,
|
||||
HostCommands::Overrides { command } => match command {
|
||||
HostOverrideCommands::List { id } => list_overrides(id, server).await,
|
||||
HostOverrideCommands::Set { id, key, boolean, string, numeric } => set_override(id, key, boolean, numeric, string, server).await,
|
||||
HostOverrideCommands::Unset { id, key } => unset_override(id, key, server).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +375,7 @@ pub async fn enroll_host(id: String, server: Url) -> Result<(), Box<dyn Error>>
|
|||
|
||||
let token = format!("{} {}", session_token, auth_token);
|
||||
|
||||
let res = client.post(server.join(&format!("/v1/hosts/{}/enrollment-code", id))?).bearer_auth(token).send().await?;
|
||||
let res = client.post(server.join(&format!("/v1/hosts/{}/enrollment-code", id))?).header("content-length", 0).bearer_auth(token).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: EnrollmentResponse = res.json().await?;
|
||||
|
@ -413,4 +418,223 @@ pub async fn block_host(id: String, server: Url) -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideResponse {
|
||||
pub data: HostConfigOverrideData
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideData {
|
||||
pub overrides: Vec<HostConfigOverrideDataOverride>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideDataOverride {
|
||||
pub key: String,
|
||||
pub value: HostConfigOverrideDataOverrideValue
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum HostConfigOverrideDataOverrideValue {
|
||||
Boolean(bool),
|
||||
Numeric(i64),
|
||||
Other(String)
|
||||
}
|
||||
|
||||
pub async fn list_overrides(id: String, server: Url) -> Result<(), Box<dyn Error>> {
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
// load session token
|
||||
let sess_token_store = dirs::config_dir().unwrap().join("tfcli-session.token");
|
||||
let session_token = fs::read_to_string(&sess_token_store)?;
|
||||
let auth_token_store = dirs::config_dir().unwrap().join("tfcli-auth.token");
|
||||
let auth_token = fs::read_to_string(&auth_token_store)?;
|
||||
|
||||
let token = format!("{} {}", session_token, auth_token);
|
||||
|
||||
let res = client.get(server.join(&format!("/v1/hosts/{}/config-overrides", id))?).bearer_auth(token).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: HostConfigOverrideResponse = res.json().await?;
|
||||
|
||||
for c_override in &resp.data.overrides {
|
||||
println!(" Key: {}", c_override.key);
|
||||
println!("Value: {}", match &c_override.value {
|
||||
HostConfigOverrideDataOverrideValue::Boolean(v) => format!("bool:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Numeric(v) => format!("numeric:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Other(v) => format!("string:{}", v)
|
||||
});
|
||||
}
|
||||
|
||||
if resp.data.overrides.is_empty() {
|
||||
println!("No overrides found");
|
||||
}
|
||||
} else {
|
||||
let resp: APIErrorResponse = res.json().await?;
|
||||
|
||||
eprintln!("[error] Error looking up config overrides: {} {}", resp.errors[0].code, resp.errors[0].message);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SetOverrideRequest {
|
||||
pub overrides: Vec<HostConfigOverrideDataOverride>
|
||||
}
|
||||
|
||||
pub async fn set_override(id: String, key: String, boolean: Option<bool>, numeric: Option<i64>, other: Option<String>, server: Url) -> Result<(), Box<dyn Error>> {
|
||||
if boolean.is_none() && numeric.is_none() && other.is_none() {
|
||||
eprintln!("[error] no value provided: you must provide at least --boolean, --numeric, or --string");
|
||||
std::process::exit(1);
|
||||
} else if boolean.is_some() && numeric.is_some() || boolean.is_some() && other.is_some() || numeric.is_some() && other.is_some() {
|
||||
eprintln!("[error] multiple values provided: you must provide only one of --boolean, --numeric, or --string");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let val;
|
||||
|
||||
if let Some(v) = boolean {
|
||||
val = HostConfigOverrideDataOverrideValue::Boolean(v);
|
||||
} else if let Some(v) = numeric {
|
||||
val = HostConfigOverrideDataOverrideValue::Numeric(v);
|
||||
} else if let Some(v) = other {
|
||||
val = HostConfigOverrideDataOverrideValue::Other(v);
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
// load session token
|
||||
let sess_token_store = dirs::config_dir().unwrap().join("tfcli-session.token");
|
||||
let session_token = fs::read_to_string(&sess_token_store)?;
|
||||
let auth_token_store = dirs::config_dir().unwrap().join("tfcli-auth.token");
|
||||
let auth_token = fs::read_to_string(&auth_token_store)?;
|
||||
|
||||
let token = format!("{} {}", session_token, auth_token);
|
||||
|
||||
let res = client.get(server.join(&format!("/v1/hosts/{}/config-overrides", id))?).bearer_auth(token.clone()).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: HostConfigOverrideResponse = res.json().await?;
|
||||
|
||||
let mut others: Vec<HostConfigOverrideDataOverride> = vec![];
|
||||
|
||||
for c_override in resp.data.overrides {
|
||||
if c_override.key != key {
|
||||
others.push(c_override);
|
||||
}
|
||||
}
|
||||
|
||||
others.push(HostConfigOverrideDataOverride {
|
||||
key,
|
||||
value: val,
|
||||
});
|
||||
|
||||
let res = client.put(server.join(&format!("/v1/hosts/{}/config-overrides", id))?).bearer_auth(token.clone()).json(&SetOverrideRequest {
|
||||
overrides: others,
|
||||
}).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: HostConfigOverrideResponse = res.json().await?;
|
||||
|
||||
for c_override in &resp.data.overrides {
|
||||
println!(" Key: {}", c_override.key);
|
||||
println!("Value: {}", match &c_override.value {
|
||||
HostConfigOverrideDataOverrideValue::Boolean(v) => format!("bool:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Numeric(v) => format!("numeric:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Other(v) => format!("string:{}", v)
|
||||
});
|
||||
}
|
||||
|
||||
if resp.data.overrides.is_empty() {
|
||||
println!("No overrides found");
|
||||
}
|
||||
|
||||
println!("Override set successfully");
|
||||
} else {
|
||||
let resp: APIErrorResponse = res.json().await?;
|
||||
|
||||
eprintln!("[error] Error setting config overrides: {} {}", resp.errors[0].code, resp.errors[0].message);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
} else {
|
||||
let resp: APIErrorResponse = res.json().await?;
|
||||
|
||||
eprintln!("[error] Error setting config overrides: {} {}", resp.errors[0].code, resp.errors[0].message);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn unset_override(id: String, key: String, server: Url) -> Result<(), Box<dyn Error>> {
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
// load session token
|
||||
let sess_token_store = dirs::config_dir().unwrap().join("tfcli-session.token");
|
||||
let session_token = fs::read_to_string(&sess_token_store)?;
|
||||
let auth_token_store = dirs::config_dir().unwrap().join("tfcli-auth.token");
|
||||
let auth_token = fs::read_to_string(&auth_token_store)?;
|
||||
|
||||
let token = format!("{} {}", session_token, auth_token);
|
||||
|
||||
let res = client.get(server.join(&format!("/v1/hosts/{}/config-overrides", id))?).bearer_auth(token.clone()).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: HostConfigOverrideResponse = res.json().await?;
|
||||
|
||||
let mut others: Vec<HostConfigOverrideDataOverride> = vec![];
|
||||
|
||||
for c_override in resp.data.overrides {
|
||||
if c_override.key != key {
|
||||
others.push(c_override);
|
||||
}
|
||||
}
|
||||
|
||||
let res = client.put(server.join(&format!("/v1/hosts/{}/config-overrides", id))?).bearer_auth(token.clone()).json(&SetOverrideRequest {
|
||||
overrides: others,
|
||||
}).send().await?;
|
||||
|
||||
if res.status().is_success() {
|
||||
let resp: HostConfigOverrideResponse = res.json().await?;
|
||||
|
||||
for c_override in &resp.data.overrides {
|
||||
println!(" Key: {}", c_override.key);
|
||||
println!("Value: {}", match &c_override.value {
|
||||
HostConfigOverrideDataOverrideValue::Boolean(v) => format!("bool:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Numeric(v) => format!("numeric:{}", v),
|
||||
HostConfigOverrideDataOverrideValue::Other(v) => format!("string:{}", v)
|
||||
});
|
||||
}
|
||||
|
||||
if resp.data.overrides.is_empty() {
|
||||
println!("No overrides found");
|
||||
}
|
||||
|
||||
println!("Override unset successfully");
|
||||
} else {
|
||||
let resp: APIErrorResponse = res.json().await?;
|
||||
|
||||
eprintln!("[error] Error unsetting config overrides: {} {}", resp.errors[0].code, resp.errors[0].message);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
} else {
|
||||
let resp: APIErrorResponse = res.json().await?;
|
||||
|
||||
eprintln!("[error] Error unsetting config overrides: {} {}", resp.errors[0].code, resp.errors[0].message);
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -203,6 +203,40 @@ pub enum HostCommands {
|
|||
Enroll {
|
||||
#[clap(short, long)]
|
||||
id: String
|
||||
},
|
||||
/// Manage config overrides set on the host
|
||||
Overrides {
|
||||
#[command(subcommand)]
|
||||
command: HostOverrideCommands
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
pub enum HostOverrideCommands {
|
||||
/// List the config overrides set on the host
|
||||
List {
|
||||
#[clap(short, long)]
|
||||
id: String
|
||||
},
|
||||
/// Set a config override on the host
|
||||
Set {
|
||||
#[clap(short, long)]
|
||||
id: String,
|
||||
#[clap(short, long)]
|
||||
key: String,
|
||||
#[clap(short, long)]
|
||||
boolean: Option<bool>,
|
||||
#[clap(short, long)]
|
||||
numeric: Option<i64>,
|
||||
#[clap(short, long)]
|
||||
string: Option<String>
|
||||
},
|
||||
/// Unset a config override on the host
|
||||
Unset {
|
||||
#[clap(short, long)]
|
||||
id: String,
|
||||
#[clap(short, long)]
|
||||
key: String
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,4 +40,4 @@ flate2 = "1.0.25"
|
|||
tar = "0.4.38"
|
||||
hex = "0.4.3"
|
||||
tempfile = "3.4.0"
|
||||
sha2 = "0.10.6"
|
||||
sha2 = "0.10.6"
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
[package]
|
||||
name = "trifid-api"
|
||||
version = "0.1.0"
|
||||
version = "0.1.4"
|
||||
edition = "2021"
|
||||
description = "Pure-rust Defined Networking compatible management server"
|
||||
license = "GPL-3.0-or-later"
|
||||
documentation = "https://git.e3t.cc/~core/trifid"
|
||||
homepage = "https://git.e3t.cc/~core/trifid"
|
||||
repository = "https://git.e3t.cc/~core/trifid"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ use crate::AppState;
|
|||
use ed25519_dalek::SigningKey;
|
||||
use ipnet::Ipv4Net;
|
||||
use log::{debug, error};
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use trifid_api_entities::entity::{
|
||||
firewall_rule, host, host_config_override, host_static_address, network, organization,
|
||||
signing_ca,
|
||||
|
@ -156,7 +157,7 @@ pub async fn generate_config(
|
|||
punchy: Some(NebulaConfigPunchy {
|
||||
punch: true,
|
||||
respond: true,
|
||||
delay: "".to_string(),
|
||||
delay: "1s".to_string(),
|
||||
}),
|
||||
cipher: NebulaConfigCipher::Aes,
|
||||
preferred_ranges: vec![],
|
||||
|
@ -191,7 +192,7 @@ pub async fn generate_config(
|
|||
cidr: None,
|
||||
}]),
|
||||
}),
|
||||
routines: 0,
|
||||
routines: 1,
|
||||
stats: None,
|
||||
local_range: None,
|
||||
};
|
||||
|
@ -203,15 +204,15 @@ pub async fn generate_config(
|
|||
for (key, kv_value) in &info.config_overrides {
|
||||
// split up the key
|
||||
// a.b.c.d = ['a']['b']['c']['d'] = value
|
||||
let key_split = key.split('.');
|
||||
let key_split = key.split('.').collect::<Vec<_>>();
|
||||
|
||||
let mut current_val = &mut value;
|
||||
|
||||
for key_iter in key_split {
|
||||
current_val = current_val.get_mut(key_iter).ok_or("Invalid key-value override")?;
|
||||
for key_iter in &key_split[..key_split.len()-1] {
|
||||
current_val = current_val.as_mapping_mut().unwrap().entry(Value::String(key_iter.to_string())).or_insert(Value::Mapping(Mapping::new()));
|
||||
}
|
||||
|
||||
*current_val = serde_yaml::from_str(kv_value)?;
|
||||
current_val.as_mapping_mut().unwrap().insert(Value::String(key_split[key_split.len()-1].to_string()), serde_yaml::from_str(kv_value)?);
|
||||
}
|
||||
|
||||
let config_str_merged = serde_yaml::to_string(&value)?;
|
||||
|
@ -237,12 +238,12 @@ pub async fn collect_info<'a>(
|
|||
};
|
||||
|
||||
let host_config_overrides = trifid_api_entities::entity::host_config_override::Entity::find()
|
||||
.filter(host_config_override::Column::Id.eq(&host.id))
|
||||
.filter(host_config_override::Column::Host.eq(&host.id))
|
||||
.all(&db.conn)
|
||||
.await?;
|
||||
|
||||
let _host_static_addresses = trifid_api_entities::entity::host_static_address::Entity::find()
|
||||
.filter(host_static_address::Column::Id.eq(&host.id))
|
||||
.filter(host_static_address::Column::Host.eq(&host.id))
|
||||
.all(&db.conn)
|
||||
.await?;
|
||||
|
||||
|
@ -267,8 +268,7 @@ pub async fn collect_info<'a>(
|
|||
|
||||
let hosts = trifid_api_entities::entity::host::Entity::find()
|
||||
.filter(host::Column::Network.eq(&network.id))
|
||||
.filter(host::Column::IsRelay.eq(true))
|
||||
.filter(host::Column::IsLighthouse.eq(true))
|
||||
.filter(Condition::any().add(host::Column::IsRelay.eq(true)).add(host::Column::IsLighthouse.eq(true)))
|
||||
.all(&db.conn)
|
||||
.await?;
|
||||
|
||||
|
@ -356,7 +356,7 @@ pub async fn collect_info<'a>(
|
|||
} else {
|
||||
format!("{}-{}", u.port_range_from, u.port_range_to)
|
||||
}),
|
||||
proto: Some(u.protocol.clone()),
|
||||
proto: Some(u.protocol.clone().to_lowercase()),
|
||||
ca_name: None,
|
||||
ca_sha: None,
|
||||
host: if u.allowed_role_id.is_some() {
|
||||
|
|
|
@ -119,6 +119,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
.service(routes::v2::enroll::enroll)
|
||||
.service(routes::v1::dnclient::dnclient)
|
||||
.service(routes::v2::whoami::whoami)
|
||||
.service(routes::v1::hosts::get_host_overrides)
|
||||
.service(routes::v1::hosts::update_host_overrides)
|
||||
})
|
||||
.bind(CONFIG.server.bind)?
|
||||
.run()
|
||||
|
|
|
@ -266,7 +266,7 @@ pub async fn dnclient(
|
|||
|
||||
ks.signing_keys.push(KSSigningKey {
|
||||
id: ks.current_signing_key + 1,
|
||||
key: SigningKey::generate(&mut OsRng),
|
||||
key: ks.signing_keys[0].key.clone(),
|
||||
});
|
||||
ks.current_signing_key += 1;
|
||||
|
||||
|
@ -322,7 +322,7 @@ pub async fn dnclient(
|
|||
let signing_key = host_in_ks
|
||||
.signing_keys
|
||||
.iter()
|
||||
.find(|u| u.id == (req.counter as u64) - 1)
|
||||
.find(|u| u.id == (req.counter as u64))
|
||||
.unwrap();
|
||||
|
||||
let msg = DoUpdateResponse {
|
||||
|
|
|
@ -76,7 +76,8 @@ use serde::{Deserialize, Serialize};
|
|||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::str::FromStr;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use trifid_api_entities::entity::{host, host_static_address, network, organization};
|
||||
use trifid_api_entities::entity::{host, host_config_override, host_static_address, network, organization};
|
||||
use trifid_api_entities::entity::prelude::HostConfigOverride;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ListHostsRequestOpts {
|
||||
|
@ -2328,3 +2329,495 @@ pub async fn create_host_and_enrollment_code(
|
|||
metadata: CreateHostAndCodeResponseMetadata {},
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideResponse {
|
||||
pub data: HostConfigOverrideData
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideData {
|
||||
pub overrides: Vec<HostConfigOverrideDataOverride>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct HostConfigOverrideDataOverride {
|
||||
pub key: String,
|
||||
pub value: HostConfigOverrideDataOverrideValue
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum HostConfigOverrideDataOverrideValue {
|
||||
Boolean(bool),
|
||||
Numeric(i64),
|
||||
Other(String)
|
||||
}
|
||||
|
||||
#[get("/v1/hosts/{host_id}/config-overrides")]
|
||||
pub async fn get_host_overrides(id: Path<String>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
||||
// For this endpoint, you either need to be a fully authenticated user OR a token with hosts:read
|
||||
let session_info = enforce_2fa(&req_info, &db.conn)
|
||||
.await
|
||||
.unwrap_or(TokenInfo::NotPresent);
|
||||
let api_token_info = enforce_api_token(&req_info, &["hosts:read"], &db.conn)
|
||||
.await
|
||||
.unwrap_or(TokenInfo::NotPresent);
|
||||
|
||||
// If neither are present, throw an error
|
||||
if matches!(session_info, TokenInfo::NotPresent)
|
||||
&& matches!(api_token_info, TokenInfo::NotPresent)
|
||||
{
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message: "This endpoint requires either a fully authenticated user or a token with the hosts:read scope".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If both are present, throw an error
|
||||
if matches!(session_info, TokenInfo::AuthToken(_))
|
||||
&& matches!(api_token_info, TokenInfo::ApiToken(_))
|
||||
{
|
||||
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_AMBIGUOUS_AUTHENTICATION".to_string(),
|
||||
message: "Both a user token and an API token with the proper scope was provided. Please only provide one.".to_string(),
|
||||
path: None
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
let org_id = match api_token_info {
|
||||
TokenInfo::ApiToken(tkn) => tkn.organization,
|
||||
_ => {
|
||||
// we have a session token, which means we have to do a db request to get the organization that this user owns
|
||||
let user = match session_info {
|
||||
TokenInfo::AuthToken(tkn) => tkn.session_info.user,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let org = match organization::Entity::find()
|
||||
.filter(organization::Column::Owner.eq(user.id))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error performing the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(org) = org {
|
||||
org.id
|
||||
} else {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_NO_ORG".to_string(),
|
||||
message: "This user does not own any organizations. Try using an API token instead.".to_string(),
|
||||
path: None
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let net_id;
|
||||
|
||||
let net = match network::Entity::find()
|
||||
.filter(network::Column::Organization.eq(&org_id))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error performing the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(net) = net {
|
||||
net_id = net.id;
|
||||
} else {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_NO_NET".to_string(),
|
||||
message: "This user does not own any networks. Try using an API token instead."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
let host = match host::Entity::find()
|
||||
.filter(host::Column::Id.eq(id.into_inner()))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let host = match host {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message:
|
||||
"This resource does not exist or you do not have permission to access it."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
if host.network != net_id {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message: "This resource does not exist or you do not have permission to access it."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
let config_overrides = match trifid_api_entities::entity::host_config_override::Entity::find().filter(host_config_override::Column::Host.eq(host.id)).all(&db.conn).await {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let overrides: Vec<HostConfigOverrideDataOverride> = config_overrides.iter().map(|u| {
|
||||
let val;
|
||||
if u.value == "true" || u.value == "false" {
|
||||
val = HostConfigOverrideDataOverrideValue::Boolean(u.value == "true");
|
||||
} else if u.value.chars().all(|c| c.is_numeric()) {
|
||||
val = HostConfigOverrideDataOverrideValue::Numeric(u.value.parse().unwrap());
|
||||
} else {
|
||||
val = HostConfigOverrideDataOverrideValue::Other(u.value.clone());
|
||||
}
|
||||
HostConfigOverrideDataOverride {
|
||||
key: u.key.clone(),
|
||||
value: val,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
HttpResponse::Ok().json(HostConfigOverrideResponse {
|
||||
data: HostConfigOverrideData {
|
||||
overrides,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct UpdateOverridesRequest {
|
||||
pub overrides: Vec<HostConfigOverrideDataOverride>
|
||||
}
|
||||
|
||||
#[put("/v1/hosts/{host_id}/config-overrides")]
|
||||
pub async fn update_host_overrides(id: Path<String>, req: Json<UpdateOverridesRequest>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
|
||||
// For this endpoint, you either need to be a fully authenticated user OR a token with hosts:read
|
||||
let session_info = enforce_2fa(&req_info, &db.conn)
|
||||
.await
|
||||
.unwrap_or(TokenInfo::NotPresent);
|
||||
let api_token_info = enforce_api_token(&req_info, &["hosts:read"], &db.conn)
|
||||
.await
|
||||
.unwrap_or(TokenInfo::NotPresent);
|
||||
|
||||
// If neither are present, throw an error
|
||||
if matches!(session_info, TokenInfo::NotPresent)
|
||||
&& matches!(api_token_info, TokenInfo::NotPresent)
|
||||
{
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message: "This endpoint requires either a fully authenticated user or a token with the hosts:read scope".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
// If both are present, throw an error
|
||||
if matches!(session_info, TokenInfo::AuthToken(_))
|
||||
&& matches!(api_token_info, TokenInfo::ApiToken(_))
|
||||
{
|
||||
return HttpResponse::BadRequest().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_AMBIGUOUS_AUTHENTICATION".to_string(),
|
||||
message: "Both a user token and an API token with the proper scope was provided. Please only provide one.".to_string(),
|
||||
path: None
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
let org_id = match api_token_info {
|
||||
TokenInfo::ApiToken(tkn) => tkn.organization,
|
||||
_ => {
|
||||
// we have a session token, which means we have to do a db request to get the organization that this user owns
|
||||
let user = match session_info {
|
||||
TokenInfo::AuthToken(tkn) => tkn.session_info.user,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let org = match organization::Entity::find()
|
||||
.filter(organization::Column::Owner.eq(user.id))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error performing the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(org) = org {
|
||||
org.id
|
||||
} else {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_NO_ORG".to_string(),
|
||||
message: "This user does not own any organizations. Try using an API token instead.".to_string(),
|
||||
path: None
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let net_id;
|
||||
|
||||
let net = match network::Entity::find()
|
||||
.filter(network::Column::Organization.eq(&org_id))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![
|
||||
APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error performing the database request, please try again later.".to_string(),
|
||||
path: None,
|
||||
}
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(net) = net {
|
||||
net_id = net.id;
|
||||
} else {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_NO_NET".to_string(),
|
||||
message: "This user does not own any networks. Try using an API token instead."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
let host = match host::Entity::find()
|
||||
.filter(host::Column::Id.eq(id.into_inner()))
|
||||
.one(&db.conn)
|
||||
.await
|
||||
{
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let host = match host {
|
||||
Some(h) => h,
|
||||
None => {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message:
|
||||
"This resource does not exist or you do not have permission to access it."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
if host.network != net_id {
|
||||
return HttpResponse::Unauthorized().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_UNAUTHORIZED".to_string(),
|
||||
message: "This resource does not exist or you do not have permission to access it."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
let config_overrides = match trifid_api_entities::entity::host_config_override::Entity::find().filter(host_config_override::Column::Host.eq(&host.id)).all(&db.conn).await {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
for c_override in config_overrides {
|
||||
match c_override.delete(&db.conn).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for c_override in &req.overrides {
|
||||
let db_override = host_config_override::Model {
|
||||
id: random_id("override"),
|
||||
key: c_override.key.clone(),
|
||||
value: match &c_override.value {
|
||||
HostConfigOverrideDataOverrideValue::Boolean(v) => v.to_string(),
|
||||
HostConfigOverrideDataOverrideValue::Numeric(v) => v.to_string(),
|
||||
HostConfigOverrideDataOverrideValue::Other(v) => v.clone(),
|
||||
},
|
||||
host: host.id.clone(),
|
||||
};
|
||||
match db_override.into_active_model().insert(&db.conn).await {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let config_overrides = match trifid_api_entities::entity::host_config_override::Entity::find().filter(host_config_override::Column::Host.eq(&host.id)).all(&db.conn).await {
|
||||
Ok(h) => h,
|
||||
Err(e) => {
|
||||
error!("Database error: {}", e);
|
||||
return HttpResponse::InternalServerError().json(APIErrorsResponse {
|
||||
errors: vec![APIError {
|
||||
code: "ERR_DB_ERROR".to_string(),
|
||||
message: "There was an error with the database query. Please try again later."
|
||||
.to_string(),
|
||||
path: None,
|
||||
}],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let overrides: Vec<HostConfigOverrideDataOverride> = config_overrides.iter().map(|u| {
|
||||
let val;
|
||||
if u.value == "true" || u.value == "false" {
|
||||
val = HostConfigOverrideDataOverrideValue::Boolean(u.value == "true");
|
||||
} else if u.value.chars().all(|c| c.is_numeric()) || u.value.starts_with('-') && u.value.chars().collect::<Vec<_>>()[1..].iter().all(|c| c.is_numeric()) {
|
||||
val = HostConfigOverrideDataOverrideValue::Numeric(u.value.parse().unwrap());
|
||||
} else {
|
||||
val = HostConfigOverrideDataOverrideValue::Other(u.value.clone());
|
||||
}
|
||||
HostConfigOverrideDataOverride {
|
||||
key: u.key.clone(),
|
||||
value: val,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
HttpResponse::Ok().json(HostConfigOverrideResponse {
|
||||
data: HostConfigOverrideData {
|
||||
overrides,
|
||||
},
|
||||
})
|
||||
}
|
|
@ -2,6 +2,11 @@
|
|||
name = "trifid_api_entities"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Database entities for trifid-api"
|
||||
license = "GPL-3.0-or-later"
|
||||
documentation = "https://git.e3t.cc/~core/trifid"
|
||||
homepage = "https://git.e3t.cc/~core/trifid"
|
||||
repository = "https://git.e3t.cc/~core/trifid"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
name = "trifid_api_migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
description = "Database migrations for trifid-api"
|
||||
license = "GPL-3.0-or-later"
|
||||
documentation = "https://git.e3t.cc/~core/trifid"
|
||||
homepage = "https://git.e3t.cc/~core/trifid"
|
||||
repository = "https://git.e3t.cc/~core/trifid"
|
||||
|
||||
[lib]
|
||||
name = "trifid_api_migration"
|
||||
|
|
|
@ -1,361 +0,0 @@
|
|||
[[hosts]]
|
||||
id = "host-IPNHZ2XBXJDY2WYOYG7709CBJ8"
|
||||
current_signing_key = 1
|
||||
current_client_key = 2
|
||||
current_config = 2
|
||||
current_cert = 2
|
||||
|
||||
[[hosts.certs]]
|
||||
id = 1
|
||||
|
||||
[hosts.certs.cert]
|
||||
signature = [112, 198, 103, 65, 58, 33, 254, 185, 255, 1, 204, 111, 236, 234, 55, 143, 24, 27, 104, 53, 89, 106, 209, 53, 201, 35, 248, 55, 109, 120, 219, 26, 171, 234, 181, 70, 174, 177, 12, 121, 190, 67, 73, 104, 218, 2, 139, 120, 116, 174, 106, 120, 56, 162, 143, 162, 143, 199, 237, 151, 215, 129, 245, 8]
|
||||
|
||||
[hosts.certs.cert.details]
|
||||
name = "asd"
|
||||
ips = ["10.17.2.3/15"]
|
||||
subnets = []
|
||||
groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"]
|
||||
public_key = [10, 175, 118, 186, 191, 43, 172, 0, 152, 238, 83, 31, 38, 79, 189, 76, 149, 38, 157, 84, 200, 210, 0, 95, 37, 169, 196, 77, 214, 209, 91, 10]
|
||||
is_ca = false
|
||||
issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f"
|
||||
|
||||
[hosts.certs.cert.details.not_before]
|
||||
secs_since_epoch = 1684171628
|
||||
nanos_since_epoch = 68795993
|
||||
|
||||
[hosts.certs.cert.details.not_after]
|
||||
secs_since_epoch = 1716312428
|
||||
nanos_since_epoch = 68796023
|
||||
|
||||
[[hosts.certs]]
|
||||
id = 2
|
||||
|
||||
[hosts.certs.cert]
|
||||
signature = [134, 249, 92, 208, 133, 181, 164, 230, 242, 79, 132, 140, 164, 28, 159, 165, 55, 176, 140, 73, 208, 50, 53, 184, 178, 242, 62, 90, 55, 187, 245, 231, 22, 89, 161, 9, 181, 56, 135, 163, 93, 102, 69, 34, 51, 139, 158, 181, 5, 207, 2, 87, 100, 236, 215, 116, 109, 43, 186, 148, 200, 235, 99, 7]
|
||||
|
||||
[hosts.certs.cert.details]
|
||||
name = "addsd"
|
||||
ips = ["10.17.2.3/15"]
|
||||
subnets = []
|
||||
groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"]
|
||||
public_key = [78, 139, 195, 146, 198, 211, 251, 196, 238, 154, 134, 158, 111, 25, 198, 228, 195, 108, 242, 146, 16, 45, 98, 155, 152, 116, 114, 218, 226, 137, 182, 11]
|
||||
is_ca = false
|
||||
issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f"
|
||||
|
||||
[hosts.certs.cert.details.not_before]
|
||||
secs_since_epoch = 1684171718
|
||||
nanos_since_epoch = 140841799
|
||||
|
||||
[hosts.certs.cert.details.not_after]
|
||||
secs_since_epoch = 1716312518
|
||||
nanos_since_epoch = 140841859
|
||||
|
||||
[[hosts.config]]
|
||||
id = 1
|
||||
|
||||
[hosts.config.config]
|
||||
routines = 0
|
||||
|
||||
[hosts.config.config.pki]
|
||||
ca = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r
|
||||
y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r
|
||||
QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r
|
||||
LCxfFB661cvoq1OZ7G5ZcgY=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
cert = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
CoYBCgNhc2QSCYOExFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZKTks1T0FL\r
|
||||
SFFDVVVWSUw4KOzWiaMGMOyys7IGOiAKr3a6vyusAJjuUx8mT71MlSadVMjSAF8l\r
|
||||
qcRN1tFbCkogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8SQHDGZ0E6\r
|
||||
If65/wHMb+zqN48YG2g1WWrRNckj+DdteNsaq+q1Rq6xDHm+Q0lo2gKLeHSuang4\r
|
||||
oo+ij8ftl9eB9Qg=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
disconnect_invalid = true
|
||||
|
||||
[hosts.config.config.lighthouse]
|
||||
interval = 60
|
||||
|
||||
[hosts.config.config.listen]
|
||||
host = "[::]"
|
||||
read_buffer = 10485760
|
||||
write_buffer = 10485760
|
||||
|
||||
[hosts.config.config.punchy]
|
||||
punch = true
|
||||
respond = true
|
||||
delay = ""
|
||||
|
||||
[hosts.config.config.relay]
|
||||
|
||||
[hosts.config.config.tun]
|
||||
dev = "trifid1"
|
||||
drop_local_broadcast = true
|
||||
drop_multicast = true
|
||||
|
||||
[hosts.config.config.firewall]
|
||||
inbound = []
|
||||
|
||||
[[hosts.config.config.firewall.outbound]]
|
||||
port = "any"
|
||||
proto = "any"
|
||||
host = "any"
|
||||
|
||||
[[hosts.config]]
|
||||
id = 2
|
||||
|
||||
[hosts.config.config]
|
||||
routines = 0
|
||||
|
||||
[hosts.config.config.pki]
|
||||
ca = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r
|
||||
y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r
|
||||
QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r
|
||||
LCxfFB661cvoq1OZ7G5ZcgY=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
cert = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
CogBCgVhZGRzZBIJg4TEUICA+P8PIiRyb2xlOnJvbGUtQTRZVE5CT01DRkpOSzVP\r
|
||||
QUtIUUNVVVZJTDgoxteJowYwxrOzsgY6IE6Lw5LG0/vE7pqGnm8ZxuTDbPKSEC1i\r
|
||||
m5h0ctriibYLSiCaTdfLXDoIawFz8Sa78guFrHiGohKdL4VzrMLiDwnsHxJAhvlc\r
|
||||
0IW1pObyT4SMpByfpTewjEnQMjW4svI+Wje79ecWWaEJtTiHo11mRSIzi561Bc8C\r
|
||||
V2Ts13RtK7qUyOtjBw==\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
disconnect_invalid = true
|
||||
|
||||
[hosts.config.config.lighthouse]
|
||||
interval = 60
|
||||
|
||||
[hosts.config.config.listen]
|
||||
host = "[::]"
|
||||
read_buffer = 10485760
|
||||
write_buffer = 10485760
|
||||
|
||||
[hosts.config.config.punchy]
|
||||
punch = true
|
||||
respond = true
|
||||
delay = ""
|
||||
|
||||
[hosts.config.config.relay]
|
||||
|
||||
[hosts.config.config.tun]
|
||||
dev = "trifid1"
|
||||
drop_local_broadcast = true
|
||||
drop_multicast = true
|
||||
|
||||
[hosts.config.config.firewall]
|
||||
inbound = []
|
||||
|
||||
[[hosts.config.config.firewall.outbound]]
|
||||
port = "any"
|
||||
proto = "any"
|
||||
host = "any"
|
||||
|
||||
[[hosts.signing_keys]]
|
||||
id = 0
|
||||
key = [108, 174, 65, 117, 166, 239, 62, 150, 81, 111, 185, 79, 158, 206, 104, 43, 163, 224, 206, 219, 147, 71, 158, 88, 103, 149, 113, 152, 123, 41, 78, 255]
|
||||
|
||||
[[hosts.signing_keys]]
|
||||
id = 1
|
||||
key = [119, 226, 183, 227, 53, 121, 14, 141, 125, 165, 249, 103, 28, 60, 102, 111, 242, 63, 26, 52, 87, 29, 29, 114, 11, 62, 138, 121, 213, 245, 193, 212]
|
||||
|
||||
[[hosts.client_keys]]
|
||||
id = 1
|
||||
dh_pub = [10, 175, 118, 186, 191, 43, 172, 0, 152, 238, 83, 31, 38, 79, 189, 76, 149, 38, 157, 84, 200, 210, 0, 95, 37, 169, 196, 77, 214, 209, 91, 10]
|
||||
ed_pub = [135, 237, 110, 71, 189, 155, 246, 66, 50, 229, 80, 254, 93, 99, 35, 29, 87, 138, 132, 193, 118, 216, 218, 60, 142, 178, 42, 126, 182, 25, 31, 103]
|
||||
|
||||
[[hosts.client_keys]]
|
||||
id = 2
|
||||
dh_pub = [78, 139, 195, 146, 198, 211, 251, 196, 238, 154, 134, 158, 111, 25, 198, 228, 195, 108, 242, 146, 16, 45, 98, 155, 152, 116, 114, 218, 226, 137, 182, 11]
|
||||
ed_pub = [178, 77, 253, 159, 81, 137, 20, 14, 184, 230, 73, 111, 130, 129, 15, 184, 114, 90, 133, 147, 178, 252, 197, 75, 82, 33, 21, 5, 38, 238, 57, 84]
|
||||
|
||||
[[hosts]]
|
||||
id = "host-2PXIOHLPQA3CQL8O7XD6CXMMRM"
|
||||
current_signing_key = 1
|
||||
current_client_key = 2
|
||||
current_config = 2
|
||||
current_cert = 2
|
||||
|
||||
[[hosts.certs]]
|
||||
id = 1
|
||||
|
||||
[hosts.certs.cert]
|
||||
signature = [160, 205, 80, 112, 16, 205, 155, 249, 221, 26, 47, 128, 2, 59, 15, 102, 153, 174, 61, 35, 207, 233, 42, 242, 212, 28, 133, 40, 189, 1, 234, 67, 24, 109, 152, 248, 130, 96, 48, 104, 69, 0, 178, 30, 103, 76, 33, 179, 216, 92, 191, 89, 6, 236, 136, 216, 9, 208, 189, 16, 140, 132, 209, 2]
|
||||
|
||||
[hosts.certs.cert.details]
|
||||
name = "testhost4"
|
||||
ips = ["10.17.4.2/15"]
|
||||
subnets = []
|
||||
groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"]
|
||||
public_key = [40, 175, 28, 13, 183, 102, 108, 21, 53, 79, 113, 191, 101, 74, 77, 151, 66, 146, 250, 155, 196, 38, 178, 44, 41, 186, 71, 1, 152, 237, 245, 93]
|
||||
is_ca = false
|
||||
issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f"
|
||||
|
||||
[hosts.certs.cert.details.not_before]
|
||||
secs_since_epoch = 1684172253
|
||||
nanos_since_epoch = 219759539
|
||||
|
||||
[hosts.certs.cert.details.not_after]
|
||||
secs_since_epoch = 1716313053
|
||||
nanos_since_epoch = 219759579
|
||||
|
||||
[[hosts.certs]]
|
||||
id = 2
|
||||
|
||||
[hosts.certs.cert]
|
||||
signature = [54, 210, 5, 3, 189, 187, 221, 142, 238, 142, 175, 248, 12, 128, 6, 58, 99, 44, 248, 198, 51, 3, 152, 118, 113, 46, 41, 191, 138, 15, 120, 103, 170, 24, 229, 27, 241, 182, 236, 220, 51, 117, 224, 118, 191, 25, 84, 111, 100, 15, 53, 234, 132, 214, 213, 66, 95, 8, 44, 162, 212, 60, 151, 13]
|
||||
|
||||
[hosts.certs.cert.details]
|
||||
name = "testhost4"
|
||||
ips = ["10.17.4.2/15"]
|
||||
subnets = []
|
||||
groups = ["role:role-A4YTNBOMCFJNK5OAKHQCUUVIL8"]
|
||||
public_key = [4, 249, 63, 6, 25, 145, 63, 132, 106, 48, 243, 192, 249, 159, 185, 160, 196, 146, 24, 7, 241, 160, 121, 122, 212, 249, 19, 213, 158, 105, 142, 86]
|
||||
is_ca = false
|
||||
issuer = "9a4dd7cb5c3a086b0173f126bbf20b85ac7886a2129d2f8573acc2e20f09ec1f"
|
||||
|
||||
[hosts.certs.cert.details.not_before]
|
||||
secs_since_epoch = 1684172313
|
||||
nanos_since_epoch = 739770378
|
||||
|
||||
[hosts.certs.cert.details.not_after]
|
||||
secs_since_epoch = 1716313113
|
||||
nanos_since_epoch = 739770429
|
||||
|
||||
[[hosts.config]]
|
||||
id = 1
|
||||
|
||||
[hosts.config.config]
|
||||
routines = 0
|
||||
|
||||
[hosts.config.config.pki]
|
||||
ca = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r
|
||||
y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r
|
||||
QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r
|
||||
LCxfFB661cvoq1OZ7G5ZcgY=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
cert = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
CowBCgl0ZXN0aG9zdDQSCYKIxFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZK\r
|
||||
Tks1T0FLSFFDVVVWSUw4KN3biaMGMN23s7IGOiAorxwNt2ZsFTVPcb9lSk2XQpL6\r
|
||||
m8QmsiwpukcBmO31XUogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8S\r
|
||||
QKDNUHAQzZv53RovgAI7D2aZrj0jz+kq8tQchSi9AepDGG2Y+IJgMGhFALIeZ0wh\r
|
||||
s9hcv1kG7IjYCdC9EIyE0QI=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
disconnect_invalid = true
|
||||
|
||||
[hosts.config.config.lighthouse]
|
||||
am_lighthouse = true
|
||||
interval = 60
|
||||
|
||||
[hosts.config.config.listen]
|
||||
host = "[::]"
|
||||
port = 5679
|
||||
read_buffer = 10485760
|
||||
write_buffer = 10485760
|
||||
|
||||
[hosts.config.config.punchy]
|
||||
punch = true
|
||||
respond = true
|
||||
delay = ""
|
||||
|
||||
[hosts.config.config.relay]
|
||||
|
||||
[hosts.config.config.tun]
|
||||
dev = "trifid1"
|
||||
drop_local_broadcast = true
|
||||
drop_multicast = true
|
||||
|
||||
[hosts.config.config.firewall]
|
||||
inbound = []
|
||||
|
||||
[[hosts.config.config.firewall.outbound]]
|
||||
port = "any"
|
||||
proto = "any"
|
||||
host = "any"
|
||||
|
||||
[[hosts.config]]
|
||||
id = 2
|
||||
|
||||
[hosts.config.config]
|
||||
routines = 0
|
||||
|
||||
[hosts.config.config.pki]
|
||||
ca = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r
|
||||
y7iEowYwy+2S0AY6II2RV3kVBopKoTe3j+aT1LbZuWTR/5oQGra185GB5W63QAES\r
|
||||
QGRgfmRuJOzhtWwwU4BGMo47uoncMGV41sz1NYcvwmruwhJDaYYJ51DLz3v5bYZV\r
|
||||
LCxfFB661cvoq1OZ7G5ZcgY=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
cert = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
CowBCgl0ZXN0aG9zdDQSCYKIxFCAgPj/DyIkcm9sZTpyb2xlLUE0WVROQk9NQ0ZK\r
|
||||
Tks1T0FLSFFDVVVWSUw4KJnciaMGMJm4s7IGOiAE+T8GGZE/hGow88D5n7mgxJIY\r
|
||||
B/GgeXrU+RPVnmmOVkogmk3Xy1w6CGsBc/Emu/ILhax4hqISnS+Fc6zC4g8J7B8S\r
|
||||
QDbSBQO9u92O7o6v+AyABjpjLPjGMwOYdnEuKb+KD3hnqhjlG/G27NwzdeB2vxlU\r
|
||||
b2QPNeqE1tVCXwgsotQ8lw0=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
disconnect_invalid = true
|
||||
|
||||
[hosts.config.config.lighthouse]
|
||||
am_lighthouse = true
|
||||
interval = 60
|
||||
|
||||
[hosts.config.config.listen]
|
||||
host = "[::]"
|
||||
port = 5677
|
||||
read_buffer = 10485760
|
||||
write_buffer = 10485760
|
||||
|
||||
[hosts.config.config.punchy]
|
||||
punch = true
|
||||
respond = true
|
||||
delay = ""
|
||||
|
||||
[hosts.config.config.relay]
|
||||
|
||||
[hosts.config.config.tun]
|
||||
dev = "trifid1"
|
||||
drop_local_broadcast = true
|
||||
drop_multicast = true
|
||||
|
||||
[hosts.config.config.firewall]
|
||||
inbound = []
|
||||
|
||||
[[hosts.config.config.firewall.outbound]]
|
||||
port = "any"
|
||||
proto = "any"
|
||||
host = "any"
|
||||
|
||||
[[hosts.signing_keys]]
|
||||
id = 0
|
||||
key = [255, 84, 221, 121, 87, 225, 7, 12, 236, 8, 209, 175, 98, 20, 119, 146, 92, 177, 79, 121, 24, 243, 247, 113, 106, 212, 183, 155, 208, 55, 219, 135]
|
||||
|
||||
[[hosts.signing_keys]]
|
||||
id = 1
|
||||
key = [98, 159, 193, 58, 183, 156, 75, 17, 70, 103, 112, 6, 71, 197, 167, 152, 99, 210, 199, 40, 49, 13, 101, 72, 57, 34, 221, 237, 142, 29, 144, 175]
|
||||
|
||||
[[hosts.client_keys]]
|
||||
id = 1
|
||||
dh_pub = [40, 175, 28, 13, 183, 102, 108, 21, 53, 79, 113, 191, 101, 74, 77, 151, 66, 146, 250, 155, 196, 38, 178, 44, 41, 186, 71, 1, 152, 237, 245, 93]
|
||||
ed_pub = [247, 172, 97, 223, 43, 24, 248, 133, 118, 219, 227, 72, 95, 25, 167, 179, 115, 225, 73, 211, 161, 216, 95, 140, 151, 59, 118, 39, 122, 136, 144, 245]
|
||||
|
||||
[[hosts.client_keys]]
|
||||
id = 2
|
||||
dh_pub = [4, 249, 63, 6, 25, 145, 63, 132, 106, 48, 243, 192, 249, 159, 185, 160, 196, 146, 24, 7, 241, 160, 121, 122, 212, 249, 19, 213, 158, 105, 142, 86]
|
||||
ed_pub = [55, 82, 153, 75, 220, 207, 87, 221, 50, 200, 77, 9, 242, 136, 64, 91, 60, 96, 31, 100, 58, 162, 150, 147, 109, 109, 117, 188, 164, 217, 248, 140]
|
|
@ -0,0 +1,98 @@
|
|||
[[hosts]]
|
||||
id = "host-CAJDSM36900G2MFGFNIODZUG2G"
|
||||
current_signing_key = 0
|
||||
current_client_key = 1
|
||||
current_config = 1
|
||||
current_cert = 1
|
||||
|
||||
[[hosts.certs]]
|
||||
id = 1
|
||||
|
||||
[hosts.certs.cert]
|
||||
signature = [254, 145, 36, 202, 32, 234, 248, 2, 147, 188, 207, 151, 147, 246, 100, 22, 114, 174, 221, 91, 62, 0, 48, 23, 106, 196, 75, 27, 116, 203, 68, 41, 110, 118, 85, 76, 230, 19, 128, 163, 134, 96, 121, 9, 227, 100, 174, 173, 144, 145, 149, 79, 189, 252, 126, 4, 113, 231, 141, 69, 77, 108, 48, 4]
|
||||
|
||||
[hosts.certs.cert.details]
|
||||
name = "Test Host"
|
||||
ips = ["10.16.1.1/15"]
|
||||
subnets = []
|
||||
groups = ["role:role-IRN57I1D5L3EOI3CDDU2TNBS5W"]
|
||||
public_key = [43, 106, 145, 119, 55, 49, 4, 83, 171, 182, 60, 167, 213, 135, 126, 129, 148, 82, 15, 219, 155, 146, 132, 112, 141, 147, 46, 131, 207, 175, 199, 15]
|
||||
is_ca = false
|
||||
issuer = "90e0d7de2b241f3cdd7005e392f5c9e45277e2735edf90602424cbec786b6f32"
|
||||
|
||||
[hosts.certs.cert.details.not_before]
|
||||
secs_since_epoch = 1687446533
|
||||
nanos_since_epoch = 957200472
|
||||
|
||||
[hosts.certs.cert.details.not_after]
|
||||
secs_since_epoch = 1719587333
|
||||
nanos_since_epoch = 957200502
|
||||
|
||||
[[hosts.config]]
|
||||
id = 1
|
||||
|
||||
[hosts.config.config.pki]
|
||||
ca = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
Cl0KK2NvcmVAY29yZWRvZXMuZGV2J3MgT3JnYW5pemF0aW9uIFNpZ25pbmcgQ0Eo\r
|
||||
sN2upAYwsJK90QY6IHetWlUyvE9ka3Q4OFRaJGeOLH98I5uqEwO0temq88RJQAES\r
|
||||
QG7FI2jb0M83FUYpqX70a4DlQA4EvsyjuOiDp2gm0jn5lgaPe3rZbuYuJ114zSO4\r
|
||||
9QZKdFiTpeGoZkaikJJz0ws=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
cert = """
|
||||
-----BEGIN NEBULA CERTIFICATE-----\r
|
||||
CowBCglUZXN0IEhvc3QSCYGCwFCAgPj/DyIkcm9sZTpyb2xlLUlSTjU3STFENUwz\r
|
||||
RU9JM0NERFUyVE5CUzVXKIXI0aQGMIWk+7MGOiArapF3NzEEU6u2PKfVh36BlFIP\r
|
||||
25uShHCNky6Dz6/HD0ogkODX3iskHzzdcAXjkvXJ5FJ34nNe35BgJCTL7HhrbzIS\r
|
||||
QP6RJMog6vgCk7zPl5P2ZBZyrt1bPgAwF2rESxt0y0QpbnZVTOYTgKOGYHkJ42Su\r
|
||||
rZCRlU+9/H4EceeNRU1sMAQ=\r
|
||||
-----END NEBULA CERTIFICATE-----\r
|
||||
"""
|
||||
disconnect_invalid = true
|
||||
|
||||
[hosts.config.config.lighthouse]
|
||||
interval = 60
|
||||
|
||||
[hosts.config.config.listen]
|
||||
host = "[::]"
|
||||
read_buffer = 10485760
|
||||
write_buffer = 10485760
|
||||
|
||||
[hosts.config.config.punchy]
|
||||
punch = true
|
||||
respond = true
|
||||
|
||||
[hosts.config.config.relay]
|
||||
|
||||
[hosts.config.config.tun]
|
||||
dev = "trifid1"
|
||||
drop_local_broadcast = true
|
||||
drop_multicast = true
|
||||
|
||||
[[hosts.config.config.firewall.inbound]]
|
||||
port = "any"
|
||||
proto = "icmp"
|
||||
host = "any"
|
||||
|
||||
[[hosts.config.config.firewall.outbound]]
|
||||
port = "any"
|
||||
proto = "any"
|
||||
host = "any"
|
||||
|
||||
[hosts.config.config.stats]
|
||||
type = "prometheus"
|
||||
listen = "0.0.0.0:8788"
|
||||
path = "/metrics"
|
||||
interval = "10s"
|
||||
message_metrics = true
|
||||
lighthouse_metrics = true
|
||||
|
||||
[[hosts.signing_keys]]
|
||||
id = 0
|
||||
key = [23, 88, 206, 16, 216, 58, 12, 80, 3, 178, 254, 16, 93, 137, 109, 69, 27, 111, 30, 32, 27, 194, 171, 200, 109, 69, 29, 45, 199, 174, 119, 46]
|
||||
|
||||
[[hosts.client_keys]]
|
||||
id = 1
|
||||
dh_pub = [43, 106, 145, 119, 55, 49, 4, 83, 171, 182, 60, 167, 213, 135, 126, 129, 148, 82, 15, 219, 155, 146, 132, 112, 141, 147, 46, 131, 207, 175, 199, 15]
|
||||
ed_pub = [62, 181, 68, 68, 230, 78, 207, 233, 92, 252, 148, 118, 38, 84, 233, 54, 98, 220, 174, 146, 240, 37, 197, 19, 254, 137, 181, 241, 240, 83, 14, 74]
|
Loading…
Reference in New Issue