How do I force HTTP / HTTPS to listen only on an internal IP?

Issue Description

I am testing Stalwart for viability. I had a previous version up which I was testing but it was consistently failing after a a week or two. I had some time today and installed the newest version exposed by install.sh.

In my previous version I had HTTP & HTTPS setup to only listen on 10.0.0.2 to prevent more exposed surface area than needed. The new version listens on [::]:8080 and [::]:443, and any ability to alter that is disabled.

I figured I can alter the config.toml, but that is gone now too, and the install directory is now /etc and not /opt like it was. The config is now obfuscated (in a DB) which is great for people who handle stuff through GUIs, but literally is counter indicated, especially when situations like this arise.

So long story short is there a straightforward way to prevent Stalwart from listening on IPs I don’t want it to? In my opinion management interfaces should be protected as much as possible (Especially with AI trolling for cracks), and as it stands out of the box this does not allow that that I see.

Expected Behavior

Why this is a bug… Old version allowed this, new version does not allow a basic common security configuration.

Actual Behavior

Can not obviously prevent HTTP / HTTPS or any listener for that matter from being available on a public interface. What is the point of [::] even being listed.

Stalwart Version

v0.16.x

Installation Method

Binary (Linux)

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

As an aside. Can we go into the DB being used and alter these settings without issue? I suspect you shoved everything into DB to protect it a bit, but in a case like this you seem to have removed a feature for which there is not direct config workaround.

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

The bind addresses are editable. In the web UI they’re under Settings › Network › Listeners: open the http and https listeners and change their bind addresses to 10.0.0.2:8080 and 10.0.0.2:443. Listeners are bound at startup, so restart the service after saving. The CLI equivalent is

stalwart-cli query NetworkListener
stalwart-cli update NetworkListener <id> --json '{"bind": {"10.0.0.2:443": true}}'

using the id from the first command. If the field was greyed out when you looked, I suspect the server was still in bootstrap or recovery mode, where a temporary listener always binds [::] and only its port can be changed.

Please don’t edit the database by hand. The settings are stored encoded, and the web UI, CLI and API validate what they write; the only file left, config.json, just points at the data store. To lock the management side down further, allowedEndpoints can restrict /admin and /api by IP or by listener: Access Control | Stalwart