Da terceirização ao desenvolvimento (Parte 1)

Olá a todos, meu nome é Sergey Emelyanchik. Sou o chefe da empresa Audit-Telecom, principal desenvolvedor e autor do sistema Veliam. Decidi escrever um artigo sobre como meu amigo e eu criamos uma empresa de terceirização, escrevemos software para nós mesmos e posteriormente começamos a distribuí-lo para todos por meio do sistema SaaS. Sobre como eu categoricamente não acreditava que isso fosse possível. O artigo conterá não apenas uma história, mas também detalhes técnicos de como o produto Veliam foi criado. Incluindo algumas partes do código-fonte. Contarei quais erros cometemos e como os corrigimos mais tarde. Havia dúvidas sobre a publicação de tal artigo. Mas achei melhor fazer, receber feedback e melhorar, do que não publicar o artigo e pensar no que teria acontecido se...

Pré-história

Trabalhei em uma empresa como funcionário de TI. A empresa era bastante grande, com uma extensa estrutura de rede. Não vou me alongar nas minhas responsabilidades profissionais, apenas direi que elas definitivamente não incluíam o desenvolvimento de nada.

Tivemos monitoramento, mas por puro interesse acadêmico quis tentar escrever o meu próprio mais simples. A ideia era esta: eu queria que estivesse na web, para poder entrar facilmente sem instalar nenhum cliente e ver o que estava acontecendo com a rede de qualquer dispositivo, inclusive um dispositivo móvel via Wi-Fi, e também realmente queria entender rapidamente o que há equipamentos na sala que ficaram “deprimidos” porque... havia requisitos muito rigorosos quanto ao tempo de resposta a tais problemas. Como resultado, nasceu na minha cabeça um plano para escrever uma página da web simples na qual houvesse um fundo jpeg com um diagrama de rede, recortar os próprios dispositivos com seus endereços IP nesta imagem e mostrar conteúdo dinâmico no topo do imagem nas coordenadas necessárias na forma de um endereço IP verde ou vermelho piscando. A tarefa foi definida, vamos começar.

Anteriormente eu programava em Delphi, PHP, JS e muito superficialmente em C++. Eu sei muito bem como as redes funcionam. VLAN, Roteamento (OSPF, EIGRP, BGP), NAT. Isso foi o suficiente para eu mesmo escrever um protótipo de monitoramento primitivo.

Escrevi o que planejei em PHP. O servidor Apache e PHP estava no Windows porque... Linux para mim naquele momento era algo incompreensível e muito complexo, como descobri mais tarde, me enganei muito e em muitos lugares o Linux é muito mais simples que o Windows, mas este é um assunto à parte e todos nós sabemos quantos holivares existem em Este tópico. O agendador de tarefas do Windows extraiu em um pequeno intervalo (não me lembro exatamente, mas algo como uma vez a cada três segundos) um script PHP que pesquisava todos os objetos com um ping banal e salvava o estado em um arquivo.

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

Sim, sim, trabalhar com banco de dados naquele momento também não era dominado por mim. Eu não sabia que era possível paralelizar processos, e passar por todos os nós da rede demorava muito, porque... isso aconteceu em um tópico. Surgiram problemas especialmente quando vários nós estavam indisponíveis, porque cada um deles atrasou o script em 300 ms. Do lado do cliente havia uma função de loop simples que, em intervalos de alguns segundos, baixava informações atualizadas do servidor com uma solicitação Ajax e atualizava a interface. Pois bem, depois de 3 pings consecutivos sem sucesso, se uma página da web com monitoramento estivesse aberta no computador, uma composição alegre tocava.

Quando tudo deu certo, fiquei muito inspirado com o resultado e pensei que poderia agregar mais (pelos meus conhecimentos e capacidades). Mas sempre não gostei de sistemas com um milhão de gráficos, que pensei então, e ainda penso até hoje, serem desnecessários na maioria dos casos. Queria colocar ali apenas o que realmente me ajudaria no meu trabalho. Este princípio permanece fundamental para o desenvolvimento da Veliam até hoje. Além disso, percebi que seria muito legal se eu não tivesse que ficar monitorando aberto e sabendo dos problemas, e quando isso acontecesse, abrir a página e ver onde está localizado esse nó de rede problemático e o que fazer com ele a seguir . De alguma forma, eu não lia e-mails naquela época, simplesmente não os usava. Descobri na Internet que existem gateways de SMS para os quais você pode enviar uma solicitação GET ou POST, e eles enviarão um SMS para o meu celular com o texto que eu escrevo. Imediatamente percebi que realmente queria isso. E comecei a estudar a documentação. Depois de algum tempo consegui e agora recebi um SMS sobre problemas de rede no meu celular com o nome de “objeto caído”. Embora o sistema fosse primitivo, ele foi escrito por mim mesmo, e o mais importante que me motivou a desenvolvê-lo foi que era um programa aplicativo que realmente me ajudou no meu trabalho.

