Skip to main content

Configuration and state

There is no server configuration file

A server's configuration has two halves with two owners, and neither is a file you edit. Nothing here is hand-edited in normal operation: the host half is written by ohm install, and the policy half is edited in the console.

The two halves​

HalfHoldsLives inWritten by
The host'sHostname; the instance, backup, archive and temp directories; the management URLs; the registry and its credentials; the PostgreSQL major version; the console key; the Fail2Ban and GeoIP service pairs/etc/antelao/agent.env and /var/lib/ohm-agent/host-state.jsonohm install, and the jobs that change the host - a PostgreSQL major-version migration, a console key rotation
The policyDescription; mail; intrusion prevention; the access rules; the GeoIP account; the certificate mode; job concurrency; image retention; the license warning window; trusted proxies; the outbound proxy; the provisioning domain; the cloud metadata blockThe ServerSettings row of the master database, its secrets encrypted under the API's key ringThe console's server pages, and ohm server config import

The agent serves the host's half to the management plane as GET /api/v1/host. The API composes the two at startup and, while the composition fails, every ten seconds until it succeeds. That is what a serverConfigLoaded: false health response means, and why fixing the cause is enough - there is nothing to restart.

The bootstrap agent's dashboard on port 5202 shows the host's half - the server id, the hostname and the registry - because that is where those are decided.

The policy half, edited in the console. Saving it applies it: what still differs afterwards is on the Pending changes page with its reason.

To change anything in the host's half, run the installer again on the host.

The server's name is the one exception with a page of its own: the Configuration page of the bootstrap agent renames the server, and so does ohm server rename on the host. Both run the same repair the installer runs for a new name, and request a certificate for the new name in the configured mode. See Renaming the server.

Local only
$ sudo ohm server rename new.example.com
sudo ANTELAO_INSTALL_HOSTNAME=new.example.com ohm install

Every change to the policy half is recorded. Configuration > Revisions is what it was before, who changed it and when.

The policy half travels as a file:

Remote or localagainst pelmo
$ ohm server config export -o settings.json
Remote or localagainst pelmo
$ ohm server config import -j settings.json

The export redacts credentials. The import replaces the row; the host's half is not in the file, so a configuration exported from one server cannot carry another server's identity onto it.

A whole server - the settings, the license, the PostgreSQL profiles, the instances and the maintenance calendar, plus the host's half - moves as one manifest instead:

Remote or localagainst pelmo
$ ohm server manifest export -j manifest.json
Remote or localagainst pelmo
$ ohm server manifest apply -j manifest.json

The server says what it would do before it does it, then queues the apply as a job. Applying the same manifest twice changes nothing the second time. --with-secrets keeps the credentials in the file, and then the file is a key to the server: treat it as one.

Where the state lives​

/root/.local/share/ohm/ the application root
├── conf/ appsettings.json - the master-database connection, and nothing else
├── data/ container data trees, generated secrets, certificates, GeoIP databases
├── logs/ ohm-cli-*.log, ohm-audit-*.log, action logs
└── license/ *.lic license files, install-id, checkin.receipt, checkin-state.json

/etc/antelao/agent.env the agent's credentials and the host's half (mode 0600)
/etc/antelao/bootstrap.json OPTIONAL one-shot install input; consumed and DELETED by a
successful fresh install, and ignored by every repair (mode 0600)
/etc/antelao/license-agreement.json the acceptance recorded on the host, before a database exists
/var/lib/ohm-agent/ the agent's task list, host-state.json, and its upgrade request
/var/lib/odoo/instances the instance trees
/var/lib/odoo/backup the backups
/var/lib/odoo/archive the archive

The master database holds everything else: users, instances, jobs, schedules, statistics, the license register and the ServerSettings row.

The stored credentials in the master database are encrypted under the API's key ring, which lives in the Docker volume ohm-api-keys; the console's own ring, for its sign-in cookies, is in ohm-web-keys.

