@@PRODUCT@@

Een server toevoegen

Van een kale Ubuntu-server naar een werkende rol-node in één commando. Je vult in het paneel in waar de machine voor is, kopieert één regel, plakt die op de server, en kijkt daarna toe.

Geschreven voor: Beheerder

Van een kale Ubuntu-server naar een werkende rol-node in één commando. Je vult in het paneel in waar de machine voor is, kopieert één regel, plakt die op de server, en kijkt daarna toe.

Alleen beheerders zien dit. Resellers en eindgebruikers zien nooit welke machines er zijn.

Wat je nodig hebt

  • Een Ubuntu 26.04 LTS-server. Zie Welke Ubuntu hieronder: 24.04 koppelt nog wel, met een waarschuwing, maar valt buiten support; elke andere versie weigert de installatie.
  • Een echte machine of een volledige virtuele machine (KVM, Xen, VMware). Een LXC- of OpenVZ-container wordt geweigerd: een node laadt zijn eigen firewall, schrijft sysctls en maakt cgroups per account, en dat kan in een container niet zonder de host te raken.
  • Een publiek IPv4-adres op de interface zelf. Achter NAT kan de server wel naar buiten, maar de DNS-records die CoreCP publiceert wijzen dan naar een adres dat niemand kan bereiken.
  • Een volledige hostnaam die klopt: hostname -f moet hetzelfde antwoorden als wat je in het paneel invult. Het certificaat wordt op die naam uitgegeven.
  • Uitgaand HTTPS naar het paneel en uitgaand 9443 naar de certificaatautoriteit. Inkomend hoeft er niets open: de server belt naar buiten, nooit andersom.
  • Een groep in het paneel. Een server hoort altijd bij een groep; op een vers paneel is er nog geen, en de wizard zegt dat dan bovenaan met een knop Naar Groepen. Daar maak je er een aan met Groep aanmaken.
  • Voor de mailrol ook uitgaande poort 25 — de meeste providers zetten die standaard dicht en openen hem op verzoek.

Welke Ubuntu

Eén versie wordt ondersteund, één koppelt nog, de rest wordt geweigerd:

versiewat er gebeurt
Ubuntu 26.04 LTSondersteund. Hier gaat alles over wat je verder in dit handboek leest.
Ubuntu 24.04 LTSinstalleert en koppelt, met een waarschuwing op beide deuren. Valt buiten support.
iets andersde installatie stopt. CORECP_FORCE=1 zet dat opzij, maar dan draai je iets wat niemand meet.

24.04 wordt niet geweigerd omdat het nog steeds is wat providers standaard neerzetten. Een weigering op een machine waar de pakketten prima installeren is een weigering die niemand gelooft — en waar mensen omheen werken. Een waarschuwing die zegt wat het kost lees je wél.

Buiten support is een concrete belofte, geen grijstint. Op 24.04 installeren de pakketten (ze hangen alleen aan systemd), koppelt de server en beheert het paneel hem gewoon — en niets daarvan is gedekt. Er worden geen bugs op aangenomen, de PHP- en MariaDB-series worden tegen de bibliotheken van 26.04 gebouwd, en het eerstvolgende dat daar verandert kan het daar simpelweg ophouden. Het is een deur die openstaat voor een machine die onderweg is naar 26.04, geen tweede platform.

Je ziet het twee keer: het paneel zegt het bij het commando dat je gaat plakken, en de machine zelf zegt het in de preflight (warn operating system … outside CoreCP support). De volledige matrix staat in docs/versions-policy.md.

Stap 1 — vertellen waar de server voor is

Paneel → Servers → Server koppelen (of ⌘K, "Server koppelen").

Je vult in:

VeldWat het doet
Volledige naamDe identiteit. Het certificaat wordt hierop uitgegeven.
Vriendelijke naamAlleen voor de lijst. Optioneel.
GroepWie de machine mag zien.
LocatieVrije tekst: datacenter, stad, rack. Optioneel.
Adressen van de serverHet IPv4- en/of IPv6-adres waarmee de server verbinding maakt. Optioneel als de naam al naar de server wijst.
ProfielDe vorm van de machine. Vult de rollen en de webserver hieronder in.
Rollenweb, db, mail, dns, back-up, ftp — meerdere tegelijk mag.
ServergroepWaar pakketten op inplannen. Optioneel.
Geldigheid15, 30 of 60 minuten.

De rollen reizen mee ín het commando. Dat is het verschil met de meeste andere panelen: de server komt al ingericht boven in plaats van gekoppeld-en-leeg.

Waarom het paneel het adres van de server wil weten

