Neste documento, descrevemos como implantar a arquitetura em Automatizar a verificação de malware para arquivos enviados ao Cloud Storage.
Este guia de implantação pressupõe que você esteja familiarizado com a funcionalidade básica das seguintes tecnologias:
Arquitetura
O diagrama a seguir mostra a arquitetura de implantação criada neste documento:
O diagrama mostra os dois pipelines a seguir que são gerenciados por essa arquitetura:
- Pipeline de verificação de arquivos, que verifica se um arquivo enviado contém malware.
- Pipeline de atualização do espelho de banco de dados de malware do ClamAV, que mantém um espelho atualizado do banco de dados de malware usado pelo ClamAV.
Para mais informações sobre a arquitetura, consulte Automatizar a verificação de malware para arquivos enviados ao Cloud Storage.
Objetivos
Crie um espelho do banco de dados de definições de malware do ClamAV em um bucket do Cloud Storage.
Crie um serviço do Cloud Run com as seguintes funções:
- Verificar arquivos em um bucket do Cloud Storage em busca de malware usando o ClamAV e mover os arquivos verificados para buckets limpos ou em quarentena com base no resultado da verificação.
- Manter um espelho do banco de dados de definições de malware do ClamAV no Cloud Storage.
Crie um gatilho do Eventarc para acionar o serviço de verificação de malware quando um arquivo for enviado ao Cloud Storage.
Crie um job do Cloud Scheduler para acionar o serviço de verificação de malware para atualizar o espelho do banco de dados de definições de malware no Cloud Storage.
Custos
Nesta arquitetura, usamos os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.
Antes de começar
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Run, Eventarc, Logging, Cloud Scheduler, Pub/Sub, and Cloud Build APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry, Cloud Run, Eventarc, Logging, Cloud Scheduler, Pub/Sub, and Cloud Build APIs.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Nesta implantação, todos os comandos serão executados no Cloud Shell.
Configure seu ambiente
Nesta seção, você atribui configurações aos valores usados na implantação, como região e zona.
Nesta implantação, você usa us-central1
como a região do
serviço do Cloud Run e us
como o local do gatilho do
Eventarc e dos buckets do Cloud Storage.
No Cloud Shell, defina variáveis comuns de shell, incluindo região e local:
REGION=us-central1 LOCATION=us PROJECT_ID=PROJECT_ID SERVICE_NAME="malware-scanner" SERVICE_ACCOUNT="${SERVICE_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
Substitua
PROJECT_ID
pela ID do seu projeto.Inicialize o ambiente
gcloud
com o ID do projeto:gcloud config set project "${PROJECT_ID}"
Crie três buckets do Cloud Storage com nomes exclusivos:
gcloud storage buckets create "gs://unscanned-${PROJECT_ID}" --location="${LOCATION}" gcloud storage buckets create "gs://quarantined-${PROJECT_ID}" --location="${LOCATION}" gcloud storage buckets create "gs://clean-${PROJECT_ID}" --location="${LOCATION}"
${PROJECT_ID}
é usado para garantir que os nomes dos buckets sejam exclusivos.Esses três buckets contêm os arquivos enviados em vários estágios durante o pipeline de verificação do arquivo:
unscanned-PROJECT_ID
: armazena os arquivos antes de serem verificados. Seus usuários fazem upload dos arquivos para esse bucket.quarantined-PROJECT_ID
: armazena os arquivos que o serviço de verificação de malware verificou e contêm malware.clean-PROJECT_ID
: armazena os arquivos que o serviço de verificação de malware verificou e encontrou não infectado.
Crie um quarto bucket do Cloud Storage:
gcloud storage buckets create "gs://cvd-mirror-${PROJECT_ID}" --location="${LOCATION}"
${PROJECT_ID}
é usado para garantir que o nome do bucket seja exclusivo.Esse bucket
cvd-mirror-PROJECT_ID
é usado para manter um espelho local do banco de dados de definições de malware, o que impede que a limitação de taxa seja acionada pela CDN do ClamAV.
Configurar uma conta de serviço para o serviço de verificação de malware
Nesta seção, você cria uma conta de serviço para usar com o serviço de verificação de malware. Em seguida, conceda os papéis apropriados à conta de serviço para que ela tenha permissões de leitura e gravação nos buckets do Cloud Storage. Os papéis garantem que a conta tenha permissões mínimas e que tenha acesso apenas aos recursos necessários.
Crie a conta de serviço
malware-scanner
:gcloud iam service-accounts create ${SERVICE_NAME}
Conceda o papel Administrador de objetos aos buckets, permitindo que o serviço leia e exclua documentos do bucket não verificado e grave arquivos nos buckets em quarentena e limpos.
gcloud storage buckets add-iam-policy-binding "gs://unscanned-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://clean-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://quarantined-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin gcloud storage buckets add-iam-policy-binding "gs://cvd-mirror-${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" --role=roles/storage.objectAdmin
Conceda o papel de gravador de métricas, que permite que o serviço grave métricas no Monitoring:
gcloud projects add-iam-policy-binding \ "${PROJECT_ID}" \ --member="serviceAccount:${SERVICE_ACCOUNT}" \ --role=roles/monitoring.metricWriter
Criar o serviço de verificação de malware no Cloud Run
Nesta seção, você implantará o serviço de verificação de malware no Cloud Run. O serviço é executado em um contêiner do Docker que contém o seguinte:
- Um
Dockerfile
para criar uma imagem de contêiner com o serviço, o ambiente de execução do Node.js, o SDK do GCloud e os binários do ClamAV. - Os arquivos Node.js do serviço do Cloud Run com detecção de malware.
- Um arquivo de configuração
config.json
para especificar os nomes de bucket do Cloud Storage. - Um
updateCvdMirror.sh
para atualizar o espelho do banco de dados de definições de malware do ClamAV no Cloud Storage. - Um serviço
cloud-run-proxy
para fazer proxy de solicitações HTTPfreshclam
, que fornecem acesso autenticado às APIs do Cloud Storage. - Um script de shell
bootstrap.sh
para executar os serviços necessários na inicialização da instância.
Para implantar o serviço, faça o seguinte:
No Cloud Shell, clone o repositório do GitHub que contém os arquivos de código:
git clone https://github.com/GoogleCloudPlatform/docker-clamav-malware-scanner.git
Altere para o diretório
cloudrun-malware-scanner
:cd docker-clamav-malware-scanner/cloudrun-malware-scanner
Edite o arquivo de configuração
config.json
para especificar os buckets do Cloud Storage que você criou. Como os nomes dos buckets são baseados no código do projeto, use uma operação de pesquisa e substituição:sed "s/-bucket-name/-${PROJECT_ID}/" config.json.tmpl > config.json
Você pode ver o arquivo de configuração atualizado:
cat config.json
Execute um preenchimento inicial do espelho do banco de dados de malware do ClamAV no Cloud Storage:
python3 -m venv pyenv . pyenv/bin/activate pip3 install crcmod cvdupdate ./updateCvdMirror.sh "cvd-mirror-${PROJECT_ID}" deactivate
O comando executa uma instalação local da ferramenta
CVDUpdate
e a usa para fazer o download do banco de dados de malware. Em seguida, o comando faz upload do banco de dados para o bucketcvd-mirror-PROJECT_ID
criado anteriormente.É possível verificar o conteúdo do bucket espelhado:
gcloud storage ls "gs://cvd-mirror-${PROJECT_ID}/cvds"
O bucket precisa conter vários arquivos CVD que contenham o banco de dados completo de malware, vários arquivos
.cdiff
que contêm as atualizações diferenciais diárias e dois arquivos.json
com informações de configuração e estado.Crie e implante o serviço do Cloud Run usando a conta de serviço que você criou anteriormente:
gcloud beta run deploy "${SERVICE_NAME}" \ --source . \ --region "${REGION}" \ --no-allow-unauthenticated \ --memory 4Gi \ --cpu 1 \ --concurrency 20 \ --min-instances 1 \ --max-instances 5 \ --no-cpu-throttling \ --cpu-boost \ --service-account="${SERVICE_ACCOUNT}"
O comando cria uma instância do Cloud Run que tem uma vCPU e usa 4 GiB de RAM. Esse tamanho é aceitável para esta implantação. No entanto, em um ambiente de produção, convém escolher um tamanho de CPU e memória maior para a instância e um parâmetro
--max-instances
maior. Os tamanhos de recursos que podem ser necessários dependem da quantidade de tráfego que o serviço precisa processar.O comando inclui as seguintes especificações:
- O parâmetro
--concurrency
especifica o número de solicitações simultâneas que cada instância pode processar. - O parâmetro
--no-cpu-throttling
permite que a instância execute operações em segundo plano, como atualizar definições de malware. - O parâmetro
--cpu-boost
dobra o número de vCPUs na inicialização da instância para reduzir a latência de inicialização. - O parâmetro
--min-instances 1
mantém pelo menos uma instância ativa, já que o tempo de inicialização de cada instância é relativamente alto. - O parâmetro
--max-instances 5
impede que o serviço seja escalonado verticalmente em demasia.
- O parâmetro
Quando solicitado, digite
Y
para criar e implantar o serviço. A criação e a implantação levam cerca de 10 minutos. Quando elas forem concluídas, a seguinte mensagem será exibida:Service [malware-scanner] revision [malware-scanner-UNIQUE_ID] has been deployed and is serving 100 percent of traffic. Service URL: https://malware-scanner-UNIQUE_ID.a.run.app
Armazene o valor
Service URL
da saída do comando de implantação em uma variável de shell. Você usará o valor posteriormente ao criar um job do Cloud Scheduler.SERVICE_URL="SERVICE_URL"
Para verificar o serviço em execução e a versão do ClamAV, execute o seguinte comando:
curl -D - -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
${SERVICE_URL}
O serviço do Cloud Run requer que todas as invocações sejam
autenticadas, e as identidades de autenticação precisam ter a
permissão run.routes.invoke
no serviço. Adicione a permissão na próxima seção.
Criar um gatilho do Eventarc no Cloud Storage
Nesta seção, você adicionará permissões para permitir que o Eventarc capture eventos do Cloud Storage e um gatilho para enviar esses eventos para o serviço malware-scanner
do Cloud Run.
Se você estiver usando um projeto criado antes de 8 de abril de 2021, adicione o papel
iam.serviceAccountTokenCreator
à conta de serviço do Pub/Sub:PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\ --role='roles/iam.serviceAccountTokenCreator'
Essa adição de papel é necessária apenas para projetos mais antigos e permite que o Pub/Sub invoque o serviço do Cloud Run.
No Cloud Shell, conceda o papel de Editor do Pub/Sub à conta de serviço do Cloud Storage:
STORAGE_SERVICE_ACCOUNT=$(gcloud storage service-agent --project="${PROJECT_ID}") gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member "serviceAccount:${STORAGE_SERVICE_ACCOUNT}" \ --role "roles/pubsub.publisher"
Permita que a conta de serviço
malware-scanner
invoque o serviço do Cloud Run e atue como um receptor de eventos do Eventarc:gcloud run services add-iam-policy-binding "${SERVICE_NAME}" \ --region="${REGION}" \ --member "serviceAccount:${SERVICE_ACCOUNT}" \ --role roles/run.invoker gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member "serviceAccount:${SERVICE_ACCOUNT}" \ --role "roles/eventarc.eventReceiver"
Crie um gatilho do Eventarc para capturar o evento do objeto finalizado no bucket do Cloud Storage não verificado e enviá-lo ao serviço do Cloud Run. O gatilho usa a conta de serviço
malware-scanner
para autenticação:BUCKET_NAME="unscanned-${PROJECT_ID}" gcloud eventarc triggers create "trigger-${BUCKET_NAME}-${SERVICE_NAME}" \ --destination-run-service="${SERVICE_NAME}" \ --destination-run-region="${REGION}" \ --location="${LOCATION}" \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=${BUCKET_NAME}" \ --service-account="${SERVICE_ACCOUNT}"
Se você receber um dos seguintes erros, aguarde um minuto e execute o comando novamente:
ERROR: (gcloud.eventarc.triggers.create) INVALID_ARGUMENT: The request was invalid: Bucket "unscanned-PROJECT_ID" was not found. Please verify that the bucket exists.
ERROR: (gcloud.eventarc.triggers.create) FAILED_PRECONDITION: Invalid resource state for "": Permission denied while using the Eventarc Service Agent. If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent. Otherwise, verify that it has Eventarc Service Agent role.
Altere o prazo de confirmação da mensagem para dois minutos na assinatura subjacente do Pub/Sub usada pelo gatilho do Eventarc. O valor padrão de 10 segundos é muito curto para arquivos grandes ou cargas altas.
SUBSCRIPTION_NAME=$(gcloud eventarc triggers describe \ "trigger-${BUCKET_NAME}-${SERVICE_NAME}" \ --location="${LOCATION}" \ --format="get(transport.pubsub.subscription)") gcloud pubsub subscriptions update "${SUBSCRIPTION_NAME}" --ack-deadline=120
O gatilho é criado imediatamente, mas pode levar até 10 minutos para que ele seja propagado e filtre eventos.
Criar um job do Cloud Scheduler para acionar atualizações de espelho do banco de dados ClamAV
Crie um job do Cloud Scheduler que execute uma solicitação
POST
HTTP no serviço do Cloud Run com um comando para atualizar o espelho do banco de dados de definições de malware. Para evitar que muitos clientes usem o mesmo horário, a ClamAV exige que você programe o job em um minuto aleatório entre 3 e 57, evitando múltiplos de 10.while : ; do # set MINUTE to a random number between 3 and 57 MINUTE="$((RANDOM%55 + 3))" # exit loop if MINUTE isn't a multiple of 10 [[ $((MINUTE % 10)) != 0 ]] && break done gcloud scheduler jobs create http \ "${SERVICE_NAME}-mirror-update" \ --location="${REGION}" \ --schedule="${MINUTE} */2 * * *" \ --oidc-service-account-email="${SERVICE_ACCOUNT}" \ --uri="${SERVICE_URL}" \ --http-method=post \ --message-body='{"kind":"schedule#cvd_update"}' \ --headers="Content-Type=application/json"
O argumento de linha de comando
--schedule
define quando o job é executado usando o formato de string unix-cron. O valor fornecido indica que o job precisa ser executado no minuto específico gerado aleatoriamente a cada duas horas.
Esse job só atualiza o espelho do ClamAV no Cloud Storage. Em cada instância do Cloud Run, o daemon de ClamAV é verificado pelo espelho a cada 30 minutos para novas definições e atualiza o daemon do ClamAV.
Fazer o upload de arquivos para testar o pipeline
Para testar o pipeline, faça upload de um arquivo limpo (sem malware) e um arquivo de teste que imite um arquivo infectado:
Crie um arquivo de texto de amostra ou use um atual não infectado para testar os processos do pipeline.
No Cloud Shell, copie o arquivo de dados de amostra para o bucket não verificado:
gcloud storage cp FILENAME "gs://unscanned-${PROJECT_ID}"
Substitua
FILENAME
pelo nome do arquivo de texto não infectado. O serviço de verificação de malware inspeciona cada documento e o transfere para um bucket apropriado. Esse arquivo é movido para o bucket limpo.Aguarde alguns segundos para o pipeline processar o arquivo e verifique o bucket limpo para ver se o arquivo processado está lá:
gcloud storage ls "gs://clean-${PROJECT_ID}" --recursive
Verifique se o arquivo foi removido do bucket não verificado:
gcloud storage ls "gs://unscanned-${PROJECT_ID}" --recursive
Faça upload de um arquivo chamado
eicar-infected.txt
que contenha a assinatura de teste antimalware padrão da EICAR no bucket não verificado:echo -e 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' \ | gcloud storage cp - "gs://unscanned-${PROJECT_ID}/eicar-infected.txt"
Essa string de texto tem uma assinatura que aciona verificadores de malware para fins de teste. Esse arquivo de teste é amplamente usado. Ele não é um malware real e é inofensivo para sua estação de trabalho. Se você tentar criar um arquivo que contenha essa string em um computador com um verificador de malware instalado, será possível acionar um alerta.
Aguarde alguns segundos e verifique o bucket em quarentena para ver se o documento passou pelo pipeline.
gcloud storage ls "gs://quarantined-${PROJECT_ID}" --recursive
O serviço também registra uma entrada do Logging quando um arquivo infectado por malware é detectado.
Verifique se o arquivo foi removido do bucket não verificado:
gcloud storage ls "gs://unscanned-${PROJECT_ID}" --recursive
Testar o mecanismo de atualização do banco de dados de definições de malware
No Cloud Shell, é possível acionar a verificação de atualizações forçando a execução do job do Cloud Scheduler:
gcloud scheduler jobs run "${SERVICE_NAME}-mirror-update" --location="${REGION}"
Os resultados desse comando são mostrados apenas nos registros detalhados.
Monitorar o serviço
É possível monitorar o serviço usando o Cloud Logging e o Cloud Monitoring.
Ver registros detalhados
No console do Google Cloud, acesse a página "Explorador de registros" do Cloud Logging.
Se o filtro Campos de registro não for exibido, clique em Campos de registro.
No filtro Campos de registro, clique em Revisão do Cloud Run.
Na seção Nome do serviço do filtro Campos de registro, clique em scanner de malware.
Os resultados da consulta mostram os registros do serviço, incluindo várias linhas que mostram as solicitações de verificação e o status dos dois arquivos enviados:
Scan request for gs://unscanned-PROJECT_ID/FILENAME, (##### bytes) scanning with clam ClamAV CLAMAV_VERSION_STRING
Scan status for gs://unscanned-PROJECT_ID/FILENAME: CLEAN (##### bytes in #### ms)
...
Scan request for gs://unscanned-PROJECT_ID/eicar-infected.txt, (69 bytes) scanning with clam ClamAV CLAMAV_VERSION_STRING
Scan status for gs://unscanned-PROJECT_ID/eicar-infected.txt: INFECTED stream: Eicar-Signature FOUND (69 bytes in ### ms)
A saída mostra a versão do ClamAV e a revisão da assinatura do banco de dados de malware, junto com o nome do malware do arquivo de teste infectado. É possível usar essas mensagens de registro para configurar alertas quando um vírus for encontrado ou para quando houver falhas durante a verificação.
A saída também mostra as definições de malware espelham os registros de atualização:
Starting CVD Mirror update
CVD Mirror update check complete. output: ...
Se o espelho foi atualizado, a saída mostra linhas adicionais:
CVD Mirror updated: DATE_TIME - INFO: Downloaded daily.cvd. Version: VERSION_INFO
Os registros de atualização do Freshclam aparecem a cada 30 minutos:
DATE_TIME -> Received signal: wake up
DATE_TIME -> ClamAV update process started at DATE_TIME
DATE_TIME -> daily.cvd database is up-to-date (version: VERSION_INFO)
DATE_TIME -> main.cvd database is up-to-date (version: VERSION_INFO)
DATE_TIME -> bytecode.cvd database is up-to-date (version: VERSION_INFO)
Se o banco de dados tiver sido atualizado, as linhas de registro do novo registro serão semelhantes às seguintes:
DATE_TIME -> daily.cld updated (version: VERSION_INFO)
Mostrar métricas
O serviço gera as seguintes métricas para fins de monitoramento e alerta:
- Número de arquivos limpos processados:
custom.googleapis.com/opencensus/malware-scanning/clean_files
- Número de arquivos infectados processados:
custom.googleapis.com/opencensus/malware-scanning/infected_files
- Tempo gasto na verificação de arquivos:
custom.googleapis.com/opencensus/malware-scanning/scan_duration
- Número total de bytes verificados:
custom.googleapis.com/opencensus/malware-scanning/bytes_scanned
- Número de verificações de malware com falha:
custom.googleapis.com/opencensus/malware-scanning/scans_failed
- Número de verificações de atualização do CVD Mirror:
custom.googleapis.com/opencensus/malware-scanning/cvd-mirror-updates
É possível ver essas métricas no explorador de métricas do Cloud Monitoring:
No console do Google Cloud, acesse a página "Metrics Explorer" do Cloud Monitoring.
Clique no campo Selecionar uma métrica e insira a string de filtro
malware
.Selecione a métrica OpenCensus/malware-scanning/clean_files. O gráfico mostra um ponto de dados que indica quando o arquivo limpo foi verificado.
Você pode usar métricas para monitorar o pipeline e criar alertas para quando o malware for detectado ou quando os arquivos falharem no processamento.
As métricas geradas têm os seguintes rótulos, que você pode usar para filtragem e agregação para visualizar detalhes mais refinados com o Metrics Explorer
source_bucket
destination_bucket
clam_version
cloud_run_revision
Lidar com vários buckets
O serviço de verificação de malware verifica arquivos de vários buckets de origem e envia os arquivos para separar buckets limpos e em quarentena. Embora essa configuração avançada esteja fora do escopo desta implantação, veja a seguir um resumo das etapas necessárias:
Crie buckets do Cloud Storage não verificados, limpos e em quarentena com nomes exclusivos.
Conceda os papéis apropriados à conta de serviço
malware-scanner
em cada bucket.Edite o arquivo de configuração
config.json
para especificar os nomes dos buckets de cada configuração:{ "buckets": [ { "unscanned": "unscanned-bucket-1-name", "clean": "clean-bucket-1-name", "quarantined": "quarantined-bucket-1-name" }, { "unscanned": "unscanned-bucket-2-name", "clean": "clean-bucket-2-name", "quarantined": "quarantined-bucket-2-name" } ] "ClamCvdMirrorBucket": "cvd-mirror-bucket-name" }
Para cada um dos buckets não verificados, crie um gatilho do Eventarc. Crie um nome de gatilho exclusivo para cada bucket.
O bucket do Cloud Storage precisa estar no mesmo projeto e região que o gatilho do Eventarc.
Limpar
A seção a seguir explica como evitar cobranças futuras para o projeto do Google Cloud usado nesta implantação.
Excluir o projeto do Google Cloud
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados nessa implantação, exclua o projeto do Google Cloud.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
A seguir
- Veja a documentação do Cloud Storage.
- Para mais arquiteturas de referência, diagramas e práticas recomendadas, confira a Central de arquitetura do Cloud.