Reading the server advisor
Every CoreCP server checks itself. Around fifty checks: is everything running, is there room, does the firewall agree with reality, is a certificate about to expire, and — new — is this address on a blocklist, is there a PHP release here th
Written for: Administrator
Every CoreCP server checks itself. Around fifty checks: is everything running, is there room, does the firewall agree with reality, is a certificate about to expire, and — new — is this address on a blocklist, is there a PHP release here that stopped getting security fixes, is something listening that nobody meant to open.
The answer is one screen: Servers → the server → Open the advisor.
The three colours, and what they mean
A check used to be right or wrong. That did not work: by far the most findings are not an outage, and not nothing either. So there are three:
| Colour | What it means | What you do |
|---|---|---|
| OK | The check passed and has nothing to say. | Nothing. |
| Attention | It passed, and it is worth saying. | Schedule it. Nothing is broken now. |
| Critical | This is wrong. | Today. |
Critical does not mean the server is down. The clearest example: if your server's address is on a spam blocklist, that is critical — your mail arrives nowhere — while every website on that machine is serving perfectly. The other way round, a full disk can be both critical and take the machine out. The advisor says how bad it is; whether the machine is serving is a different question, and that one is on the server dashboard.
There is no score. Deliberately: "your server is 82% healthy" answers no question anybody actually has. You get a list of findings, worst first.
The screen
Top to bottom:
- The header — the server's name, and one word for how it is doing. Under it one sentence: "2 critical item(s), 4 wanting attention", with when it was last looked at.
- Check now — the button top right. See below.
- The category bar — All · Security · Performance · Configuration · Software, each carrying how many items want attention inside it. Click one and the list below narrows to it. The filter is in the address, so "the security findings on stck1" is a link you can paste into a ticket.
- Needs attention — only the items at attention or worse, worst first, each with the button that takes you to the screen that fixes it. If there is nothing, a green line says so.
- All checks — the full list, including the green ones. They are there on purpose: when you have just fixed something you want to watch the row go green, and a screen that only shows problems cannot do that.
The button on a finding reads Fix when it goes to a screen in the panel, and Open when it leaves the panel — for a blocklist that is the delisting form of the list itself, which is not ours.
Check now
Three of the checks cannot be answered from the machine alone:
- is my address on a blocklist — that is a question for Spamhaus;
- does this PHP release still get fixes — that is a question for a lifecycle register on the internet;
- how well is the PHP cache doing — that means asking every PHP worker on the machine to work something out.
Those three are far too slow — and far too rude to the other end — to ask again on every page view. So they are measured on a schedule (a job runs on the server every hour) and the screen reads the result. That is why such rows say "— measured 12 minutes ago": that is how old the measurement is.
Press Check now and the server measures them again, now. It takes a few seconds. Do it after you have fixed something — after having your address removed from a blocklist, say — or you are looking at the old answer.
Somebody who may only look does not see the button: re-measuring sends the server out to the internet, and that is an administrator's action.
The new checks, and what they watch for
| Check | Category | When it fires |
|---|---|---|
| Open ports | Security | Something is listening on a public address that the firewall policy does not declare. A data service (MySQL, Redis) exposed with nothing filtering is critical. |
| OPcache | Performance | The PHP cache is under 95%, or switched off somewhere. This is the cheapest performance win there is. |
| IP reputation | Configuration | An address of this server is on zen.spamhaus.org. Critical, with the link to the delisting form on the row. |
| Runtime support | Software | A PHP release, distribution or database edition is running that gets no security fixes any more, or stops within three months. |
A few things the advisor deliberately does not do:
- A PHP worker that has served fewer than 500 requests since its restart gets no verdict on its cache. The number means nothing then, and an amber row that says nothing teaches people to ignore amber.
- A blocklist that refuses your question (which happens through a public DNS server) is not reported as "you are listed" but as "I could not ask, and here is why". That difference matters: the other one would send you to a delisting form for a listing that does not exist.
- If the server has more PHP workers than fit in one measuring round (twelve), it takes a different group each round. After a few hours everybody has had a turn, and the row says how many are still waiting.
From the terminal
Everything on the screen is in corectl — the screen reads literally this:
# The whole list, with a severity and a category per row
corectl doctor
[ ok ] config operating system Ubuntu 26.04 LTS
[warn] software pending updates 5 pending upgrade(s)
[CRIT] config ip reputation 185.117.226.120 on zen.spamhaus.org (XBL …)
...
Node is healthy. 1 critical, 2 to look at (corectl doctor --json).Note the last line: "Node is healthy" and a critical item at the same time. That is exactly the difference above — the machine is serving, and something is wrong.
# Only what wants attention
corectl doctor --json | python3 -c '
import json,sys
for c in json.load(sys.stdin)["checks"]:
if c["severity"] != "ok":
print(f"{c[\"severity\"]:5} {c[\"name\"]:20} {c[\"detail\"]}")'
# Re-measure what is due — respects the intervals, so this often does nothing
corectl advisor refresh
nothing was due — every measurement is still fresh (--force to re-measure)
# Re-measure everything, now. This is what "Check now" does.
corectl advisor refresh --force
measured: ip reputation, runtime support, opcache (573ms)The hourly job that does the measuring:
systemctl list-timers corecp-advisor.timer
journalctl -u corecp-advisor.service --since -1dAbove one machine: the platform and an account
The advisor above looks at one server. The same checklist exists at two levels above it, and both of those are panel questions: a machine cannot report that it is silent, and it does not know which names a customer published, which plan sits under an account, or which release channel a wave expects.
On the front page: the platform
The panel asks every joined machine (node.doctor), rolls the answers up, and adds the things only the panel knows:
| Row | When it fires |
|---|---|
| Node unreachable | The agent answered before and does not now. |
| Node has stopped reporting | It is recorded as joined and has produced no metrics for over a quarter of an hour. |
| Checklist unreadable | The machine answers; its checklist does not. That is not the same as "nothing wrong". |
| Service is down | The node answers and a service it should be running is stopped. |
| Disk space / Inodes across the fleet | A filesystem is filling up — in bytes, or in files. |
| Fleet certificate | The certificate the panel talks to every node with is expiring. |
| Channel drift | A machine follows a different release channel than its wave expects. |
| Backups across the fleet | A machine with the backup role has no recent snapshot. |
| Failed tasks · Suspended accounts | Work that did not finish, and accounts serving nobody. |
Under those are the machines' own findings, with the machine's name on them — so two servers with the same problem are two rows and you can see which is which.
Every row clicks through to its own list. With exactly one machine at fault the button opens that machine; with several it opens the filtered list (/nodes?state=degraded). A number that names a problem and goes nowhere is a dead end.
On an account: one customer's hosting
Customers → the account → Overview. The same attention panel is at the top, and the account's full checklist is under it:
| Row | When it fires |
|---|---|
| The website answers | The name points here and the server returns no page. Critical — this is what a visitor sees. |
| DNS points here | The website exists here and its name resolves somewhere else. |
| SSL certificate | Less than 30 days left (attention) or less than 14 (critical), or there is none. |
| SPF · DKIM · DMARC | The domain sends mail from here and publishes no such record. |
| The plan's disk space | Over 80% of what the plan allows (attention) or over 95% (critical). |
| File limit | The account is running out of files rather than of space. |
| PHP support | A website runs a PHP release that gets no security fixes. |
| Your own backups | The account holds no recent backup of its own. |
And among them, under the same check name as on the server itself, sits IP reputation: if an address of the machine is on a blocklist, you see it on that machine and on every account running on it. One finding, two screens — because the customer whose mail is bouncing has to be able to see why without opening a server screen. They do not get the button to the delisting form: that is an operator action.
What a customer does not see are the machine rows that only concern the operator — an expiring agent certificate, for instance. A warning about something you cannot see and cannot fix is noise.
DMARC at p=none is amber, not red
The most common row, and the deliberate choice behind it. p=none says: "dear receiver, do check my mail, but do nothing about it yet — just send me reports." That is the correct first rung of the ladder; it is how you are supposed to start. It is only the wrong rung to stay on.
So: amber, with a button to Mail security, where you move it to quarantine and then to reject. Never red — marking somebody red for doing it in the right order only teaches them to ignore red.
Check now, and what does not happen by itself
An ordinary page load sends nothing out of the panel. The fleet fan-out, the DNS lookups and the request to your website all read a five-minute cache. Only Check now actually leaves — otherwise a dashboard somebody leaves on a wall would fetch customers' websites every thirty seconds.
A certificate that does not verify does not count as "the site is down", by the way: that is what the certificate row is for. The advisor retries once without verification, purely to learn whether there is a server behind it.
From the terminal, on the panel
# The whole fleet: the rolled-up rows, then what each machine reports itself
corecp-panel advisor platform --config /etc/corecp-panel/panel.yaml
the platform: crit · 3 machine(s), 1 unreachable · measured 2026-08-13T21:04:11Z
SEVERITY CHECK CATEGORY DETAIL
CRIT platform.config.node-unreachable config 1 machine answered before and does not now: ns2.corecp.dev
CRIT node.config.blocklist.stck1-… config stck1.corecp.dev: 185.117.226.120 on zen.spamhaus.org
WARN platform.software.channel-drift software stck2.corecp.dev follows edge, wave wave-2 expects stable
# Including the checks that passed
corecp-panel advisor platform --all
# One customer, by panel id, by node/username, or by a unique username
corecp-panel advisor account test300
# Measure again instead of reading the cache
corecp-panel advisor account test300 --refreshAnd the round that runs by itself, by hand:
# Gather, report what changed, and say how much
corecp-panel advisor run --json
{"changed":1}
# Again, on a fleet where nothing changed
corecp-panel advisor run --json
{"changed":0}That second zero is the point. A finding that has not changed says so once and then stops — otherwise it is not a warning, it is wallpaper.
One finding, one message
The advisor never mails anybody. Two findings are handed to the notification system, and exactly two:
- an address of a server on a blocklist;
- a website that stopped answering.
Those two had no owner. Certificates, backups and quota do have one — they already produce a system mail with their own thresholds and damping — so the advisor leaves them alone. It shows them; it does not report them. Otherwise one expiring certificate would be a mail and a bell, which is exactly the double stream this removed.
The two that do go through send no mail either: they write an audit row, and that row is the bell, web push and Telegram — each filtered by the reader's own preferences.
# Which check goes through which channel, in one table
corecp-panel health kinds --config /etc/corecp-panel/panel.yaml
ID AUDIT ACTION CATEGORY MAIL KIND PAGES WHAT
health.node.blocklist node.health.blocklist fleet - no An address of a node is on a blocklist
health.site.down domain.health.down account - no A website is not answering
health.cert.expiring cert.health.expiring account cert.expiring no A certificate is expiringA dash in MAIL KIND and no in PAGES: that is what "no double message" looks like from the outside.
When something is not right
| What you see | What it usually is |
|---|---|
| "not measured yet" on three rows | No measurement has run yet. Press Check now, or wait an hour. |
| "measured 2 days ago" | The hourly job is not running. Look with systemctl list-timers corecp-advisor.timer. |
| "the resolver on this node is not allowed to query zen.spamhaus.org" | The server is asking through a public DNS server (8.8.8.8 and the like), and Spamhaus does not answer those. Put a resolver of its own on the machine. |
| A row is amber and you cannot see why | Open it in All checks: under the name is what the server measured, and the button beside it takes you to the screen that fixes it. |
| There is no Check now button | You may look but not administer. Ask a server administrator. |
| The address was listed and you had it removed | Press Check now. Otherwise the old measurement stands for up to six hours. |
| The front page says "Checklist unreadable" | The machine answers; its checklist does not. Open the server page — this is not the same as "nothing wrong". |
| A website reads The website answers · critical while it plainly works | The measurement is up to five minutes old. Press Check now on the account. |
| DNS points here is amber for a domain that has not moved yet | Correct: the website exists here and its name still resolves elsewhere. The row goes when the delegation does. |
DMARC stays amber after setting p=quarantine | DNS caches. Press Check now on the account; the advisor reads what is published, not what is configured. |
Getting an address removed from a blocklist without first knowing why it was on there is wasted effort, by the way: a compromised site or a forwarded mail stream puts it back within a day, and a relisting costs far more time than the wait did.
See also
- The firewall of a server — where Open ports sends you.
- The PHP policy of a server — where OPcache and Runtime support send you.
- Server settings and services — where most of Configuration sends you.
- Email we send you — when a critical item actually reaches you.
- Mail security and DNSSEC — where the account advisor's SPF, DKIM and DMARC rows send you.
- Making email arrive — the same three records, without the jargon.