Linux mangfoldig: korleis arbeida pÄ kva som helst distribusjon

Linux mangfoldig: korleis arbeida pÄ kva som helst distribusjon

Å lage ei app for sikkerheitskopiering som fungerer pĂ„ kva som helst distribusjon er ei krevjande oppgĂ„ve. For Ă„ sikre at Veeam Agent for Linux fungerer pĂ„ distribusjonar frĂ„ Red Hat 6 til Debian 6, OpenSUSE 15.1 og Ubuntu 19.04, mĂ„ ein lĂžysa eit spekter av problem, spesielt med tanke pĂ„ at programvaren inkluderer ein kjerne-modul.

Artikkelen er basert pÄ materiale frÄ eit foredrag pÄ konferansen LinuxPiter 2019.

Linux er ikkje berre eitt av dei mest populÊre operativsystema. I utgangspunktet er det ei plattform der ein kan lage noko unikt, noko eige. Takka vere dette har Linux mange distribusjonar som skil seg frÄ kvarandre ved hjelp av ei rekkje programvarekomponentar. Her oppstÄr problemet: For at programvaren skal fungere pÄ kva som helst distribusjon, mÄ ein ta omsyn til eigenskapene til kvar enkelt.

PakkehÄndterarar. .deb vs .rpm

La oss byrja med det Äpenbare problemet med distribusjon av produktet for ulike distribusjonar.
Den mest vanlege mÄten Ä distribuere programvara pÄ er Ä leggje ut ein pakke i eit repositorium slik at den innebygde pakkehÄndteraren i systemet kan installere den derfrÄ.
Det er imidlertid to populÊre pakkformat: rpm og deb. Det betyr at vi mÄ stÞtte kvar enkelt.

I verda av deb-pakkar er kompabiliteten imponerande. Den same pakken installerer og fungerer like godt pÄ bÄde Debian 6 og Ubuntu 19.04. Standardane for pakkeoppretting og arbeid med dei som blei lagt i tidlege Debian-distribusjonar, er fremdeles relevante ogsÄ i moderne Linux Mint og elementary OS. Difor er det nok med ein deb-pakke for kvar maskinvareplattform for Veeam Agent for Linux.

Derimot er forskjellane i verda av rpm-pakkar store. For det fÞrste fordi det finst to heilt uavhengige distribusjonar, Red Hat og SUSE, som ikkje har noko behov for kompabilitet. For det andre har desse distribusjonane bÄde distribusjonar med teknisk stÞtte og eksperimentelle. Mellom desse er kompabilitet ogsÄ unÞdvendig. Det viser seg at vi har eigne pakkar for el6, el7 og el8. I tillegg ein eigen pakke for Fedora. Pakkar for SLES11 og 12 og ein eigen for openSUSE. Hovudproblemet er avhengigheiter og namn pÄ pakkar.

Problemet med avhengigheiter

Dessverre har dei same pakkane ofte ulike namn i forskjellige distribusjonar. Nedenfor er ein ufullstendig liste over avhengigheiter for veeam-pakken.

For EL7:
For SLES 12:

  • libblkid
  • libgcc
  • libstdc++
  • ncurses-libs
  • fuse-libs
  • file-libs
  • veeamsnap = 3.0.2.1185
  • libblkid1
  • libgcc_s1
  • libstdc++6
  • libmagic1
  • libfuse2
  • veeamsnap-kmp = 3.0.2.1185

Som fĂžlger av dette blir avhengighetslisten unik for distribusjonen.

Det blir enda verre nÄr en oppdatert versjon begynner Ä skjule seg under det gamle pakkenavnet.

Eksempel:

I Fedora 24 ble pakken oppdatert ncurses fra versjon 5 til versjon 6. VÄr produkt ble bygget med versjon 5 for Ä sikre kompatibilitet med gamle distribusjoner. For Ä bruke den gamle versjon 5 av biblioteket pÄ Fedora 24 mÄtte man bruke pakken ncurses-compat-libs.

Som et resultat fÄr Fedora to pakker, med forskjellige avhengigheter.

SĂ„ blir det mer interessant. Etter en ny oppdatering av distribusjonen blir pakken ncurses-compat-libs med versjon 5 av biblioteket utilgjengelig. For distributĂžren er det besvĂŠrlig Ă„ trekke gamle biblioteker inn i den nye versjonen av distribusjonen. Etter en tid dukket det samme problemet opp i SUSE-distribusjoner.

