Windows Server

Cert Camel

Installing on a server that nobody is signed in to, where renewal has to run unattended and more than one person needs to open the console. One decision — which Windows account you are signed in as when you run setup — determines whether any of that works, and it cannot be changed afterwards from inside the program.

1. The one decision

Everything on this page follows from a single line, which appears in setup.ps1 and again in acme-lib.ps1:

$userId = [Security.Principal.WindowsIdentity]::GetCurrent().Name

Whoever runs First Time Setup becomes the account that all four scheduled tasks run as. There is no prompt for this and no setting to change it afterwards. The program does not ask, because it has no way to verify a password you typed on somebody else's behalf.

A second constraint arrives from the other direction. Credentials — your DNS API token, load balancer API passwords — are encrypted with Windows DPAPI, which ties them to one Windows user on one machine. The account that saves a credential is the only account that can ever read it back.

These two facts have to agree

Renewal runs as the task's account and needs to decrypt the DNS token. If the tasks run as svc-certcamel but the credentials were saved by you, renewal fails at the DNS step — and it fails quietly, months later, when a certificate first comes up for renewal. Task Scheduler reports Ready the entire time.

Making them agree is simple: do the whole install signed in as the service account. Not as yourself, and not as whichever domain admin happens to be helping.

2. Ask your systems team

Send this before you book the change window. The account has to exist before you touch the machine, and two of these are easy to forget and painful to discover live on a screen share.

What to ask forWhy it matters
A service account, e.g. svc-certcamel It owns the scheduled tasks and the encrypted credentials, permanently.
Password set not to expire Renewal is unattended. An expired password stops it with no warning.
Local administrator on this VM Registering a task that runs while signed out needs elevation. Needed for setup only — the tasks themselves run unelevated.
Allowed to sign in over RDP You have to be this account to install. Service accounts are often denied interactive logon by policy, which is precisely the thing that stops this install dead.
“Log on as a batch job” Scheduled tasks need it. Usually granted implicitly — ask explicitly rather than find out on the first unattended run that it was not.

Nothing needs opening on the firewall. The console binds to 127.0.0.1 and is reachable only from the machine itself, over RDP. Renewal uses DNS-01 challenges, so it needs no inbound anything — only outbound HTTPS to your DNS provider and your certificate authority.

3. Sign in as the service account

RDP to the server as the service account itself. Not as yourself with a plan to switch over later.

The trap that silently ruins the install

If the service account is not a local administrator, right-click → Run as administrator asks for admin credentials and then runs the program as that administrator. GetCurrent().Name returns the admin, every task is registered to the wrong account, and there is no error and nothing on screen to notice.

That is why local admin on the account matters. When the account is already an administrator, elevation keeps its own identity.

Confirm who you are before going any further:

whoami

It must print the service account. If it prints you, stop and sign out.

4. Get the folder onto the server

Two ways, and on a server the choice has a consequence worth a moment's thought.

git clone https://github.com/Isaiah63/CertCamel.git C:\CertCamel

A clone lets Settings → Update pull new versions in place, which is worth having on a machine you visit twice a year. It also skips the unblock step below, because the files never arrived through a browser. It does need git installed on the server, which is sometimes a conversation of its own.

Otherwise download the release .zip, and before extracting it: right-click → Properties → tick Unblock → OK. Windows marks files that came from the internet and PowerShell refuses to run them. If you have already extracted it:

Get-ChildItem -Recurse C:\CertCamel | Unblock-File
Not in a synced or redirected folder

C:\CertCamel is fine. Not OneDrive, not a redirected Documents folder, not a roaming profile path. The folder holds unencrypted private certificate keys, and a synced folder copies them to somebody else's servers. Folder redirection is common on servers and easy to miss — check where C:\Users\svc-certcamel\Documents actually resolves before using anything beneath it.

5. Run First Time Setup

Right-click First Time Setup.batRun as administrator.

Elevation is not optional here. Without it, task registration falls back to a mode that runs only while that user is signed in, and it does so with a warning that is easy to click past. Section 6 is how you prove that did not happen to you.

Setup asks whether to keep the page running. Say yes. On a server the alternative is a console that exists only while somebody has a window open, and is gone after every reboot until a human signs in and starts it again.

It offers a fixed port for that. Take it — a pinned port is what makes the address predictable enough to write down in a runbook.

6. Prove the tasks are right

Do not take the screen's word for it. Run this before moving on:

Get-ScheduledTask -TaskName 'Cert Camel Renew','SSL Cert Check',
    'Cert Camel Monthly Report','Cert Camel Server' |
  Select-Object TaskName,
                @{n='RunsAs';   e={$_.Principal.UserId}},
                @{n='LogonType';e={$_.Principal.LogonType}}

