Dall'outsourcing allo sviluppo (Parte 1)

Ciao a tutti, mi chiamo Sergey Emelyanchik. Sono il capo della società Audit-Telecom, principale sviluppatore e autore del sistema Veliam. Ho deciso di scrivere un articolo su come io e il mio amico abbiamo creato una società di outsourcing, scritto software per noi stessi e successivamente abbiamo iniziato a distribuirlo a tutti tramite il sistema SaaS. Di come categoricamente non credevo che ciò fosse possibile. L'articolo conterrà non solo una storia, ma anche i dettagli tecnici su come è stato creato il prodotto Veliam. Inclusi alcuni pezzi di codice sorgente. Ti dirò quali errori abbiamo commesso e come li abbiamo corretti in seguito. C'erano dubbi se pubblicare un articolo del genere. Ma ho pensato che fosse meglio farlo, ottenere feedback e migliorare, piuttosto che non pubblicare l'articolo e pensare a cosa sarebbe successo se...

Sfondo

Ho lavorato in un'azienda come dipendente IT. L'azienda era piuttosto grande con un'ampia struttura di rete. Non mi soffermerò sulle mie responsabilità lavorative, dirò solo che sicuramente non prevedevano lo sviluppo di nulla.

Avevamo un monitoraggio, ma per puro interesse accademico volevo provare a scriverne uno più semplice. L'idea era questa: volevo che fosse sul web, in modo da poter entrare facilmente senza installare alcun client e vedere cosa succedeva con la rete da qualsiasi dispositivo, compreso un dispositivo mobile tramite Wi-Fi, e ho anche davvero volevo capire velocemente cosa ci sono apparecchiature nella stanza che sono diventate “mopey” perché... c'erano requisiti molto severi per i tempi di risposta a tali problemi. Di conseguenza, nella mia testa è nato il piano di scrivere una semplice pagina web su cui c'era uno sfondo jpeg con un diagramma di rete, ritagliare i dispositivi stessi con i loro indirizzi IP in questa immagine e mostrare il contenuto dinamico sopra immagine nelle coordinate richieste sotto forma di indirizzo IP verde o rosso lampeggiante. Il compito è stato impostato, cominciamo.

In precedenza, programmavo in Delphi, PHP, JS e, in modo molto superficiale, C++. So abbastanza bene come funzionano le reti. VLAN, instradamento (OSPF, EIGRP, BGP), NAT. Questo mi è bastato per scrivere io stesso un prototipo di monitoraggio primitivo.

Ho scritto quello che avevo pianificato in PHP. Il server Apache e PHP era su Windows perché... Linux per me in quel momento era qualcosa di incomprensibile e molto complesso, come si è scoperto in seguito, mi sbagliavo di grosso e in molti posti Linux è molto più semplice di Windows, ma questo è un argomento a parte e sappiamo tutti quanti holivar ci sono su questo argomento. L'utilità di pianificazione di Windows eseguiva a un breve intervallo (non ricordo esattamente, ma qualcosa come una volta ogni tre secondi) uno script PHP che interrogava tutti gli oggetti con un banale ping e salvava lo stato in un file.

system(“ping -n 3 -w 100 {$ip_address}“); 

Sì, sì, anche lavorare con un database in quel momento non era padroneggiato per me. Non sapevo che fosse possibile parallelizzare i processi, e percorrere tutti i nodi della rete richiedeva molto tempo, perché... questo è successo in un thread. I problemi sono sorti soprattutto quando diversi nodi non erano disponibili, perché ognuno di loro ha ritardato la sceneggiatura di 300 ms. Lato client era presente una semplice funzione di looping che, ad intervalli di pochi secondi, scaricava informazioni aggiornate dal server con una richiesta Ajax e aggiornava l'interfaccia. Bene, allora, dopo 3 ping consecutivi senza successo, se sul computer era aperta una pagina web con monitoraggio, veniva riprodotta una composizione allegra.

Quando tutto ha funzionato, sono rimasto molto ispirato dal risultato e ho pensato che avrei potuto aggiungerne altro (grazie alle mie conoscenze e capacità). Ma non mi sono sempre piaciuti i sistemi con un milione di grafici, che allora pensavo, e penso ancora oggi, non siano necessari nella maggior parte dei casi. Ho voluto inserire lì solo ciò che mi avrebbe realmente aiutato nel mio lavoro. Questo principio rimane ancora oggi fondamentale per lo sviluppo di Veliam. Inoltre, mi sono reso conto che sarebbe stato molto bello se non avessi dovuto tenere aperto il monitoraggio e conoscere i problemi e, quando si fosse verificato, aprire la pagina e vedere dove si trova questo nodo di rete problematico e cosa farne dopo . In qualche modo allora non leggevo la posta elettronica, semplicemente non la usavo. Mi sono imbattuto su Internet che esistono gateway SMS ai quali è possibile inviare una richiesta GET o POST e loro invieranno un SMS al mio cellulare con il testo che scrivo. Ho subito capito che lo volevo davvero. E ho iniziato a studiare la documentazione. Dopo un po' ci sono riuscito e ora ho ricevuto sul mio cellulare un SMS sui problemi di rete con il nome di un “oggetto caduto”. Sebbene il sistema fosse primitivo, è stato scritto da me personalmente e la cosa più importante che mi ha motivato a svilupparlo è che si trattava di un programma applicativo che mi ha davvero aiutato nel mio lavoro.