Back up the master database, the application root and the ohm-api-keys volume together. None of them is much use without the others: the database's credentials open only with that key ring. See Credentials on the backup targets page.

appsettings.json​

The one file under conf/. The CLI and the API both read it: it says which master-database provider to use and how to reach it, and it is where the API's own process settings below are set.

/root/.local/share/ohm/conf/appsettings.json
{
"Connection": {
"Default": "PostgreSQL"
},
"ConnectionStrings": {
"PostgreSQL": "Host=localhost;Port=5432;Database=master;SSL Mode=Prefer;Timeout=30;Cancellation Timeout=-1",
"SqlServer": ""
}
}

Default is PostgreSQL or SqlServer. Those are the two providers the product supports, and only the connection string Default names is used; leave any other entry in ConnectionStrings as it is.

PostgreSQL in the bundled ohm-postgres container is the default, and ohm install creates the database and its schema. Moving to an external SQL Server is a job, not a file edit:

Remote or localagainst pelmo
$ ohm system database migrate --to SqlServer
The migration drops and re-imports the destination

It runs inside the API rather than on the host, because the stored credentials are re-encrypted on the way and the API is what holds the key ring. It switches the configured provider in appsettings.json and takes effect when ohm-api and ohm-web restart.

The SQL Server connection string must be complete and must name a dedicated database. Never the engine's own master: the application database merely happens to share that name on the PostgreSQL container.

Master data exports the whole master database as a SQL script for its engine, and imports one. The import asks for the confirmation word IMPORT and writes a safety export first.

Alerting and uptime settings​

Two sections of the API's own configuration, read once, when the API starts. Neither has a console page. The ones worth knowing are the retentions and the two switches.

To change one, add it to conf/appsettings.json under Api, beside what the file already holds, then restart ohm-api on Core services. For example, to switch the uptime probe off and keep alert events for 30 days:

/root/.local/share/ohm/conf/appsettings.json
{
"Connection": { "Default": "PostgreSQL" },
"ConnectionStrings": { "PostgreSQL": "...", "SqlServer": "" },
"Api": {
"Uptime": { "Enabled": false },
"Alerting": { "EventRetentionDays": 30 }
}
}

Api:Alerting​

SettingDefaultWhat it does
EnabledtrueWhether the hub publishes at all
MaxDeliveriesPerMinute30The per-channel budget
PauseAfterFailures10Consecutive failures that pause a channel
EventRetentionDays90How long an event is kept
DeliveryRetentionDays30How long a delivery row is kept
ExecutorGraceSeconds120How long the container event relay may be silent before the executor is called unreachable
DeliveryTimeoutSeconds15How long one attempt may take
ResponseBodyCapBytes65536How much of a response is read before it is abandoned
Leave AllowPrivateTargets off

AllowPrivateTargets lets a channel target a loopback or private address, which the webhook policy otherwise refuses. Switching it on removes the guard that stops a webhook being used to reach inside your network. No page or job ever sets it; do not set it on a server.

Api:Uptime​

SettingDefaultWhat it does
EnabledtrueWhether the probe runs. Turn it off if you monitor from elsewhere
IntervalSeconds60How often a tick runs, floored at 30 - a tighter value probes faster than nginx answers
HttpTimeoutSeconds10How long one check may take
Concurrency8How many instances are checked at once
FailuresBeforeDown3Consecutive failures that open an outage
SuccessesBeforeUp2Consecutive successes that close one
CertificateWarnDays14Days left before the certificate warning
CertificateCriticalDays3Days left before it becomes critical
FineRetentionDays14How long the five-minute rows are kept before compaction
RetentionDays400How long the daily rows are kept

A filesystem's disk alert has no boundaries of its own here: it is raised by Usage warning (%) and Usage critical (%) under Configuration, 80 and 90 by default, the same pair the Statistics and Storage pages colour a reading by.

See Alerting and Uptime for what these govern.

Api:Audit​

KeyDefaultWhat it decides
RetentionDays365How long the audit trail is kept before the retention job prunes it

