stalwartlabs / mail-server

Secure & Modern All-in-One Mail Server (IMAP, JMAP, POP3, SMTP)
https://stalw.art
3.53k stars 135 forks source link

[bug]: Stalwart assume config file to writeable #531

Closed dantefromhell closed 2 weeks ago

dantefromhell commented 2 weeks ago

What happened?

When deploying stalwart on NixOS the configuration ends may end up in the "nix store" which is a location that is intentionally read-only for all users, including root.

How can we reproduce the problem?

Configure stalwart on NixOS with the Minimal configuration

  services.stalwart-mail = {
    enable = true;
    package = pkgs.stalwart-mail;
    settings = {
      tracer."stdout" = {
        type = "stdout";
        level = "debug";
        ansi = false;
        enable = true;
      };
      store = {
        rocksdb = {
          type = "rocksdb";
          path = "/var/lib/stalwart-mail/data";
          compression = "lz4";
        };
      };

      storage = {
        data = "rocksdb";
        fts = "rocksdb";
        blob = "rocksdb";
        lookup = "rocksdb";
        directory = "internal";
      };

      server.listener."management" = {
        bind = ["[::]:8080"];
        protocol = "http";
      };

      authentication.fallback-admin = {
        user = "<REDACTED>";
        secret = "<REDACTED>";
      };

      server.listener = {
        smtp = {
          bind = ["[::]:25"];
          protocol = "smtp";
        };

        ssl_submissions = {
          bind = ["[::]:465"];
          protocol = "smtp";
          tls.implicit = true;
        };

        starttls_submissions = {
          bind = ["[::]:587"];
          protocol = "smtp";
        };

        imaptls = {
          bind = ["[::]:993"];
          protocol = "imap";
          tls.implicit = true;
        };
      };

      directory = {
        internal = {
          type = "internal";
          store = "rocksdb";
        };
      };
    };
  };

Version

v0.8.x

What database are you using?

RocksDB

What blob storage are you using?

RocksDB

Where is your directory located?

Internal

What operating system are you using?

Linux

Relevant log output

During startup an error regarding being unable to "write local configuration file" occurs:

Jun 11 21:00:03 pipeline systemd[1]: Starting stalwart-mail.service...
Jun 11 21:00:03 pipeline systemd[1]: Started stalwart-mail.service.
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.113236Z  INFO common::manager::boot: Starting Stalwart Mail Server v0.8.1...
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.193898Z DEBUG common::manager::webadmin: WebAdmin successfully unpacked path="/tmp/STALWART_WEBADMIN"
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194303Z ERROR utils::config: Build error for key "*": Failed to update configuration: Internal Error: Failed to write local configuration file: Read-only file system (os error 30)
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194451Z DEBUG jmap::services::housekeeper: Housekeeper task started.
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194842Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=895 event=Session
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194937Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=10795 event=Account
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194941Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=21595 event=Store(0)
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194957Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=25195 event=Store(1)
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194960Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=28795 event=Store(2)
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194969Z DEBUG jmap::services::housekeeper: Scheduling housekeeper event. due_in=28795 event=Store(3)
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.194642Z  INFO common::listener::listen: Starting listener id="imaptls" protocol=Imap bind.ip="0.0.0.0" bind.port=993 tls=true
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.195448Z  INFO common::listener::listen: Starting listener id="ssl_submissions" protocol=Smtp bind.ip="0.0.0.0" bind.port=465 tls=true
Jun 11 21:00:04 pipeline stalwart-mail[149903]: 2024-06-11T21:00:04.195458Z  INFO common::listener::listen: Starting listener id="starttls_submissions" protocol=Smtp bind.ip="0.0.0.0" bind.port=587 tls=false

On the management web interface value can (e.g. hostname) can be changed, but result in a HTTP/500 error and the following log entries occur:

Jun 11 23:06:18 pipeline stalwart-mail[163602]: 2024-06-11T23:06:18.678367Z DEBUG session{instance="management" protocol=Http remote.ip="<REDACTED>" remote.port=38142}: jmap::api::http: event="request" uri="/api/settings"
Jun 11 23:06:18 pipeline stalwart-mail[163602]: 2024-06-11T23:06:18.680115Z ERROR jmap::api::http: Database error context="store" error=Internal Error: Failed to write local configuration file: Read-only file system (os error 30)

Despite the HTTP/500 the web interface will display the updated hostname until the stalwart process is restarted.



### Code of Conduct

- [X] I agree to follow this project's Code of Conduct
mdecimus commented 2 weeks ago

Closing as this is not a bug. Stalwart needs write access to the configuration file if you use the webadmin or if not all required settings are present. When you use the minimal configuration Stalwart is trying to update the configuration file with the defaults to some of the missing settings. See this file for details.