Estou usando um contêiner Postgres para executar alguns pequenos aplicativos e sites não críticos. Está estável há algum tempo, mas agora o contêiner começou a consumir uma CPU séria depois de ser executado por um curto período de tempo. Eu removi todos os outros contêineres que usam o contêiner Postgres e, mesmo após iniciar uma nova instância, a utilização excessiva da CPU ocorre novamente. No meu host ( docker stats
), vejo isso:
CONTAINER ID NAME
CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS cd553249727d data_postgresql.1.ft2gof5jci25xs5w5uqw6eezi
814.52% 22.11MiB / 46.95GiB 0.05% 129kB / 116kB 0B / 692kB 23
E isso ( top
):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28923 70 20 0 633580 19664 488 S 696.7 0.0 2408:51 Dp2N
No container ( top
), vejo isso:
Mem: 42042244K used, 7183656K free, 3622600K shrd, 1952K buff, 30585480K cached
CPU: 63% usr 9% sys 0% nic 26% idle 0% io 0% irq 0% sirq
Load average: 9.77 9.70 9.66 13/508 11090
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
94 1 postgres S 618m 1% 3 58% ./Dp2N <----- WTF?!?!?
53 52 postgres S 1588 0% 1 1% {systemd} /bin/sh ./systemd
47 1 postgres S 163m 0% 8 0% postgres: postgrea67 postgres 10.2
22 1 postgres S 161m 0% 0 0% postgres: autovacuum launcher proc
20 1 postgres S 161m 0% 8 0% postgres: writer process
21 1 postgres S 161m 0% 5 0% postgres: wal writer process
1 0 postgres S 161m 0% 0 0% postgres
19 1 postgres S 161m 0% 8 0% postgres: checkpointer process
23 1 postgres S 19988 0% 1 0% postgres: stats collector process
11081 53 postgres R 1588 0% 4 0% [systemd]
33 0 root S 1576 0% 9 0% sh
52 47 postgres S 1568 0% 10 0% sh -c setsid ./systemd
39 33 root R 1508 0% 11 0% top
11083 11081 postgres Z 0 0% 5 0% [grep]
11084 11081 postgres Z 0 0% 4 0% [awk]
Atividade de consulta (sem ideia do que select fun308928987('setsid ./systemd')
faz):
postgres=# select backend_start, usename, application_name, client_addr, client_hostname, query from pg_stat_activity;
backend_start | usename | application_name | client_addr | client_hostname | query
-------------------------------+------------+------------------+-------------+-----------------+-------------------------------------------------------------------------------------------------------------
2018-05-23 07:34:14.694057+00 | postgres | psql | | | select backend_start, usename, application_name, client_addr, client_hostname, query from pg_stat_activity;
2018-05-23 01:26:55.235556+00 | postgrea67 | | 10.255.0.2 | | select fun308928987('setsid ./systemd');
2018-05-23 07:26:03.519231+00 | postgrea67 | | 10.255.0.2 | | select fun308928987('setsid ./systemd');
Nos logs do serviço também há uma grande quantidade de instâncias desse erro:
data_postgresql.1.ft2gof5jci25@IS-57436 | ps: bad -o argument 'command', supported arguments: user,group,comm,args,pid,ppid,pgid,etime,nice,rgroup,ruser,time,tty,vsz,stat,rss
Se eu matar o Dp2N
processo dentro do contêiner, o uso da CPU volta ao normal, mas algo imediatamente gira esse processo de volta. Pesquisei no Google para ver se acho alguma informação sobre Dp2N
o , mas sem sucesso. Ele está localizado em um volume montado externamente:
/ # ls -al /var/lib/postgresql/data/pgdata/Dp2N
-rwxrwxrwx 1 postgres postgres 1886536 May 22 23:25 /var/lib/postgresql/data/pgdata/Dp2N
mas aparentemente é criado, pois não faz parte da imagem base até onde posso ver.
Estou usando postgres:9.6.9-alpine. O problema começou com postgres:9.6.8-alpine, mas a atualização não resolveu. Qualquer ajuda seria muito apreciada, pois isso está me deixando louco!
Detalhes adicionais
Resultados da corrida file
:
sudo file /var/data/pgdata/pgdata/Dp2N
/var/data/pgdata/pgdata/Dp2N: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=bcb5ccf2bc22d1fcb0676506d7c7f31a9b7148bc, stripped
Acontece que o Alpine vem com uma versão limitada do ps
comando. Executando isso:
apk --no-cache add procps
obtém a versão aprimorada e evita o ps
erro relacionado nos logs. Atualizei a imagem do Postgres para incluir isso e até agora o problema não ressurgiu. A especulação é que a CPU está sendo derrotada tentando executar o comando repetidamente após a falha.
Diagnóstico
De acordo com a resposta abaixo, acontece que fui hackeado. Eu estou atualmente em uma perda de como eles entraram embora. Servidor bloqueado para usuário específico com certificado SSH / sem acesso por senha e root desabilitado. ('last' mostra apenas meus acessos - a menos que tenha sido hackeado.) Nenhum acesso público ao postgresql. Senha de administrador de banco de dados muito forte. Acessado apenas de 1 outro contêiner atualmente. Parece provável que eles tenham entrado pelos sites da Web no servidor, mas só chegaram ao sistema operacional do contêiner neste caso, não ao sistema operacional host. FWIW Estou executando um site Wordpress, Grafana, Kibana, Traefik, Portainer e minha própria API baseada em .NET. Estou começando com um shakedown do Wordpress primeiro, pois já experimentei infecções relacionadas a plug-ins antes.
Para fins educacionais:
Você foi hackeado e agora está minerando criptomoedas para o hacker.
Eles entraram adivinhando a senha da conta de superusuário do seu servidor postgresql. Em seguida, eles usaram o recurso lo_export para descartar o binário para uma função definida pelo usuário que executa comandos shell arbitrários. É isso que fun308928987 é, a função SQL que foi criada para encapsular esse binário.
A melhor limpeza é apenas destruir o servidor e reconstruí-lo, desta vez configurando uma senha forte real para a conta de superusuário. Ou melhor ainda, altere também o pg_hba.conf para não permitir conexões de superusuários, ou preferencialmente quaisquer conexões, do mundo exterior.