E poi è arrivato il giorno in cui uno dei canali Internet ha smesso di funzionare e il mio monitoraggio non me ne ha fatto sapere. Poiché il ping di Google DNS funziona ancora perfettamente. È tempo di pensare a come monitorare che il canale di comunicazione sia attivo. C'erano idee diverse su come farlo. Non avevo accesso a tutta l'attrezzatura. Abbiamo dovuto capire come capire quale dei canali è in diretta, ma senza riuscire in qualche modo a visualizzarlo sull'apparecchiatura di rete stessa. Poi un collega ha avuto l'idea che è possibile che il percorso verso i server pubblici possa differire a seconda del canale di comunicazione attualmente utilizzato per accedere a Internet. Ho controllato ed è risultato così. Durante il tracciamento c'erano percorsi diversi.

system(“tracert -d -w 500 8.8.8.8”);

Quindi è apparso un altro script, o meglio, per qualche motivo è stata aggiunta una traccia alla fine dello stesso script, che ha eseguito il ping di tutti i dispositivi della rete. Dopotutto, questo è un altro lungo processo che è stato eseguito nello stesso thread e ha rallentato il lavoro dell'intero script. Ma allora non era così ovvio. Ma in un modo o nell'altro ha fatto il suo lavoro, il codice ha definito rigorosamente quale tipo di tracciamento dovrebbe essere per ciascuno dei canali. Cominciò così a funzionare il sistema, che già monitorava (detto a voce alta, perché non c'era raccolta di metriche, ma solo ping) i dispositivi di rete (router, switch, wi-fi, ecc.) e i canali di comunicazione con il mondo esterno . Gli SMS arrivavano regolarmente e il diagramma mostrava sempre chiaramente dov'era il problema.

Inoltre, nel lavoro quotidiano dovevo fare cross-crossing. E mi sono stancato di andare ogni volta sugli switch Cisco per vedere quale interfaccia utilizzare. Quanto sarebbe bello fare clic su un oggetto nel monitoraggio e vedere un elenco delle sue interfacce con le descrizioni. Mi farebbe risparmiare tempo. Inoltre, in questo schema non ci sarebbe bisogno di eseguire Putty o SecureCRT per inserire account e comandi. Ho semplicemente cliccato sul monitoraggio, ho visto cosa era necessario e sono andato a fare il mio lavoro. Ho iniziato a cercare modi per interagire con gli interruttori. Mi sono subito imbattuto in 2 opzioni: SNMP o accedere allo switch tramite SSH, inserendo i comandi di cui avevo bisogno e analizzando il risultato. Ho scartato SNMP a causa della complessità della sua implementazione; ero impaziente di ottenere il risultato. con SNMP bisognerebbe scavare a lungo nel MIB e, sulla base di questi dati, generare dati sulle interfacce. C'è una squadra meravigliosa in CISCO

show interface status

Mostra esattamente ciò di cui ho bisogno per gli incroci incrociati. Perché preoccuparsi di SNMP quando voglio solo vedere l'output di questo comando, ho pensato. Dopo qualche tempo, ho realizzato questa opportunità. Clic su un oggetto in una pagina web. È stato attivato un evento grazie al quale il client AJAX ha contattato il server e, a sua volta, si è connesso tramite SSH allo switch di cui avevo bisogno (le credenziali erano codificate nel codice, non c'era alcun desiderio di perfezionarlo, di creare alcuni menu separati in cui sarebbe possibile cambiare account dall'interfaccia, avevo bisogno del risultato e velocemente) ho inserito lì il comando sopra e l'ho rispedito al browser. Così ho iniziato a vedere le informazioni sulle interfacce con un clic del mouse. Ciò era estremamente comodo, soprattutto quando dovevi visualizzare queste informazioni su diversi interruttori contemporaneamente.

Il monitoraggio dei canali basato sulla traccia si è rivelato non essere l'idea migliore, perché... a volte si lavorava sulla rete, e il tracciamento poteva cambiare e il monitoraggio cominciava a gridarmi che c'erano problemi con il canale. Ma dopo aver dedicato molto tempo all'analisi, mi sono reso conto che tutti i canali funzionavano e il mio monitoraggio mi stava ingannando. Di conseguenza, ho chiesto ai miei colleghi che gestivano gli switch di formazione dei canali di inviarmi semplicemente il syslog quando cambiava lo stato di visibilità dei vicini. Di conseguenza, era molto più semplice, veloce e preciso del tracciamento. È arrivato un evento come il vicino perso e invio immediatamente una notifica relativa al canale inattivo.

Inoltre, quando si fa clic su un oggetto sono apparsi molti altri comandi ed è stato aggiunto SNMP per raccogliere alcune metriche, e fondamentalmente è tutto. Il sistema non si è mai sviluppato ulteriormente. Ha fatto tutto ciò di cui avevo bisogno, era un buon strumento. Molti lettori probabilmente mi diranno che su Internet esistono già molti software per risolvere questi problemi. Ma in realtà, allora non cercavo su Google prodotti gratuiti del genere e volevo davvero sviluppare le mie capacità di programmazione, e quale modo migliore per spingere per questo se non un vero problema applicativo. A questo punto la prima versione del monitoraggio è stata completata e non è stata più modificata.

Creazione della società Audit-Telecom

Con il passare del tempo ho iniziato a lavorare part-time in altre aziende, fortunatamente i miei orari di lavoro me lo permettevano. Quando lavori in aziende diverse, le tue competenze in vari settori crescono molto rapidamente e i tuoi orizzonti si sviluppano bene. Ci sono aziende in cui, come si suol dire, sei uno svedese, un mietitore e un trombettista. Da un lato è difficile, dall’altro se non sei pigro diventi un generalista e questo ti permette di risolvere i problemi in modo più veloce ed efficace perché sai come funziona il settore correlato.

Il mio amico Pavel (anche lui specialista IT) ha cercato costantemente di incoraggiarmi ad avviare un'attività in proprio. C'erano innumerevoli idee con diverse varianti di ciò che stavano facendo. Di questo si parla da anni. E alla fine non sarebbe dovuto succedere nulla perché io sono scettico e Pavel è un sognatore. Ogni volta che proponeva un’idea io non ci credevo e mi rifiutavo di partecipare. Ma volevamo davvero aprire un'attività in proprio.

Alla fine, siamo riusciti a trovare un’opzione adatta a entrambi e a fare ciò che sappiamo fare. Nel 2016 abbiamo deciso di creare una società IT che aiutasse le aziende a risolvere i problemi IT. Si tratta dell'implementazione dei sistemi IT (1C, terminal server, mail server, ecc.), della loro manutenzione, del classico HelpDesk per gli utenti e dell'amministrazione della rete.

Francamente, al momento della creazione dell'azienda, non ci credevo al 99,9%. Ma in qualche modo Pavel è riuscito a convincermi a provare e, guardando al futuro, si è rivelato avere ragione. Pavel e io abbiamo versato 300 rubli ciascuno, abbiamo registrato una nuova LLC "Audit-Telecom", abbiamo affittato un piccolo ufficio, abbiamo realizzato fantastici biglietti da visita, beh, in generale, come probabilmente la maggior parte degli uomini d'affari alle prime armi inesperti, e abbiamo iniziato a cercare clienti. Trovare clienti è una storia completamente diversa. Forse scriveremo un articolo separato come parte del blog aziendale se qualcuno è interessato. Chiamate a freddo, volantini, ecc. Ciò non ha dato alcun risultato. Come leggo ora da molte storie di affari, in un modo o nell'altro, molto dipende dalla fortuna. Siamo stati fortunati. e letteralmente un paio di settimane dopo la creazione dell'azienda, mio ​​fratello Vladimir si è rivolto a noi, che ci ha portato il primo cliente. Non vi annoierò con i dettagli del lavoro con i clienti, non è di questo che tratta l'articolo, dirò solo che abbiamo fatto un audit, individuato le aree critiche e queste aree si sono guastate mentre si decideva se farlo collaborano con noi su base continuativa come outsourcer. Successivamente è stata presa immediatamente una decisione positiva.

Poi, soprattutto grazie al passaparola tra amici, hanno cominciato ad apparire altre società di servizi. L'Helpdesk era in un unico sistema. Le connessioni agli apparati di rete e ai server sono diverse, o meglio diverse. Alcune persone hanno salvato scorciatoie, altre hanno utilizzato rubriche RDP. Il monitoraggio è un altro sistema separato. È molto scomodo per un team lavorare su sistemi disparati. Si perdono di vista informazioni importanti. Ebbene, ad esempio, il terminal server del cliente non è più disponibile. Le richieste degli utenti di questo client vengono ricevute immediatamente. Lo specialista del supporto apre una richiesta (è stata ricevuta telefonicamente). Se gli incidenti e le richieste fossero registrati in un unico sistema, lo specialista del supporto vedrebbe immediatamente qual è il problema dell'utente e glielo spiegherebbe, collegandosi contemporaneamente all'oggetto richiesto per risolvere la situazione. Tutti sono consapevoli della situazione tattica e lavorano in armonia. Non abbiamo trovato un sistema in cui tutto questo sia combinato. È diventato chiaro che era giunto il momento di realizzare il nostro prodotto.

Lavoro continuo sul vostro sistema di monitoraggio

Era chiaro che il sistema scritto in precedenza era del tutto inadatto ai compiti attuali. Né in termini di funzionalità né in termini di qualità. Ed è stato deciso di scrivere il sistema da zero. Graficamente avrebbe dovuto apparire completamente diverso. Doveva essere un sistema gerarchico in modo che fosse possibile aprire rapidamente e comodamente l'oggetto giusto per il cliente giusto. Lo schema della prima versione non era assolutamente giustificato nel caso attuale, perché I clienti sono diversi e non importava in quale sede si trovassero le apparecchiature. Questo è già stato trasferito alla documentazione.

Quindi i compiti sono:

  1. Struttura gerarchica;
  2. Una sorta di parte del server che può essere collocata presso la sede del cliente sotto forma di macchina virtuale per raccogliere le metriche di cui abbiamo bisogno e inviarle al server centrale, che riassumerà tutto questo e ce lo mostrerà;
  3. Avvisi. Quelli che non possono mancare, perché... a quel tempo non era possibile per qualcuno sedersi e limitarsi a guardare il monitor;
  4. Sistema applicativo. Cominciarono ad apparire clienti per i quali servivamo non solo server e apparecchiature di rete, ma anche postazioni di lavoro;
  5. Possibilità di connettersi rapidamente a server e apparecchiature dal sistema;

I compiti sono stati fissati, cominciamo a scrivere. Lungo il percorso, elaborazione delle richieste dei clienti. A quel tempo eravamo già in 4. Abbiamo iniziato a scrivere entrambe le parti contemporaneamente: il server centrale e il server per l'installazione sui client. A questo punto Linux non era più una novità per noi e fu deciso che le macchine virtuali che avrebbero avuto i client sarebbero state su Debian. Non ci saranno programmi di installazione, creeremo semplicemente un progetto di parte server su una macchina virtuale specifica e poi lo cloneremo sul client desiderato. Questo è stato un altro errore. Successivamente è diventato chiaro che in un tale schema il meccanismo di aggiornamento era completamente sottosviluppato. Quelli. stavamo aggiungendo qualche nuova funzionalità, e poi c'era tutto il problema di distribuirla a tutti i server client, ma torneremo su questo più tardi, tutto in ordine.

Abbiamo realizzato il primo prototipo. È stato in grado di eseguire il ping dei dispositivi e dei server di rete client di cui avevamo bisogno e di inviare questi dati al nostro server centrale. E lui, a sua volta, ha aggiornato questi dati in blocco sul server centrale. Qui scriverò non solo una storia su come e cosa ha avuto successo, ma anche quali errori amatoriali sono stati commessi e come in seguito ho dovuto pagarli con il tempo. Pertanto, l'intero albero degli oggetti è stato archiviato in un unico file sotto forma di oggetto serializzato. Mentre collegavamo diversi client al sistema, tutto era più o meno normale, anche se a volte si verificavano degli artefatti completamente incomprensibili. Ma quando abbiamo collegato una dozzina di server al sistema, i miracoli hanno cominciato ad accadere. A volte, per qualche motivo sconosciuto, tutti gli oggetti nel sistema semplicemente scomparivano. È importante notare qui che i server dei client inviano i dati al server centrale ogni pochi secondi tramite una richiesta POST. Un lettore attento e un programmatore esperto hanno già intuito che c'era un problema di accesso multiplo allo stesso file in cui era memorizzato l'oggetto serializzato da thread diversi contemporaneamente. E proprio mentre ciò avveniva, avvennero i miracoli con la scomparsa degli oggetti. Il file è semplicemente diventato vuoto. Ma tutto questo non è stato scoperto subito, ma solo durante il funzionamento con più server. Durante questo periodo è stata aggiunta la funzionalità di scansione delle porte (i server hanno inviato alla centrale non solo informazioni sulla disponibilità dei dispositivi, ma anche sulle porte aperte su di essi). Ciò è stato fatto chiamando il comando:

$connection = @fsockopen($ip, $port, $errno, $errstr, 0.5);

i risultati erano spesso errati e il completamento delle scansioni richiedeva molto tempo. Mi sono completamente dimenticato del ping, è stato fatto tramite fping:

system("fping -r 3 -t 100 {$this->ip}");

Anche questo non è stato parallelizzato e quindi il processo è stato molto lungo. Successivamente, l'intero elenco degli indirizzi IP necessari per la verifica è stato inviato immediatamente a fping e in cambio abbiamo ricevuto un elenco già pronto di coloro che hanno risposto. A differenza nostra, fping è riuscito a parallelizzare i processi.

Un altro lavoro di routine comune era l'impostazione di alcuni servizi via WEB. Bene, ad esempio, ECP di MS Exchange. Fondamentalmente è solo un collegamento. E abbiamo deciso che dobbiamo poter aggiungere tali collegamenti direttamente al sistema, in modo da non dover cercare nella documentazione o altrove nei segnalibri come accedere all'ECP di un cliente specifico. È così che è apparso il concetto di collegamenti alle risorse per il sistema, la loro funzionalità è disponibile fino ad oggi e non è cambiata, beh, quasi.

Come funzionano i collegamenti alle risorse in Veliam
Dall'outsourcing allo sviluppo (Parte 1)

Connessioni remote

Questo è come appare in azione nell'attuale versione di Veliam
Dall'outsourcing allo sviluppo (Parte 1)

Uno dei compiti era connettersi rapidamente e comodamente ai server, di cui ce n'erano già molti (più di cento) e ordinare milioni di collegamenti RDP pre-salvati era estremamente scomodo. Era necessario uno strumento. Esistono software su Internet che assomigliano a una rubrica per tali connessioni RDP, ma non sono integrati con il sistema di monitoraggio e gli account non possono essere salvati. Inserire ogni volta account per clienti diversi è un vero inferno quando ti connetti decine di volte al giorno a server diversi. Con SSH le cose vanno un po' meglio; ci sono molti buoni software che permettono di organizzare tali connessioni in cartelle e ricordarne gli account. Ma ci sono 2 problemi. Il primo è che non abbiamo trovato un solo programma per le connessioni RDP e SSH. La seconda è che se ad un certo punto non sono al computer e ho bisogno di connettermi velocemente, o ho semplicemente reinstallato il sistema, dovrò andare nella documentazione per vedere l'account di questo client. È scomodo e una perdita di tempo.

La struttura gerarchica di cui avevamo bisogno per i server client era già disponibile nel nostro prodotto interno. Dovevo solo capire come collegare le connessioni rapide all'attrezzatura necessaria lì. Per cominciare, almeno all'interno della tua rete.

Tenendo conto del fatto che il client nel nostro sistema era un browser che non ha accesso alle risorse locali del computer, per poter avviare semplicemente l'applicazione di cui avevamo bisogno con qualche comando, è stato inventato di fare tutto tramite il comando "Windows schema URL personalizzato”. È così che è apparso un certo "plug-in" per il nostro sistema, che includeva semplicemente Putty e Remote Desktop Plus e, durante l'installazione, registrava semplicemente lo schema URI in Windows. Ora, quando volevamo connetterci a un oggetto tramite RDP o SSH, facevamo clic su questa azione sul nostro sistema e l'URI personalizzato funzionava. È stato lanciato il mstsc.exe standard integrato in Windows o putty, che faceva parte del "plug-in". Ho messo la parola plugin tra virgolette perché non si tratta di un plugin per il browser nel senso classico.

Almeno era già qualcosa. Pratica rubrica. Inoltre, nel caso di Putty, in generale tutto andava bene, gli potevano essere fornite connessioni IP, login e password come parametri di input. Quelli. Ci siamo già collegati ai server Linux sulla nostra rete con un clic senza inserire password. Ma con RDP non è così semplice. MSTSC standard non può fornire credenziali come parametri. Remote Desktop Plus è venuto in soccorso. Ha permesso che ciò accadesse. Ora possiamo farne a meno, ma per molto tempo è stato un fedele assistente nel nostro sistema. Con i siti HTTP(S) tutto è semplice, tali oggetti si aprono semplicemente nel browser e il gioco è fatto. Comodo e pratico. Ma questa era felicità solo nella rete interna.

Dato che abbiamo risolto la maggior parte dei problemi in remoto dall’ufficio, la cosa più semplice è stata rendere disponibili le VPN ai clienti. E poi è stato possibile connettersi a loro dal nostro sistema. Ma era comunque un po' scomodo. Per ciascun client, era necessario mantenere una serie di connessioni VPN memorizzate su ciascun computer e, prima di connettersi a qualcuno, era necessario abilitare la VPN corrispondente. Utilizziamo questa soluzione da parecchio tempo. Ma il numero di clienti è in aumento, anche il numero di VPN è in aumento e tutto questo ha cominciato a mettere a dura prova e bisognava fare qualcosa al riguardo. Soprattutto mi sono venute le lacrime agli occhi dopo aver reinstallato il sistema, quando ho dovuto reinserire dozzine di connessioni VPN in un nuovo profilo Windows. Smettila di sopportare tutto questo, ho detto, e ho iniziato a pensare a cosa avrei potuto fare al riguardo.

È successo che tutti i clienti disponessero come router di dispositivi della nota azienda Mikrotik. Sono molto funzionali e convenienti per eseguire quasi tutte le attività. Lo svantaggio è che vengono “dirottati”. Abbiamo risolto questo problema semplicemente chiudendo ogni accesso dall'esterno. Ma era necessario in qualche modo accedervi senza recarsi a casa del cliente, perché... il suo lungo. Abbiamo semplicemente creato dei tunnel per ciascuno di questi Mikrotik e li abbiamo separati in una piscina separata. senza alcun routing, in modo che non vi sia alcuna connessione della vostra rete con le reti dei client e delle loro reti tra loro.

L'idea è nata per fare in modo che quando clicco sull'oggetto che mi occorre nel sistema, il server di monitoraggio centrale, conoscendo gli account SSH di tutti i client Mikrotik, si colleghi a quello desiderato, crei una regola di inoltro all'host desiderato con il porto richiesto. Ci sono diversi punti qui. La soluzione non è universale: funzionerà solo per Mikrotik, poiché la sintassi dei comandi è diversa per tutti i router. Inoltre, tali inoltri dovevano essere in qualche modo cancellati e la parte server del nostro sistema essenzialmente non poteva tracciare in alcun modo se avevo terminato la mia sessione RDP. Ebbene, tale inoltro è un buco per il cliente. Ma non abbiamo perseguito l’universalità, perché... il prodotto è stato utilizzato solo all'interno della nostra azienda e non si pensava di rilasciarlo al pubblico.

Ciascuno dei problemi è stato risolto a modo suo. Quando è stata creata la regola, questo inoltro era disponibile solo per uno specifico indirizzo IP esterno (da cui è stata inizializzata la connessione). Quindi è stata evitata una falla di sicurezza. Ma con ciascuna di queste connessioni, una regola Mikrotik veniva aggiunta alla pagina NAT e non veniva cancellata. E tutti sanno che più regole ci sono, più viene caricato il processore del router. E in generale, non potevo accettare che un giorno sarei andato in qualche Mikrotik e ci sarebbero state centinaia di regole morte e inutili.

Poiché il nostro server non può monitorare lo stato della connessione, lascia che sia Mikrotik a monitorarlo da solo. E ho scritto uno script che monitorava costantemente tutte le regole di inoltro con una descrizione specifica e verificava se la connessione TCP aveva una regola adeguata. Se non ce n'è più da tempo, probabilmente la connessione è già stata stabilita e questo inoltro può essere cancellato. Tutto ha funzionato, la sceneggiatura ha funzionato bene.

A proposito, eccolo qui:

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
	}
}

