Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Cloudron Forum

Apps - Status | Demo | Docs | Install
imc67I

Marcel C

@imc67
translator
Unfollow Follow
About
Posts
979
Topics
182
Shares
0
Groups
1
Followers
3
Following
0

Posts

Recent Best Controversial

  • def_whitelist_from_rcvd / welcomelist_from_rcvd does not fire on Cloudron mail app (SpamAssassin 4.0.0) — also no GUI option for sender whitelisting
    imc67I imc67

    Cloudron mail app version: cloudron/mail 3.18.2 (SpamAssassin 4.0.0, 2022-12-13)

    Summary

    There is no GUI (or API) way to whitelist a trusted sender domain in the Cloudron mail app — the only exposed mechanism is the free-text "Custom SpamAssassin rules" field, which maps directly to /app/data/spamd/custom.cf (included from local.cf). While investigating recurring false positives on legitimate Microsoft 365 senders, I found that the relay-verified whitelist directive (whitelist_from_rcvd / its current alias welcomelist_from_rcvd, including the def_ variants) does not fire at all in this setup — confirmed on both long-standing entries and newly added ones. The unauthenticated variant (welcomelist_from, From-header only, no relay check) works correctly.

    Environment

    • Cloudron mail app 3.18.2, SpamAssassin 4.0.0
    • spamd invocation (from ps) : /usr/sbin/spamd --max-children 2 --port 7833 --nouser-config --virtual-config /app/data/spamd/%u --syslog stderr -u cloudron --allow-tell
    • /etc/spamassassin/local.cf (shipped, resets on update) includes two persistent files under /app/data/spamd/: acl.cf (GUI-managed sender allow/blocklist) and custom.cf (GUI "Custom SpamAssassin rules" free-text field — this is the only place available for score/whitelist tuning).
    • No trusted_networks / internal_networks directive is present anywhere in the shipped config (local.cf, *.pre files) or in custom.cf.

    Steps to reproduce

    1. In the mail app's "Custom SpamAssassin rules" field, add:
      def_whitelist_from_rcvd *@outlook.com *.protection.outlook.com
      
    2. Save (this restarts spamd — confirmed via ps -o etime on the spamd process).
    3. Take a real inbound message from an *@outlook.com sender that passed through *.protection.outlook.com relays (verified via the Received headers).
    4. Re-score it: docker exec mail spamassassin -t < message.eml
    5. Observe X-Spam-Status — no USER_IN_WELCOMELIST / USER_IN_DEF_WHITELIST (deprecated alias) test appears, and the score is identical to a run with the whitelist line removed.

    Repeated with:

    • A newly added entry for a specific business partner domain (def_whitelist_from_rcvd *@example.nl *.protection.outlook.com) on a real message from that domain — same result, rule does not fire.
    • The current directive name instead of the deprecated alias (def_welcomelist_from_rcvd *@example.nl *.protection.outlook.com) — same result.
    • A synthetic minimal .eml with a single clean Received header (from HOST.outbound.protection.outlook.com (mail-....outbound.protection.outlook.com [IP]) by my.<domain> (Haraka) ...) and a matching From address — same result. SpamAssassin's own debug log correctly identifies this Received header as __LAST_UNTRUSTED_RELAY_NO_AUTH (i.e. it does parse the relay boundary correctly), yet the whitelist rule still does not fire.

    Control test (confirms the mechanism itself, isolates the bug)

    spamassassin -t --cf="welcomelist_from *@example.nl" < message.eml
    

    → X-Spam-Status: No, score=-100.0 ... tests=...,USER_IN_WELCOMELIST — fires immediately and correctly, at the rule's hardcoded default score of -100.

    So: the address-only, non-relay-verified directive works reliably; the relay-verified directive (which is presumably intended to be the "safe" option, since it additionally confirms the mail actually arrived via the claimed infrastructure, not just a forged From: header) never fires, in this container/config, regardless of naming (whitelist_from_rcvd vs welcomelist_from_rcvd) or entry age (default-shipped vs newly added).

    Suspected cause

    _check_welcomelist_rcvd (in Mail::SpamAssassin::Plugin::WLBLEval, called from check_from_in_default_welcomelist) presumably relies on SpamAssassin's own trusted/internal relay boundary detection to know which Received header to compare against the second (origin) parameter. Since this Cloudron config declares no trusted_networks / internal_networks, that auto-detection may be picking the wrong boundary or failing silently for this reason — even though the same debug run shows SpamAssassin does correctly tag the relevant Received header as the last untrusted relay via a different, unrelated eval (__LAST_UNTRUSTED_RELAY_NO_AUTH). I have not been able to fully confirm this from the plugin source in the time available; posting here in case someone has already solved this or knows the missing config.

    Workaround in use

    Switched the partner-domain entries to the non-relay-verified directive with a tuned-down score (rather than the default -100, which would let a spoofed From: header fully bypass filtering):

    score USER_IN_WELCOMELIST -4.0
    welcomelist_from *@example.nl
    

    This is good enough to counter a BAYES/HELO false-positive but does not fully bypass SPF/DKIM/DNSBL-driven detection the way the (non-working) relay-verified version was intended to. It's a knowingly weaker mechanism (spoofable From header) — would much prefer the relay-verified variant to actually work.

    Ask

    1. Is whitelist_from_rcvd / welcomelist_from_rcvd known to be broken in this SpamAssassin/Cloudron combination, and if so is there a missing config directive (e.g. trusted_networks) that should be shipped by default or that we should add ourselves in custom.cf?
    2. Separately: is there any plan for a proper GUI/API-level "trusted sender domain" feature in the mail app, so this doesn't require hand-editing SpamAssassin rule syntax in a free-text field?

    Happy to provide more debug output / test further if useful.

    Support spamassassin

  • client_max_body_size 2m in /api/ location blocks the large blocklists
    imc67I imc67

    A follow-up, because raising nginx client_max_body_size alone turns out not to be enough — there is a second, hard-coded ceiling that hits right after.

    Even with the /api/ location bumped to 10m, a blocklist POST now fails with HTTP 500 and this JSON body:

    {"status":"Internal Server Error","message":"request entity too large"}
    

    Note it is a 500, not an nginx 413 — the body passes nginx and is then rejected
    inside box. The cause is the JSON body-parser limit in:

    box/src/server.js  (9.0.0, ~line 41)
    const QUERY_LIMIT = '2mb', // max size for json queries (see also client_max_body_size in nginx)
    ...
    const json = middleware.json({ strict: true, limit: QUERY_LIMIT }, true);
    

    That QUERY_LIMIT applies to every JSON POST route, including
    POST /api/v1/network/blocklist. So there are two coupled limits — the nginx one
    and this one — and the box default (2mb = 2,097,152 bytes) is the real wall for
    large blocklists.

    Concrete numbers from a live install: the combined blocklist is ~90,600 entries and
    the JSON request body is 2,096,109 bytes — about 1 KB under the 2 MiB limit. One of my
    servers already fails as soon as a few hundred new IPs are added, while others with a
    slightly shorter list still squeak through. (JSON encoding inflates it further: each
    newline becomes \n → \n, ~90 KB on top of the raw list. JSON_UNESCAPED_SLASHES is
    already applied.)

    Request: please raise both limits, ideally toward the ipset capacity (262,144
    entries). At minimum, give the blocklist route a QUERY_LIMIT that matches a raised
    client_max_body_size (e.g. 8–10 MB) — otherwise raising the nginx value has no effect
    for this endpoint. The in-code comment already acknowledges the two are meant to track
    each other.

    Happy to provide a sample 90k-entry blocklist for testing if useful.

    Support api nginx

  • Cloudron v9.2.0 makes app-menu items disappear
    imc67I imc67

    O now I see it, I would appreciate it when the "admin page/url" won't be obsolete because its not always obvious where the admin-page is (like Surfer) 😊

    Support gui cloudron

  • Cloudron v9.2.0 makes app-menu items disappear
    imc67I imc67

    I noticed that since 9.2.0 the menu below is not complete anymore:

    Scherm­afbeelding 2026-05-26 om 09.13.06.png

    Cloudron 9.1.7:
    Scherm­afbeelding 2026-05-26 om 09.14.13.png

    Support gui cloudron

  • client_max_body_size 2m in /api/ location blocks the large blocklists
    imc67I imc67

    @robi I'm not a developer but a security concerned Cloudron user. The reason I started this application (LAMP-app, php and py) was that one of the users was lured into a phishing mail, his password was used for almost 2 months to send spam (via a direct SMTP connection, so no traces in IMAP). I was not able to discover this in Cloudron, that made me angry and extremely concerned: "what is happening more in the 3 Cloudrons I don't know because I can't see".

    So I took a Claude AI subscription and in about 10 weeks daily coding, step-by-step I created this application but never with the thought of distributing it. So there is functionality (GUI) to add one or more Cloudrons, but ie. there is no user management (only 1 user) and the access is IP restricted to my 2 WAN IP's via DDNS reversed IP lookup, but on the other hand API keys (Cloudrons, AbuseIPDB, Pushover, ClaudeAI for daily email summary) etc. are managed via GUI.

    To make it even a community app is totally out of my knowledge and comfort zone, moreover updating the app and being (feeling) responsible for others is too much. Maybe @staff can have a look with me to get inspired?

    Support api nginx

  • client_max_body_size 2m in /api/ location blocks the large blocklists
    imc67I imc67

    @nebulon I created CRMON — Cloudron Security Monitor, CRMON is a self-built security monitoring platform I run to monitor three Cloudron servers. It combines several threat intelligence sources and pushes a consolidated blocklist nightly to each Cloudron's network firewall via the /api/v1/network/blocklist API.

    Beyond the blocklist, CRMON also uses the Cloudron API to continuously monitor event logs: mail delivery events, IMAP/SMTP authentication failures, user login anomalies and nginx failed login attempts are fetched every few minutes and cross-referenced against AbuseIPDB. IPs exceeding configurable abuse score thresholds are auto-blocked and immediately (hourly alas because the API is not per IP) synced to the firewall.

    The blocklist has 5 layers, each with a different purpose:

    Layer Count Source
    Individual auto-blocks ~6,200 IMAP brute-force, login anomalies, mail abuse — auto-blocked based on AbuseIPDB score thresholds
    Wordfence (WordPress) ~4,200 A MU-plugin on ~25 WordPress sites reports attacker IPs in real time to CRMON, which syncs them to the firewall
    AbuseIPDB blacklist ~9,600 Daily import of the top-scoring IPs from the AbuseIPDB API
    FireHOL level1 ~4,500 Known malicious network CIDR ranges (botnets, scanners, exploits)
    Geo/country blocking ~63,000 IP ranges (IPv4 + IPv6) for ~23 high-risk countries (CN, RU, IR, KP, etc.)

    Why it grows: The Wordfence layer is the fastest-growing (+150–280 IPs/day) as WordPress sites under management continuously see new attackers. The geo layer is the largest by far — country-level CIDR ranges, especially for China and Russia, account for the bulk of entries.

    The geo ranges alone explain why we're pushing well over 80,000 entries. Without geo blocking, the list would be ~20,000 entries and the 2 MB limit would never be an issue.

    Support api nginx

  • client_max_body_size 2m in /api/ location blocks the large blocklists
    imc67I imc67

    @james the current blocklist payload (~2.03 MB) link I've sent you via PM

    Note: this is the GET response (Python-encoded by our nightly geo sync, which doesn't escape /). The actual PHP POST payload was ~68 KB larger because PHP's json_encode() escapes all forward slashes as / by default — one extra byte per CIDR entry, ~68,000 CIDR entries total. This pushed the payload to ~2.10 MB, triggering the 413.

    Workaround applied: json_encode($body, JSON_UNESCAPED_SLASHES) in our PHP code reduces it back to ~2.03 MB. We also manually patched the nginx config to client_max_body_size 10m as a structural fix.

    Both are a temporary workaround as the list is increasing with 300-500 IP's a day.

    Support api nginx

  • client_max_body_size 2m in /api/ location blocks the large blocklists
    imc67I imc67

    Following the fix in #10547 that raised the ipset limit to 262,144 elements, we ran into the next bottleneck: the nginx client_max_body_size 2m on the /api/ location in the dashboard config prevents actually reaching anywhere near that element count via the API.

    In /home/yellowtent/platformdata/nginx/applications/dashboard/<hostname>.conf:

    location /api/ {
        proxy_pass   http://127.0.0.1:3000;
        client_max_body_size 2m;   ← limits POST body to ~86k entries
    }
    

    At ~23 bytes per entry (JSON-encoded), 2MB caps the blocklist at roughly 86,000 entries — well below the 262k ipset capacity. Anything larger returns HTTP 413.

    Workaround: changing 2m to 10m in that location block fixes it immediately.

    Request: could this limit be raised (or set to 0) in a future Cloudron release? Given the server-level client_max_body_size 0 already applies to all app traffic, the 2m restriction on /api/ seems overly conservative for the network blocklist endpoint.

    Support api nginx

  • Reverse geocoding (addition to Dawarich)
    imc67I imc67

    Dawarich can be setup with "reverse geocoding", this is the process of converting geographic coordinates into a human-readable address.

    The result is that Dawarich can create "visits and places", this feature tracks your visits to locations to build a comprehensive picture of your daily activities and travel history.

    For this Dawarich recommends:

    Currently, Dawarich supports 4 options for reverse geocoding services:

    • Geoapify (free, limited usage, see Geoapify pricing)
    • Photon (free, limited usage, 1 request per second)
    • Self-hosted Photon (free, unlimited usage)
    • Nominatim (free, limited usage, see Nominatim usage policy) or self-hosted Nominatim instance (free, unlimited usage)

    So an new Cloudron-app either Photon or Nomanitim is very welcome to get the most out of Dawarich.

    Feature Requests dawarich geocoding

  • Dovecot > Sieve > central management
    imc67I imc67

    @James does the moving from 'support' to 'feature requests' means it's currently not possible 😉?

    Feature Requests

  • Dawarich signup env doesn't prevent from signing up
    imc67I imc67

    o, wait, obviously there was somewhere an update and the setting is now in the app GUI! Be sure everyone to check this as the env didn't work anymore!

    @staff please correct this in the docs

    Dawarich

  • Dawarich signup env doesn't prevent from signing up
    imc67I imc67

    Hi guys,

    this is a serious issue: setting this https://docs.cloudron.io/packages/dawarich#disable-registration doesn't work, I still can signup ... 😡

    Dawarich

  • Dovecot > Sieve > central management
    imc67I imc67

    I was wondering if it is possible in Cloudron to manage sieve centrally (via for example API or else) with server-wide rules?

    Currently the only way to "push" server-wide "marks" on incoming email is via "Email Address Blocklist" but the result of that is: the mail is still delivered to the user's spam-folder.

    I'm looking for a way to reject emails (discard) based on sender (I know it's possible at senders' IP address via blocklist)

    Feature Requests

  • What's coming in Cloudron 10
    imc67I imc67

    @girish said:

    @imc67 yes, that's part of the plan

    @girish Would it be feasible to change the current methodology from text lists to database records for all block/allow-lists (mail, IP)? I manage the IP blocklist, via API, with around 90k rows and update it every hour with new and it takes about 2-3 minutes for each Cloudron-server to "handle" this. Better would be to have an API functionality with "list, add, remove"-commands.

    Announcements

  • How to update IP database?
    imc67I imc67

    is it updating the database itself (I guess the IP-location info is changing often?) or still needed by app update and if so how often will the app be updated?

    IP2Location

  • How to update IP database?
    imc67I imc67

    @nebulon sounds like "an update of the app package is coming soon" 😊 ?

    IP2Location

  • How to update IP database?
    imc67I imc67

    It’s not in the docs and the forum posts are also not 100% clear in the answer for: how does this app updates its IP2location database?

    IP2Location

  • Feature Request: 🔥 Simple per-App WAF with Templates (KISS) 🏰
    imc67I imc67

    @necrevistonnezr said:

    You got an upvote for me in any event, but for this feature: https://docs.cloudron.io/guides/community/blocklist-updates

    Haha, true, that’s my code (with your additions) I know that, but it’s not per app 😉

    Feature Requests waf security firewall

  • What's coming in Cloudron 10
    imc67I imc67

    @girish does this includes the email spam whitelist mentioned here with API and GUI?
    https://forum.cloudron.io/topic/15310/spam-acl-whitelist-in-api-but-not-in-gui/

    Announcements
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search