It is set in the same file, under Api, and the next prune reads it. The prune deletes; it does not archive. Export before the window closes if you need longer.

Ports​

Every port the server listens on, with its defaults. Bound to is the address the service listens on: the loopback answers the server itself and nothing else; every interface answers whatever can route to the server, unless a firewall stops it. Firewall script is what the firewall script antelao-ohm-ufw.sh does with the port: open to everyone, open to your own addresses only, or nothing (the script's default refuses it). Service is the container, or for SSH the host's own program, that answers; ohm-<id> is an instance's container.

PortProtocolBound toFirewall scriptServiceWhat it is
22SSHEvery interfaceYour addressessshdThe host's own SSH server, not part of the product
80HTTPEvery interfaceEveryoneohm-nginxThe web server in front of the instances: Let's Encrypt's HTTP check and the redirect to HTTPS
443HTTPSEvery interfaceEveryoneohm-nginxThe instances, and the consoles a Published (443) rule publishes under /admin, /pgadmin, /portainer and /metabase
5201HTTPLoopbackNothingohm-agentThe host agent, for the command line and the server's own parts
5202HTTPSEvery interfaceYour addressesohm-agentThe host agent's page and API. Protected by its key and by who may reach the agent
5311HTTPLoopbackNothingohm-apiThe management API, for the command line and the console on the server itself
5312HTTPSEvery interfaceYour addressesohm-apiThe management API
5321HTTPLoopbackNothingohm-webThe console, for the server itself and an SSH tunnel
5322HTTPSEvery interfaceYour addressesohm-webThe console
5323HTTPSEvery interfaceYour addressesohm-webThe browser editor an instance's Code tab opens, with the console's certificate. Allow it wherever you allow 5322
5411HTTPLoopbackNothingohm-geoipThe GeoIP service, for the management API
5421HTTPLoopbackNothingohm-fail2banThe Fail2Ban service, for the management API
5431HTTPLoopbackNothingohm-crowdsecCrowdSec's local API, while CrowdSec is switched on
2500SMTPLoopbackNothingohm-postfixThe mail relay the server's own mail leaves through
5432PostgreSQLLoopbackNothingohm-postgresThe PostgreSQL cluster
5433PostgreSQLLoopbackNothingohm-postgres-replicaThe read replica, once installed
6432PostgreSQLLoopbackNothingohm-pgbouncerThe connection pooler, once installed
8000TCPEvery interfaceNothingohm-portainerPortainer's tunnel for its Edge agents, while installed. The product does not use it: keep it closed
8081HTTPLoopbackYour addressesohm-pgadminpgAdmin. It answers the server itself only, whatever the script allows: reach it through an SSH tunnel
5511HTTPEvery interfaceYour addressesohm-metabaseAnalytics, once installed
5512HTTPSEvery interfaceYour addressesohm-metabaseAnalytics, with the management certificate
9000HTTPEvery interfaceYour addressesohm-portainerPortainer, while installed
9443HTTPSEvery interfaceYour addressesohm-portainerPortainer, while installed
2222SSHEvery interfaceYour addressesohm-sshThe SSH gateway for developers, while it is switched on. The port can be moved; the script names 2222
5680-5779TCPEvery interfaceYour addressesohm-<id>An instance's debugger, while remote debugging is on for it
6680-6779HTTPEvery interfaceYour addressesohm-<id>An instance's own HTTP port, while remote debugging is on for it

Only the web server on 80 and 443 is in front of the instances. Every other port is answered by its service directly, without the web server's protection, so keep each one closed to everyone but your administrators: with the firewall script, a provider firewall that admits the same list from the same addresses, or a VPN.

The script opens 80 and 443 to everyone and every port marked "Your addresses" to the addresses you give it, and refuses everything else. pgAdmin, analytics, the SSH gateway and the debugger ranges are published by a container, which Docker lets past UFW's own rules; the script therefore writes the same allow-list into Docker's DOCKER-USER chain as well. Get it and run it as Restricting the management ports shows.

The server's own containers, the Odoo instances and the code editors among them, cannot open a connection to the agent, the management API, the console or Portainer at all: the server keeps a firewall rule of its own for that, puts it back whenever the agent starts, and takes it away when the product is removed. A firewall tool that reloads the server's rules, such as ufw reload, removes it until sudo systemctl restart ohm-agent.

The consoles on port 443​

The console, pgAdmin, Portainer and Metabase can also be served on port 443, at https://<the server's host name>/admin, /pgadmin, /portainer and /metabase. That is no longer a switch on Configuration > General: a console is served there while a rule on Security > Firewall > Rules > Published (443) governs it, and those rules decide who reaches it. The web server that serves your instances passes every request on with the visitor's own address, so the sign-in limits and the audit trail keep seeing the person rather than the web server. See Publishing consoles on port 443.

With no enabled rule on Published (443) the site is removed; the consoles stay on their own ports.

Trusted proxies​

Configuration > Network > Trusted proxies lists the proxies, load balancers or tunnels that forward visitors to this server: addresses or CIDR ranges, comma separated. A listed proxy is believed when it names the visitor it forwards for, so the access rules, the sign-in limits and the audit trail see the visitor rather than the proxy. The list applies to the web server on ports 80 and 443 (the instances and the consoles published on port 443) and to the console and the management API on their own ports. A range may be no wider than /8 for IPv4 or /32 for IPv6. An instance's own Trusted proxies, on its Configuration page, can be changed by an Administrator only; an Operator sees them read-only.

A program on the server itself that forwards to port 443, such as a tunnel agent reaching localhost:443, arrives at the web server from an address of the server's own container network rather than from loopback. List that address to trust it; the untrusted proxy notice names it.

Fail2Ban and CrowdSec never ban a listed proxy. CrowdSec also never bans this server itself, the addresses in its own whitelist or the proxies an instance lists for itself, and judges every other address, private networks included. A load balancer or proxy on your own network that is not listed can therefore be banned, and everyone behind it with it. After changing an instance's own Trusted proxies, use Install on the CrowdSec tab to bring CrowdSec's whitelist up to date.

A proxy that forwards without being listed is not trusted: everybody behind it looks like the proxy. Administrators then see a notice on every console page and the server raises the Untrusted proxy alert. List the proxy if it is yours.

Behind a listed proxy, a Fail2Ban ban cannot block the visitor at the host firewall, which only sees the proxy's address. The web server refuses the banned address the proxy forwards instead, with a 403, within half a minute of the ban and until it is lifted. See Intrusion prevention.

The instances are watched the same way: a proxy in front of an instance's site that is not listed is named in the notice, on the instance's Configuration tab and on the Fail2Ban and CrowdSec tabs. Trust this proxy on the notice adds it to this list and applies it. An instance's own Trusted proxies field, when filled, replaces this list for that instance, so a proxy in front of such an instance belongs there.

The provisioning domain​

An instance created, cloned or restored without a host name of its own is named after its id. Configuration > Network > Provisioning domain decides the rest of the name: with a domain such as customers.example.com set, the instance is named <id>.customers.example.com; with none, which is the default, it is named <id>.localhost, which only this server can reach.

The names have to point at this server, so the Domain field needs a wildcard DNS record, *.customers.example.com, of type A (and AAAA when the server has an IPv6 address) with the server's public address. Check the wildcard record resolves a random name under the domain and says whether it reaches this server; a record that is not in place yet is a warning, never a refusal, because the record is often created after the setting.

Only new instances use the domain: setting, changing or clearing it renames no instance. A development copy always keeps its localhost name, and so does every instance on a workstation or on the Developer edition. The domain is saved with the page's Save; nothing on the host is applied for it.

From the command line, on the server or with --server:

Remote or localagainst pelmo
$ ohm server config domain show
Remote or localagainst pelmo
$ ohm server config domain set customers.example.com
Remote or localagainst pelmo
$ ohm server config domain clear

show also prints the name an instance created now without one would get. set accepts *.customers.example.com too. The installer takes the domain from the bootstrap document's provisioningDomain, --provisioning-domain or ANTELAO_INSTALL_PROVISIONING_DOMAIN. See Install the server.

Cloud metadata​

On a cloud server, the address 169.254.169.254 answers with facts about the machine and, when the machine has a cloud identity (an AWS instance role, an Azure managed identity, a Google Cloud service account), with credentials for that cloud account. On Azure, 168.63.129.16 serves the machine's agent as well.

Configuration > Network > Cloud metadata carries Block the cloud metadata addresses, which is on by default. With it on, the Odoo instances and the other containers on the server's networks cannot reach either address, so an Odoo module cannot pick up those credentials. Name lookups through 168.63.129.16 keep working, and the server itself and its management services are not affected. Switch it off only for a module that needs the cloud's metadata.

It takes effect when the server configuration is applied, and again after every restart of the server or of Docker. A reload of the server's firewall does not lift it for long either: the server checks the block every minute and puts back what a reload took away, and the UFW ruleset carries the block itself from 0.24.0 on.

The outbound proxy​

For a network that lets nothing out except through a proxy, Configuration > Network > Outbound proxy names the proxy the server sends its Internet traffic through: its address (http://host:port, or https://host:port for a proxy that speaks TLS itself), an optional user name and password, and a list of names that go out directly. Empty, which is the default, sends everything out directly. The password is stored encrypted and is never shown again; leave the field empty to keep it.

Test the proxy sends one request through the proxy as it is entered on the card, saved or not, and says "The outbound proxy works (answered in 53 ms)." or "The outbound proxy did not work:" and the reason - a proxy that wants a password it does not get answers 407.

Saving applies it at once. With a proxy set:

  • The management service and the host agent send their own requests through it: the license check-in, the update checks (Docker Hub, nightly.odoo.com, GitHub), the GeoIP account check, GitHub and GitLab sign-in and lookups, the payment providers' address lists, backup storage at your provider, the management plane link, the speed test and the Internet card.
  • Image pulls go through it: Docker is given the proxy. Docker reads it when it starts, so a Docker that keeps its containers running across a restart ("live-restore": true) is restarted for you a few seconds after the save; any other Docker uses the proxy for pulls after its next restart, which is yours to choose, because it stops every instance with it.
  • Image builds pass it to the build, so the package and Python downloads inside them use it.
  • Module downloads from git use it.
  • The GeoIP service and CrowdSec are recreated with it, and certificate requests use it.
  • A Python package install inside an instance gets it for that one command.
  • The host's own package updates get it: the server writes a package manager setting for it.

Always direct, whatever the list says: this machine itself (localhost, 127.0.0.1, ::1), the server's host name, and every instance's name and host names; ohm server config proxy show lists them. The Odoo instances themselves are never given the proxy: an instance on a server without a way out stays without one.

Some traffic cannot go through an HTTP proxy:

TrafficWhat happens
Outgoing mail (SMTP)Not through the proxy. The mail relay needs its own way out to your mail server
FTP backup targetsNot through the proxy. They need their own way out
Odoo's upgrade serviceCannot go through a proxy, so an Enterprise database upgrade is refused on a server with a proxy set
The DNS record checksAsked over HTTPS (cloudflare-dns.com, dns.google) through the proxy instead of DNS on port 53
The Internet cardTimes a connection opened through the proxy, and says so. The public address it shows is the proxy's, not the server's
Alert webhooksSent through the proxy. The proxy resolves the name, so the check of the address a webhook resolves to is the proxy's to make

Clearing the address takes everything back out again: Docker's and the package manager's settings, and the proxy in the GeoIP and CrowdSec containers.

From the command line, on the server or with --server:

Remote or localagainst pelmo
$ ohm server config proxy set --url http://proxy.example.com:3128 --username ohm --password
Remote or localagainst pelmo
$ ohm server config proxy test
Remote or localagainst pelmo
$ ohm server config proxy show
Remote or localagainst pelmo
$ ohm server config proxy clear

--password asks for the password at a masked prompt; --password-file and --password-stdin read it from a file or standard input. --no-proxy takes the list of names that go out directly.

What the server reaches​

For your proxy's allow-list. Which of these you need depends on what you use; everything else in the list can stay closed.

AddressWhat for
packages.antelao.ioThe package, the installer and its scripts, and the proxy test
ghcr.io, pkg-containers.githubusercontent.comThe product's images
license.antelao.io, license.antelao.appThe license check-in and activation
antelao.ioBug reports and feature requests sent from the Support page to Antelao's helpdesk
registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com, hub.docker.comThe Odoo and service images, and the update check's look at their tags
nightly.odoo.comOdoo's nightly builds, for images built from Odoo's own recipe and the update check
upgrade.odoo.com, and Odoo's upgrade servers on ports 32768 to 60999Upgrading Enterprise databases. Direct only, never through the proxy
github.com, api.github.com, codeload.github.com, objects.githubusercontent.comOdoo's and your modules' code, commit lookups, GitHub sign-in for developers, support tickets
gitlab.com, or your own git serverModules hosted there
deb.debian.org, security.debian.org, archive.ubuntu.com, pypi.org, files.pythonhosted.org, registry.npmjs.org, apt.postgresql.org, www.postgresql.orgThe packages image builds install
download.maxmind.comThe GeoLite2 databases, with a MaxMind account
hub-cdn.crowdsec.net, api.crowdsec.netCrowdSec's collections and community blocklist, when CrowdSec is on
acme-v02.api.letsencrypt.org, and your DNS provider's APILet's Encrypt certificates
stripe.com, api.paddle.com, ip-ranges.mollie.comThe payment providers' webhook addresses, for the Payments firewall rules
open-vsx.orgExtensions for the browser editor
Your backup storage: *.blob.core.windows.net, management.azure.com, login.microsoftonline.com, *.backblazeb2.com, *.r2.cloudflarestorage.com, api.cloudflare.com, your S3 endpointBackups at your provider
Your management plane and your alert webhooksWhen you use them
api.anthropic.com, api.openai.com, your Azure OpenAI resource's endpointDiagnose, for the AI providers that are switched on
challenges.cloudflare.comCloudflare Turnstile on the console's sign-in, when it is on
cloudflare-dns.com, dns.googleThe DNS record checks
www.microsoft.com, www.cloudflare.com, www.google.com, speed.cloudflare.com, ipv4.icanhazip.com, ipv6.icanhazip.com, ifconfig.coThe Internet card, the speed test and the public address readouts
Your distribution's package mirrors, download.docker.comThe host's own package updates

Installing behind a proxy​

The installer downloads the package and the first images before the server exists to apply its own setting, so on a host that has no direct way out, give the package manager and Docker the proxy first:

# The package manager
echo 'Acquire::http::Proxy "http://proxy.example.com:3128/";
Acquire::https::Proxy "http://proxy.example.com:3128/";' | sudo tee /etc/apt/apt.conf.d/80proxy

# Docker (merge into an existing /etc/docker/daemon.json rather than replacing it)
echo '{ "proxies": { "http-proxy": "http://proxy.example.com:3128",
"https-proxy": "http://proxy.example.com:3128", "no-proxy": "localhost,127.0.0.1,::1" } }' \
| sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

