Hej alla, jag heter Sergey Emelyanchik. Jag Ă€r chef för företaget Audit-Telecom, huvudutvecklare och författare till systemet Veliam. Jag beslöt mig för att skriva en artikel om hur jag och en vĂ€n skapade ett outsourcingföretag, skrev programvara för oss sjĂ€lva och senare började distribuera den till alla intresserade genom SaaS-systemet. Om hur jag kategoriskt inte trodde att detta var möjligt. Artikeln kommer att innehĂ„lla inte bara berĂ€ttelsen, utan ocksĂ„ tekniska detaljer om hur produkten Veliam skapades. Inklusive vissa delar av koden. Jag kommer att berĂ€tta om vilka misstag vi gjorde och hur vi senare rĂ€ttade till dem. Det fanns tvivel om huruvida man skulle publicera en sĂ„dan artikel. Men jag tĂ€nkte att det Ă€r bĂ€ttre att göra det, fĂ„ feedback och förbĂ€ttra sig, Ă€n att inte publicera artikeln och fundera pĂ„ vad som skulle ha hĂ€nt omâŠ
Bakgrund
Jag arbetade som IT-anstÀlld i ett företag. Företaget var ganska stort med en komplex nÀtverksstruktur. Jag kommer inte att gÄ in pÄ mina arbetsuppgifter, jag kan bara sÀga att utveckling av nÄgot inte ingick i dem.
Vi hade övervakning, men av rent akademiskt intresse ville jag prova att skriva min egen enklaste version. Idén var densamma: jag ville att det skulle vara i webben, sÄ att man enkelt utan installation av nÄgra klienter skulle kunna logga in och se vad som hÀnder med nÀtverket frÄn vilken enhet som helst, inklusive mobil enhet via Wi-Fi, och jag ville Àven snabbt förstÄ i vilket rum utrustningen som "strulade" lÄg, eftersom det fanns mycket strikta krav pÄ svarstid vid sÄdana problem. Resultatet blev att jag hade en plan i huvudet att skriva en enkel webbsida, dÀr bakgrunden skulle vara en jpeg med nÀtverksdiagrammet, skÀra ut de egna enheterna med deras IP-adresser frÄn den bilden, och över bilden i rÀtt koordinater visa dynamiskt innehÄll i form av en grön eller blinkande röd IP-adress. Uppgiften var stÀlld, vi sÀtter igÄng.
Tidigare har jag sysslat med programmering i Delphi, PHP, JS och mycket ytligt C++. Jag har ganska bra kunskap om nÀtverksarbete. VLAN, Routing (OSPF, EIGRP, BGP), NAT. Detta var tillrÀckligt för att skriva en prototyp av en primitiv övervakning sjÀlv.
Jag skrev det jag tÀnkt pÄ i PHP. Servern Apache och PHP kördes pÄ Windows eftersom Linux vid den tidpunkten kÀndes vÀldigt komplicerat och oförstÄeligt för mig; som jag senare insÄg, gjorde jag ett stort misstag, dÄ Linux pÄ mÄnga sÀtt Àr mycket enklare Àn Windows. Men det Àr ett separat Àmne, och vi vet alla hur mycket debatt det finns kring detta. Windows schemalÀggaren körde PHP-skriptet med korta intervall (jag minns inte exakt, men nÄgot som en gÄng var tredje sekund) för att göra en pingfrÄga pÄ alla objekt och spara status i en fil.
system(âping -n 3 -w 100 {$ip_address}â);
Ja, jag hade ocksÄ inte börjat arbeta med databaser vid den tiden. Jag visste inte att man kunde köra processer parallellt, och genomgÄngen av alla noder i nÀtverket tog lÄng tid eftersom detta skedde i ett enda flöde. SÀrskilt problematiskt blev det nÀr flera noder var otillgÀngliga, eftersom varje nod fördröjde skriptet med 300 ms. PÄ klientsidan fanns en enkel loopande funktion som med nÄgra sekunders intervall hÀmtade uppdaterad information frÄn servern via en Ajax-förfrÄgan och uppdaterade grÀnssnittet. Efter tre misslyckade pings i rad, om en webbsida för övervakning var öppen pÄ datorn, spelades en trevlig melodi.
NĂ€r allt lyckades blev jag verkligen inspirerad av resultatet och tĂ€nkte att jag skulle kunna koppla dit mer (utifrĂ„n mina kunskaper och möjligheter). Men jag har alltid ogillat system med en miljon diagram, som jag dĂ„ ansĂ„g, och fortfarande anser, oftast Ă€r onödiga. Jag ville bara koppla dit det som verkligen skulle hjĂ€lpa mig i mitt arbete. Denna princip kvarstĂ„r Ă€n idag som grundlĂ€ggande vid utvecklingen av Veliam. Vidare insĂ„g jag att det skulle vara fantastiskt om jag inte behövde ha övervakningen öppen och vara medveten om problemen, utan istĂ€llet kunna öppna sidan nĂ€r nĂ„got intrĂ€ffat, för att se var det problematiska nĂ€tverksknutpunkten var och vad jag skulle göra med den. Jag lĂ€ste sĂ€llan e-posten dĂ„, jag anvĂ€nde den helt enkelt inte. Jag snubblade över att det fanns SMS-gateways som man kunde skicka GET- eller POST-förfrĂ„gningar till, och de skulle skicka ett SMS med texten jag skrev till min mobiltelefon. Jag förstod direkt att jag verkligen ville ha detta. Och började studera dokumentationen. Efter en tid lyckades jag, och nu fick jag SMS om problem i nĂ€tverket till min mobil med namnet pĂ„ den "kraschade objektet". Ăven om systemet var primitivt, sĂ„ var det skrivet av mig sjĂ€lv, och det som motiverade mig mest till dess utveckling var att det var en applikation som verkligen hjĂ€lpte mig i mitt arbete.
Och sÄ kom dagen dÄ en av Internet-kanalerna pÄ jobbet gick ner, och min övervakning gav mig inga signaler om detta. Eftersom Googles DNS fortfarande var utmÀrkt pÄ att pinga. Det var dags att tÀnka pÄ hur man kan övervaka att kommunikationskanalen Àr aktiv. Det fanns olika idéer om hur man skulle göra detta. Jag hade inte tillgÄng till all utrustning. Jag mÄste komma pÄ hur jag kunde förstÄ vilken av kanalerna som var aktiv, utan möjlighet att kolla pÄ sjÀlva nÀtverksutrustningen. DÄ föreslog en kollega att det kanske var sÄ att spÄrning av rutten till offentliga servrar kunde skilja sig beroende pÄ vilken kommunikationskanal som anvÀndes för att komma ut pÄ internet. Jag kontrollerade, och det visade sig stÀmma. Det fanns olika rutter vid spÄrningen.
system(âtracert -d -w 500 8.8.8.8â);
SÄ föddes Ànnu ett skript, eller mer exakt, spÄrningen lades av nÄgon anledning till i slutet av samma skript som pingade alla enheter i nÀtverket. Det var trots allt Ànnu en lÄng process som utfördes i samma trÄd och bromsade hela skriptets funktion. Men dÄ var det inte sÄ uppenbart. Hur som helst gjorde det sin uppgift, kodningen var hÄrt skriven för hur spÄrningen skulle se ut för varje kanal. SÄ hÀr började systemet som redan övervakade (om man nu kan kalla det sÄ, eftersom inga mÀtvÀrden samlades in, utan bara ping) nÀtverksenheter (routrar, switchar, Wi-Fi, osv.) och kommunikationskanaler med omvÀrlden. SMS:en kom pÄlitligt och det var alltid tydligt pÄ schemat var problemet lÄg.
Vidare, i det dagliga arbetet var jag tvungen att syssla med korskopplingar. Och varje gÄng var jag tvungen att logga in pÄ Cisco-switcharna för att se vilken port som behövdes. Det skulle vara sÄ praktiskt att klicka pÄ övervakningen av objektet och se en lista över dess portar med beskrivningar. Det skulle spara mig tid. Dessutom skulle det i detta scenario inte vara nödvÀndigt att starta Putty eller SecureCRT för att ange inloggningar och kommandon. Jag skulle bara kunna klicka i övervakningen, se vad som behövdes och gÄ vidare med mitt arbete. Jag började leta efter hur jag kunde interagera med switcharna. Först fann jag tvÄ alternativ: SNMP eller logga in pÄ switchen via SSH, skriva in de kommandon jag behövde och analysera resultatet. Jag avfÀrdade SNMP pÄ grund av implementeringssvÄrigheterna, jag ville snabbt ha resultat. Med SNMP skulle jag behöva grÀva lÀnge i MIB för att basera dessa data pÄ grÀnssnittsdata. Det finns ett fantastiskt kommando i CISCO.
show interface statusDen visar precis vad jag behöver för korsningar. Varför plÄga mig med SNMP nÀr jag bara vill se utdata frÄn det hÀr kommandot, tÀnkte jag. Efter ett tag genomförde jag denna möjlighet. Jag klickade pÄ objektet pÄ webbsidan. En hÀndelse utlöste en AJAX-förfrÄgan till servern, som i sin tur kopplade upp sig via SSH till den switch jag behövde (inloggningsuppgifterna var inbÀddade i koden, jag hade ingen lust att förfina det, skapa nÄgra separata menyer dÀr jag kunde Àndra kontoinstÀllningarna frÄn grÀnssnittet, jag behövde resultatet snabbt) och skickade in det ovan nÀmnda kommandot och gav tillbaka till webblÀsaren. PÄ sÄ sÀtt började jag se information om grÀnssnitten med ett enda musklick. Det var extremt bekvÀmt, sÀrskilt nÀr jag behövde visa denna information pÄ flera switchar samtidigt.
Ăvervakning av kanaler baserat pĂ„ spĂ„rning visade sig slutligen vara en mindre bra idĂ©, eftersom det ibland gjordes arbeten i nĂ€tverket, och spĂ„rningen kunde Ă€ndras vilket fick övervakningen att skrika att det fanns problem med kanalen. Men efter att ha lagt ner en hel del tid pĂ„ analys insĂ„g jag att alla kanaler fungerade, medan min övervakning lurade mig. I slutĂ€ndan bad jag kollegor som hanterade de kanalbildande switcharna att bara skicka mig syslog nĂ€r tillstĂ„ndet för grannarna Ă€ndrades. Det var dĂ€rför mycket enklare, snabbare och mer pĂ„litligt Ă€n spĂ„rning. NĂ€r ett meddelande som 'granne förlorad' kom in, gjorde jag genast en avisering om kanalfallet.
DÀrefter tillkom nya utdata vid klick pÄ objektet, ytterligare flera kommandon lades till och SNMP för insamling av vissa metrikar implementerades, och i stort sett var det hela. Systemet utvecklades inte ytterligare. Det gjorde allt jag behövde, det var ett bra verktyg. MÄnga lÀsare kommer nog att sÀga att det redan finns en massa mjukvara för dessa uppgifter pÄ internet. Men i verkligheten lyckades jag inte hitta nÄgra gratisprodukter dÄ, och jag ville verkligen utveckla mina programmeringskunskaper, och vad kan vara bÀttre för att driva detta Àn ett verkligt praktiskt problem. SÄ den första versionen av övervakningen avslutades och modifierades inte lÀngre.
Skapandet av företaget Audit-Telecom
Med tiden började jag jobba extra pÄ andra företag, tur att mitt arbetsschema tillÀt mig att göra det. NÀr man arbetar pÄ olika företag vÀxer fÀrdigheterna snabbt inom olika omrÄden och vÀrldsbilden utvecklas. Det finns företag dÀr man, som det sÀgs, gör allt möjligt. Det Àr jobbigt Ä ena sidan, men Ä andra sidan, om man inte Àr lat, blir man en specialist inom flera omrÄden, vilket gör att man snabbare och effektivare kan lösa uppgifter eftersom man vet hur angrÀnsande omrÄden fungerar.
Min vÀn Pavel (ocksÄ IT-tekniker) försökte stÀndigt fÄ mig att starta eget företag. Det fanns otaliga idéer med olika alternativ för egna affÀrer. Detta diskuterades i flera Är. Och i slutÀndan ledde det ingenstans eftersom jag Àr skeptisk och Pavel Àr en drömmare. Varje gÄng han föreslog en idé trodde jag aldrig pÄ den och vÀgrade delta. Men vi ville verkligen starta eget.
Till slut lyckades vi hitta en lösning som passade oss bÄda och jobbade med det vi kan. à r 2016 beslutade vi att skapa ett IT-företag som skulle hjÀlpa företag med IT-relaterade uppgifter. Detta inkluderar installation av IT-system (1C, terminalservrar, e-postservrar etc.), deras support, klassisk HelpDesk för anvÀndare och nÀtverksadministration.
Ărligt talat trodde jag inte pĂ„ företaget nĂ€r vi startade det, ungefĂ€r 99,9% av mig var skeptisk. Men pĂ„ nĂ„got sĂ€tt lyckades Pavel fĂ„ mig att prova, och för att inte spoila, han hade rĂ€tt. Vi slĂ€ngde ihop 300 000 rubel var och registrerade det nya bolaget "Audit-Telecom", hyrde ett pyttelitet kontor, tryckte upp coola visitkort, ja, som de flesta oerfarna, nybörjande företagare. Vi började leta efter kunder. Att söka kunder Ă€r verkligen en egen historia. Kanske skriver vi en separat artikel pĂ„ företagsbloggen om det, om nĂ„gon skulle vara intresserad. Kalla samtal, flygblad och sĂ„ vidare. Det gav inga resultat. Som jag nu lĂ€ser i mĂ„nga affĂ€rshistorier beror mycket Ă€ndĂ„ pĂ„ tur. Vi hade tur. Redan nĂ„gra veckor efter företagets start kontaktade min bror Vladimir oss, som ledde till vĂ„r första kund. Jag ska inte trötta ut er med detaljer om arbetet med kunder, artikeln handlar inte om det, jag sĂ€ger bara att vi Ă„kte pĂ„ en revision, identifierade kritiska punkter och dessa punkter rasade medan beslutet togs om huruvida de skulle samarbeta med oss som outsourcingleverantörer pĂ„ lĂ„ng sikt. Efter detta togs ett positivt beslut omgĂ„ende.
DĂ€refter, frĂ€mst genom mun-till-mun via bekanta, började andra företag dyka upp för att fĂ„ service. Helpdesk var i ett system. Anslutningar till nĂ€tverksenheter och servrar i ett annat, eller snarare beroende pĂ„ hur det var. NĂ„gon sparade genvĂ€gar, nĂ„gon anvĂ€nde RDP-adressböcker. Ăvervakning var en helt annan separat system. Att arbeta för teamet i splittrade system Ă€r mycket opraktiskt. Viktig information gĂ„r förlorad. Till exempel, om terminalservern hos kunden blir otillgĂ€nglig. Omedelbart kommer Ă€renden in frĂ„n anvĂ€ndarna hos den kunden. Supportspecialisten registrerar ett Ă€rende (det kom in via telefon). Om incidenter och Ă€renden registrerades i ett och samma system, skulle supportspecialisten omedelbart se vad problemet var för anvĂ€ndaren och informerat dem om detta, samtidigt som de redan kopplade upp sig mot den aktuella enheten för att hantera situationen. Alla Ă€r medvetna om den taktiska situationen och arbetar smidigt. Vi hittade inget sĂ„dant system dĂ€r allt detta var samlat. Det blev tydligt att det var dags att skapa vĂ„r egen produkt.
FortsÀttning av arbetet med vÄrt övervakningssystem
Det stod klart att det system som skrevs tidigare inte alls passade de aktuella behoven. Varken nÀr det gÀllde funktionalitet eller kvalitet. DÀrför beslutades det att skriva ett nytt system frÄn grunden. Grafiskt skulle det behöva se helt annorlunda ut. Det skulle vara ett hierarkiskt system sÄ att man snabbt och enkelt kunde öppna rÀtt objekt för rÀtt kund. Skisslösningen i första versionen var i detta fall helt otillrÀcklig, eftersom kunderna var olika och det spelade ingen roll i vilka lokaler utrustningen stod. Detta hade redan överförts till dokumentationen.
SĂ„, uppgifter:
- Hierarkisk struktur;
- En sorts serverdel som kan placeras hos kunden i form av en virtuell maskin för att samla in de mÀtvÀrden vi behöver och skicka dem till en central server som sammanfattar allt och visar det för oss;
- Aviseringar. SÄdana som inte fÄr missas, eftersom det vid den tiden inte fanns möjlighet för nÄgon att bara sitta och titta pÄ en monitor;
- Ett system för Àrenden. Kunder började dyka upp som vi inte bara servade server- och nÀtverksutrustning, utan Àven arbetsstationer;
- Möjlighet att snabbt ansluta till servrar och utrustning frÄn systemet;
Uppgifterna var klara, vi börjar skriva. Samtidigt hanterar vi Àrenden frÄn kunder. Vid den tidpunkten var vi redan 4 personer. Vi började skriva bÄde centrala serverdelen och servern för installation hos kunderna. Vid det hÀr laget var Linux inte lÀngre frÀmmande för oss och vi beslutade att de virtuella maskiner som skulle stÄ hos kunder skulle vara pÄ Debian. Det skulle inte bli nÄgra installatörer, vi skulle bara göra projektet för serverdelen pÄ en specifik virtuell maskin och sedan bara klona den till rÀtt kund. Detta var ett ytterligare misstag. Senare blev det klart att mekanismen för uppdateringar i ett sÄdant system var helt otillrÀcklig. Det vill sÀga, vi lade till nÄgon ny funktion, och sedan var det ett helt problem att sprida den till alla kunders servrar, men vi Äterkommer till det senare, allt i tur och ordning.
Vi skapade den första prototypen. Den kunde pinga de nÀtverksenheter som vÄra kunder och servrar behövde och skicka dessa data till vÄr centrala server. Och den uppdaterade i sin tur dessa uppgifter i den totala mÀngden pÄ den centrala servern. Jag kommer hÀr att skriva inte bara historien om vad som lyckades utan Àven vilka amatörmÀssiga misstag som begicks och hur vi sedan fick betala för dem med tid. SÄ, hela objekttrÀdet lagrades i en enda fil i form av ett serialiserat objekt. NÀr vi anslöt nÄgra kunder till systemet fungerade allt mer eller mindre normalt, Àven om det ibland uppstod nÄgra artefakter som var helt oförstÄeliga. Men nÀr vi anslöt ett dussin servrar till systemet började underverk att hÀnda. Ibland, utan nÄgon uppenbar anledning, försvann alla objekt i systemet. Det Àr viktigt att notera att servrarna som kunderna hade skickade data till den centrala servern var femte sekund via en POST-förfrÄgan. Den uppmÀrksamma lÀsaren och erfarna programmeraren har redan listat ut att det uppstod ett problem med samtidig Ätkomst till just den fil i vilken det serialiserade objektet lagrades frÄn olika trÄdar samtidigt. Och precis nÀr detta hÀnde, uppstod underverken med försvinnandet av objekt. Filen blev helt enkelt tom. Men detta upptÀcktes inte genast, utan först i samband med driften av flera servrar. Under denna tid lades funktionalitet för portskanning till (servrarna skickade till den centrala inte bara information om tillgÀngligheten av enheter utan ocksÄ om de öppna portarna pÄ dem). Detta gjordes genom att anropa kommandot:
$connection = @fsockopen($ip, $port, $errno, $errstr, 0.5);
Resultaten var ofta felaktiga och skanningen tog vÀldigt lÄng tid. Jag glömde helt bort att pinga, det gjordes med fping:
system("fping -r 3 -t 100 {$this->ip}");
Det hÀr var ocksÄ inte parallelliserat och dÀrför var processen vÀldigt lÄng. Senare började fping att ta emot hela listan över IP-adresser som behövde kontrolleras direkt och vi fick tillbaka en fÀrdig lista över dem som svarade. Till skillnad frÄn oss, kunde fping parallellisera processerna.
En annan vanlig rutinuppgift var att konfigurera olika tjÀnster via WEB. Till exempel ECP frÄn MS Exchange. I grund och botten Àr det bara en lÀnk. Vi bestÀmde oss för att vi behövde möjligheten att lÀgga till sÄdana lÀnkar direkt i systemet, sÄ att vi slapp leta i dokumentationen eller nÄgon annanstans bland bokmÀrken för att fÄ tillgÄng till ECP för en specifik klient. SÄ kom begreppet resurslÀnkar till systemet, och dess funktionalitet Àr fortfarande tillgÀnglig och har inte genomgÄtt nÄgra förÀndringar, nÀstan.
Arbete med resurslÀnkar i Veliam

