Plesk License Expired: What Still Works and How I Got Around It

An expired Plesk license blocks the panel and the plesk CLI, but sites and mail keep running. How I restored a mailbox anyway with mailmng-core.

Share
Plesk License Expired: What Still Works and How I Got Around It

A Plesk box I look after ended up running on an expired license. It had been a trial, the trial ran out, and the decision on whether to buy a real license (or move off Plesk entirely) wasn't made yet. Meanwhile the server had to keep doing its job — and then I needed to restore a mailbox on it.

Turns out an expired Plesk license is a strange half-state. Most of the server keeps running just fine. The panel and the plesk CLI refuse to do anything. And underneath that, Plesk's own low-level tools still work, if you're willing to talk to them directly.

TL;DR: With an expired license, websites and mail keep serving. The web UI and every plesk bin ... command refuse with a license error. Let's Encrypt auto-renewal through Plesk stops — move TLS to certbot before your certs expire. plesk db still works. And the mail backend tools in /usr/local/psa/admin/sbin/ (mailmng-core, mailmng-domain, mailmng-outgoing) don't check the license — that's how I restored a mailbox without the panel.

What keeps running

From what I saw on this box:

  • nginx/Apache keep serving sites. Existing vhost configs stay in place, PHP-FPM keeps running.
  • Postfix and Dovecot keep running. Mail in and out, IMAP logins, SMTP AUTH — all fine.
  • MySQL/MariaDB keeps running, and you can still reach it as Plesk's admin user from the shell:
mysql -uadmin -p"$(cat /etc/psa/.psa.shadow)"
  • plesk db — the shortcut into Plesk's own database — still works. I only used it for SELECTs to see what Plesk thought the mail config looked like. I wouldn't write to the Plesk DB by hand.
  • fail2ban, unattended-upgrades, cron, Docker — anything that isn't Plesk doesn't care about Plesk's license.

What stops

  • The panel UI on :8443 — you get the license screen and nothing else.
  • Every plesk bin command. Creating a domain, a database, a mailbox, changing a PHP handler — all of it fails with a "license key has expired" message.
  • Let's Encrypt renewal through Plesk. The certificates already installed keep working until they expire. Then they don't, and nothing renews them. That's the one that actually takes sites down, weeks later, when nobody remembers the license. I wrote up the escape route in moving Plesk's Let's Encrypt to certbot — do it while you still have time.
  • Licensed add-ons that hang off the Plesk license. On this box there were pending updates for a security add-on whose license status depends on Plesk's; I wouldn't count on those updating.
  • Domain limits. A trial or small license comes with a domain limit. On an expired license I didn't test what Plesk enforces and when — but I wouldn't bet the sites on "it's been fine so far".

The job: restore one mailbox

A printer with scan-to-email sends its scans through this server. It logs in via SMTP AUTH to its own mailbox on this server and sends from there. That mailbox existed on an older server that was gone; it wasn't part of what got migrated. I had the old server's full Plesk backup locally.

Normally: create the mailbox in the panel, set the password, done. With the panel dead, plesk bin mail --create refused too.

Two useful things were in the backup:

  • the Maildir, in the domain's backup_domainmail_*.tzst
  • the mailbox password, in the domain's backup_info_*.xml — stored as <password type="plain">. In plain text.

That second one is a security note on its own: a Plesk backup can contain mailbox passwords in plaintext. Treat the backup files like a password database. Encrypt them at rest, restrict who can read them. In this case it was convenient: same password, so the printer didn't need reconfiguring.

Gotcha: mailmng-core and friends don't check the license

plesk bin mail is just a front end. The actual work on Postfix/Dovecot is done by tools in /usr/local/psa/admin/sbin/:

ls /usr/local/psa/admin/sbin/ | grep mailmng
# mailmng-core, mailmng-domain, mailmng-outgoing, ...

/usr/local/psa/admin/sbin/mailmng-core --help

These didn't check the license. What I used:

Tool Actions
mailmng-core --add-domain, --add-mailname, --add-mailbox, --set-password
mailmng-domain --set-domain-key, --install-certificate
mailmng-outgoing --add-subscription, --add-mailname

They take their input as JSON on stdin, with --wait-stdin. The password for --set-password comes from the PSA_PASSWORD environment variable, not from an argument — good, it doesn't land in the process list or shell history.

# shape only — build the JSON from --help and your existing config
/usr/local/psa/admin/sbin/mailmng-core --add-mailname --wait-stdin < mail.json

PSA_PASSWORD='the-old-password' \
  /usr/local/psa/admin/sbin/mailmng-core --set-password --wait-stdin < mail.json

I'm not going to paste a full JSON here because I'd be guessing at fields for your Plesk version. What I can tell you from making it work:

  • The --help output does not list everything that's required. My calls failed until I added a maillists field that the help never mentioned.
  • certificates belongs on the top level of the JSON, not inside the domain object.
  • Once you have a JSON that works, keep it. Next time you'll need it again.

Gotcha: the order of calls

--add-domain failed on the first try because it wanted to set a quota and the mailname directories didn't exist yet. The sequence that worked:

  1. --add-domain — fails at the quota step, ignore it
  2. --add-mailname
  3. --add-mailbox
  4. --add-domain again — now it succeeds, and the domain shows up in Postfix's virtual_domains map

Then copy the Maildir from the backup into the mailbox directory, fix ownership, done.

Gotcha: "You are not allowed to use sendmail utility"

The mailbox could log in and receive. Sending failed with "You are not allowed to use sendmail utility". That message comes from Plesk's mail milter (psa-pc-remote, listening on a local port), which only lets known senders through. The mailname has to be registered with mailmng-outgoing as well (--add-subscription, then --add-mailname). After that, the printer could send.

Gotcha: back up the Postfix maps first

Before touching anything, I copied Postfix's map files to a dated directory under /root/. The same server hosts other domains' mail, and these tools rewrite shared maps. If something had gone sideways, I wanted the old state of everything one cp away. I also checked afterwards that the other domains' mail was untouched.

TLS for the mail hostname

The printer connects to a mail. hostname, so that name needs a valid certificate on SMTP. I got it with certbot (webroot on Plesk's default vhost, not the site docroot — the ACME challenge is served from there), installed it into Postfix's SNI map with mailmng-domain --install-certificate, and added a certbot deploy hook so renewals re-install it. Same pattern as in the certbot migration post.

Verifying

# SMTP AUTH on submission
openssl s_client -connect mail.example.com:587 -starttls smtp -quiet
# then EHLO, AUTH ... by hand, or use swaks:
swaks --to someone@example.org --from scan@example.com \
      --server mail.example.com:587 --tls --auth-user scan@example.com

# IMAPS login
openssl s_client -connect mail.example.com:993 -quiet

SMTP AUTH on 587 worked, IMAPS login worked, inbound delivery worked.

Gotcha: delivery still failed — DNS

Sending worked from the server's side, and the big mail providers still rejected the scans. The domain had no SPF, no DKIM, no DMARC records. Gmail rejects that with 550-5.7.26 (unauthenticated sender). Nothing on the server fixes that; the records go into the DNS zone. Whether Plesk's DKIM signing even runs on an expired license I didn't verify — a locally delivered test mail had no DKIM header. SPF alone gets you past the hard rejection in many cases, but set all three. And lower the TTL before you change DNS if your zone has day-long TTLs.

The panel itself

One more thing: an expired panel on :8443 is still a login page on the public internet. It does nothing useful anymore, so I'd restrict it to your own IP until the license question is decided — with the host firewall, carefully, since Plesk and fail2ban have their own iptables chains. And SSH should be key-only regardless — see the SSH hardening checklist.

Buy, or leave?

Running Plesk on an expired license works for a while if you know where the levers are. It's not a state to stay in: you can't manage anything through the supported paths, and every change is you reverse-engineering Plesk's internals. Either buy the license or move to something that doesn't stop working when a key expires — for example KeyHelp as a free Plesk alternative.


Related posts