Sicuramente poteva essere reso più bello, più veloce, ecc., ma ha funzionato, non ha caricato Mikrotik e ha fatto un ottimo lavoro. Finalmente siamo riusciti a connetterci ai server e alle apparecchiature di rete dei clienti con un solo clic. Senza aprire una VPN o inserire password. Il sistema è diventato davvero conveniente con cui lavorare. Il tempo di servizio è stato ridotto e tutti abbiamo trascorso il tempo lavorando anziché connetterci agli oggetti necessari.

Backup Microtik

Abbiamo configurato il backup di tutti i Mikrotik su FTP. E nel complesso è andato tutto bene. Ma quando avevi bisogno di ottenere un backup, dovevi aprire questo FTP e cercarlo lì. Abbiamo un sistema in cui tutti i router sono collegati; possiamo comunicare con i dispositivi tramite SSH. Perché non facciamo in modo che il sistema stesso esegua quotidianamente i backup di tutti i Mikrotik, ho pensato. E ha iniziato a implementarlo. Ci siamo collegati, abbiamo effettuato un backup e lo abbiamo archiviato.

Codice script in PHP per eseguire un backup da 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 < $len && ($buf = fread($stream, $len - $read))) {
        $read += strlen($buf);
        $contents .= $buf;
    }
    file_put_contents ($BACKUP_NAME . ‘.rsc’,$contents);
    @fclose($stream);

    ssh2_exec($connection, '/file remove atmon.backup');
    ssh2_exec($connection, '/file remove atmon.rsc');