Every row must show:

  • RunsAs — the service account. If it shows you, the elevation trap in section 3 caught you. Sign in properly as the service account and run setup again.
  • LogonTypeS4U. If it says Interactive, setup was not elevated. Renewal will never fire while nobody is signed in, and Task Scheduler will still show Ready.

The third task really is called SSL Cert Check rather than Cert Camel Check — an older name that stuck.

Why S4U rather than a stored password

S4U signs the account on without a password, so no password has to be stored anywhere to run the tasks. The obvious worry is that a passwordless logon cannot reach DPAPI, and would therefore fail to decrypt the DNS token on an unattended run. It can, and it does — that was tested rather than assumed.

7. Enter the credentials

Open the console with Open Tracker.bat, still signed in as the service account, and add your DNS provider and any load balancer credentials under Settings.

There is a detail here that is reassuring once you see it. The person at the keyboard never writes the credential — the server does. The page is a window onto a process already running as the service account, so anything saved through the console is encrypted as that account no matter who clicked the button. That is what makes section 9 possible.

Issue one certificate against staging before you finish. Settings → Certificate Authorities has the switch. Staging certificates are untrusted by browsers and free of rate limits, which makes them the right way to prove the DNS credential works while somebody is still watching.

8. A name and HTTPS

Set up while running setup, which walks through it as its last step. The console serves itself over HTTPS on the name you give it, using a certificate it issued; 127.0.0.1 keeps working alongside, which is the way back in if the name stops resolving or the certificate lapses. Settings → General → Tracker address is where the name lives afterwards, and clearing it is what returns the console to plain HTTP — there is no separate switch.

The name resolves to 127.0.0.1 through the machine's hosts file — no public DNS record is needed or wanted. Read the warnings on that panel before ticking HSTS; they describe how to get back in if it goes wrong.

9. Who can open it

This is the part most people picture incorrectly.

Installing had to happen as the service account. Opening the console day to day does not. Any local administrator on the server can sign in as themselves and use it, without ever knowing the service account's password.

The token granting access to the API lives in jobs\session.json, and that file is locked to exactly three principals: SYSTEM, BUILTIN\Administrators, and the account running the server. A local administrator can read it. Anybody else cannot, and gets no console at all.

For them the routine is simply: RDP in, double-click Open Tracker.bat. It detects the copy already running from the boot task, opens the browser at its address, and closes itself rather than starting a second server.

Themes are per person, not shared

The theme is stored in the browser rather than on the server, so two administrators never overwrite each other's choice — each keeps their own. It is also per address: the same person opening https://tracker.example.com:8787 and http://127.0.0.1:8787 gets two independent themes, which looks like a bug and is not.

10. What must never happen

Nobody re-runs First Time Setup as themselves

It re-registers all four tasks to whoever runs it. A colleague running it in six months to “repair” something would silently move renewal onto their own account, which then cannot decrypt secrets.xml. Renewal stops. Nothing reports an error until a certificate expires.

Write it on the change ticket. If setup genuinely does need re-running — after moving the folder, for instance — sign in as the service account first, exactly as on day one.

The same applies to resources\setup.ps1 -RepairTasks, which exists for the case where the folder moved and the tasks still point at the old path. Useful, and it must be run as the service account.

11. Handover checklist

Everything on this list is something you can demonstrate on the screen share, which is what makes it the right place to stop.

  • whoami printed the service account while you installed
  • All four tasks show the service account and S4U
  • A staging certificate was issued end to end
  • The console is reachable after a reboot with nobody signed in
  • A second administrator has opened it as themselves
  • Alerts are configured and a test email arrived — on an unattended box, email is the only thing that will tell you renewal has stopped
  • The folder is not in a synced or redirected path
  • The change ticket says: never re-run First Time Setup as anyone but the service account

12. When it breaks

What you seeWhat it is
Tasks show Interactive, not S4U Setup was not elevated. Run it as administrator, signed in as the service account.
Tasks show the wrong account Setup ran as somebody else — usually the elevation trap in section 3. Sign in as the service account and run setup again.
Renewal fails on the DNS credential The credential was saved by a different account than the task runs as. Re-enter it through the console while the server is running as the task's account.
Console is gone after a reboot The Cert Camel Server task was not installed, or was declined during setup. Run setup again and answer yes.
A colleague gets no console They are not a local administrator, so they cannot read the session token. That is the design rather than a fault.
“Not recognised as a cmdlet” on a fresh extract The archive was not unblocked before extracting. Run the Unblock-File line from section 4.

The run logs in jobs\ carry the narrative of every scheduled run, including the ones nobody watched. Logs → Run logs in the console is the same thing with a reader attached.