E então chegou o dia em que um dos canais da Internet caiu no trabalho e meu monitoramento não me avisou. Já que o DNS do Google ainda pingou perfeitamente. É hora de pensar em como você pode monitorar se o canal de comunicação está ativo. Havia ideias diferentes sobre como fazer isso. Não tive acesso a todos os equipamentos. Tivemos que descobrir como entender qual dos canais está ao vivo, mas sem poder visualizá-lo de alguma forma no próprio equipamento de rede. Então um colega teve a ideia de que é possível que o rastreamento de rotas para servidores públicos possa diferir dependendo de qual canal de comunicação é usado atualmente para acessar a Internet. Eu verifiquei e acabou assim. Havia rotas diferentes durante o rastreamento.

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

Então apareceu outro script, ou melhor, por algum motivo o trace foi adicionado ao final do mesmo script, que fez ping em todos os dispositivos da rede. Afinal, esse é mais um processo longo que foi executado no mesmo thread e atrasou o trabalho de todo o script. Mas então não era tão óbvio. Mas de uma forma ou de outra ele fez o seu trabalho, o código definia estritamente que tipo de rastreamento deveria ser para cada um dos canais. Foi assim que começou a funcionar o sistema, que já monitorava (falou em voz alta, porque não havia coleta de nenhuma métrica, apenas ping) dispositivos de rede (roteadores, switches, wi-fi, etc.) e canais de comunicação com o mundo exterior . As mensagens SMS chegavam regularmente e o diagrama sempre mostrava claramente onde estava o problema.

Além disso, no trabalho diário, tive que fazer cruzamentos. E cansei de ir sempre aos switches Cisco para ver qual interface usar. Que legal seria clicar em um objeto no monitoramento e ver uma lista de suas interfaces com descrições. Isso me pouparia tempo. Além disso, neste esquema não haveria necessidade de executar Putty ou SecureCRT para inserir contas e comandos. Apenas cliquei no monitoramento, vi o que era necessário e fui fazer meu trabalho. Comecei a procurar maneiras de interagir com switches. Imediatamente me deparei com 2 opções: SNMP ou login no switch via SSH, inserindo os comandos necessários e analisando o resultado. Dispensei o SNMP devido à complexidade de sua implementação; estava impaciente para obter o resultado. com o SNMP, você teria que se aprofundar no MIB por muito tempo e, com base nesses dados, gerar dados sobre as interfaces. Há uma equipe maravilhosa na CISCO

show interface status

Mostra exatamente o que preciso para cruzamentos. Por que me preocupar com o SNMP quando quero apenas ver a saída deste comando, pensei. Depois de algum tempo, percebi essa oportunidade. Clicou em um objeto em uma página da web. Foi acionado um evento pelo qual o cliente AJAX entrou em contato com o servidor, e este, por sua vez, se conectou via SSH ao switch que eu precisava (as credenciais estavam codificadas no código, não havia desejo de refiná-lo, de fazer alguns menus separados onde seria possível trocar de conta pela interface, precisava do resultado e rápido) digitei o comando acima lá e enviei de volta para o navegador. Então comecei a ver informações sobre interfaces com um clique do mouse. Isso foi extremamente conveniente, especialmente quando você precisava visualizar essas informações em diferentes switches ao mesmo tempo.

O monitoramento de canal baseado em trace acabou não sendo a melhor ideia, porque... às vezes era feito trabalho na rede, e o rastreamento podia mudar e o monitoramento começou a gritar comigo que havia problemas com o canal. Mas depois de passar muito tempo analisando, percebi que todos os canais estavam funcionando e meu monitoramento estava me enganando. Como resultado, pedi aos meus colegas que gerenciavam switches formadores de canal que simplesmente me enviassem o syslog quando o status de visibilidade dos vizinhos mudasse. Conseqüentemente, era muito mais simples, rápido e preciso do que o rastreamento. Chegou um evento como vizinho perdido e imediatamente emito uma notificação sobre o canal fora do ar.

Além disso, vários outros comandos apareceram ao clicar em um objeto, e o SNMP foi adicionado para coletar algumas métricas, e é basicamente isso. O sistema nunca se desenvolveu mais. Fez tudo que eu precisava, foi uma boa ferramenta. Muitos leitores provavelmente me dirão que já existem muitos softwares na Internet para resolver esses problemas. Mas, na verdade, eu não pesquisei esses produtos gratuitos no Google naquela época e realmente queria desenvolver minhas habilidades de programação, e que melhor maneira de promover isso do que um problema real de aplicativo. Neste ponto, a primeira versão do monitoramento foi concluída e não foi mais modificada.