Then run the installer with HTTPS_PROXY exported for its own download, and put the same proxy in the bootstrap document's outboundProxy, so the server takes it over. Once the server has applied its own setting, remove your 80proxy file: the server writes its own.

The master database schema​

The schema is owned by the application and upgraded forward. The upgrade is forward-only: an older binary refuses to start against a newer schema, so rolling a release back means restoring the database from before the upgrade too.

Updating the containers does not by itself upgrade the schema, and neither does Apply Update in the console. When a build expects a newer one than the database carries, the API refuses to start and says so, and this is the way past it:

Local only
$ sudo ohm database upgrade

ohm install does the same as part of a repair, before it rolls any container.

Global options​

Five options are on the root command and therefore on every command. They are omitted from the tables in the command reference.

OptionMeaning
-v, --verbosity <level>Debug, Error, Fatal, Info, None, Trace or Warn for this invocation
--error-action <action>Continue, SilentlyContinue or Stop. Default Stop
--server <name|url>Run against a stored connection or a management API URL
--token <key>The API key for remote mode
--localForce local execution even when a connection is configured

Three more appear on the commands that can use them rather than on all of them: -y, --yes to answer confirmations for unattended use, -f, --force to recreate or overwrite instead of reusing what exists, and --show-secrets to print credentials unmasked instead of ****.

