Naar de inhoud

Blog ·

Webhosting verkopen met Virtualmin

Verkoop hosting op Virtualmin: welke Webmin-gebruiker en welk wachtwoord, waarom de TLS-fingerprint verplicht is, en wanneer quotavelden leeg blijven.

Door Provibr

Virtualmin is een van de oudste controlepanelen die nog echt gebruikt worden (het bestaat sinds 2004) en het heeft een installed base die je op GitHub niet ziet. Op 21 augustus 2026 had de repository 412 sterren, 129 forks en 46 bijdragers. Dat is klein naar GitHub-maatstaven en zegt vrijwel niets over hoeveel kleine hosters het draaien.

Wat het wél zegt, is dat er bijzonder weinig geschreven is over verkopen op Virtualmin. Deze pagina is dat: hoe Provibr aan een Virtualmin-machine koppelt, welke beslissingen het paneel je oplegt, en waar de scherpe randen zitten. Alles hieronder is gemeten tegen een echte installatie van Virtualmin GPL 8.1.2 op Ubuntu 24.04.

Webmin is het paneel, Virtualmin doet de hosting

Je kent het product als Webmin. Dat staat op de inlogpagina, in de documentatie en in elke zoekopdracht. Maar kale Webmin beheert een Linux-machine: het kent het begrip hostingaccount helemaal niet. Wat Provibr werkelijk aanstuurt is Virtualmin: de module die domeinen, plannen en quota kent.

Dat is belangrijker dan het klinkt. Op een machine zónder die module is het remote-API-eindpunt van Virtualmin er simpelweg niet: het antwoordt precies zoals een modulenaam die je verzint. Dat is gemeten in stap nul van het onderzoek, vóór er iets geïnstalleerd was. Er valt dus niet terug te vallen op kale Webmin, en Provibr doet ook niet alsof: de koppeling wordt geweigerd met een reden in plaats van half aangemaakt.

Wat je nodig hebt om te koppelen

Vier velden, waarvan er twee strenger zijn dan bij elk ander controlepaneel dat we ondersteunen.

VeldWaarde
HostHet adres van het paneel. Moet https zijn. Poort 10000 wordt voor je ingevuld.
Webmin-gebruikerroot werkt, maar een gebruiker die alleen de Virtualmin-module heeft is beter.
WachtwoordHet wachtwoord van die gebruiker.
TLS-fingerprintVerplicht.

Waarom https én de fingerprint allebei moeten. Onze andere controlepaneel-integraties accepteren een kaal http-adres en vertellen je wat dat kost. Deze niet, en het verschil zit in de aard van het geheim.

De remote API van Webmin spreekt HTTP Basic. Het geheim is hier een wachtwoord en geen token; dat is een eigenschap van Webmin, geen keuze van ons. Een DirectAdmin-loginsleutel kan tot een handvol commando's beperkt worden; een Webmin-wachtwoord kan helemaal niet beperkt worden. Dat onversleuteld versturen, of naar een certificaat dat niemand geverifieerd heeft, is geen afweging die wij namens jou maken. En de installer van Webmin laat een self-signed certificaat achter, dus het fingerprintveld is niet theoretisch: het is het normale geval.

Praktisch advies: maak een aparte Webmin-gebruiker aan en geef die de Virtualmin-module. Hij kan alles wat Virtualmin kan, en dat is veel, maar niet alles wat Webmin kan.

Twee dingen die een integratie zullen bijten

Dit zijn de twee gemeten gedragingen die je een middag kosten als je dit zelf bouwt.

Elke fout komt met HTTP 200 binnen. Virtualmin kent twee foutvormen (error op wrapperniveau en failure op programmaniveau) en levert ze allebei met statuscode 200. De statuscode zegt niets. Alles wat niet exact status: "success" is, is een fout, en de wrapper-fout moet vóór elke tekstvergelijking gecontroleerd worden, anders leest "Remote program xyz does not exist" als een ontbrekend account.

(Dit is een familietrek van controlepaneel-API's en geen eigenaardigheid van Virtualmin. DirectAdmin doet hetzelfde op zijn eigen manier: HTTP 200 met error=1 in de body. Een integratie die op de statuscode vertrouwt slaagt stil terwijl er niets gebeurd is.)

Een UI-pad antwoordt met 200 en een inlogpagina. Richt je op een Webmin-modulepad in plaats van op de remote API, dan krijg je HTTP 200 met een HTML-inlogpagina: bij een fout wachtwoord, een juist wachtwoord en géén wachtwoord alle drie, op statuscodeniveau niet te onderscheiden. De remote API zelf doet het wél netjes met een 401. Dat verschil maakt de fout bruikbaar: een 200 mét HTML kan alleen betekenen dat je niet op de API mikt, en Provibr zegt dat met zoveel woorden in plaats van je een JSON-parsefout te tonen op een paneel dat prima werkt.

Bij sommige installaties staat de remote-API-route uit. Je zet hem terug aan onder Webmin → Webmin Configuration → Advanced Options.

Instellingen: die zijn er niet

Een Virtualmin-server bepaalt zelf waar een account leeft en welk adres het krijgt. Er valt voor jou niets te kiezen, dus op het tabblad Instellingen staat niets anders dan het opnieuw versturen van inloggegevens.

Dat geldt ook voor het IP-adres. Virtualmin zet een account standaard op het gedeelde adres van de host (we maten ip_address als 192.0.2.10 (Shared)), dus het IP-beheer van Provibr staat voor deze provider uit. Een IPAM die suggereert dat hij het adres toewijst zou liegen.

Plannen

Een Virtualmin-plan is de eigen beschrijving die het paneel van een account heeft: schijfquotum, maandelijks verkeer, hoeveel domeinen en mailboxen, welke features aan staan. Het is geen Provibr-plan en geen besturingssysteem: het is een naam waar we naar verwijzen, en de inhoud ervan kan op jouw server veranderen zonder dat wij het merken.

De integratiepagina leest de lijst met plannen inclusief hun inhoud, zodat je ziet wat je kiest in plaats van een naam uit je hoofd te typen. Een Provibr-webplan pint daarna één Virtualmin-plan vast op één integratie en geeft het een eigen naam. Bestellen via een plan wint van een losse keuze, en de losse kiezer blijft beschikbaar voor de gevallen die een plan niet dekt.

⚠️ Eén gemeten valkuil is het weten waard: modify-domain met een plannaam die niet bestaat antwoordt met status: "success" en laat het plan precies staan waar het stond. Er is dus geen foutvorm om op te classificeren: de weigering is stilte. Provibr vergelijkt wat er gevraagd is met wat hij er daarna uitleest, dus een planwijziging die niet doorging wordt gemeld als een wijziging die niet doorging.

Hoe een account er in Provibr uitziet

Een hostingaccount is een gewone serverrij van het type webserver. Er aanmaken vraagt een domein, een e-mailadres, een plan en een wachtwoord.

  • De identiteit is het interne nummer dat Virtualmin aan het domein geeft, niet de naam. Virtualmin kan een domein hernoemen; een sleutel op naam raakt los van zijn rij zodra iemand dat doet.
  • De unix-gebruiker wordt afgeleid uit het domein, dus mijn-klant.nl levert mijn-klant. Koppeltekens zijn hier de normale vorm en niet de uitzondering, en de grens is die van Linux zelf: 32 tekens. Dat wijkt af van DirectAdmin en cPanel, die hun eigen strengere naamregels hebben.
  • De accountgrens is de unix-gebruiker, niet het domein. Sub-servers en aliassen zouden anders elk als apart hostingaccount in de licentietelling landen.
  • Het wachtwoord wordt nergens vastgelegd. Alleen het feit dát je er een gaf; de waarde reist apart en belandt nooit in een auditrij.
  • Daarna kun je opschorten, hervatten, van plan wisselen en verwijderen. Er is geen console: een hostingaccount heeft er geen.

Opgeschort betekent dat een veld bestaat

Dit is het scherpste detail van de hele integratie, en het is precies wat een zelfgebouwde parser fout doet.

Bij een opgeschort account krijgt list-domains er een veld disabled bij. Bij een actief account ontbreekt dat veld gewoon. Er is geen disabled: "No".

Een parser die op een waarde zoekt vindt er nooit een en leest élk account als actief, ook de opgeschorte. In een facturatiecontext is dat geen cosmetische bug: het betekent dat een account dat je wegens niet-betalen opschortte zichzelf als live rapporteert, en dat je capaciteitstelling fout staat in de richting die je geld kost.

Quota en verbruik: soms is er niets te tonen

Schijfquotum en verkeer liften mee op de gewone poll, dus een account krijgt een verbruiksgrafiek zonder dat er iets extra's aangezet hoeft te worden, mits de server ze kan meten.

Virtualmin rapporteert quota en verbruik alleen wanneer filesystem-quota's aanstaan, en op een verse installatie staan die uit. We hebben het gemeten: quotaon -p / meldde off op een standaardinstallatie, omdat de installer het oude quotaformaat in /etc/fstab zet terwijl een moderne ext4-kernel journaled quota wil. Zolang niemand ze aanzet komt er geen enkel quotaveld uit de API.

Provibr toont dan niets in plaats van een nul. Geen meting en geen verbruik zijn niet hetzelfde, en een grafiek die op nul staat ziet eruit als het tweede terwijl het het eerste is.

Een verwante noot als je de rauwe uitvoer ooit zelf leest: kies de machineleesbare velden (created_unix_time, databases_byte_size) boven hun menselijke tegenhangers (created_on, databases_size). Die menselijke dragen eenheden en een datumnotatie die van de locale van het paneel afhangen, en ze parsen is precies het soort stille fout dat als eerste opvalt bij een klant met een andere instelling.

Twee bewuste weglatingen

De verbindingstest toont geen versieregel. Virtualmin heeft geen enkel API-programma dat zijn eigen versie teruggeeft: virtualmin info kent eenentwintig zoeksleutels en geen versie, en de header Server: MiniServ draagt geen nummer. Een lege regel zou beweren dat we het probeerden en niet konden lezen; hem weglaten zegt de waarheid. De test toont in plaats daarvan je plannenlijst, en dat is wat je werkelijk wilt bevestigen.

En er wordt niets geheims van het paneel opgeslagen. list-domains --multiline draagt hashed_password, password_for_mysql en password_storage letterlijk in zijn uitvoer. Provibr filtert met een allowlist vóór het lezen, niet door achteraf te redigeren; een verbodenlijst mist per definitie het volgende geheim dat anders heet. We hebben het met een tegenproef in dezelfde run geverifieerd: het rauwe paneelantwoord draagt die drie velden aantoonbaar, en de importlijst bevat er nul.

Bestaande accounts overnemen

Het importtabblad somt de accounts op het paneel op en laat je de gewenste in Provibr trekken. Accounts die al bekend zijn worden getoond maar kunnen niet opnieuw geselecteerd worden, zodat je het hele plaatje ziet in plaats van een gefilterd plaatje.

Geïmporteerde accounts tellen precies zoals bestelde mee voor je capaciteit. Importeer je er meer dan je ruimte hebt, dan opent er een overschrijding, met de gebruikelijke respijtperiode.

Wat dit betekent voor een kleine hoster

Virtualmin geeft je een degelijk hostingpaneel en helemaal geen commerciële laag. Het gebruikelijke advies (stap over op iets waar de billingsystemen al mee praat) vraagt je om levende klanten van een werkende machine af te halen om een administratieprobleem op te lossen.

Provibr koppelt aan controlepanelen, hypervisors en gamepanelen naast elkaar. Hou de Virtualmin-machine die je hebt, zet er bestellen en capaciteitstelling bovenop, en zet er volgend jaar een VPS of een gamepaneel naast zonder dat er iets aan de hostingkant verandert.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.