Criação da empresa Audit-Telecom

Com o passar do tempo comecei a trabalhar meio período em outras empresas, felizmente meu horário de trabalho me permitiu fazer isso. Quando você trabalha em empresas diferentes, suas habilidades em diversas áreas crescem muito rapidamente e seus horizontes se desenvolvem bem. Existem empresas em que, como dizem, você é sueco, ceifador e trompetista. Por um lado é difícil, por outro lado, se você não for preguiçoso, você se torna um generalista e isso permite resolver problemas com mais rapidez e eficiência porque você sabe como funciona a área relacionada.

Meu amigo Pavel (também especialista em TI) tentava constantemente me encorajar a abrir seu próprio negócio. Havia inúmeras ideias com diferentes variações do que estavam fazendo. Isso tem sido discutido há anos. E no final, não deveria ter dado em nada porque sou um cético e Pavel é um sonhador. Cada vez que ele propunha uma ideia, eu não acreditava e me recusava a participar. Mas queríamos muito abrir nosso próprio negócio.

Finalmente, conseguimos encontrar uma opção que nos convinha e fazer o que sabemos fazer. Em 2016, decidimos criar uma empresa de TI que ajudaria as empresas a resolver problemas de TI. Trata-se da implantação de sistemas de TI (1C, servidor de terminal, servidor de correio, etc.), sua manutenção, HelpDesk clássico para usuários e administração de rede.

Falando francamente, na hora de criar a empresa eu não acreditava nela em cerca de 99,9%. Mas de alguma forma Pavel conseguiu que eu tentasse e, olhando para o futuro, ele estava certo. Pavel e eu investimos 300 rublos cada, registramos uma nova LLC “Audit-Telecom”, alugamos um pequeno escritório, fizemos cartões de visita legais, bem, em geral, como provavelmente a maioria dos empresários novatos e inexperientes, e começamos a procurar clientes. Encontrar clientes é uma história completamente diferente. Talvez escrevamos um artigo separado como parte do blog corporativo, se alguém estiver interessado. Chamadas não solicitadas, folhetos, etc. Isso não deu nenhum resultado. Como li agora muitas histórias sobre negócios, de uma forma ou de outra, depende muito da sorte. Nós tivemos sorte. e literalmente algumas semanas após a criação da empresa, meu irmão Vladimir nos abordou, trazendo nosso primeiro cliente. Não vou aborrecê-los com os detalhes do trabalho com clientes, não é disso que trata o artigo, direi apenas que fizemos uma auditoria, identificamos áreas críticas e essas áreas quebraram enquanto era tomada a decisão de fazer ou não. cooperar conosco continuamente como terceirizados. Depois disso, uma decisão positiva foi tomada imediatamente.

Depois, principalmente através do boca a boca através de amigos, começaram a surgir outras empresas de serviços. O Helpdesk estava em um sistema. As conexões com equipamentos de rede e servidores são diferentes, ou melhor, diferentes. Algumas pessoas salvaram atalhos, outras usaram catálogos de endereços RDP. O monitoramento é outro sistema separado. É muito inconveniente para uma equipe trabalhar em sistemas diferentes. Informações importantes são perdidas de vista. Bem, por exemplo, o servidor de terminal do cliente ficou indisponível. As inscrições dos usuários deste cliente são recebidas imediatamente. O especialista de suporte abre uma solicitação (recebida por telefone). Se incidentes e solicitações fossem registrados em um sistema, o especialista de suporte veria imediatamente qual é o problema do usuário e o informaria, ao mesmo tempo em que se conectaria ao objeto necessário para resolver a situação. Todos estão cientes da situação tática e trabalham de forma harmoniosa. Não encontramos um sistema onde tudo isso se combine. Ficou claro que era hora de fazer nosso próprio produto.

Trabalho contínuo em seu sistema de monitoramento

Ficou claro que o sistema escrito anteriormente era completamente inadequado para as tarefas atuais. Nem em termos de funcionalidade nem em termos de qualidade. E foi decidido escrever o sistema do zero. Graficamente deveria ter parecido completamente diferente. Tinha que ser um sistema hierárquico para que fosse possível abrir de forma rápida e conveniente o objeto certo para o cliente certo. O esquema da primeira versão não se justificava de forma alguma no presente caso, porque Os clientes são diferentes e não importava em que local o equipamento estava localizado. Isso já foi transferido para a documentação.