?>

Il backup viene eseguito in due forme: configurazione binaria e testo. Il binario aiuta a ripristinare rapidamente la configurazione richiesta e quello testuale consente di capire cosa è necessario fare se c'è una sostituzione forzata dell'attrezzatura e il binario non può essere caricato su di essa. Di conseguenza, abbiamo ottenuto un'altra comoda funzionalità nel sistema. Inoltre, quando ho aggiunto il nuovo Mikrotik, non è stato necessario configurare nulla; ho semplicemente aggiunto l'oggetto al sistema e impostato un account tramite SSH. Quindi il sistema stesso si è occupato di eseguire i backup. L'attuale versione di SaaS Veliam non dispone ancora di questa funzionalità, ma la porteremo presto.

Schermate di come appariva il sistema interno
Dall'outsourcing allo sviluppo (Parte 1)

Transizione alla normale archiviazione del database

Ho già scritto sopra che sono comparsi degli artefatti. A volte l'intero elenco di oggetti nel sistema semplicemente scompariva, a volte durante la modifica di un oggetto le informazioni non venivano salvate e l'oggetto doveva essere rinominato tre volte. Ciò ha irritato terribilmente tutti. La scomparsa degli oggetti si verificava raramente e veniva facilmente ripristinata ripristinando proprio questo file, ma si verificavano abbastanza spesso errori durante la modifica degli oggetti. Probabilmente inizialmente non l’ho fatto tramite il database perché non mi veniva in mente come fosse possibile mantenere un albero con tutte le connessioni in una tabella piatta. È piatto, ma l'albero è gerarchico. Ma una buona soluzione per l'accesso multiplo e successivamente (man mano che il sistema diventa più complesso) transazionale, è un DBMS. Probabilmente non sono il primo a riscontrare questo problema. Ho iniziato a cercare su Google. Si è scoperto che tutto era già stato inventato prima di me e ci sono diversi algoritmi che costruiscono un albero da un tavolo piatto. Dopo averli esaminati ciascuno, ne ho implementato uno. Ma questa era già una nuova versione del sistema, perché... In effetti, a causa di ciò, ho dovuto riscrivere parecchio. Il risultato è stato naturale, i problemi di comportamento casuale del sistema sono scomparsi. Alcuni potrebbero dire che gli errori sono molto amatoriali (script a thread singolo, memorizzazione di informazioni a cui si accede più volte contemporaneamente da thread diversi in un file, ecc.) nel campo dello sviluppo del software. Forse è vero, ma il mio lavoro principale era l'amministrazione, e la programmazione era un lavoro secondario per la mia anima, e semplicemente non avevo esperienza di lavoro in un team di programmatori, dove cose così basilari mi sarebbero state immediatamente suggerite dal mio senior compagni. Pertanto, ho riempito tutti questi dossi da solo, ma ho imparato molto bene il materiale. Inoltre, il mio lavoro prevede incontri con i clienti, azioni volte a cercare di promuovere l'azienda, una serie di questioni amministrative all'interno dell'azienda e molto, molto altro ancora. Ma in un modo o nell'altro, ciò che già c'era era richiesto. Io e i ragazzi abbiamo utilizzato il prodotto nel nostro lavoro quotidiano. Ci sono state idee e soluzioni francamente infruttuose su cui si è perso tempo, ma alla fine è diventato chiaro che quello non era uno strumento di lavoro e nessuno lo ha utilizzato e non è finito a Veliam.

