Packaging: the binary and package are inbuxa, INBUXA_* settings with STALWART_* fallback
- crates/main: package and [[bin]] renamed to inbuxa; homepage inbuxa.org; license AGPL-3.0-only (upstream is dual; the fork takes the AGPL). - types::branding::env_var reads INBUXA_<name>, falling back to STALWART_<name> with a warning, for all nine server settings. STALWART_APP_ and STALWART_SPAM_* storage keys are unchanged. - New-install default paths /var/lib/inbuxa and /var/log/inbuxa. - Dockerfiles, systemd unit, launchd plist and AppArmor profile renamed. - Upstream's .github moved to .github-upstream so none of it runs. - install.sh stubbed: upstream's would install Stalwart. - Two missed brand strings: the SMTP Received header and the utils user agent.
This commit is contained in:
Generated
+32
-32
@@ -3923,6 +3923,38 @@ dependencies = [
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inbuxa"
|
||||
version = "0.16.22"
|
||||
dependencies = [
|
||||
"common",
|
||||
"coordinator",
|
||||
"dav",
|
||||
"directory",
|
||||
"email",
|
||||
"groupware",
|
||||
"http 0.16.22",
|
||||
"http_proto",
|
||||
"imap",
|
||||
"jmap",
|
||||
"managesieve",
|
||||
"migration",
|
||||
"pop3",
|
||||
"registry",
|
||||
"rustls",
|
||||
"scim",
|
||||
"services",
|
||||
"smtp",
|
||||
"smtp-proto",
|
||||
"spam-filter",
|
||||
"store",
|
||||
"tikv-jemallocator",
|
||||
"tokio",
|
||||
"trc",
|
||||
"types",
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "include-flate"
|
||||
version = "0.3.4"
|
||||
@@ -8222,38 +8254,6 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "stalwart"
|
||||
version = "0.16.22"
|
||||
dependencies = [
|
||||
"common",
|
||||
"coordinator",
|
||||
"dav",
|
||||
"directory",
|
||||
"email",
|
||||
"groupware",
|
||||
"http 0.16.22",
|
||||
"http_proto",
|
||||
"imap",
|
||||
"jmap",
|
||||
"managesieve",
|
||||
"migration",
|
||||
"pop3",
|
||||
"registry",
|
||||
"rustls",
|
||||
"scim",
|
||||
"services",
|
||||
"smtp",
|
||||
"smtp-proto",
|
||||
"spam-filter",
|
||||
"store",
|
||||
"tikv-jemallocator",
|
||||
"tokio",
|
||||
"trc",
|
||||
"types",
|
||||
"utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
||||
+14
-14
@@ -21,7 +21,7 @@ RUN rustup target add "$(cat /target.txt)"
|
||||
COPY --from=planner /recipe.json /recipe.json
|
||||
RUN RUSTFLAGS="$(cat /flags.txt)" cargo chef cook --target "$(cat /target.txt)" --release --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" --recipe-path /recipe.json
|
||||
COPY . .
|
||||
RUN RUSTFLAGS="$(cat /flags.txt)" cargo build --target "$(cat /target.txt)" --release -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
|
||||
RUN RUSTFLAGS="$(cat /flags.txt)" cargo build --target "$(cat /target.txt)" --release -p inbuxa --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
|
||||
RUN mv "/build/target/$(cat /target.txt)/release" "/output"
|
||||
|
||||
FROM docker.io/debian:trixie-slim
|
||||
@@ -29,18 +29,18 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates curl libcap2-bin && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
groupadd -r -g 2000 stalwart && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M stalwart && \
|
||||
mkdir -p /etc/stalwart /var/lib/stalwart && \
|
||||
chown stalwart:stalwart /etc/stalwart /var/lib/stalwart
|
||||
COPY --from=builder --chmod=0755 /output/stalwart /usr/local/bin/stalwart
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/stalwart
|
||||
USER stalwart
|
||||
WORKDIR /var/lib/stalwart
|
||||
VOLUME ["/etc/stalwart", "/var/lib/stalwart"]
|
||||
groupadd -r -g 2000 inbuxa && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M inbuxa && \
|
||||
mkdir -p /etc/inbuxa /var/lib/inbuxa && \
|
||||
chown inbuxa:inbuxa /etc/inbuxa /var/lib/inbuxa
|
||||
COPY --from=builder --chmod=0755 /output/inbuxa /usr/local/bin/inbuxa
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/inbuxa
|
||||
USER inbuxa
|
||||
WORKDIR /var/lib/inbuxa
|
||||
VOLUME ["/etc/inbuxa", "/var/lib/inbuxa"]
|
||||
EXPOSE 443 25 110 587 465 143 993 995 4190 8080
|
||||
ENV STALWART_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
ENV INBUXA_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$STALWART_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/stalwart"]
|
||||
CMD ["--config", "/etc/stalwart/config.json"]
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$INBUXA_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/inbuxa"]
|
||||
CMD ["--config", "/etc/inbuxa/config.json"]
|
||||
|
||||
+32
-32
@@ -108,7 +108,7 @@ RUN \
|
||||
--mount=type=cache,target=/usr/local/cargo/git \
|
||||
source /env-cargo && \
|
||||
if [ ! -z "${FDB_ARCH}" ]; then \
|
||||
RUSTFLAGS="-L /usr/lib" cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats"; \
|
||||
RUSTFLAGS="-L /usr/lib" cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p inbuxa --no-default-features --features "foundationdb s3 redis nats"; \
|
||||
fi
|
||||
RUN \
|
||||
--mount=type=secret,id=ACTIONS_RESULTS_URL,env=ACTIONS_RESULTS_URL \
|
||||
@@ -116,7 +116,7 @@ RUN \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/usr/local/cargo/git \
|
||||
source /env-cargo && \
|
||||
cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
|
||||
cargo chef cook --recipe-path recipe.json --zigbuild --release --target ${TARGET} -p inbuxa --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats"
|
||||
# Copy the source code
|
||||
COPY . .
|
||||
ENV RUSTC_WRAPPER="sccache" \
|
||||
@@ -129,8 +129,8 @@ RUN \
|
||||
--mount=type=cache,target=/usr/local/cargo/git \
|
||||
source /env-cargo && \
|
||||
if [ ! -z "${FDB_ARCH}" ]; then \
|
||||
RUSTFLAGS="-L /usr/lib" cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "foundationdb s3 redis nats" && \
|
||||
mv /app/target/${TARGET}/release/stalwart /app/artifact/stalwart-foundationdb; \
|
||||
RUSTFLAGS="-L /usr/lib" cargo zigbuild --release --target ${TARGET} -p inbuxa --no-default-features --features "foundationdb s3 redis nats" && \
|
||||
mv /app/target/${TARGET}/release/inbuxa /app/artifact/inbuxa-foundationdb; \
|
||||
fi
|
||||
# Build generic version
|
||||
RUN \
|
||||
@@ -139,8 +139,8 @@ RUN \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/usr/local/cargo/git \
|
||||
source /env-cargo && \
|
||||
cargo zigbuild --release --target ${TARGET} -p stalwart --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" && \
|
||||
mv /app/target/${TARGET}/release/stalwart /app/artifact/stalwart
|
||||
cargo zigbuild --release --target ${TARGET} -p inbuxa --no-default-features --features "sqlite postgres mysql rocks s3 redis azure nats" && \
|
||||
mv /app/target/${TARGET}/release/inbuxa /app/artifact/inbuxa
|
||||
|
||||
# *****************
|
||||
# Binary stage
|
||||
@@ -156,21 +156,21 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates curl tzdata libcap2-bin && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
groupadd -r -g 2000 stalwart && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M stalwart && \
|
||||
mkdir -p /etc/stalwart /var/lib/stalwart && \
|
||||
chown stalwart:stalwart /etc/stalwart /var/lib/stalwart
|
||||
COPY --from=builder --chmod=0755 /app/artifact/stalwart /usr/local/bin/stalwart
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/stalwart
|
||||
USER stalwart
|
||||
WORKDIR /var/lib/stalwart
|
||||
VOLUME ["/etc/stalwart", "/var/lib/stalwart"]
|
||||
groupadd -r -g 2000 inbuxa && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M inbuxa && \
|
||||
mkdir -p /etc/inbuxa /var/lib/inbuxa && \
|
||||
chown inbuxa:inbuxa /etc/inbuxa /var/lib/inbuxa
|
||||
COPY --from=builder --chmod=0755 /app/artifact/inbuxa /usr/local/bin/inbuxa
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/inbuxa
|
||||
USER inbuxa
|
||||
WORKDIR /var/lib/inbuxa
|
||||
VOLUME ["/etc/inbuxa", "/var/lib/inbuxa"]
|
||||
EXPOSE 443 25 110 587 465 143 993 995 4190 8080
|
||||
ENV STALWART_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
ENV INBUXA_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$STALWART_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/stalwart"]
|
||||
CMD ["--config", "/etc/stalwart/config.json"]
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$INBUXA_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/inbuxa"]
|
||||
CMD ["--config", "/etc/inbuxa/config.json"]
|
||||
|
||||
# *****************
|
||||
# Runtime image for musl targets
|
||||
@@ -178,18 +178,18 @@ CMD ["--config", "/etc/stalwart/config.json"]
|
||||
FROM --platform=$TARGETPLATFORM alpine AS musl
|
||||
RUN apk add --update --no-cache ca-certificates curl tzdata libcap && \
|
||||
rm -rf /var/cache/apk/* && \
|
||||
addgroup -S -g 2000 stalwart && \
|
||||
adduser -S -D -H -u 2000 -G stalwart -s /sbin/nologin stalwart && \
|
||||
mkdir -p /etc/stalwart /var/lib/stalwart && \
|
||||
chown stalwart:stalwart /etc/stalwart /var/lib/stalwart
|
||||
COPY --from=builder --chmod=0755 /app/artifact/stalwart /usr/local/bin/stalwart
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/stalwart
|
||||
USER stalwart
|
||||
WORKDIR /var/lib/stalwart
|
||||
VOLUME ["/etc/stalwart", "/var/lib/stalwart"]
|
||||
addgroup -S -g 2000 inbuxa && \
|
||||
adduser -S -D -H -u 2000 -G inbuxa -s /sbin/nologin inbuxa && \
|
||||
mkdir -p /etc/inbuxa /var/lib/inbuxa && \
|
||||
chown inbuxa:inbuxa /etc/inbuxa /var/lib/inbuxa
|
||||
COPY --from=builder --chmod=0755 /app/artifact/inbuxa /usr/local/bin/inbuxa
|
||||
RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/inbuxa
|
||||
USER inbuxa
|
||||
WORKDIR /var/lib/inbuxa
|
||||
VOLUME ["/etc/inbuxa", "/var/lib/inbuxa"]
|
||||
EXPOSE 443 25 110 587 465 143 993 995 4190 8080
|
||||
ENV STALWART_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
ENV INBUXA_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$STALWART_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/stalwart"]
|
||||
CMD ["--config", "/etc/stalwart/config.json"]
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$INBUXA_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/inbuxa"]
|
||||
CMD ["--config", "/etc/inbuxa/config.json"]
|
||||
|
||||
+14
-14
@@ -53,28 +53,28 @@ COPY Cargo.lock .
|
||||
COPY crates/ crates/
|
||||
COPY resources/ resources/
|
||||
COPY tests/ tests/
|
||||
RUN cargo build -p stalwart --no-default-features --features "foundationdb s3 redis azure nats" --release
|
||||
RUN cargo build -p inbuxa --no-default-features --features "foundationdb s3 redis azure nats" --release
|
||||
|
||||
FROM debian:trixie-slim AS runtime
|
||||
|
||||
COPY --from=builder --chmod=0755 /app/target/release/stalwart /usr/local/bin/stalwart
|
||||
COPY --from=builder --chmod=0755 /app/target/release/inbuxa /usr/local/bin/inbuxa
|
||||
COPY --from=builder /usr/lib/libfdb_c.so /usr/lib/libfdb_c.so
|
||||
RUN export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates curl libcap2-bin && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
groupadd -r -g 2000 stalwart && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M stalwart && \
|
||||
mkdir -p /etc/stalwart /var/lib/stalwart && \
|
||||
chown stalwart:stalwart /etc/stalwart /var/lib/stalwart && \
|
||||
setcap 'cap_net_bind_service=+ep' /usr/local/bin/stalwart
|
||||
groupadd -r -g 2000 inbuxa && \
|
||||
useradd -r -u 2000 -g 2000 -s /usr/sbin/nologin -M inbuxa && \
|
||||
mkdir -p /etc/inbuxa /var/lib/inbuxa && \
|
||||
chown inbuxa:inbuxa /etc/inbuxa /var/lib/inbuxa && \
|
||||
setcap 'cap_net_bind_service=+ep' /usr/local/bin/inbuxa
|
||||
|
||||
USER stalwart
|
||||
WORKDIR /var/lib/stalwart
|
||||
VOLUME ["/etc/stalwart", "/var/lib/stalwart"]
|
||||
USER inbuxa
|
||||
WORKDIR /var/lib/inbuxa
|
||||
VOLUME ["/etc/inbuxa", "/var/lib/inbuxa"]
|
||||
EXPOSE 443 25 110 587 465 143 993 995 4190 8080
|
||||
ENV STALWART_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
ENV INBUXA_HEALTHCHECK_URL=https://127.0.0.1:443/healthz/live
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$STALWART_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/stalwart"]
|
||||
CMD ["--config", "/etc/stalwart/config.json"]
|
||||
CMD curl -fsSk -H "X-Forwarded-For: 127.0.0.1" "$INBUXA_HEALTHCHECK_URL" || curl -fsS -H "X-Forwarded-For: 127.0.0.1" http://127.0.0.1:8080/healthz/live || exit 1
|
||||
ENTRYPOINT ["/usr/local/bin/inbuxa"]
|
||||
CMD ["--config", "/etc/inbuxa/config.json"]
|
||||
|
||||
@@ -45,11 +45,15 @@ The report for every import is in `docs/fork/strip-reports/`. See
|
||||
## Building
|
||||
|
||||
```bash
|
||||
cargo build --release -p stalwart
|
||||
cargo build --release -p inbuxa # the binary is target/release/inbuxa
|
||||
docker build -t inbuxa . # or the container image
|
||||
```
|
||||
|
||||
The binary and package are still named `stalwart` while the packaging is
|
||||
reworked.
|
||||
Settings are read from `INBUXA_*` environment variables. An existing Stalwart
|
||||
install's `STALWART_*` variables still work, with a warning to rename them.
|
||||
New installs keep their data in `/var/lib/inbuxa` and logs in
|
||||
`/var/log/inbuxa`. Existing installs keep the paths their configuration
|
||||
already names, so none of their data moves.
|
||||
|
||||
## License and credits
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ impl Listeners {
|
||||
bind: Map::new(vec![
|
||||
SocketAddr::from_str(&format!(
|
||||
"[::]:{}",
|
||||
std::env::var("STALWART_RECOVERY_MODE_PORT")
|
||||
types::branding::env_var("RECOVERY_MODE_PORT")
|
||||
.ok()
|
||||
.and_then(|p| p.parse::<u16>().ok())
|
||||
.unwrap_or(8080)
|
||||
|
||||
@@ -503,7 +503,7 @@ impl Tracers {
|
||||
}
|
||||
} else {
|
||||
// Add default tracer if none were found
|
||||
let level = std::env::var("STALWART_RECOVERY_MODE_LOG_LEVEL")
|
||||
let level = types::branding::env_var("RECOVERY_MODE_LOG_LEVEL")
|
||||
.ok()
|
||||
.and_then(|level| Level::from_str(&level).ok())
|
||||
.unwrap_or(Level::Info);
|
||||
|
||||
@@ -43,7 +43,7 @@ const HELP: &str = concat!(
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
r#"
|
||||
|
||||
Usage: stalwart [OPTIONS]
|
||||
Usage: inbuxa [OPTIONS]
|
||||
|
||||
Options:
|
||||
-c, --config <PATH> Start server with the specified configuration file
|
||||
|
||||
@@ -529,7 +529,7 @@ async fn insert_safe_defaults(bp: &mut Bootstrap) -> trc::Result<()> {
|
||||
ansi: false,
|
||||
prefix: "stalwart.log".into(),
|
||||
rotate: LogRotateFrequency::Daily,
|
||||
path: "/var/log/stalwart".into(),
|
||||
path: "/var/log/inbuxa".into(),
|
||||
..Default::default()
|
||||
})
|
||||
.into(),
|
||||
|
||||
@@ -657,7 +657,7 @@ fn map_dns_server(dns_server: &DnsServerBootstrap) -> Option<registry::schema::s
|
||||
const DEFAULT_DATA_PATH: &str = if cfg!(target_os = "freebsd") {
|
||||
"/var/db/stalwart/"
|
||||
} else {
|
||||
"/var/lib/stalwart/"
|
||||
"/var/lib/inbuxa/"
|
||||
};
|
||||
|
||||
fn build_default_bootstrap(server: &Server) -> Bootstrap {
|
||||
@@ -676,7 +676,7 @@ fn build_default_bootstrap(server: &Server) -> Bootstrap {
|
||||
in_memory_store: InMemoryStore::Default,
|
||||
directory: DirectoryBootstrap::Internal,
|
||||
tracer: Tracer::Log(TracerLog {
|
||||
path: "/var/log/stalwart/".to_string(),
|
||||
path: "/var/log/inbuxa/".to_string(),
|
||||
prefix: "stalwart".to_string(),
|
||||
ansi: true,
|
||||
enable: true,
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
[package]
|
||||
name = "stalwart"
|
||||
name = "inbuxa"
|
||||
description = "INBUXA Mail and Collaboration Server, a fork of Stalwart"
|
||||
authors = [ "Stalwart Labs LLC <[email protected]>"]
|
||||
repository = "https://github.com/stalwartlabs/stalwart"
|
||||
homepage = "https://stalw.art"
|
||||
homepage = "https://inbuxa.org"
|
||||
keywords = ["imap", "jmap", "smtp", "email", "mail", "webdav", "server"]
|
||||
categories = ["email"]
|
||||
license = "AGPL-3.0-only OR LicenseRef-SEL"
|
||||
# Upstream offers AGPL-3.0-only OR LicenseRef-SEL; INBUXA takes the AGPL only.
|
||||
license = "AGPL-3.0-only"
|
||||
version = "0.16.22"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "stalwart"
|
||||
name = "inbuxa"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -4143,7 +4143,7 @@ impl Default for Bootstrap {
|
||||
request_tls_certificate: true,
|
||||
generate_dkim_keys: true,
|
||||
data_store: DataStore::RocksDb(RocksDbStore {
|
||||
path: "/var/lib/stalwart/".to_string(),
|
||||
path: "/var/lib/inbuxa/".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
blob_store: BlobStore::Default,
|
||||
@@ -4151,7 +4151,7 @@ impl Default for Bootstrap {
|
||||
in_memory_store: InMemoryStore::Default,
|
||||
directory: DirectoryBootstrap::Internal,
|
||||
tracer: Tracer::Log(TracerLog {
|
||||
path: "/var/log/stalwart/".to_string(),
|
||||
path: "/var/log/inbuxa/".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
dns_server: DnsServerBootstrap::Manual,
|
||||
|
||||
@@ -1051,7 +1051,7 @@ impl<T: SessionStream> Session<T> {
|
||||
}
|
||||
headers.extend_from_slice(b"by ");
|
||||
headers.extend_from_slice(self.hostname.as_bytes());
|
||||
headers.extend_from_slice(b" (Stalwart SMTP) with ");
|
||||
headers.extend_from_slice(concat!(" (", types::brand!(), " SMTP) with ").as_bytes());
|
||||
headers.extend_from_slice(match (self.stream.is_tls(), !self.is_authenticated()) {
|
||||
(true, true) => b"ESMTPS",
|
||||
(true, false) => b"ESMTPSA",
|
||||
|
||||
@@ -31,18 +31,18 @@ impl RegistryStore {
|
||||
.collect::<String>();
|
||||
eprintln!();
|
||||
eprintln!("════════════════════════════════════════════════════════════");
|
||||
eprintln!("🔑 Stalwart bootstrap mode - temporary administrator account");
|
||||
eprintln!("🔑 INBUXA bootstrap mode - temporary administrator account");
|
||||
eprintln!();
|
||||
eprintln!(" username: admin");
|
||||
eprintln!(" password: {password}");
|
||||
eprintln!();
|
||||
eprintln!("Use these credentials to complete the initial setup at the");
|
||||
eprintln!("/admin web UI. Once setup is done, Stalwart will provision a");
|
||||
eprintln!("/admin web UI. Once setup is done, the server will provision a");
|
||||
eprintln!("permanent administrator and this temporary account will no");
|
||||
eprintln!("longer apply.");
|
||||
eprintln!();
|
||||
eprintln!("This password is shown only once. To pin a credential");
|
||||
eprintln!("instead, set STALWART_RECOVERY_ADMIN=admin:<password> in the");
|
||||
eprintln!("instead, set INBUXA_RECOVERY_ADMIN=admin:<password> in the");
|
||||
eprintln!("env file.");
|
||||
eprintln!("════════════════════════════════════════════════════════════");
|
||||
eprintln!();
|
||||
|
||||
@@ -17,7 +17,7 @@ pub(crate) enum RegistryInit {
|
||||
|
||||
impl RegistryStoreInner {
|
||||
pub(crate) fn new(local_path: PathBuf) -> Self {
|
||||
let env_hostname = std::env::var("STALWART_HOSTNAME")
|
||||
let env_hostname = types::branding::env_var("HOSTNAME")
|
||||
.ok()
|
||||
.filter(|h| !h.is_empty())
|
||||
.unwrap_or_else(|| {
|
||||
@@ -35,30 +35,30 @@ impl RegistryStoreInner {
|
||||
store: Store::None,
|
||||
id_generator: SnowflakeIdGenerator::new(),
|
||||
node_id: 0,
|
||||
env_recovery_mode: std::env::var("STALWART_RECOVERY_MODE")
|
||||
env_recovery_mode: types::branding::env_var("RECOVERY_MODE")
|
||||
.ok()
|
||||
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
|
||||
.unwrap_or(false),
|
||||
env_recovery_admin: std::env::var("STALWART_RECOVERY_ADMIN")
|
||||
env_recovery_admin: types::branding::env_var("RECOVERY_ADMIN")
|
||||
.ok()
|
||||
.and_then(|v| {
|
||||
v.split_once(':')
|
||||
.map(|(a, p)| (a.trim().to_string(), p.trim().to_string()))
|
||||
})
|
||||
.filter(|(a, p)| !a.is_empty() && !p.is_empty()),
|
||||
env_cluster_role: std::env::var("STALWART_ROLE")
|
||||
env_cluster_role: types::branding::env_var("ROLE")
|
||||
.ok()
|
||||
.filter(|r| !r.is_empty()),
|
||||
env_push_shard_id: std::env::var("STALWART_PUSH_SHARD")
|
||||
env_push_shard_id: types::branding::env_var("PUSH_SHARD")
|
||||
.ok()
|
||||
.and_then(|id| id.parse::<u32>().ok().and_then(|v| v.checked_sub(1)))
|
||||
.unwrap_or(0),
|
||||
env_public_url: std::env::var("STALWART_PUBLIC_URL")
|
||||
env_public_url: types::branding::env_var("PUBLIC_URL")
|
||||
.ok()
|
||||
.map(|v| v.trim().trim_end_matches('/').to_string())
|
||||
.filter(|u| !u.is_empty())
|
||||
.or_else(|| {
|
||||
std::env::var("STALWART_HTTPS_PORT").ok().and_then(|p| {
|
||||
types::branding::env_var("HTTPS_PORT").ok().and_then(|p| {
|
||||
p.parse::<u16>()
|
||||
.ok()
|
||||
.map(|port| format!("https://{}:{}", env_hostname, port))
|
||||
|
||||
@@ -45,3 +45,22 @@ macro_rules! brand_url {
|
||||
"https://inbuxa.org"
|
||||
};
|
||||
}
|
||||
|
||||
/// Reads one of the server's environment variables by its unprefixed name,
|
||||
/// such as `RECOVERY_ADMIN`.
|
||||
///
|
||||
/// `INBUXA_<name>` wins. `STALWART_<name>` is still read when the new name
|
||||
/// isn't set, so an existing Stalwart install moves over without editing its
|
||||
/// environment, and a warning says which variable to rename.
|
||||
pub fn env_var(name: &str) -> Result<String, std::env::VarError> {
|
||||
match std::env::var(format!("INBUXA_{name}")) {
|
||||
Err(std::env::VarError::NotPresent) => {
|
||||
let legacy = std::env::var(format!("STALWART_{name}"));
|
||||
if legacy.is_ok() {
|
||||
eprintln!("Warning: STALWART_{name} is deprecated; set INBUXA_{name} instead.");
|
||||
}
|
||||
legacy
|
||||
}
|
||||
found => found,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ pub fn build_http_client(
|
||||
allow_invalid_certs: bool,
|
||||
) -> Result<Client, String> {
|
||||
let mut headers = build_http_headers(raw_headers, username, password, token, content_type)?;
|
||||
headers.insert(USER_AGENT, "Stalwart/1.0.0".parse().unwrap());
|
||||
headers.insert(USER_AGENT, "INBUXA/1.0.0".parse().unwrap()); // types::brand!(); utils does not depend on types
|
||||
|
||||
match http_client_builder(allow_invalid_certs)
|
||||
.connect_timeout(timeout)
|
||||
|
||||
+32
-4
@@ -103,10 +103,12 @@ repository. Instead:
|
||||
- Each import's full strip report is committed on `main` under
|
||||
`docs/fork/strip-reports/<ref>.md` (and `.json`), beside the merge that
|
||||
brought the release in.
|
||||
- The snapshot includes upstream's `.github/` workflows, release automation
|
||||
included. They're kept on `upstream` as upstream shipped them, but must be
|
||||
disabled or replaced on `main` before the repository is ever pushed
|
||||
anywhere that runs them.
|
||||
- The snapshot includes upstream's `.github/`: its CI and release workflows,
|
||||
workflows that auto-close issues and PRs from anyone not on its allowlist,
|
||||
issue templates and Dependabot. On `main` the whole directory is moved to
|
||||
`.github-upstream/`, so GitHub never runs it. Upstream changes to it still
|
||||
merge there on each sync. INBUXA writes its own `.github/` when the
|
||||
repository is first published.
|
||||
|
||||
### 2.2b What the first import proved (v0.16.22, 2026-09-18)
|
||||
|
||||
@@ -179,6 +181,32 @@ one edition.
|
||||
interoperability, not branding, and renaming them breaks every existing
|
||||
client. Anything the fork adds uses its own namespace (open: which one).
|
||||
|
||||
### 2.5 Packaging
|
||||
|
||||
Done 2026-09-18:
|
||||
|
||||
- The package and binary are `inbuxa` (`cargo build -p inbuxa`). The binary's
|
||||
help, banner and every protocol greeting say INBUXA (the branding module,
|
||||
`types::brand!()`).
|
||||
- Settings come from `INBUXA_*` environment variables. Each still falls back
|
||||
to its `STALWART_*` name, with a startup warning to rename it
|
||||
(`types::branding::env_var`). That covers all nine the server reads:
|
||||
`HOSTNAME`, `RECOVERY_MODE`, `RECOVERY_ADMIN`, `RECOVERY_MODE_PORT`,
|
||||
`RECOVERY_MODE_LOG_LEVEL`, `ROLE`, `PUSH_SHARD`, `PUBLIC_URL`, `HTTPS_PORT`.
|
||||
- **Not renamed, on purpose:** `STALWART_APP_` and the two `STALWART_SPAM_...`
|
||||
names. They look like environment variables, but they're keys inside the
|
||||
data store, so renaming them would orphan existing installed apps and
|
||||
spam-classifier models.
|
||||
- New installs default to `/var/lib/inbuxa` for data and `/var/log/inbuxa` for
|
||||
logs. Existing installs keep the paths their configuration names, so no data
|
||||
moves.
|
||||
- The container image runs as user `inbuxa` (uid 2000, as upstream), with
|
||||
`/etc/inbuxa` and `/var/lib/inbuxa` as volumes, `INBUXA_HEALTHCHECK_URL`, and
|
||||
`inbuxa --config /etc/inbuxa/config.json`. The systemd unit
|
||||
(`inbuxa.service`), launchd plist and AppArmor profile are renamed to match.
|
||||
- `install.sh` is a stub that says there's no release yet. Upstream's version
|
||||
would download and install Stalwart itself.
|
||||
|
||||
## 3. Clean room
|
||||
|
||||
INBUXA runs on a paid Stalwart Enterprise license, so its maintainer is a
|
||||
|
||||
+10
-1067
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
#include <tunables/global>
|
||||
|
||||
profile stalwart flags=(attach_disconnected) {
|
||||
profile inbuxa flags=(attach_disconnected) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/openssl>
|
||||
@@ -17,8 +17,8 @@ profile stalwart flags=(attach_disconnected) {
|
||||
owner /proc/*/net/if_inet6 r,
|
||||
owner /proc/*/net/ipv6_route r,
|
||||
|
||||
# Full write access to /opt/stalwart
|
||||
/opt/stalwart/** rwk,
|
||||
# Full write access to /opt/inbuxa
|
||||
/opt/inbuxa/** rwk,
|
||||
|
||||
# Allow creating directories under /tmp
|
||||
/tmp/ r,
|
||||
@@ -51,9 +51,9 @@ profile stalwart flags=(attach_disconnected) {
|
||||
network inet6 dgram bind port 7911,
|
||||
|
||||
# Basic system access
|
||||
/usr/bin/stalwart rix,
|
||||
/etc/stalwart/** r,
|
||||
/var/log/stalwart/** w,
|
||||
/usr/bin/inbuxa rix,
|
||||
/etc/inbuxa/** r,
|
||||
/var/log/inbuxa/** w,
|
||||
|
||||
# Additional permissions might be needed depending on specific requirements
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>stalwart.mail</string>
|
||||
<string>inbuxa.mail</string>
|
||||
<key>ServiceDescription</key>
|
||||
<string>Stalwart</string>
|
||||
<string>INBUXA</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>__PATH__/bin/stalwart</string>
|
||||
<string>__PATH__/bin/inbuxa</string>
|
||||
<string>--config=__PATH__/etc/config.json</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
@@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=Stalwart Server
|
||||
Description=INBUXA Server
|
||||
Conflicts=postfix.service sendmail.service exim4.service
|
||||
ConditionPathExists=__PATH__/etc/config.json
|
||||
After=network-online.target
|
||||
@@ -11,10 +11,10 @@ KillMode=process
|
||||
KillSignal=SIGINT
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
ExecStart=__PATH__/bin/stalwart --config=__PATH__/etc/config.json
|
||||
SyslogIdentifier=stalwart
|
||||
User=stalwart
|
||||
Group=stalwart
|
||||
ExecStart=__PATH__/bin/inbuxa --config=__PATH__/etc/config.json
|
||||
SyslogIdentifier=inbuxa
|
||||
User=inbuxa
|
||||
Group=inbuxa
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
Reference in New Issue
Block a user