Então as tarefas são:

  1. Estrutura hierárquica;
  2. Algum tipo de parte do servidor que pode ser colocada nas instalações do cliente em forma de máquina virtual para coletar as métricas que necessitamos e enviá-las ao servidor central, que irá resumir tudo isso e nos mostrar;
  3. Alertas. Aquelas que não podem faltar, porque... naquela época não era possível alguém sentar e apenas olhar para o monitor;
  4. Sistema de aplicação. Começaram a aparecer clientes para os quais atendíamos não só servidores e equipamentos de rede, mas também estações de trabalho;
  5. Capacidade de conectar-se rapidamente a servidores e equipamentos do sistema;

As tarefas estão definidas, começamos a escrever. Ao longo do caminho, processando solicitações de clientes. Naquela época já éramos 4. Começamos a escrever as duas partes ao mesmo tempo: o servidor central e o servidor para instalação nos clientes. A essa altura, o Linux não era mais um estranho para nós e foi decidido que as máquinas virtuais que os clientes teriam seriam no Debian. Não haverá instaladores, apenas faremos um projeto de parte do servidor em uma máquina virtual específica e depois clonaremos para o cliente desejado. Este foi outro erro. Mais tarde, ficou claro que nesse esquema o mecanismo de atualização era completamente subdesenvolvido. Aqueles. estávamos adicionando algum recurso novo e depois havia todo o problema de distribuí-lo para todos os servidores clientes, mas voltaremos a isso mais tarde, tudo em ordem.

Fizemos o primeiro protótipo. Ele conseguiu fazer ping nos dispositivos e servidores de rede do cliente de que precisávamos e enviar esses dados para nosso servidor central. E ele, por sua vez, atualizou esses dados em massa no servidor central. Aqui escreverei não apenas uma história sobre como e o que deu certo, mas também quais erros amadores foram cometidos e como mais tarde tive que pagar por isso com o tempo. Assim, toda a árvore de objetos foi armazenada em um único arquivo na forma de um objeto serializado. Embora conectamos vários clientes ao sistema, tudo estava mais ou menos normal, embora às vezes houvesse alguns artefatos completamente incompreensíveis. Mas quando conectamos uma dúzia de servidores ao sistema, milagres começaram a acontecer. Às vezes, por algum motivo desconhecido, todos os objetos do sistema simplesmente desapareciam. É importante observar aqui que os servidores dos clientes enviavam dados para o servidor central a cada poucos segundos por meio de uma solicitação POST. Um leitor atento e um programador experiente já adivinharam que havia um problema de acesso múltiplo ao próprio arquivo no qual o objeto serializado estava armazenado a partir de diferentes threads ao mesmo tempo. E justamente quando isso acontecia, milagres aconteciam com o desaparecimento de objetos. O arquivo simplesmente ficou vazio. Mas tudo isso não foi descoberto de imediato, mas apenas durante a operação com vários servidores. Durante esse período, foi adicionada a funcionalidade de varredura de portas (os servidores enviavam à central não apenas informações sobre a disponibilidade dos dispositivos, mas também sobre as portas abertas neles). Isso foi feito chamando o comando:

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

os resultados muitas vezes eram incorretos e as verificações demoravam muito para serem concluídas. Esqueci completamente do ping, foi feito via fping:

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

Isso também não foi paralelizado e, portanto, o processo foi muito longo. Posteriormente, toda a lista de endereços IP necessários para verificação foi enviada ao fping de uma só vez, e de volta recebemos uma lista pronta daqueles que responderam. Ao contrário de nós, o fping foi capaz de paralelizar processos.

Outro trabalho rotineiro comum era configurar alguns serviços via WEB. Bem, por exemplo, ECP do MS Exchange. Basicamente é apenas um link. E decidimos que precisávamos poder adicionar esses links diretamente ao sistema, para não ter que procurar na documentação ou em algum outro lugar nos favoritos como acessar o ECP de um cliente específico. Foi assim que surgiu o conceito de links de recursos para o sistema, sua funcionalidade está disponível até hoje e não mudou, enfim, quase.

Como funcionam os links de recursos no Veliam
Da terceirização ao desenvolvimento (Parte 1)

Conexões remotas

Isto é o que parece em ação na versão atual do Veliam
Da terceirização ao desenvolvimento (Parte 1)

Uma das tarefas era conectar-se de forma rápida e conveniente aos servidores, dos quais já existiam muitos (mais de cem) e classificar milhões de atalhos RDP pré-salvos era extremamente inconveniente. Era necessária uma ferramenta. Existem softwares na Internet que funcionam como um catálogo de endereços para essas conexões RDP, mas eles não estão integrados ao sistema de monitoramento e as contas não podem ser salvas. Inserir contas para clientes diferentes todas as vezes é um inferno quando você se conecta dezenas de vezes por dia a servidores diferentes. Com o SSH, as coisas são um pouco melhores: existem muitos softwares bons que permitem organizar essas conexões em pastas e lembrar as contas delas. Mas existem 2 problemas. A primeira é que não encontramos um único programa para conexões RDP e SSH. A segunda é que se em algum momento eu não estiver no meu computador e precisar me conectar rapidamente, ou apenas reinstalar o sistema, terei que consultar a documentação para ver a conta deste cliente. É inconveniente e uma perda de tempo.

