Mais um post da série “causos de ALM nos cliente Lambda3“.

De um lado, os desenvolvedores querendo ter acesso irrestrito ao NuGet (www.nuget.org) por razões óbvias. De outro lado, o pessoal responsável por segurança e infraestrutura preocupados com o risco de liberar o acesso irrestrito ao NuGet no firewall.

#comofaz?

O problema

O grande desafio encontrado neste caso – que, aliás, é comum à maioria de nossos clientes – é como equilibrar entre a conveniência para os desenvolvedores e a segurança para a empresa?

Mais especificamente: a política de firewall da empresa em questão prevê, entre outras coisas, whitelisting de IPs que podem ser acessados a partir de sua rede interna. Em outras palavras, é preciso liberar um determinado range de IPs para que eles possam ser acessados.

Entretanto, em tempos de cloud computing e de endereços IPv4 esgotados, está cada vez difícil sustentar esta estratégia. Isso porque é cada vez mais comum que provedores de serviço mudem os IPs de seus serviços com uma certa frequência, contando com os serviços de DNS para notificar os clientes quando tais mudanças acontecem.

No caso do NuGet, isso quer dizer que os IPs dos endpoints de serviço do NuGet podem mudar. Veja o resultado atual (consultado no dia da publicação deste post) do DNS lookup para um dos domínios do NuGet:

C:\> nslookup api.nuget.org

Server:   ***************
Address:  ***.***.***.***

Non-authoritative answer:
Name:    cs9.wpc.v0cdn.net
Addresses:  2606:2800:157:1508:1539:174:1a75:1191
          192.16.48.200
Aliases:  api.nuget.org
          db16.wpc.azureedge.net

Viu como o domínio api.nuget.org é, na verdade, um alias (ou CNAME) para um CDN? Isso quer dizer que não há nenhuma garantia de que o IP retornado por api.nuget.org vai ser sempre 192.16.48.200. Pelo contrário – a natureza dinâmica dos CDN é quase uma certeza de que esse IP vai mudar em algum momento.

Portanto, uma liberação baseada em IPs não resolve. Neste caso, qual a alternativa?

Soluções

Obviamente precisamos de uma alternativa. Principalmente porque, no caso deste cliente, ele nos perguntou explicitamente:

Como outros clientes de você atuam nesta situação?

Bem, deixe-me compartilhar com vocês o que andamos vendo em nossos clientes:

Acesso irrestrito a *.nuget.org

Sim, é claro que esta é uma opção válida – ainda que pouco desejável em muitos de nossos clientes, que ficam desconfortáveis com acesso irrestrito à internet. Entretanto, esta é uma opção relativamente comum, em especial naqueles clientes que não podem (ou não querem) ter o overhead de gerenciar o acesso ao NuGet. Afinal, limitações de acesso aqui podem impactar diretamente na produtividade dos desenvolvedores.

Se você não se quiser liberar todos os domínios abaixo de nuget.org (*.nuget.org), pode liberar apenas estes dois:

  • www.nuget.org (HTTP, HTTPS);
  • api.nuget.org (HTTP, HTTPS).

O maior inconveniente dessa abordagem (segundo alguns de nossos clientes) é que o acesso precisa ser dado para todo mundo: desenvolvedores, agentes de build e release, servidores… Todo mundo pode precisar acessar o NuGet.org.

Será que não tem um meio-termo?

Servidor proxy de NuGet

Sim, há um meio-termo. Com um servidor de proxy de NuGet (usamos o ProGet em alguns de nossos clientes), não há a necessidade de liberar o acesso ao NuGet.org para todo mundo. Apenas o servidor de ProGet precisa ter acesso irrestrito ao NuGet.org.

Quando você configura um servidor ProGet interno, ele é quem baixa os pacotes do NuGet.org para você – por isso é que ele é um “proxy” do NuGet. Isso implica em uma mudança na configuração do NuGet na máquina dos desenvolvedores.

No Visual Studio de cada desenvolvedor, vá em Tools | Options, selecione a página Package Sources da configuração do NuGet e faça duas coisas:

  • Inclua o endereço do feed do seu proxy (http://proget/nuget/default no meu exemplo); e
  • Desabilite os outros feeds de acesso ao NuGet público.

Caixa de diálogo de configuração do Visual Studio, na página "Package Sources", com um feed personalizado apontando para um servidor ProGet interno e os outros feeds desabilitados

Caso você queira evitar de fazer esse processo de configração “na mão”, pode ao invés disso atualizar o arquivo de configuração do NuGet de cada desenvolvedor (por padrão, fica em C:\Users\<nome do usuário>\AppData\Roaming\NuGet\nuget.config), seguindo o exemplo abaixo:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="Package source" value="http://proget/nuget/default" />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
  </packageSources>
  <disabledPackageSources>
    <add key="nuget.org" value="true" />
    <add key="Microsoft and .NET" value="true" />
    <add key="Microsoft Visual Studio Offline Packages" value="true" />
  </disabledPackageSources>
</configuration>

Um benefício adicional, do ponto de vista de segurança, é que o ProGet permite fazer a “curadoria” dos pacotes – ou seja, é possível aprovar/reprovar pacotes que aparecem à disposição dos desenvolvedores. Com isso, as empresas acabam com uma alternativa ainda mais segura: o invés de barrar/liberar o NuGet.org como um todo, podem fazer isso seletivamente – pacote a pacote, se necessário.

Importante

O recurso de proxy de feeds do ProGet não está disponível na versão gratuita. Para mais detalhes, visite http://inedo.com/proget/pricing

Liberação por IP

Bom, se ainda assim nada der certo e você precisar fazer a liberação por IP, resta um problema: Como saber se/quando os IPs do nuget.org mudaram? Uma alternativa é criar um script e executá-lo de tempos em tempos, a fim de verificar se os IPs mudaram ou não (visto que não há um feed oficial com essa finalidade).

Como ponto de partida, você pode dar uma olhada nest Gist. Ele tem uma função chamada Resolve-ServerAddress que recebe um FQDN como parâmetro e retorna seu IP atual, indicando se ele mudou desde a última execução. Em caso positivo, você poderia por exemplo enviar um email para um administrador avisando da mudança, a fim de que ele possa reconfigurar as regras de firewall. Daí, basta agendar sua execução (via Agendador de Tarefas do Windows) e pronto!

Passando a régua

NuGet é algo que veio para resolver um monte de problemas no ecossistema .NET – mas, como qualquer mudança de paradigma, traz seus próprios desafios. Achar o ponto de equilíbrio entre a conveniência desejada pelos desenvolvedores e a segurança necessária para a infraestrutura da empresa não é fácil, mas não dá para empurrar com a barriga. Sem resolver esse tipo de questão, não faz o menor sentido começar a discutir DevOps e assuntos correlatos.

E aí, o que achou? Deixe seus comentários!

Um abraço,
Igor

(Cross-post de http://www.tshooter.com.br/2017/01/27/como-usar-nuget-sem-escancarar-rede/)