Een nieuwe server haalt zijn certificaat bij de certificaatdienst van het paneel, op poort 9443. Die poort staat dicht voor iedereen, behalve voor de servers die je hier uitnodigt. Zodra je op Code uitgeven drukt, gaat de poort open voor de adressen van deze server — tot de code verloopt. Na de koppeling blijven ze toegelaten, want de server vernieuwt zijn certificaat daar elke paar weken.

  • Laat je het veld leeg, dan gebruikt het paneel wat het al van de server weet, en anders waar de naam naartoe wijst. Op het volgende scherm staat onder Toegelaten adressen welke adressen dat werden.
  • Wijst de naam nog nergens naar, dan zegt het veld dat. Vul dan het adres in waarmee de server naar buiten gaat — achter NAT is dat het adres van de router, niet dat van de server zelf.
  • Trek je de code in met Token intrekken, dan gaat de poort voor die server meteen weer dicht.
  • Neem je een server uit dienst, dan verliest hij zijn certificaat én zijn toegang tot de poort.

Zie je Geen — de certificaatdienst heeft geen eigen firewall, dan heeft een beheerder op de paneelserver bewust gekozen voor corectl ca firewall off, omdat een firewall ervóór (bijvoorbeeld die van je provider) poort 9443 al beperkt. Zet de poort daar dan alleen open voor de adressen van je servers.

Weigert de wizard elke nieuwe code met een melding over de firewall, dan zijn de firewallregels van de paneelserver niet geladen. De installatie zet ze nooit zelf uit; laad de regels (nft -f /etc/nftables.conf) en draai bash /usr/lib/corecp-panel/setup.sh finish.

De backuprol kiest een bestemming

Vink je back-up aan bij de rollen, dan verschijnt er één extra veld: Backup-bestemming. Daar staan de opslagplekken die je al hebt vastgelegd, zodat je hier geen adres, pad en wachtwoord opnieuw hoeft in te tikken.

Op dit moment bestaat de machine nog niet — je hebt een naam en een koppelcommando en verder niets — dus de keuze wordt bij de server vastgelegd en er gaat nog niets heen. Zodra de machine antwoordt zegt zijn eigen backuppagina dat er nog gekoppeld moet worden, met de knop ernaast.

Heb je nog geen bestemming, dan zegt het scherm dat ook: de server krijgt de rol, en waar hij heen schrijft kies je later. Zie De backups van je servers.

Je hoeft hier trouwens niets te beslissen. Zodra de machine is aangemeld toont de laatste stap van deze wizard de aanbeveling van het paneel zelf: naar welke bestemming deze machine zou moeten schrijven, met de vijf metingen waarop die volgorde berust, en één knop om hem te koppelen. Dezelfde kaart staat op de backuppagina van de machine zolang er niets is vastgelegd, dus dit veld leeg laten kost je niets.

Wat er met een nieuw account op deze server gebeurt

Onderaan stap 1 staat een kaart die de plaatsing hardop uitspreekt, nog vóór je een koppelcommando krijgt:

web + dns hier · database op stck2.corecp.dev · mail op stck2.corecp.dev

Dat is geen beschrijving van de regels maar het antwoord zelf: dezelfde plaatsingsmotor die straks het eerste account plaatst, met deze machine er alvast in. Eronder staat per rol de server die hem draagt en de reden die de motor gaf ("de minste websites in servergroep eu-shared").

Klopt die keuze niet, dan zet je hem per rol vast met de keuzelijst ernaast, en de kaart rekent opnieuw — je ziet dus wat er écht gaat gebeuren, inclusief het geval waarin je keuze niet kan en de pool de rol terugneemt.

Twee rollen hebben geen keuzelijst. Web niet, omdat het account op deze machine wordt aangemaakt en zijn bestanden hier staan. DNS niet, omdat een naamserverset wordt opgesomd en niet gekozen: een zone staat op álle naamservers van de pool, en er één vastzetten zou de set terugbrengen tot één machine.

Kiest een rol een andere server, dan regelt het paneel bij het eerste account de rest zelf: die machine krijgt te horen dat deze server erbij mag, de firewall gaat open voor precies dit adres en de databaselogins van het account krijgen er toegang vanaf. Je hoeft daar niets voor te doen.

Begin bij een profiel

Het formulier begint met een profiel: shared voor een alles-in-één machine, db-dedicated voor een databaseserver, mail-dedicated, dns-edge, backup-target, wordpress. Kies je er een, dan zie je meteen waar hij voor is en wat hij afstelt, en worden de rollen en de webserver hieronder ingevuld.