A estrutura hierárquica que precisávamos para servidores clientes já estava disponível em nosso produto interno. Eu só precisava descobrir como conectar conexões rápidas ao equipamento necessário. Para começar, pelo menos dentro da sua rede.

Levando em consideração que o cliente do nosso sistema era um navegador que não tem acesso aos recursos locais do computador, para simplesmente iniciar a aplicação que precisávamos com algum comando, foi inventado para fazer tudo através do “Windows esquema de URL personalizado”. Foi assim que apareceu um certo “plugin” para o nosso sistema, que simplesmente incluía Putty e Remote Desktop Plus e, durante a instalação, simplesmente registrava o esquema URI no Windows. Agora, quando queríamos nos conectar a um objeto via RDP ou SSH, clicamos nesta ação em nosso sistema e o URI personalizado funcionou. O mstsc.exe padrão integrado ao Windows ou putty, que fazia parte do “plugin”, foi lançado. Coloquei a palavra plugin entre aspas porque este não é um plugin de navegador no sentido clássico.

Pelo menos isso era alguma coisa. Catálogo de endereços conveniente. Além disso, no caso do Putty, em geral estava tudo bem, podendo ser fornecidas conexões IP, login e senha como parâmetros de entrada. Aqueles. Já nos conectamos aos servidores Linux em nossa rede com um clique, sem inserir senhas. Mas com o RDP não é tão simples. O mstsc padrão não pode fornecer credenciais como parâmetros. O Remote Desktop Plus veio em socorro. Ele permitiu que isso acontecesse. Agora podemos passar sem ele, mas por muito tempo foi um fiel assistente em nosso sistema. Com sites HTTP(S) tudo é simples, basta abrir tais objetos no navegador e pronto. Conveniente e prático. Mas isso era felicidade apenas na rede interna.

Como resolvemos a grande maioria dos problemas remotamente no escritório, o mais fácil foi disponibilizar VPNs aos clientes. E então foi possível conectar-se a eles a partir do nosso sistema. Mas ainda era um pouco inconveniente. Para cada cliente era necessário manter um monte de conexões VPN lembradas em cada computador, e antes de conectar a alguma era necessário habilitar a VPN correspondente. Usamos essa solução há muito tempo. Mas o número de clientes está aumentando, o número de VPNs também está aumentando, e tudo isso começou a ficar tenso e algo precisava ser feito a respeito. Lágrimas vieram especialmente aos meus olhos depois de reinstalar o sistema, quando tive que inserir novamente dezenas de conexões VPN em um novo perfil do Windows. Pare de tolerar isso, eu disse, e comecei a pensar no que poderia fazer a respeito.

Acontece que todos os clientes possuíam dispositivos da conhecida empresa Mikrotik como roteadores. Eles são muito funcionais e convenientes para realizar quase todas as tarefas. A desvantagem é que eles são “sequestrados”. Resolvemos este problema simplesmente fechando todos os acessos externos. Mas era preciso de alguma forma ter acesso a eles sem ir até a casa do cliente, porque... é longo. Simplesmente fizemos túneis para cada Mikrotik e os separamos em um pool separado. sem nenhum roteamento, para que não haja conexão da sua rede com as redes dos clientes e suas redes entre si.

A ideia nasceu para garantir que ao clicar no objeto que preciso no sistema, o servidor central de monitoramento, conhecendo as contas SSH de todos os clientes Mikrotik, se conecte ao desejado, crie uma regra de encaminhamento para o host desejado com o porta necessária. Existem vários pontos aqui. A solução não é universal - só funcionará para Mikrotik, já que a sintaxe do comando é diferente para todos os roteadores. Além disso, esses encaminhamentos tiveram que ser excluídos de alguma forma, e a parte do servidor do nosso sistema essencialmente não conseguiu rastrear de forma alguma se eu havia encerrado minha sessão RDP. Pois bem, esse encaminhamento é um buraco para o cliente. Mas não buscamos a universalidade, porque... o produto foi utilizado apenas dentro de nossa empresa e não houve intenção de divulgá-lo ao público.

Cada um dos problemas foi resolvido à sua maneira. Quando a regra foi criada, esse encaminhamento estava disponível apenas para um endereço IP externo específico (a partir do qual a conexão foi inicializada). Assim, uma falha de segurança foi evitada. Mas a cada uma dessas conexões, uma regra do Mikrotik era adicionada à página NAT e não era apagada. E todos sabem que quanto mais regras houver, mais carregado será o processador do roteador. E em geral eu não poderia aceitar que um dia eu iria para algum Mikrotik, e haveria centenas de regras mortas e inúteis.