Som et resultat mÄtte man for noen distribusjoner gi opp den eksplisitte avhengigheten fra ncurses-libs, og produktet mÄtte justeres slik at det kunne fungere med hvilken som helst versjon av biblioteket.

Forresten, i Red Hat versjon 8 finnes ikke lenger meta-pakken python, som refererte til den gamle gode python 2.7. Det finnes python2 og python3.

Alternativ til pakkebehandlerne

Problemet med avhengigheter er gammelt og Äpenbart. Bare minn om Dependency hell.
Å samle ulike biblioteker og applikasjoner slik at de alle fungerer stabilt og ikke konflikter — dette er utvilsomt oppgaven enhver Linux-distributĂžr prĂžver Ă„ lĂžse.

Helt annerledes forsĂžker pakkebehandleren Snappy fra Canonical. Hovedideen: applikasjonen kjĂžres i en isolert og beskyttet sandkasse fra hovedsystemet. Hvis applikasjonen trenger biblioteker, leveres de sammen med selve applikasjonen.

Flatpak lar ogsÄ kjÞre applikasjoner i sandkassen ved bruk av Linux Containers. Ideen om sandkasse brukes ogsÄ av AppImage.

Disse lÞsningene gjÞr det mulig Ä lage én pakke for alle distribusjoner. NÄr det gjelder Flatpak kan installasjon og kjÞring av applikasjonen skje selv uten administratorens viten.

Hovedproblemet er at ikke alle applikasjoner kan fungere i sandkassen. Noen trenger direkte tilgang til plattformen. Jeg nevner ikke engang kjerne-moduler som er sterkt avhengige av kjernen og ikke passer inn i sandkasse-konseptet.

Det andre problemet er at de populĂŠre distribusjonene fra Red Hat og SUSE i enterprise-miljĂžet fortsatt ikke stĂžtter Snappy og Flatpak.

Som fÞlge av dette er Veeam Agent for Linux verken tilgjengelig pÄ snapcraft.io eller pÄ flathub.org.

For Ä avslutte spÞrsmÄlet om pakkeadministratorer vil jeg bemerke at det er et alternativ Ä helt slutte Ä bruke pakkeadministratorer, og i stedet samle binÊrfiler og skripter for installasjon i én pakke.

En slik pakke gjÞr det mulig Ä lage én felles pakke for forskjellige distribusjoner og plattformer, og gjennomfÞre en interaktiv installasjonsprosess med nÞdvendig tilpasning. Jeg har bare sett slike pakker for Linux fra VMware.

Problemet med oppdateringer

Linux mangfoldig: korleis arbeida pÄ kva som helst distribusjon
Selv om alle avhengighetsproblemer er lÞst, kan programmet oppfÞre seg ulikt pÄ samme distribusjon. Det skyldes oppdateringene.

Det finnes 3 strategier for oppdateringer:

  • Den enkleste er Ă„ aldri oppdatere. Du konfigurerer serveren og glemmer den. Hvorfor oppdatere nĂ„r alt fungerer? Problemer begynner sĂ„ snart du tar kontakt med supporttjenesten. Distribusjonens utvikler stĂžtter kun den oppdaterte versjonen.
  • Du kan stole pĂ„ distributĂžren og sette opp automatiske oppdateringer. I sĂ„ fall er det sannsynlig at du mĂ„ ringe supporten umiddelbart etter en mislykket oppdatering.
  • Alternativet med manuell oppdatering kun etter testing i testinfrastrukturen er det sikreste, men det er dyrt og arbeidstungt. Langt fra alle har rĂ„d til det.

Siden forskjellige brukere anvender forskjellige oppdateringsstrategier, mÄ bÄde den nyeste utgivelsen og alle tidligere utgivelser stÞttes. Dette kompliserer bÄde utviklingsprosessen og testingen, og gir supporttjenesten mer hodebry.

Mangfold av maskinvareplattformer

Ulike maskinvareplattformer er et problem som i stor grad er spesifikt for native-kode. Minst mÄ man bygge binÊrfiler for hver stÞttet plattform.

I prosjektet Veeam Agent for Linux klarer vi ennÄ ikke Ä stÞtte noe som helst RISC-relatert.

