Малварь в /tmp и как я её вычистил
Детекция малвары
Несколько дней к ряду у меня срабатывал алерт в телеграм от хостера, что у меня пляшет ЦПУ больше 80% на сервере. В конце концов я решил проверить, что там так сильно жрет. По итогу я увидел вот такой процесс:
./YvXvlwke
Он выжирал 100% цпу и был задублирован.
Тогда я проверил, что это за файл такой вообще:
root@hhblipions:~# ls -lah /proc/$(pidof YvXvlwke)/exe
lrwxrwxrwx 1 root root 0 May 7 06:20 /proc/412062/exe -> '/tmp/YvXvlwke (deleted)'
Очень подозрительно - подумал я. Файл удален, но процесс все еще работает
Тогда я грохнул его kill -9 412062
и проверил:
- содержимое папки
/tmp
и процессов, которые работают из/tmp
- кроны и сервисы
ls -lah /tmp
ps aux | grep tmp
crontab -l
ls -lah /etc/cron*
cat /etc/rc.local
systemctl list-units --type=service | grep tmp
Закроем все сервисы, которые смотрят в мир
ss -tunap
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 83.222.20.213:55806 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=46))
udp UNCONN 0 0 0.0.0.0:6771 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=36))
udp UNCONN 0 0 0.0.0.0:6771 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=35))
udp UNCONN 0 0 0.0.0.0:6771 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=14))
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=672,fd=13))
udp UNCONN 0 0 172.18.0.1%br-8bbe0e3d5152:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=21))
udp UNCONN 0 0 83.222.20.213%eth0:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=20))
udp UNCONN 0 0 127.0.0.1%lo:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=17))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=627))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=595))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=31))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=40))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=39))
udp UNCONN 0 0 *:6771 *:* users:(("qbittorrent-nox",pid=321248,fd=38))
udp UNCONN 0 0 [fe80::30af:71ff:fe16:4792]%veth75dc8ce:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=33))
udp UNCONN 0 0 [fe80::4031:b5ff:fe8c:c385]%vethf4b38ea:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=42))
udp UNCONN 0 0 [fe80::d836:c3ff:fefe:5d9d]%veth3ab9399:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=30))
udp UNCONN 0 0 [fe80::c0e4:d3ff:fe07:c07c]%br-8bbe0e3d5152:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=28))
udp UNCONN 0 0 [fe80::27e:3dff:fe56:2757]%eth0:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=26))
udp UNCONN 0 0 [::1]%lo:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=24))
tcp LISTEN 0 30 83.222.20.213%eth0:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=18))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=902,fd=3))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=311213,fd=7),("nginx",pid=311212,fd=7),("nginx",pid=311211,fd=7),("nginx",pid=311210,fd=7))
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=311213,fd=6),("nginx",pid=311212,fd=6),("nginx",pid=311211,fd=6),("nginx",pid=311210,fd=6))
tcp LISTEN 0 30 127.0.0.1%lo:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=16))
tcp LISTEN 0 30 172.18.0.1%br-8bbe0e3d5152:57611 0.0.0.0:* users:(("qbittorrent-nox",pid=321248,fd=19))
tcp LISTEN 0 4096 0.0.0.0:3000 0.0.0.0:* users:(("docker-proxy",pid=451756,fd=7))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=672,fd=14))
tcp ESTAB 0 0 83.222.20.213:22 88.87.93.46:60679 users:(("sshd",pid=451225,fd=4))
tcp ESTAB 0 132 83.222.20.213:22 142.91.15.89:61084 users:(("sshd",pid=457819,fd=4))
tcp LISTEN 0 30 [fe80::30af:71ff:fe16:4792]%veth75dc8ce:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=32))
tcp LISTEN 0 30 [fe80::27e:3dff:fe56:2757]%eth0:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=25))
tcp LISTEN 0 30 [fe80::d836:c3ff:fefe:5d9d]%veth3ab9399:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=29))
tcp LISTEN 0 30 [fe80::c0e4:d3ff:fe07:c07c]%br-8bbe0e3d5152:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=27))
tcp LISTEN 0 30 [fe80::4031:b5ff:fe8c:c385]%vethf4b38ea:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=41))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=902,fd=4))
tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=311213,fd=8),("nginx",pid=311212,fd=8),("nginx",pid=311211,fd=8),("nginx",pid=311210,fd=8))
tcp LISTEN 0 50 *:8080 *:* users:(("qbittorrent-nox",pid=321248,fd=49))
tcp LISTEN 0 4096 [::]:3000 [::]:* users:(("docker-proxy",pid=451762,fd=7))
tcp LISTEN 0 30 [::1]%lo:57611 [::]:* users:(("qbittorrent-nox",pid=321248,fd=23))
tcp ESTAB 0 0 [::ffff:83.222.20.213]:8080 [::ffff:142.91.15.89]:62153 users:(("qbittorrent-nox",pid=321248,fd=880))
Тут видно, что на внешнем IP у меня слушали следующие сервисы:
qbittorrent-nox
sshd
docker
nginx
По nginx все окей - там проксируетсяlinkwarden
, которые работают на порту3000
Но он доступен как по IP, так и по внешнему адресу. Несмотря на включенную авторизацию в ней нет особо много смысла, так как у ip нет https :)
qbittorrent
В общем тогда мне пришлось настроить проксирование qbittorrent
через nginx - сделал это по классике:
- направил нужный поддомен на мой серв
- настроить простенький прокси в nginx
server {
server_name torrent.tulashvili.com;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/torrent.tulashvili.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/torrent.tulashvili.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = torrent.tulashvili.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name torrent.tulashvili.com;
return 404; # managed by Certbot
}
- Выпустил серт
certbot
- В ui
qbittorrent
указал:
Итого:
🔒 http://83.222.20.213:8080 больше не доступен извне.
🌐 https://torrent.<мой_домен> — единственная точка доступа.
🔐 С защищённым HTTPS и доступом по паролю.
linkwarden
Также сделал и для linkwarden
. Тут пришлось повозиться, так как была ошибка подключения к postgres:
docker logs linkwarden_linkwarden_1
Please make sure your database server is running at localhost:5432.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn run v1.22.19
$ /data/node_modules/.bin/prisma migrate deploy
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"
Error: P1001: Can't reach database server at localhost:5432
Please make sure your database server is running at localhost:5432.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Ошибка была не в указанном маппинге:
ports:
- "127.0.0.1:3000:3000"
Ошибка была в строчке для подключения к psql
в docker-compose.yaml
:
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@localhost:5432/postgres?schema=public
Но верно было указать так:
DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@linkwarden_postgres_1:5432/postgres?schema=public
Docker контейнеры по умолчанию могут общаться друг с другом по именам контейнеров, поэтому это решило проблему и контейнер запустился успешно.
Дополнительно, вот мой конфиг nginx для проксирования linkwarden
:
server {
server_name bookmarks.tulashvili.com www.bookmarks.tulashvili.com;
location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/bookmarks.tulashvili.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/bookmarks.tulashvili.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.bookmarks.tulashvili.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = bookmarks.tulashvili.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name bookmarks.tulashvili.com www.bookmarks.tulashvili.com;
return 404; # managed by Certbot
}
ssh
Создание нового юзера и запрет авторизации под root
adduser user
usermod -aG sudo user
mkdir -p /home/user/.ssh
cp /root/.ssh/authorized_keys /home/user/.ssh/
chown -R user:user /home/user/.ssh
chmod 700 /home/user/.ssh
chmod 600 /home/user/.ssh/authorized_keys
sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
echo 'PermitRootLogin no' >> /etc/ssh/sshd_config
systemctl reload sshd
Доступ только со статических ip-адресов
Не хочу заморачиваться с firewall, поэтому сделаю старым, но рабочим способом:
sudo vim /etc/hosts.allow
sshd: 142.91.15.89
sshd: 88.87.93.46
sudo vim /etc/hosts.denny
sshd: ALL
На следующий день это повторилось:
sudo pkill -f ./2N6CNQ60
sudo systemctl stop qbittorrent-nox.service
Ввиду того, что ранее я заблокировал доступ к серверу по ssh с незнакомых ip-адресов, я могу предположить:
- torrent как-то пустил какаху, так как там есть файл, который скачался, но все еще раздается
- малвара все еще в системе несмотря на меры, которые я предпринял ранее
При этом я заметил, что история очищается каждый раз, когда у меня срабатывает мониторинг на данную проблему