Como nosso servidor não consegue rastrear o status da conexão, deixe o próprio Mikrotik rastreá-los. E escrevi um script que monitorava constantemente todas as regras de encaminhamento com uma descrição específica e verificava se a conexão TCP tinha uma regra adequada. Se não houver há algum tempo, provavelmente a conexão já foi concluída e esse encaminhamento pode ser excluído. Deu tudo certo, o roteiro funcionou bem.

A propósito, aqui está:

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

Com certeza poderia ter ficado mais bonito, mais rápido, etc., mas funcionou, não carregou o Mikrotik e fez um excelente trabalho. Finalmente conseguimos nos conectar aos servidores e equipamentos de rede dos clientes com apenas um clique. Sem abrir uma VPN ou inserir senhas. O sistema tornou-se realmente conveniente de trabalhar. O tempo de serviço foi reduzido e todos passamos mais tempo trabalhando em vez de nos conectarmos aos objetos necessários.

Backup Mikrotik

Configuramos backup de todo Mikrotik para FTP. E no geral estava tudo bem. Mas quando você precisava fazer um backup, era necessário abrir esse FTP e procurá-lo lá. Temos um sistema onde todos os roteadores estão conectados, podemos nos comunicar com os dispositivos via SSH. Por que não fazemos com que o próprio sistema faça backups de todos os Mikrotik diariamente, pensei. E ele começou a implementá-lo. Conectamos, fizemos um backup e levamos para o armazenamento.

Código de script em PHP para fazer backup do 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');

?>

O backup é feito de duas formas - configuração binária e de texto. O binário ajuda a restaurar rapidamente a configuração necessária, e o texto permite que você entenda o que precisa ser feito se houver uma substituição forçada do equipamento e o binário não puder ser carregado nele. Como resultado, obtivemos outra funcionalidade conveniente no sistema. Além disso, ao adicionar o novo Mikrotik, não houve necessidade de configurar nada, simplesmente adicionei o objeto ao sistema e configurei uma conta para ele via SSH. Então o próprio sistema se encarregou de fazer backups. A versão atual do SaaS Veliam ainda não possui essa funcionalidade, mas iremos portá-la em breve.

Capturas de tela de como era o sistema interno
Da terceirização ao desenvolvimento (Parte 1)

Transição para armazenamento normal de banco de dados

Já escrevi acima que apareceram artefatos. Às vezes, toda a lista de objetos do sistema simplesmente desaparecia, às vezes, ao editar um objeto, as informações não eram salvas e o objeto tinha que ser renomeado três vezes. Isso irritou terrivelmente a todos. O desaparecimento de objetos ocorria raramente e era facilmente restaurado restaurando esse mesmo arquivo, mas falhas na edição de objetos aconteciam com bastante frequência. Provavelmente, inicialmente não fiz isso através do banco de dados porque não cabia na minha cabeça como era possível manter uma árvore com todas as conexões em uma tabela plana. É plano, mas a árvore é hierárquica. Mas uma boa solução para acesso múltiplo e, posteriormente (à medida que o sistema se torna mais complexo) transacional, é um SGBD. Provavelmente não sou o primeiro a encontrar esse problema. Comecei a pesquisar no Google. Acontece que tudo já foi inventado antes de mim e existem vários algoritmos que constroem uma árvore a partir de uma mesa plana. Depois de analisar cada um, implementei um deles. Mas esta já era uma nova versão do sistema, porque... Na verdade, por causa disso, tive que reescrever bastante. O resultado foi natural, os problemas de comportamento aleatório do sistema desapareceram. Alguns podem dizer que os erros são muito amadores (scripts de thread único, armazenamento de informações que foram acessadas várias vezes simultaneamente de diferentes threads em um arquivo, etc.) na área de desenvolvimento de software. Talvez isso seja verdade, mas meu trabalho principal era administração, e a programação era uma atividade secundária para minha alma, e eu simplesmente não tinha experiência em trabalhar em uma equipe de programadores, onde coisas tão básicas teriam sido imediatamente sugeridas a mim por meu sênior camaradas. Portanto, preenchi todas essas saliências sozinho, mas aprendi muito bem o material. E também, meu trabalho envolve reuniões com clientes, ações que visam tentar divulgar a empresa, um monte de questões administrativas dentro da empresa e muito, muito mais. Mas de uma forma ou de outra, o que já existia era procurado. A galera e eu mesmo utilizamos o produto no nosso dia a dia de trabalho. Houve ideias e soluções francamente mal sucedidas nas quais se perdeu tempo, mas no final ficou claro que esta não era uma ferramenta de trabalho e ninguém a utilizou e não acabou em Veliam.