Daarna mag je alles nog aanpassen — een profiel is een startpunt, geen keurslijf. Vink je een rol bij of af, dan meldt het scherm dat de machine niet meer bij het profiel past, en wordt hij gekoppeld met precies de keuzes die op het scherm staan. Hij krijgt dan geen profielnaam, want een machine die de naam van een profiel draagt waar hij niet aan voldoet zou vanaf de eerste minuut een afwijking melden. Het profiel later alsnog geven kan altijd, op het tabblad Configuratie van de server.

Wil je gewoon zelf de rollen aanvinken, kies dan Aangepast.

Reist het profiel wél mee, dan zet de server zichzelf ermee op — inclusief de tools, de eigen serverinstellingen en de plafonds die erbij horen:

root@stck2:~# corectl join --code corecp1.… --show
panel        https://panel1.corecp.dev
node         stck2.corecp.dev
roles        db
profile      db-dedicated  (the roles above come from it)
authority    build.corecp.dev:9443

Zie ook het artikel Serverprofielen.

Stap 2 — het commando

Je krijgt één regel terug, met een zichtbare aftelling. Op de nieuwe server:

# 1 — de agent installeren (sla over als corectl er al staat)
curl -fsSL https://get.corecp.dev | bash

# 2 — koppelen (het paneel geeft je de echte code)
corectl join --code corecp1.eyJ2IjoxLCJwIjoiaHR0cHM6Ly9wYW5lbDEu…Q.78d8e8b8

De code is één keer bruikbaar, verloopt, en draagt de vingerafdruk van de certificaatautoriteit in zich. Daardoor is het eerste contact geen "vertrouw-wat-er-antwoordt": de server pint op die vingerafdruk vóórdat hij iets gelooft wat de autoriteit zegt.

Je kunt de code eerst lezen zonder iets te doen:

corectl join --show --code corecp1.…
panel        https://panel1.corecp.dev
node         stck2.corecp.dev
roles        web, db
authority    build.corecp.dev:9443
ca pin       c4430ea564db75b6
expires      2026-08-09T16:05:00Z
panel ips    185.117.226.121, 2a10:7180:100::121

Stap 3 — toekijken

Vanaf het moment dat je op enter drukt loopt de kaart in het paneel mee. Zes fasen, in deze volgorde:

FaseWat er gebeurt
PreflightDe machine wordt gelezen. Er wordt niets geschreven.
HardeningBasispakketten, sysctls, ssh-hardening, fail2ban, nftables.
mTLS-inschrijvingDe autoriteit ondertekent het certificaat van de node.
RolpakkettenDe gekozen rollen worden geïnstalleerd.
DienstenDe agent en de roldiensten gaan draaien.
Gezondheidcorectl doctor — "gekoppeld" betekent "werkend".

Voor elke fase staat een gekleurd bolletje, en onder de preflight staat er één per controle:

KleurBetekenis
GroenGelukt.
PaarsHier is hij nu mee bezig.
AmberEen waarschuwing — het gaat door, maar lees hem.
RoodHier is het misgegaan; hieronder staat waarom.
GrijsNog niet aan toe.

Op de server zie je hetzelfde:

[corecp] joining https://panel1.corecp.dev as stck2.corecp.dev
[corecp] roles: web, db
[corecp] certificate authority build.corecp.dev:9443, pinned on c4430ea564db75b6…

[corecp] == preflight == checking this machine before anything is installed
  ok   operating system             Ubuntu 26.04 LTS
  ok   architecture                 amd64
  ok   virtualization               kvm virtual machine
  ok   memory                       3.9 GB (db, web needs 2.0 GB)
  ok   port 80/tcp free             HTTP, nothing listening
  ok   panel reachable              https://panel1.corecp.dev answers, outbound is open
  ok   public IPv4                  185.133.89.70, the same address the panel sees
[corecp] preflight: this machine can carry db, web

De preflight

Dit is het stuk dat CoreCP anders doet. Andere panelen documenteren hun eisen; hier worden ze gecontroleerd, vóórdat er één pakket wordt gedownload. Faalt er één check, dan stopt het en is er niets geïnstalleerd.

Wat er gecontroleerd wordt: het besturingssysteem (Ubuntu LTS), de architectuur, of het geen container is, of poort 80/443 (en 25 voor mail, 53 voor dns) vrij is, of er geen restanten van MySQL/Postfix/een ander paneel staan, RAM en schijf per gekozen rol, een statisch publiek IPv4 en NAT-detectie, of het paneel uitgaand bereikbaar is, en de tijdsynchronisatie. Voor de mailrol daarbovenop uitgaande poort 25 en het PTR-record; voor de dns-rol dat 53 vrij is.