FjÀrranslutningar
SÄ hÀr ser det ut i praktiken i den nuvarande versionen av Veliam

En av uppgifterna var att snabbt och enkelt ansluta till servrar, av vilka det nu har blivit mĂ„nga (inte bara hundra), och att gĂ„ igenom miljontals sparade RDP-genvĂ€gar var extremt opraktiskt. Ett verktyg behövdes. Det finns mjukvara pĂ„ internet som fungerar som en adressbok för sĂ„dana RDP-anslutningar, men de Ă€r inte integrerade med övervakningssystemet, och anvĂ€ndarkonton kan inte sparas. Att varje gĂ„ng behöva skriva in uppgifterna för olika klienter Ă€r en verklig mardröm, speciellt nĂ€r man pĂ„ en dag ansluter flera gĂ„nger till olika servrar. För SSH-anslutningar Ă€r lĂ€get nĂ„got bĂ€ttre, det finns mĂ„nga bra program dĂ€r det Ă€r möjligt att organisera sĂ„dana anslutningar i mappar och spara anvĂ€ndaruppgifter. Men det finns tvĂ„ problem. För det första â för RDP- och SSH-anslutningar har vi inte hittat ett enda program. För det andra â om jag vid nĂ„got tillfĂ€lle inte sitter vid min dator och snabbt behöver ansluta, eller om jag bara har installerat om systemet, kommer jag att behöva gĂ„ igenom dokumentationen för att se uppgifterna för den kunden. Det Ă€r opraktiskt och slöseri med tid.
Den hierarkiska struktur vi behövde för klienternas servrar fanns redan i vÄr interna produkt. Vi behövde bara komma pÄ hur vi skulle koppla dit snabba anslutningar till den nödvÀndiga utrustningen. Först och frÀmst, Ätminstone inom vÄrt eget nÀtverk.
Eftersom kunden i vÄrt system var en webblÀsare som inte har tillgÄng till datorns lokala resurser för att helt enkelt kunna starta den önskade applikationen med ett kommando, var tanken att göra allt genom "Windows custom url scheme". SÄ föddes en slags "plugin" till vÄrt system, som helt enkelt inkluderade Putty och Remote Desktop Plus, och vid installation registrerade den URI-schemat i Windows. Nu, nÀr vi ville ansluta till en enhet via RDP eller SSH, klickade vi pÄ ÄtgÀrden i vÄrt system och Custom URI aktiverades. Den startade standard mstsc.exe som Àr inbyggd i Windows eller putty som följde med "pluginen". Jag sÀtter ordet plugin inom citat, eftersom det inte Àr en webblÀsarplugin i klassisk bemÀrkelse.
Det var Ätminstone nÄgot. En praktisk adressbok. Och i fallet med Putty var allt faktiskt bra, eftersom man kunde ange bÄde IP-adress och inloggning samt lösenord som inparametrar. D.v.s. till Linux-servrar i vÄrt nÀtverk kunde vi redan ansluta med ett klick utan att behöva ange lösenord. Men med RDP var det inte sÄ enkelt. I standardmstsc kan man inte ange referenser som parametrar. HÀr kom Remote Desktop Plus till hjÀlp. Den gjorde det möjligt. Nu klarar vi oss utan den, men under lÄng tid var den en trogen följeslagare i vÄrt system. Med HTTP(S)-sajter var allt enkelt, sÄdana objekt öppnades bara i webblÀsaren och det var allt. Praktiskt och bekvÀmt. Men det var bara en lycka i det interna nÀtverket.
Eftersom vi löste de flesta problemen pÄ distans frÄn kontoret, var det enklast att skapa VPN:er till kunderna. Och dÄ kunde vi ansluta till dem frÄn vÄrt system. Men det var fortfarande lite krÄngligt. För varje kund behövde vi ha massor av sparade anslutningar pÄ varje dator, och innan vi anslöt till nÄgon av dem var vi tvungna att aktivera motsvarande VPN. Den lösningen anvÀnde vi under en ganska lÄng tid. Men antalet kunder ökade, antalet VPN:er ocksÄ, och allt detta började bli en belastning och vi behövde göra nÄgot Ät det. SÀrskilt tÄrar började rinna efter systemÄterstÀllningen, nÀr vi var tvungna att ange dussintals VPN-anslutningar pÄ nytt i den nya Windows-profilen. Det Àr dags att stÄ ut med detta, sa jag och började tÀnka pÄ vad vi kunde göra. VPN anslutningar och innan man kopplade till nÄgon, var man tvungen att aktivera motsvarande VPN. Den lösningen anvÀnde vi under ganska lÄng tid. Men antalet kunder ökade, antalet VPN:er ocksÄ och allt detta började bli pÄfrestande, och vi behövde göra nÄgot Ät det. Speciellt kom tÄrarna fram efter ominstallation av systemet, nÀr man behövde mata in tiotals VPN-anslutningar pÄ nytt i den nya Windows-profilen. Nu rÀcker det, sa jag och började tÀnka pÄ vad som kunde göras Ät detta.
Det har blivit sÄ att alla kunder har anvÀnt routerutrustning frÄn det vÀlkÀnda företaget Mikrotik. De Àr mycket funktionella och bekvÀma för att hantera nÀstan alla uppgifter. En nackdel Àr att de ofta "hackas". Vi löste det problemet enkelt genom att stÀnga av all extern Ätkomst. Men vi behövde ÀndÄ ha tillgÄng till dem utan att behöva Äka till kunden, eftersom det tar för lÄng tid. Vi skapade helt enkelt tunnlar till varje Mikrotik och sammanstÀllde dem i en separat pool, utan nÄgon routing för att undvika att blanda vÄrt nÀtverk med kundernas nÀtverk och deras nÀtverk sinsemellan.
IdĂ©n föddes att göra sĂ„ att nĂ€r jag klickade pĂ„ ett objekt i systemet, skulle den centrala övervakningsservern, med kĂ€nnedom om SSH-inloggningarna till alla kunders Mikrotik-enheter, koppla upp sig mot den aktuella, skapa en portöppning till rĂ€tt vĂ€rd med rĂ€tt port. HĂ€r finns flera aspekter. Lösningen Ă€r inte universell â den fungerar bara för Mikrotik, eftersom kommandots syntax Ă€r specifik för varje router. Dessutom mĂ„ste dessa portöppningar pĂ„ nĂ„got sĂ€tt tas bort senare, och serverdelen av vĂ„rt system kunde i grunden inte spĂ„ra om jag var klar med min RDP-session. Och en sĂ„dan portöppning utgör en sĂ€kerhetsrisk för kunden. Vi strĂ€vade inte efter universell lösning eftersom produkten anvĂ€ndes internt i vĂ„rt företag och vi hade inte ens tankar pĂ„ att offentliggöra den.
Var och en av dessa problem löstes pÄ ett sÀtt. NÀr portöppningen skapades var den endast tillgÀnglig för en specifik extern IP-adress (den frÄn vilken anslutningen initierades). SÄ vi lyckades undvika sÀkerhetsrisker. Men vid varje sÄdan anslutning lades en regel till Mikrotik pÄ NAT-sidan och togs inte bort. Och det Àr allmÀnt kÀnt att ju fler regler dÀr finns, desto mer belastas routerns processor. Dessutom kunde jag inte acceptera tanken pÄ att jag en dag skulle logga in pÄ en Mikrotik och dÀr skulle finnas hundratals döda regler som ingen behöver.
Eftersom vÄr server inte kan övervaka anslutningens tillstÄnd, lÄt Mikrotik övervaka dem sjÀlv. Jag skrev ett skript som kontinuerligt övervakade alla portregler med en viss beskrivning (description) och kontrollerade om det fanns en TCP-anslutning som passade regeln. Om det inte fanns nÄgon under en tid, var det troligt att anslutningen redan var avslutad och den porten kunde tas bort. Allt fungerade, skriptet fungerade bra.
Förresten, hÀr Àr det:
global atmonrulecounter {"dontDelete"="dontDelete"}
:foreach i in=[/ip firewall nat find comment~"atmon_script_main"] do={
local dstport [/ip firewall nat get value-name="dst-port" $i]
local dstaddress [/ip firewall nat get value-name="dst-address" $i]
local dstaddrport "$dstaddress:$dstport"
#log warning message=$dstaddrport
local thereIsCon [/ip firewall connection find dst-address~"$dstaddrport"]
if ($thereIsCon = "") do={
set ($atmonrulecounter->dstport) ($atmonrulecounter->dstport + 1)
#:log warning message=($atmonrulecounter->dstport)
if (($atmonrulecounter->dstport) > 5) do={
#log warning message="Removing nat rules added automaticaly by atmon_script"
/ip firewall nat remove [/ip firewall nat find comment~"atmon_script_main_$dstport"]
/ip firewall nat remove [/ip firewall nat find comment~"atmon_script_sub_$dstport"]
set ($atmonrulecounter->dstport) 0
}
} else {
set ($atmonrulecounter->dstport) 0
}
}
Det gÄr sÀkert att göra det snyggare, snabbare osv., men det fungerade, belastade inte Mikrotik och klarade sig utmÀrkt. Vi kunde Àntligen ansluta till servrar och kundernas nÀtverksutrustning bara med ett musklick. Utan att köra VPN och utan att skriva in lösenord. Det blev verkligen mycket mer bekvÀmt att arbeta med systemet. Tiden för underhÄll minskade, och vi tillbringade vÄr tid pÄ att arbeta, istÀllet för att ansluta till nödvÀndiga objekt.
Backup av Mikrotik
Vi hade stÀllt in backup av alla Mikrotik pÄ FTP. Och överlag var allt bra. Men nÀr vi behövde hÀmta en backup, behövde vi öppna den FTP:n och leta efter den dÀr. Vi har ett system dÀr alla routrar Àr registrerade, vi kan kommunicera med enheter via SSH. Vad skulle hindra oss frÄn att lÄta systemet dagligen hÀmta backuper frÄn alla Mikrotik, tÀnkte jag. Och satte igÄng att implementera det. Vi anslöt, gjorde en backup och sparade den i lagringen.
PHP-skriptkoden för att ta backup frÄn Mikrotik:
<?php
$IP = '0.0.0.0';
$LOGIN = 'admin';
$PASSWORD = '';
$BACKUP_NAME = 'test';
$connection = ssh2_connect($IP, 22);
if (!ssh2_auth_password($connection, $LOGIN, $PASSWORD)) exit;
ssh2_exec($connection, 'system backup save name="atmon" password="atmon"');
stream_get_contents($connection);
ssh2_exec($connection, 'export file="atmon.rsc"');
stream_get_contents($connection);
sleep(40); // Waiting bakup makes
$sftp = ssh2_sftp($connection);
// Download backup file
$size = filesize("ssh2.sftp://$sftp/atmon.backup");
$stream = fopen("ssh2.sftp://$sftp/atmon.backup", 'r');
$contents = '';
$read = 0;
$len = $size;
while ($read < $len && ($buf = fread($stream, $len - $read))) {
$read += strlen($buf);
$contents .= $buf;
}
file_put_contents ($BACKUP_NAME . '.backup',$contents);
@fclose($stream);
sleep(3);
// Download RSC file
$size = filesize("ssh2.sftp://$sftp/atmon.rsc");
$stream = fopen("ssh2.sftp://$sftp/atmon.rsc", 'r');
$contents = '';
$read = 0;
$len = $size;
while ($read
Backup tas som görs i tvĂ„ former â binĂ€r och textkonfiguration. BinĂ€ren hjĂ€lper att snabbt Ă„terstĂ€lla den nödvĂ€ndiga konfigurationen, medan textversionen gör att man förstĂ„r vad som behöver göras om det sker en ofrivillig hĂ„rdvarubyte och binĂ€ren inte kan laddas. Resultatet blir en till anvĂ€ndbar funktionalitet i systemet. Dessutom, nĂ€r nya MikroTik-enheter lades till behövde ingenting konfigureras, man la bara till objektet i systemet och angav en SSH-inloggning för den. Systemet tog hand om backupen automatiskt. I den aktuella versionen av SaaS Veliam finns denna funktionalitet Ă€nnu inte, men den kommer snart att porteras.
Screendumpar över hur det sÄg ut i det interna systemet

ĂvergĂ„ng till normal lagring i databasen
Jag har tidigare nÀmnt att det uppstod artefakter. Ibland försvann hela listan över objekt i systemet, och ibland sparades inte informationen vid redigering av ett objekt, vilket ledde till att jag var tvungen att byta namn pÄ objektet tre gÄnger. Det irriterade alla enormt. Försvinnandet av objekt intrÀffade sÀllan och kunde enkelt ÄtgÀrdas genom att ÄterstÀlla filen, men problemen vid redigering av objekt var vanliga. Troligtvis gjorde jag det inte via databasen frÄn början eftersom jag inte kunde förstÄ hur man skulle hÄlla ett trÀd med alla relationer i en platt tabell. Den Àr ju platt, medan trÀdet Àr hierarkiskt. Men en bra lösning för samtidig Ätkomst, och senare (i takt med att systemet blev mer komplicerat) Àven för transaktioner, Àr en databas. Jag Àr sÀker pÄ att jag inte Àr den första som har stött pÄ det hÀr problemet. Jag började googla. Det visade sig att allt redan var tÀnkt innan mig, och det finns flera algoritmer som bygger ett trÀd frÄn en platt tabell. Efter att ha tittat pÄ varje, implementerade jag en av dem. Men det var redan en ny version av systemet, eftersom det i grunden krÀvdes ganska mycket omarbetning pÄ grund av detta. Resultatet var förvÀntat, problemen med systemets slumpmÀssiga beteende försvann. NÄgon kan sÀga att felen var ganska amatörmÀssiga (enkla skript, lagring av information som hade flera samtidiga Ätkomster frÄn olika trÄdar i en fil osv.) inom programvaruutveckling. Kanske Àr det sÄ, men mitt huvudjobb var administration, och programmering var en hobby för sjÀlen, och jag hade helt enkelt ingen erfarenhet av att arbeta i ett team av programmerare som kunde ha pÄmint mig om sÄdana grundlÀggande saker. DÀrför fick jag lÀra mig pÄ egen hand, men jag tog definitivt till mig materialet. Dessutom innebÀr mitt arbete - möten med kunder, aktiviteter riktade mot att försöka marknadsföra företaget, massor av administrativa frÄgor internt i företaget och mycket mer. Men pÄ ett eller annat sÀtt var det som fanns efterfrÄgat. Killarna och jag sjÀlv anvÀnde produkten i vÄrt dagliga arbete. Det fanns Àven uppenbart misslyckade idéer och lösningar som kostade tid, och i slutÀndan blev det klart att det var ett odugligt verktyg som ingen anvÀnde, och det hamnade inte i Veliam.
SupporttjĂ€nst â HelpDesk
Det Àr ocksÄ vÀrt att nÀmna hur HelpDesk har utvecklats. Det Àr verkligen en egen historia, eftersom det i Veliam redan Àr den tredje helt nya versionen, som skiljer sig frÄn alla tidigare. Nu Àr det ett enkelt system, intuitivt förstÄeligt utan onödiga utsmyckningar och finesser, med möjlighet att integreras med domÀnen, samt med möjlighet att fÄ tillgÄng till samma anvÀndarprofil frÄn vilket stÀlle som helst via en lÀnk i ett mail. Och det viktigaste av allt, det finns möjlighet att ansluta till anvÀndaren via VNC direkt frÄn Àrendet utan VPN eller portforwarding, oavsett var jag befinner mig (hemma eller pÄ kontoret). Jag kommer att berÀtta hur vi kom hit, vad som var före och vilka fruktansvÀrda lösningar som fanns.
Vi kopplade upp oss till anvÀndarna via det vÀlkÀnda TeamViewer. PÄ alla datorer dÀr anvÀndarna vi supportar har TeamViewer installerat. Det första vi gjorde fel, och som vi senare tog bort, var att knyta varje klients HWID till hÄrdvaran. Hur logger en anvÀndare in i HW-systemet för att lÀmna en begÀran? Förutom TeamViewer hade vi installerat ett speciellt verktyg skrivet i Lazarus (mÄnga kommer att höja ögonbrynen och kanske till och med börja googla vad det Àr, men av de kompilatorer jag kÀnde till var Delphi det bÀsta, och Lazarus Àr nÀstan detsamma, bara gratis). AnvÀndaren körde en speciell batchfil som startade detta verktyg, som i sin tur lÀste av systemets HWID och dÀrefter startades webblÀsaren och autentiseringen skedde. Varför gjorde vi sÄ hÀr? I vissa företag rÀknas de supportade anvÀndarna individuellt, och priset för supporten för varje mÄnad baseras pÄ antalet personer. Det Àr tydligt, sÀger du, men varför knyta det till hÄrdvaran? VÀldigt enkelt, vissa individer kom hem och lÀmnade en begÀran frÄn sin bÀrbara dator i stil med "gör allt fint hÀr". Förutom att lÀsa av systemets HWID, hÀmtade verktyget Àven den aktuella ID:n för TeamViewer frÄn registret och skickade det till oss. TeamViewer har ett API för integration. Och vi gjorde denna integration. Men det fanns en hake. Genom detta API kan man inte ansluta till anvÀndarens dator om denne inte initierar sessionen och efter att man försökt att ansluta till dem mÄste de fortfarande trycka pÄ "bekrÀfta". Vid den tiden verkade det logiskt för oss att ingen skulle koppla upp sig utan anvÀndarens medgivande, och eftersom personen Àr vid datorn, sÄ initierade denne sessionen och gav positivt svar pÄ begÀran om fjÀrranslutning. SÄ blev det inte. De som ansökte glömde att initiera sessionen, och vi var tvungna att nÀmna detta i telefonsamtalet. Det tog tid och irriterade bÄda parter i processen. Dessutom var det inte ovanligt att en person lÀmnade en begÀran, men endast tillÀt anslutning nÀr denne gick pÄ lunch. Eftersom det inte var ett kritiskt problem ville de inte avbryta sitt arbetsflöde. DÀrför tryckte de inte pÄ nÄgra knappar för att tillÄta anslutning. SÄ uppstod den extra funktionen vid autentiseringen i HelpDesk - avlÀsning av TeamViewer-ID. Vi kÀnde till det fasta lösenord som anvÀndes vid installationen av TeamViewer. Mer exakt, det var endast systemet som kÀnde till det, eftersom det var inbakat i installationen och vÄrt system. SÄ det fanns en knapp för att ansluta frÄn begÀran som nÀr man tryckte pÄ den inte behövde vÀnta, utan direkt öppnades TeamViewer och anslutningen skedde. Resultatet blev tvÄ typer av möjliga anslutningar. Genom TeamViewers officiella API och vÄr egen lösning. Till min överraskning slutade anvÀndningen av det första nÀstan omedelbart, Àven om det var angivet att man endast skulle anvÀnda det i sÀrskilda fall och nÀr anvÀndaren sjÀlv ger sitt medgivande. SÀkerhet Àr viktiga nu för tiden. Men det visade sig att de som begÀrde inte behövde det. De hade överhuvudtaget inget emot att bli anslutna utan bekrÀftelseknappen. Och eftersom det var sÄ behövde vi inte lÀngre ansluta via API.
ĂvergĂ„ng till flerkörning i Linux
FrÄgan om att snabba upp nÀtverkskanarens angrepp pÄ öppnandet av en förbestÀmd lista av portar och det enkla pingandet av nÀtverksobjekt har lÀnge varit aktuell. Det första sjÀlvklara svaret som dyker upp Àr flerkörning. Eftersom den största tiden som gÄr Ät till att pinga Àr vÀntan pÄ att paketet ska Äterkomma, och nÀsta ping inte kan starta förrÀn det föregÄende paketet har kommit tillbaka, Àr det redan trögt för företag med mer Àn 20 servrar plus nÀtverksutrustning. PoÀngen Àr att ett paket kan försvinna, och det skulle inte vara möjligt att omedelbart notifiera systemadministratören om detta. Han skulle snabbt sluta ta hand om sÄdan spam. Det betyder att varje objekt mÄste pingas flera gÄnger innan man drar slutsatsen om det Àr otillgÀngligt. Utan att gÄ in pÄ för mycket detaljer, mÄste man parallellisera, för om man inte gör det, kommer systemadministratören förmodligen att fÄ höra om problemet av kunden, inte av övervakningssystemet.
PHP kan i sig sjÀlv inte hantera flerkörning direkt. Det kan hantera flersprocessbarhet, man kan förgrena sig. Men jag hade redan i praktiken skrivit en frÄgemekanism och ville göra sÄ att jag bara lÀste alla nödvÀndiga noder frÄn databasen en gÄng, pingade dem alla pÄ en gÄng, vÀntade pÄ svar frÄn varje och först efter det skrev jag omedelbart ner data. Detta sparar pÄ antalet lÀsförfrÄgningar. Idén med flerkörning passade perfekt. För PHP finns det modulen PThreads, som gör verklig flerkörning möjlig. Det krÀvdes dock en hel del arbete för att konfigurera detta pÄ PHP 7.2, men det blev gjort. Portskanning och pingande blev snabba. Och istÀllet för exempelvis 15 sekunder tidigare, tog den hÀr processen nu 2 sekunder. Det var ett bra resultat.
Snabb granskning av nya företag
Hur kom funktionen för insamling av olika mÀtvÀrden och hÄrdvarukarakteristik till? Det Àr enkelt. Ibland bestÀller kunder bara en granskning av den nuvarande IT-infrastrukturen. Och samma sak behövs för att snabba upp granskningen av en ny kund. Vi behövde nÄgot som gjorde att vi snabbt kunde komma in i ett medelstort eller stort företag och fÄ en överblick över vad de faktiskt har. Pingen i det interna nÀtverket blockeras, tycker jag, bara av dem som vill komplicera livet för sig sjÀlva, och de Àr i vÄr erfarenhet inte mÄnga. Men de finns. DÀrför kan man snabbt skanna nÀtverken efter enheter med en enkel ping. DÀrefter kan man lÀgga till dem och skanna dem för öppna portar som vi Àr intresserade av. Egentligen fanns denna funktion redan, det behövdes bara en kommandofunktion frÄn den centrala servern till den underordnade, sÄ att den kunde skanna de angivna nÀten och lÀgga till allt den hittar i listan. Jag glömde att nÀmna att vi antog att vi redan hade en fÀrdig bild med ett konfigurerat system (den underordnade övervakningsservern) som vi helt enkelt kunde rulla ut hos kunden under granskningen och koppla till vÄrt moln.
Men resultatet av audit brukar vanligtvis att innehÄlla en mÀngd olika information, och en av dessa Àr vad för enheter som finns i nÀtverket. Först och frÀmst var vi intresserade av Windows-servrar och Windows-arbetsstationer inom domÀnen. Eftersom avsaknaden av en domÀn i medelstora och stora företag förmodligen Àr en undantag frÄn regeln. För att prata samma sprÄk, vad jag anser vara genomsnittligt, Àr det 100+ personer. Det behövdes en metod för att samla in data frÄn alla Windows-maskiner och servrar, med vetskap om deras IP och domÀnadministratörens konto, utan att installera nÄgot program pÄ var och en av dem. HÀr kommer WMI-grÀnssnittet till hjÀlp. Windows Management Instrumentation (WMI) Àr bokstavligt översatt till Windows hanteringsverktyg. WMI Àr en av de grundlÀggande teknologierna för centraliserad hantering och övervakning av olika delar av datorinfrastrukturen som körs pÄ Windows-plattformen. Hittat pÄ wiki. Vidare fick vi Äterigen arbeta med att samla in wmic (detta Àr WMI-klienten) för Debian. NÀr allt var klart Äterstod endast att frÄga de nödvÀndiga noderna genom wmic efter den information som behövdes. Genom WMI kan man hÀmta nÀstan vilken information som helst frÄn en Windows-dator, och dessutom kan man ocksÄ styra datorn, till exempel skicka en omstart. SÄ kom insamlingen av information om Windows-stationer och servrar in i vÄrt system. Dessutom kom aktuell information om systemets belastningsvÀrden med. Dessa frÄgar vi oftare, medan informationen om hÄrdvaran sÀllan. Efter detta blev det lite trevligare att genomföra en revision.
Beslut om programvarudistribution
Vi anvÀnder sjÀlva systemet dagligen, och det Àr alltid öppet för varje teknisk anstÀlld. Och vi tÀnkte att vi ocksÄ kan dela med oss av vad vi redan har med andra. Systemet var fortfarande oklart redo för distribution. Mycket behövde omarbetas för att den lokala versionen skulle omvandlas till SaaS. Det handlar om förÀndringar i olika tekniska aspekter av systemets arbete (fjÀrranslutningar, supporttjÀnst), analys av moduler för licensiering, shardning av kundernas databaser, skalning av varje tjÀnst och utveckling av system för automatisk uppdatering av alla delar. Men det kommer att vara i del tvÄ av artikeln.
Uppdatering
KĂ€lla: habr.com