Helpdesk - Helpdesk

Non sarebbe fuori luogo menzionare come è stato formato l'HelpDesk. Questa è una storia completamente diversa, perché... in Veliam questa è già la terza versione completamente nuova, diversa da tutte le precedenti. Ora è un sistema semplice, intuitivo senza fronzoli inutili, con la possibilità di integrarsi con un dominio, nonché la possibilità di accedere allo stesso profilo utente da qualsiasi luogo utilizzando un collegamento da un'e-mail. E, cosa più importante, è possibile connettersi al richiedente tramite VNC da qualsiasi luogo (a casa o in ufficio) direttamente dall'applicazione senza VPN o port forwarding. Ti dirò come siamo arrivati ​​a questo, cosa è successo prima e quali terribili decisioni sono state prese.

Ci siamo collegati agli utenti tramite il noto TeamViewer. Tutti i computer di cui serviamo gli utenti hanno la TV installata. La prima cosa che abbiamo sbagliato, e successivamente l'abbiamo rimossa, è stata collegare ciascun client HD all'hardware. Come ha fatto l'utente ad accedere al sistema HD per lasciare una richiesta? Oltre alla TV, tutti avevano un'utilità speciale installata sui propri computer, scritta in Lazarus (molte persone qui alzeranno gli occhi al cielo e forse andranno anche su Google di cosa si tratta, ma il miglior linguaggio compilato che conoscevo era Delphi, e Lazarus è quasi la stessa cosa, solo gratis). In generale, l'utente ha avviato uno speciale file batch che ha avviato questa utility, che a sua volta ha letto l'HWID del sistema, quindi è stato avviato il browser e si è verificata l'autorizzazione. Perché è stato fatto questo? In alcune aziende, il numero di utenti serviti viene conteggiato individualmente e il prezzo del servizio per ogni mese si basa sul numero di persone. Questo è comprensibile, dici, ma perché è legato all'hardware? È molto semplice, alcune persone sono tornate a casa e hanno fatto una richiesta dal proprio laptop di casa nello stile di "rendimi tutto bello qui". Oltre a leggere l'HWID del sistema, l'utilità ha estratto l'ID Teamviewer corrente dal registro e ce lo ha anche trasmesso. Teamviewer dispone di un'API per l'integrazione. E abbiamo fatto questa integrazione. Ma c'era un problema. Attraverso queste API è impossibile connettersi al computer dell’utente quando questi non avvia esplicitamente questa sessione e dopo aver tentato di connettersi ad essa deve anche cliccare su “conferma”. Allora ci sembrava logico che nessuno dovesse connettersi senza la richiesta dell’utente e, poiché la persona è davanti al computer, avvierà la sessione e risponderà affermativamente alla richiesta di connessione remota. Tutto è andato storto. I candidati si sono dimenticati di premere per avviare la sessione e hanno dovuto dirlo loro in una conversazione telefonica. Ciò ha fatto perdere tempo ed è stato frustrante per entrambi i lati del processo. Inoltre, non è affatto raro che tali momenti in cui una persona lasci una richiesta, ma possa connettersi solo quando esce per pranzo. Perché il problema non è critico e non vuole che il suo processo lavorativo venga interrotto. Di conseguenza, non premerà alcun pulsante per consentire la connessione. Ecco come sono apparse funzionalità aggiuntive quando si accede all'HelpDesk: leggendo l'ID di Teamviwer. Conoscevamo la password permanente utilizzata durante l'installazione di Teamviwer. Più precisamente, solo il sistema lo sapeva, poiché era integrato nell'installatore e nel nostro sistema. Di conseguenza, è stato visualizzato un pulsante di connessione dall'applicazione, facendo clic sul quale non era necessario attendere nulla, ma Teamviewer si è immediatamente aperto e si è verificata una connessione. Di conseguenza, c'erano due tipi di connessioni possibili. Attraverso l'API ufficiale di Teamviewer e quella creata da noi. Con mia sorpresa, hanno smesso di usare il primo quasi subito, anche se c'era l'istruzione di usarlo solo in casi particolari e quando l'utente stesso dà il via libera. Comunque dammi sicurezza adesso. Ma si è scoperto che i ricorrenti non ne avevano bisogno. Sono tutti assolutamente d'accordo nel connettersi a loro senza un pulsante di conferma.