Elke check komt terug, ook de geslaagde. Wie een machine aan het repareren is wil de hele lijst, niet het eerste dat misging. Bij elke rode regel staat wat je eraan doet.

Je kunt de preflight ook los draaien, zonder te koppelen:

# op de machine zelf
corectl node preflight --roles web,db --panel https://panel1.corecp.dev

# of, voor een machine die al gekoppeld is, vanuit het paneel:
#   Servers → <server> → rol toevoegen

Exitcode 1 betekent "deze machine kan het niet dragen", dus dit is bruikbaar in een script.

Alleen de preflight draaien met de echte code, zonder te installeren:

corectl join --code corecp1.… --dry-run

De controle vóór de installatie: DNS, PTR en glue

De preflight hierboven kijkt naar de machine. Of de wereld de machine goed ziet, controleert hij maar ten dele: hij vergelijkt de PTR alleen voor de mailrol, en alleen met een waarschuwing. Zet je een reeks servers tegelijk neer, zoals een nieuwe productieomgeving, draai dan eerst de losse controle uit de repository. Die leest niets van een paneel en verandert niets op de server:

bash production-preflight.sh --fqdn web1.voorbeeld.nl --ipv4 192.0.2.10 \
     --ipv6 2001:db8::10 --roles web,dns-primary --ns ns1.voorbeeld.nl

Hij controleert per server de naam, het besturingssysteem, of het een VM is (en of de gastagent draait), processors, geheugen en schijf per rol, de klok, of de adressen op een interface staan, het privénetwerk, de A- en AAAA-records bij élke gezaghebbende nameserver, de PTR met de mailnaam en of die naam terugwijst, de glue van je nameservers bij het register, en of uitgaande poort 25 open is. Elke regel is groen of rood met de reden erbij.

De controle stelt zijn DNS-vragen altijd aan de echte resolver, nooit aan de lokale stub op 127.0.0.53. Die stub beantwoordt de eigen hostnaam en de eigen adressen uit de lokale configuratie, ook als er in DNS niets bestaat. Een PTR-controle via de stub is daardoor altijd groen.

Het volledige stappenplan voor een nieuwe productieomgeving staat in het draaiboek docs/operations/productie-opzetten.md.

Als het misgaat

Onderbroken halverwege. Draai hetzelfde commando opnieuw met --retry:

corectl join --code corecp1.… --retry

Dat is idempotent. Rollen die al staan worden met rust gelaten, en als de autoriteit het token niet nog eens wil tekenen — want het is opgebruikt door de poging die stukliep — gaat de run verder met het certificaat dat die poging heeft opgehaald.

De server komt niet bij de certificaatdienst. De koppeling stopt in de fase enrolment met een melding dat de dienst alleen de adressen uit de wizard toelaat. De server gaat dan via een ander adres naar buiten dan je opgaf. Trek de code in, vul het juiste adres in en geef een nieuwe code uit.

Een gekoppelde server kreeg een ander adres. Hij blijft werken, maar kan zijn certificaat niet meer vernieuwen. Op de paneelserver:

corectl ca firewall show
corectl ca firewall admit --name web1.example.net --address 192.0.2.20

Verminkt geplakt. De code heeft een controlesom. Een regel die in een chat of een e-mail is afgekapt geeft:

corectl: this join code is incomplete or was altered in transit

Kopieer hem opnieuw uit het paneel. Regeleindes en spaties in het midden zijn geen probleem — die worden eruit gehaald.

Verlopen. Het token gaat na 15-60 minuten dood; het commando zegt tot wanneer het geldig was. Geef een nieuw token uit in het paneel.

Firewall van de provider. Herkenbaar aan panel reachable of outbound SMTP (port 25) die faalt. De node belt uit; er hoeft niets ingaand open te staan. Wat wél open moet: uitgaand 443 naar het paneel, uitgaand 9443 naar de autoriteit, en uitgaand 25 als je de mailrol wilt.

Opnieuw beginnen. In het paneel: Servers → de server → gevarenzone → Server vergeten en opnieuw beginnen. Dat trekt het token en het certificaat in en verwijdert het record. Daarna op de machine zelf:

corectl join --reset            # certificaat en paneelbinding weg
corectl join --reset --purge --yes   # ook node.yaml: rollen en configuratie weg

--purge is een aparte vlag met een bevestiging, omdat node.yaml geen identiteit is maar configuratie: de rollen, de webserverkeuze, de DNS-primaries. Op een machine die nog accounts draait is dat geen reset maar een wissen.