Helpdesk - HelpDesk

Não seria errado mencionar como o HelpDesk foi formado. Esta é uma história completamente diferente, porque... no Veliam esta já é a 3ª versão completamente nova, diferente de todas as anteriores. Agora é um sistema simples, intuitivo, sem sinos e assobios desnecessários, com capacidade de integração com um domínio, bem como possibilidade de acessar o mesmo perfil de usuário de qualquer lugar através de um link de um e-mail. E o mais importante, é possível conectar-se ao solicitante via VNC de qualquer lugar (em casa ou no escritório) diretamente do aplicativo, sem VPN ou encaminhamento de porta. Vou lhe contar como chegamos a isso, o que aconteceu antes e que decisões terríveis foram tomadas.

Nós nos conectamos aos usuários através do conhecido TeamViewer. Todos os computadores cujos usuários atendemos possuem TV instalada. A primeira coisa que fizemos de errado, e posteriormente removemos, foi vincular cada cliente HD ao hardware. Como o usuário se logou no sistema HD para deixar uma solicitação? Além da TV, todos tinham um utilitário especial instalado em seus computadores, escrito em Lazarus (muita gente aqui vai revirar os olhos, e talvez até pesquisar no Google o que é, mas a melhor linguagem compilada que eu conhecia era Delphi, e Lazarus é quase a mesma coisa, só que grátis). Em geral, o usuário lançava um arquivo em lote especial que lançava este utilitário, que por sua vez lia o HWID do sistema e depois disso o navegador era iniciado e ocorria a autorização. Por que isso foi feito? Em algumas empresas, o número de usuários atendidos é contabilizado individualmente, e o preço do serviço de cada mês é baseado no número de pessoas. Isso é compreensível, você diz, mas por que está vinculado ao hardware? É muito simples, algumas pessoas chegaram em casa e fizeram um pedido do laptop de casa no estilo “deixe tudo lindo para mim aqui”. Além de ler o HWID do sistema, o utilitário extraiu o ID atual do Teamviewer do registro e também o transmitiu para nós. Teamviewer possui uma API para integração. E fizemos essa integração. Mas havia um problema. Através destas APIs, é impossível conectar-se ao computador do usuário quando ele não inicia explicitamente esta sessão e após tentar conectar-se a ela deverá também clicar em “confirmar”. Naquele momento, parecia-nos lógico que ninguém se conectasse sem a solicitação do usuário e, como a pessoa está no computador, iniciará a sessão e responderá afirmativamente à solicitação de conexão remota. Tudo deu errado. Os candidatos esqueceram-se de pressionar iniciar a sessão e tiveram que informá-los por telefone. Isso foi uma perda de tempo e foi frustrante para ambos os lados do processo. Além disso, não é incomum que haja momentos em que uma pessoa deixa um pedido, mas só pode se conectar quando sai para almoçar. Porque o problema não é crítico e ele não quer que seu processo de trabalho seja interrompido. Conseqüentemente, ele não pressionará nenhum botão para permitir a conexão. Foi assim que uma funcionalidade adicional apareceu ao fazer login no HelpDesk - lendo o ID do Teamviwer. Sabíamos a senha permanente usada ao instalar o Teamviwer. Mais precisamente, apenas o sistema sabia disso, uma vez que estava integrado no instalador e no nosso sistema. Assim, havia um botão de conexão do aplicativo, clicando no qual não havia necessidade de esperar nada, mas o Teamviewer abriu imediatamente e ocorreu uma conexão. Como resultado, havia dois tipos de conexões possíveis. Através da API oficial do Teamviewer e da nossa própria. Para minha surpresa, pararam de usar o primeiro quase imediatamente, embora houvesse instrução para usá-lo apenas em casos especiais e quando o próprio usuário autorizasse. Mesmo assim, me dê segurança agora. Mas descobriu-se que os candidatos não precisavam disso. Todos estão absolutamente bem em estarem conectados a eles sem um botão de confirmação.

Mudando para multithreading no Linux

A questão de acelerar a passagem de um scanner de rede para a abertura de uma lista predeterminada de portas e simples ping de objetos de rede já começou a surgir. Aqui, é claro, a primeira solução que vem à mente é o multithreading. Como o principal tempo gasto no ping é aguardar o retorno do pacote, e o próximo ping não pode começar até que o pacote anterior seja retornado, em empresas que tinham mais de 20 servidores mais equipamentos de rede, isso já funcionava bem devagar. A questão é que um pacote pode desaparecer, mas não notifique imediatamente o administrador do sistema sobre isso. Ele simplesmente deixará de aceitar esse tipo de spam muito rapidamente. Isso significa que você precisa executar ping em cada objeto mais de uma vez antes de concluir sobre a inacessibilidade. Sem entrar em muitos detalhes, é necessário paralelizá-lo, pois se isso não for feito, muito provavelmente o administrador do sistema saberá do problema pelo cliente, e não pelo sistema de monitoramento.