Jeg vil ikke gÄ i dybden pÄ dette temaet. Jeg vil bare nevne de viktigste problemene: plattformavhengige typer, som size_t, strukturjustering og byte-rekkefÞlge.

Statisk og/eller dynamisk lenking

Linux mangfoldig: korleis arbeida pÄ kva som helst distribusjon
SpÞrsmÄlet «Hvordan skal man lenke med biblioteker - dynamisk eller statisk?» er verdt Ä diskutere.

Som regel bruker C/C++-applikasjoner pÄ Linux dynamisk linking. Dette fungerer utmerket hvis applikasjonen er bygget spesifikt for en bestemt distribusjon.

Hvis mÄlet er Ä dekke ulike distribusjoner med én binÊrfil, mÄ man rette seg etter den eldste stÞttede distribusjonen. For oss er dette Red Hat 6. Den inneholder gcc 4.4, som ikke engang stÞtter standard C++11 fullt ut. fullstendig.

Vi bygger prosjektet vÄrt med gcc 6.3, som stÞtter C++14 fullt ut. I sÄ fall mÄ vi dra med oss libstdc++ og boost-biblioteket pÄ Red Hat 6. Det enkleste er Ä linke til dem statisk.

Men dessverre kan ikke alle biblioteker linkes statisk.

For det fÞrste mÄ systembiblioteker, som libfuse, libblkid linkes dynamisk for Ä sikre kompatibilitet med kjernen og dens moduler.

For det andre er det en nyanse med lisenser.

GPL-lisensen tillater i prinsippet Ă„ linke biblioteker kun med opensource-kode. MIT og BSD tillater statisk linking og lar inkludere biblioteker i prosjektet. Derimot synes LGPL ikke Ă„ motsette seg statisk linking, men krever Ă„ gi tilgang til filene som er nĂždvendige for linking.

Generelt vil bruk av dynamisk linking beskytte mot behovet for Ă„ gi noe ut.

Bygging av C/C++-applikasjoner

For Ă„ bygge C/C++-applikasjoner for ulike plattformer og distribusjoner, er det tilstrekkelig Ă„ finne eller bygge en passende versjon av gcc og bruke krysskompilatorer for spesifikke arkitekturer, samt Ă„ samle hele settet av biblioteker. Dette arbeidet er fullt mulig, men ganske tidkrevende. Og det er ingen garantier for at den valgte kompilatoren og bibliotekene vil gi en fungerende variant.

En Äpenbar fordel: infrastrukturen blir sterkt forenklet, da hele byggeprosessen kan utfÞres pÄ én maskin. I tillegg er det tilstrekkelig Ä samle ett sett av binÊrfiler for én arkitektur, og sÄ kan de pakkes i pakker for forskjellige distribusjoner. Slik blir veeam-pakkene for Veeam Agent for Linux bygget.

I motsetning til dette alternativet kan man enkelt forberede en bygningsgÄrd, det vil si flere maskiner for bygging. Hver av disse maskinene vil sÞrge for kompilering av applikasjonen og bygging av pakken for en spesifikk distribusjon og bestemt arkitektur. I sÄ fall utfÞres kompileringen med de midlene som distribusjonen har forberedt. Med andre ord,forberedelsestrinnet for kompilatoren og valg av biblioteker faller bort. I tillegg kan byggeprosessen enkelt paralleliseres.

Det er imidlertid en ulempe med en slik tilnÊrming: for hver distribusjon innenfor en arkitektur mÄ man samle sitt eget sett av binÊrfiler. En annen ulempe er at et sÄ stort antall maskiner mÄ vedlikeholdes, noe som krever mye diskplass og RAM.

Slik blir KMOD-pakkene for veeamsnap-kjernemodulen samlet for Red Hat-distribusjoner.

Open Build Service

Kollegene fra SUSE forsĂžkte Ă„ oppnĂ„ en slags gullstandard i form av en spesialtjeneste for kompilering av applikasjoner og bygging av pakker — openbuildservice.

I prinsippet er dette en hypervisor som oppretter en virtuell maskin, installerer alle nĂždvendige pakker, utfĂžrer kompilering av applikasjonen og bygging av pakken i dette isolerte miljĂžet, hvoretter denne virtuelle maskinen frigjĂžres.

Linux mangfoldig: korleis arbeida pÄ kva som helst distribusjon