Environment variables​

VariableUsed byPurpose
OHM_API_URLohmDefault management API endpoint for remote mode
OHM_API_KEYohmThe API key for remote mode
ANTELAO_INSTALL_*ohm installThe installer's answers, when they are not being prompted for. See Install the server
ANTELAO_BOOT_*ohm-agentThe agent's entire configuration, in /etc/antelao/agent.env. Written by ohm install; the line below and ANTELAO_BOOT_ALLOW are the ones you may change by hand
ANTELAO_INSTALL_OUTBOUND_PROXY_URL, _USERNAME, _PASSWORD, _NO_PROXYohm installThe outbound proxy, over the bootstrap document's outboundProxy; the password is stored encrypted
ANTELAO_INSTALL_PROVISIONING_DOMAINohm installThe provisioning domain, over the bootstrap document's provisioningDomain
ANTELAO_INSTALL_TURNSTILE_SITE_KEY, ANTELAO_INSTALL_TURNSTILE_SECRET_KEYohm installThe keys of Cloudflare Turnstile, stored by the install (the secret encrypted). Both or neither
ANTELAO_BOOT_TURNSTILE_BYPASSohm-agenttrue turns Turnstile on the console sign-in off once ohm install has recreated the management containers, and wins over the setting. The emergency line you may add by hand; a repair keeps it. The faster way is ohm server turnstile disable