Passaggio al multithreading in Linux

La questione di accelerare il passaggio di uno scanner di rete per l'apertura di un elenco predeterminato di porte e il semplice ping degli oggetti di rete ha cominciato a sorgere da tempo. Qui, ovviamente, la prima soluzione che mi viene in mente è il multithreading. Poiché la maggior parte del tempo impiegato per il ping è attendere la restituzione del pacchetto e il ping successivo non può iniziare finché non viene restituito il pacchetto precedente, nelle aziende che avevano anche più di 20 server più apparecchiature di rete, questo funzionava già piuttosto lentamente. Il punto è che un pacchetto potrebbe scomparire, ma non avvisarne immediatamente l'amministratore di sistema. Smetterà semplicemente di accettare tale spam molto rapidamente. Ciò significa che è necessario eseguire il ping di ciascun oggetto più di una volta prima di giungere ad una conclusione sull'inaccessibilità. Senza entrare troppo nei dettagli, è necessario parallelizzarlo perché se ciò non viene fatto, molto probabilmente l'amministratore di sistema verrà a conoscenza del problema dal client e non dal sistema di monitoraggio.

PHP stesso non supporta il multithreading immediato. Capace di multiprocessing, puoi biforcarlo. Ma, in effetti, avevo già scritto un meccanismo di polling e volevo farlo in modo tale da contare una volta tutti i nodi di cui avevo bisogno dal database, eseguire il ping di tutto in una volta, attendere una risposta da ciascuno e solo dopo scrivere immediatamente i dati. Ciò consente di risparmiare sul numero di richieste di lettura. Il multithreading si adatta perfettamente a questa idea. Per PHP c'è un modulo PThreads che ti permette di fare un vero multithreading, anche se ci sono voluti un bel po' di tentativi per impostarlo su PHP 7.2, ma è stato fatto. La scansione delle porte e il ping sono ora veloci. E invece dei 15 secondi al giro precedenti, ad esempio, questo processo ha iniziato a durare 2 secondi. È stato un buon risultato.