Planleggeren innebygd i OpenBuildService vil selv avgjÞre hvor mange virtuelle maskiner den kan starte for optimal hastighet ved pakkebygging. Den innebygde signeringsmekanismen vil automatisk signere pakkene og legge dem ut pÄ den innebygde lagringsplassen. Det innebygde versjonskontrollsystemet vil lagre historikken for endringer og bygg. Det gjenstÄr bare Ä legge inn sine kildefiler i dette systemet. Det er ikke engang nÞdvendig Ä sette opp en server selv, man kan bruke den Äpne.

Men her er det et problem: en slik kombinasjon passer ikke godt inn i den eksisterende infrastrukturen. For eksempel er versjonskontrollen ikke nÞdvendig, da vi allerede har vÄr for kildefilene. Signeringsmekanismen vÄr er annerledes: en spesiell server benyttes. Lagringsplassen er heller ikke nÞdvendig.

I tillegg er stĂžtten for andre distribusjoner — for eksempel Red Hat — ganske mager, noe som er forstĂ„elig.

Fordelen med en slik tjeneste er rask stÞtte for den nyeste versjonen av SUSE-distribusjonen. FÞr den offisielle kunngjÞringen om utgivelsen legges nÞdvendige pakker ut i et offentlig repository. Den nye distribusjonen vises pÄ listen over tilgjengelige distribusjoner i OpenBuildService. Vi setter en hake, og den legges til i byggeplanen. Dermed kan tillegget av en ny distribusjonsversjon gjÞres praktisk talt med ett klikk.

I vÄr infrastruktur, som bruker OpenBuildService, bygges et mangfold av KMP-pakker for veeamsnap-modulen til SUSE-distribusjoner.

Deretter vil jeg gjerne stoppe opp ved spÞrsmÄl som er spesifikke for kjernemoduler.

kernel ABI

Linux-kjernemoduler har historisk blitt distribuert som kildekode. Årsaken er at kjernens utviklere ikke tar seg bryet med Ă„ opprettholde et stabilt API for kjernemoduler, langt mindre pĂ„ binĂŠrt nivĂ„, videre kABI.

For Ă„ bygge en modul for det vanlige kjernen, er det nĂždvendig med header-filer for nettopp denne kjernen, og den vil kun fungere med denne kjernen.

DKMS lar deg automatisere prosessen med Ă„ bygge moduler ved oppdatering av kjernen. Som et resultat bruker brukere av Debian-repositoryet (og dets mange slektninger) kjernemoduler enten fra distributĂžrens repository eller bygget fra kildekode ved hjelp av DKMS.

Men slik situasjonen er, tilfredsstiller det ikke Enterprise-segmentet sĂŠrlig godt. Distribusjoner av proprietĂŠr kode Ăžnsker Ă„ distribuere produktet i form av ferdigbygde binĂŠrfiler.

Administratorer Ăžnsker ikke Ă„ ha utviklingsverktĂžy pĂ„ produksjonsservere av sikkerhetsmessige Ă„rsaker. Distribusjoner av Enterprise Linux – som Red Hat og SUSE – har besluttet at de kan stĂžtte sine brukere med stabil kABI. Som et resultat har KMOD-pakker for Red Hat og KMP-pakker for SUSE dukket opp.

Kjernen i en slik lÞsning er ganske enkel. For en spesifikk versjon av distribusjonen fryses API-et i kjernen. DistributÞren erklÊrer at de bruker en spesifikk kjerne, for eksempel 3.10, og gjÞr bare feilrettinger og forbedringer som ikke berÞrer kernelgrensesnittene, og moduler bygget for den aller fÞrste kjernen kan brukes for alle pÄfÞlgende uten rekompilering.

Red Hat uttaler at kABI-kompatibilitet for distribusjonen gjelder gjennom hele livssyklusen. Det betyr at en bygget modul for rhel 6.0 (utgivelse november 2010) ogsÄ skal fungere pÄ versjon 6.10 (utgivelse juni 2018). Og dette er nesten 8 Är. Naturligvis er dette en ganske vanskelig oppgave.
Vi har registrert flere tilfeller der modulen veeamsnap sluttet Ä fungere pÄ grunn av problemer med kABI-kompatibiliteten.