Who may reach the agent​

The agent answers HTTPS on 5202 on every interface, like the other management ports, and plain HTTP on 5201 on the server itself only. Its key is the protection, and ANTELAO_BOOT_ALLOW in /etc/antelao/agent.env says from which addresses the key may be presented. Loopback is always admitted.

ANTELAO_BOOT_ALLOWWho reaches the agent
EmptyEvery address, and the key alone protects the page
Addresses or CIDR rangesThose and the server itself. Any other address gets a bare "403 Forbidden" with no explanation; the agent's log records the refusal

ohm install writes it, and its default depends on whether you gave management addresses at install (--api-allow, or ANTELAO_INSTALL_API_ALLOW):

  • Without management addresses the list is empty: every address may reach the agent's page, behind its key. This is what lets you reach the page from a browser elsewhere when the console is down.
  • With management addresses the list is this server's own addresses and those, and every other address is refused.

ANTELAO_INSTALL_AGENT_ALLOW writes any list you choose instead, for example sudo ANTELAO_INSTALL_AGENT_ALLOW=203.0.113.7,10.8.0.0/24 ohm install, and so does editing ANTELAO_BOOT_ALLOW by hand followed by sudo systemctl restart ohm-agent. ohm install prints who may reach the agent under its address.

An existing server keeps a list you wrote, on every install and update. Two lists an earlier release wrote without anyone choosing them are replaced by the default above on the next install: every address (0.0.0.0/0,::/0), and the server's own addresses alone. On a server installed without a management address that default is the empty list, so the agent's page stays open to every address behind its key. To keep 0.0.0.0/0,::/0 as it is, run the install with ANTELAO_INSTALL_AGENT_ALLOW=0.0.0.0/0,::/0. Plain HTTP that answered on every interface is moved to the loopback.

While the list names 0.0.0.0/0 or ::/0, the agent's Dashboard and ohm install warn that its key is the only protection.