Audit rapido di nuove società

Come è nata la funzionalità per la raccolta di vari parametri e caratteristiche hardware? È semplice. A volte ci viene semplicemente ordinato di verificare l'attuale infrastruttura IT. Ebbene, la stessa cosa è necessaria per velocizzare l'audit di un nuovo cliente. Avevamo bisogno di qualcosa che ci permettesse di venire in un'azienda di medie o grandi dimensioni e capire rapidamente cosa hanno. Secondo me il ping sulla rete interna viene bloccato solo da chi vuole complicarsi la vita, e secondo la nostra esperienza ce ne sono pochi. Ma ci sono anche persone simili. Di conseguenza, puoi scansionare rapidamente le reti per la presenza di dispositivi con un semplice ping. Quindi possiamo aggiungerli e cercare le porte aperte che ci interessano. In realtà questa funzionalità esisteva già, bastava solo aggiungere un comando dal server centrale a quello slave affinché scansionasse le reti specificate e aggiungesse alla lista tutto ciò che trovava. Ho dimenticato di menzionare che si presupponeva che avessimo già un'immagine già pronta con un sistema configurato (server di monitoraggio slave) che avremmo potuto semplicemente distribuire dal client durante un audit e collegarlo al nostro cloud.

Ma il risultato di un audit di solito include una serie di informazioni diverse e una di queste è il tipo di dispositivi presenti sulla rete. Innanzitutto ci interessavano i server Windows e le workstation Windows come parte di un dominio. Poiché nelle aziende di medie e grandi dimensioni la mancanza di un dominio è probabilmente un'eccezione alla regola. Per parlare una lingua, la media, secondo me, è di oltre 100 persone. Era necessario trovare un modo per raccogliere dati da tutte le macchine e server Windows, conoscendo il loro IP e l'account di amministratore del dominio, ma senza installare alcun software su ciascuno di essi. L'interfaccia WMI viene in soccorso. Strumentazione gestione Windows (WMI) significa letteralmente strumenti di gestione di Windows. WMI è una delle tecnologie di base per la gestione centralizzata e il monitoraggio del funzionamento di varie parti dell'infrastruttura informatica che esegue la piattaforma Windows. Tratto da Wiki. Successivamente ho dovuto armeggiare di nuovo per compilare wmic (questo è un client WMI) per Debian. Dopo che tutto fu pronto, tutto ciò che restava era semplicemente interrogare i nodi necessari tramite wmic per ottenere le informazioni necessarie. Tramite WMI puoi ottenere quasi tutte le informazioni da un computer Windows e inoltre puoi anche controllare il computer tramite esso, ad esempio inviarlo al riavvio. Ecco come è apparsa la raccolta di informazioni sulle stazioni e sui server Windows nel nostro sistema. Oltre a ciò, c'erano informazioni aggiornate sugli attuali indicatori di carico del sistema. Li richiediamo più spesso e le informazioni sull'hardware meno spesso. Dopodiché l’auditing divenne un po’ più piacevole.

Decisione sulla distribuzione del software

Noi stessi utilizziamo il sistema ogni giorno ed è sempre aperto a ogni dipendente tecnico. E abbiamo pensato di poter condividere con gli altri ciò che già abbiamo. Il sistema non era ancora pronto per essere distribuito. È stato necessario rielaborare molto affinché la versione locale diventasse SaaS. Questi includono cambiamenti in vari aspetti tecnici del sistema (connessioni remote, servizio di supporto), analisi dei moduli per le licenze, partizionamento dei database dei clienti, ridimensionamento di ciascun servizio e sviluppo di sistemi di aggiornamento automatico per tutte le parti. Ma questa sarà la seconda parte dell’articolo.

Aggiornanento

Seconda parte

Fonte: habr.com

Aggiungi un commento