O próprio PHP não suporta multithreading imediatamente. Capaz de multiprocessamento, você pode bifurcar. Mas, na verdade, eu já tinha um mecanismo de pesquisa escrito e queria fazê-lo de forma que pudesse contar todos os nós necessários do banco de dados, executar ping em tudo de uma vez, aguardar uma resposta de cada um e só depois escrever imediatamente os dados. Isso economiza no número de solicitações de leitura. Multithreading se encaixa perfeitamente nessa ideia. Para PHP existe um módulo PThreads que permite fazer multithreading real, embora tenha sido necessário alguns ajustes para configurá-lo no PHP 7.2, mas foi feito. A varredura de portas e o ping agora são rápidos. E em vez de, por exemplo, 15 segundos por volta anterior, esse processo passou a levar 2 segundos. Foi um bom resultado.

Auditoria rápida de novas empresas

Como surgiu a funcionalidade de coleta de diversas métricas e características de hardware? É simples. Às vezes, somos simplesmente obrigados a auditar a infraestrutura de TI atual. Pois bem, o mesmo é necessário para agilizar a auditoria de um novo cliente. Precisávamos de algo que nos permitisse chegar a uma empresa de médio ou grande porte e descobrir rapidamente o que ela tem. Na minha opinião, o ping na rede interna é bloqueado apenas por quem quer complicar a própria vida e, pela nossa experiência, são poucos. Mas também existem essas pessoas. Assim, você pode verificar rapidamente as redes em busca de dispositivos com um simples ping. Então podemos adicioná-los e procurar portas abertas que nos interessem. Na verdade, esta funcionalidade já existia, bastava adicionar um comando do servidor central ao servidor escravo para que este fizesse a varredura das redes especificadas e adicionasse à lista tudo o que encontrasse. Esqueci de mencionar, presumia-se que já tínhamos uma imagem pronta com um sistema configurado (servidor de monitoramento escravo) que poderíamos simplesmente lançar do cliente durante uma auditoria e conectá-lo à nossa nuvem.

Mas o resultado de uma auditoria geralmente inclui um monte de informações diferentes, e uma delas é que tipo de dispositivos estão na rede. Em primeiro lugar, estávamos interessados ​​em servidores Windows e estações de trabalho Windows como parte de um domínio. Já que em médias e grandes empresas a falta de domínio é provavelmente uma exceção à regra. Para falar um idioma, a média, na minha opinião, é de mais de 100 pessoas. Foi necessário encontrar uma forma de coletar dados de todas as máquinas e servidores Windows, conhecendo seu IP e conta de administrador de domínio, mas sem instalar nenhum software em cada uma delas. A interface WMI vem em socorro. Windows Management Instrumentation (WMI) significa literalmente ferramentas de gerenciamento do Windows. WMI é uma das tecnologias básicas para gerenciamento centralizado e monitoramento da operação de diversas partes da infraestrutura de computadores rodando a plataforma Windows. Retirado do wiki. Em seguida, tive que mexer novamente para compilar o wmic (este é um cliente WMI) para o Debian. Depois que tudo estava pronto, só faltou pesquisar os nós necessários através do wmic para obter as informações necessárias. Através do WMI você pode obter quase todas as informações de um computador Windows e, além disso, também pode controlar o computador através dele, por exemplo, enviá-lo para reiniciar. Foi assim que surgiu a coleta de informações sobre estações e servidores Windows em nosso sistema. Além disso, havia informações atualizadas sobre os indicadores atuais de carga do sistema. Nós os solicitamos com mais frequência e informações sobre hardware com menos frequência. Depois disso, a audição ficou um pouco mais agradável.

Decisão de distribuição de software

Nós próprios utilizamos o sistema todos os dias e está sempre aberto a todos os funcionários técnicos. E pensamos que poderíamos compartilhar com outras pessoas o que já temos. O sistema ainda não estava pronto para ser distribuído. Muita coisa teve que ser reformulada para que a versão local virasse SaaS. Isso inclui alterações em diversos aspectos técnicos do sistema (conexões remotas, serviço de suporte), análise de módulos para licenciamento, fragmentação de bancos de dados de clientes, escalonamento de cada serviço e desenvolvimento de sistemas de atualização automática para todas as partes. Mas esta será a segunda parte do artigo.

Atualizar

A segunda parte

Fonte: habr.com

Adicionar um comentário