Etter at modulen veeamsnap, bygget for RHEL 7.0, viste seg Ă„ vĂŠre inkompatibel med kjernen fra RHEL 7.5, men likevel ble lastet inn og garantert krasjet serveren, forkastet vi bruken av kABI-kompatibilitet for RHEL 7 helt.

For Ăžyeblikket inneholder KMOD-pakken for RHEL 7 en bygging for hver versjon av utgivelsen og et skript som sĂžrger for lasting av modulen.

SUSE har tatt en mer forsiktig tilnĂŠrming til kABI-kompatibilitet. De sikrer kABI-kompatibilitet bare innenfor ett servicepakke.

For eksempel ble utgivelsen SLES 12 lansert i september 2014. Og SLES 12 SP1 kom allerede i desember 2015, altsÄ gikk det litt over ett Är. Til tross for at begge utgivelser bruker kjerne 3.12, er de kABI-incompatible. Det er Äpenbart at det er betydelig enklere Ä opprettholde kABI-kompatibilitet i lÞpet av bare ett Är. Et Ärlig oppdateringssyklus for modulkjernen bÞr ikke forÄrsake problemer for modulskaperne.

Som et resultat av denne politikken fra SUSE har vi ikke registrert noen problemer med kABI-kompatibilitet med vÄr modul veeamsnap. Faktisk er antallet pakker for SUSE nesten pÄ nivÄ med en orden stÞrre.

Patch og bakporter

Selv om distributÞrene prÞver Ä sikre kABI-kompatibilitet og stabilitet i kjernen, prÞver de ogsÄ Ä forbedre ytelsen og rette opp feil i denne stabile kjernen.

I tillegg til sitt eget "arbeid med feil" fÞlger utviklerne av enterprise linux-kjernen med pÄ endringene i vaniljekjernen og overfÞrer dem til sin "stabile".

Noen ganger fĂžrer dette til nye feil.

I den siste utgivelsen av Red Hat 6 ble det gjort en feil i en av de mindre oppdateringene. Denne fÞrte til at modulen veeamsnap garantert krasjet systemet ved frigjÞring av et snapshot. Etter Ä ha sammenlignet kildekodene til kjernen fÞr og etter oppdateringen, fant vi ut at det var bakporten som var ansvarlig. En tilsvarende fiks ble utfÞrt i vaniljekjernen versjon 4.19. Men i vaniljekjernen fungerte denne fiksen normalt, mens overfÞringen til det "stabile" 2.6.32 medfÞrte et problem med spin-lÄsingen.

SelvfÞlgelig, fejl opstÄr altid for alle, men var det vÊrd at trÊkke kode fra 4.19 til 2.6.32, risikerende stabiliteten?.. Jeg er ikke sikker


Det vÊrste er, nÄr marketing ogsÄ blander sig i det at trÊkke i det strÊk, der handler om "stabilitet""modernisering". Marketingafdelingen har brug for, at kernen i den opdaterede distribution er stabil, pÄ den ene side, men samtidig skal den ogsÄ vÊre bedre i ydeevne og have nye funktioner. Dette fÞrer til mÊrkelige kompromisser.

Da jeg prÞvede at samle modulet pÄ kernen 4.4 fra SLES 12 SP3, blev jeg overrasket over at opdage funktionalitet fra den rene 4.8. Efter min mening ligner implementeringen af blokind- og udgang fra kernen 4.4 fra SLES 12 SP3 mere kernen 4.8 end den tidligere udgave af den stabile 4.4 kerne fra SLES 12 SP2. Jeg vil ikke vurdere, hvad procentdelen af den overfÞrte kode fra kernen 4.8 til SLES' 4.4 for SP3 er, men jeg kan ikke kalde kernen den samme stabile 4.4.

Det mest frustrerende ved at skrive et modul, der fungerer godt pÄ forskellige kerner, er, at man ikke lÊngere kan stole pÄ kerneversionen. Man skal ogsÄ tage hensyn til distributionen. Heldigvis kan man nogle gange binde sig til en define, som dukker op med den nye funktionalitet, men denne mulighed opstÄr ikke altid.

Resultatet er, at koden bliver fyldt med bizarre preproces directives.

Der er ogsÄ patches, der Êndrer det dokumenterede API for kernen.
Jeg stÞdte pÄ distributionen KDE neon 5.16 og blev meget overrasket over at se, at kaldet til lookup_bdev i denne kerneversion havde Êndret listen af indparametre.