Token intrekken zonder de server te vergeten. In het paneel bij het commando: Token intrekken. Dat gaat ook naar de certificaatautoriteit — een intrekking die de ondertekenaar niet kent, is een knop die liegt.

Stap 4 — wat gaat deze machine doen?

Zodra de voortgangskaart geslaagd meldt, verschijnt er een vierde kaart: Wat gaat deze machine doen? Hij noemt de rollen die de machine draagt, zegt in welke servergroep hij zit — bij een verse machine: in geen enkele — en geeft je één keuzelijst en één knop om hem in een pool te zetten.

Dat is precies de zin hieronder, veranderd in een handeling. Tot deze sessie stond die zin in dit handboek en was de enige knop ervoor de eerste stap van de wizard: had je de servergroep daar overgeslagen, dan stond de machine er voor altijd buiten en was de opdrachtregel de enige weg terug.

Later doen is een echt antwoord en staat er als zodanig. Een platform waarvan alle machines hetzelfde doen heeft helemaal geen pools nodig — dan plant elk pakket in op de hele nodegroep, en dat werkt. Zijn er nog geen pools, dan zegt de kaart dat en wijst hij naar Servers → Plaatsingspools.

Later alsnog, zonder de wizard:

curl -s -b jar -X POST https://panel1.corecp.dev/api/v1/nodes/stck2.corecp.dev/pool \
  -H 'Content-Type: application/json' -d '{"server_group_id":"<pool>"}'

Zie Waar een website draait voor wat een pool is en wat het beleid ervan doet.

Na de koppeling

  • Firewall en fail2ban staan er, per rol ingericht.
  • De node abonneert zich op het kanaal waar de vloot op staat.
  • Bestaande websites verhuizen niet. Nieuwe capaciteit krijgt pas werk als je de machine in een servergroep zet — de kaart in stap 4 is daarvoor.

Nog aan te sluiten

Onder de vorige kaart verschijnt Nog aan te sluiten: twee instellingen die niet in het koppelcommando pasten en pas kunnen zodra de machine antwoordt.

Uitgaande e-mail. Laat deze server zijn uitgaande post via een andere server versturen — bijvoorbeeld de mailgateway van de vloot. Zonder relay levert hij zelf af op poort 25. Vraagt de relay om een login, dan vul je die erbij in; het wachtwoord gaat in de aanvraag naar de machine en komt nooit terug uit het paneel. Van de commandoregel is het hetzelfde:

root@stck1:~# corectl mail smarthost set mail1.corecp.dev
[corecp] smarthost set to [mail1.corecp.dev]
root@stck1:~# corectl mail smarthost show
smarthost: [mail1.corecp.dev]
user:      none (no SASL)

Heeft deze machine de mailrol niet, dan zegt de kaart dat: hij verstuurt dan rechtstreeks, en een relay instellen kan pas met de mailrol erop.

Naamserver. Draagt de machine de dns-rol, dan serveert hij nog niets tot hij in een naamserverset zit. De knop brengt je er direct heen; zie Gedeelde naamservers.

De kaart herhaalt bovendien waar de overige diensten van een account terechtkomen, zodat je dat ook terugziet als je deze pagina later opnieuw opent.

Dit bewijzen zonder reserveserver

De acceptatietest van deze functie (scripts/e2e-r2-node-wizard.sh) heeft geen wegwerp-VM tot zijn beschikking — de buildserver is zelf een KVM-gast zonder geneste virtualisatie. Deel (b) is daarom een echte herinschrijving van ns2.corecp.dev door dezelfde flow: een echte joincode, een echte preflight, een echt door de echte CA ondertekend CSR, de echte rolfase en de echte doctor. Het script maakt vooraf een kopie van het certificaat en node.yaml en zet die terug als er iets misgaat; op groen blijft er één verschil over, namelijk dat de node een nieuwer certificaat heeft — en dat is precies waar een koppeling voor is.

De installer laat zien wat een server gaat vertrouwen

De regel curl -fsSL https://get.<domein> | bash die de wizard toont, hoort bij de pakketbron van dit paneel: staging bij de buildserver, productie bij het productiepaneel. De installer leest op die plek welke pakketbron en welke sleutels de server moet vertrouwen en toont hun vingerafdrukken voordat hij iets schrijft; vergelijk ze met je draaiboek. Daarna staan ze in de serverinstellingen en toont corectl update trust ze op de server. De voorbeeldnaam in het naamveld (web2.example.net) is een voorbeeld.