For at kunne samle det mÄtte jeg tilfÞje et script til makefile, der kontrollerede, om der var en mask parameter til funktionen lookup_bdev.

Undertegnelse af kernemoduler

Men lad os vende tilbage til spÞrgsmÄlet om distributionspakker.

En af fordelene ved stabil kABI er, at kernemoduler i form af binÊre filer kan signeres. PÄ denne mÄde kan udvikleren vÊre sikker pÄ, at modulet ikke er blevet beskadiget ved en fejl eller Êndret bevidst. Dette kan tjekkes med kommandoen modinfo.

Distributioner som Red Hat og SUSE tillader at kontrollere signaturen pÄ modulet og indlÊse det kun, hvis det relevante certifikat er registreret i systemet. Certifikatet er en offentlig nÞgle, som modulet bliver signeret med. Vi distribuerer det som en separat pakke.

Problemet her er, at certifikater enten kan vĂŠre indbyggede i kernen (de anvendes af distributionsudbydere) eller skal skrives til den ikke-flygtige EFI-hukommelse ved hjĂŠlp af et vĂŠrktĂžj. mokutil. The utility mokutil ved installation af certifikatet krĂŠver det genstart af systemet og tilbydes administratoren at tillade indlĂŠsning af det nye certifikat fĂžr indlĂŠsning af operativsystemkernen.

SÄledes krÊver tilfÞjelse af certifikatet fysisk adgang til systemet fra administratoren. Hvis maskinen er placeret et sted i skyen eller blot i en fjern server, hvor adgang kun er muligt via netvÊrket (f.eks. via ssh), kan certifikatet ikke tilfÞjes.

EFI pÄ virtuelle maskiner

Selvom EFI lÊnge har vÊret understÞttet af nÊsten alle producenter af bundkort, kan administratoren ved installation af systemet mÄske ikke overveje behovet for EFI, og det kan vÊre deaktiveret.

Ikke alle hypervisorer understĂžtter EFI. VMWare vSphere understĂžtter EFI fra version 5.
Microsoft Hyper-V har ogsÄ fÄet stÞtte for EFI, begyndende med Hyper-V for Windows Server 2012R2.

Men i standardkonfigurationen er denne funktionalitet deaktiveret for Linux-maskiner, hvilket betyder, at certifikatet ikke kan installeres.

I vSphere 6.5 kan du indstille muligheden Secure Boot kun i den gamle version af webgrĂŠnsefladen, som fungerer gennem Flash. Web UI i HTML-5 er stadig meget bagud.

Eksperimentelle distributioner

Og til sidst vil vi se pÄ spÞrgsmÄlet om eksperimentelle distributioner og distributioner uden officiel stÞtte. PÄ den ene side vil du nÊppe finde sÄdanne distributioner pÄ serverne i seriÞse organisationer. Der er ikke officiel stÞtte til sÄdanne distributioner. Derfor kan teknisk support af produktet ikke ydes pÄ en sÄdan distribution.

Men sÄdanne distributioner bliver et praktisk forum til at afprÞve nye eksperimentelle lÞsninger. For eksempel, Fedora, OpenSUSE Tumbleweed eller Unstable-versioner af Debian. De er ret stabile. De har altid nye versioner af programmerne og altid en ny kerne. Om et Är kan denne eksperimentelle funktionalitet findes i den opdaterede RHEL, SLES eller Ubuntu.

SÄ hvis noget ikke virker pÄ en eksperimentel distribution, er det en grund til at undersÞge problemet og lÞse det. Man skal vÊre klar til, at denne funktionalitet snart vil dukke op pÄ production-serverne hos brugerne.

Den eksisterende listen over offisielt stÞttede distribusjoner for versjon 3.0 kan du studere her. Men den virkelige listen over distribusjoner som produktet vÄrt kan fungere pÄ, er mye bredere.

Personlig var jeg interessert i et eksperiment med operativsystemet «Elbrus». Etter tilpasning av veeam-pakken ble produktet vÄrt installert og fungerte. Jeg skrev om dette eksperimentet pÄ Habr i artikkelen.

StÞtten for nye distribusjoner fortsetter. Vi venter pÄ at versjon 4.0 skal komme. Betaen bÞr snart vÊre tilgjengelig, sÄ fÞlg med pÄ whats-new!

Kilde: habr.com

KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere đŸ”„ KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster