Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов
-
Материал ориентирован на разработчиков и тех, кто не живёт в терминале 24/7, но хочет уверенно чувствовать себя на сервере.
1. Навигация и файловая структура
Где я и что вокруг
pwd # показать текущую директорию ls # список файлов ls -la # список с правами/владельцами/скрытыми файлами cd /path # перейти в директорию cd .. # на уровень выше cd - # переключиться в предыдущую директориюДля чего:
- Проверка, куда деплоится сайт, где лежат логи и конфиги.
- Контроль, нет ли «левых» директорий рядом с проектом.
2. Просмотр и поиск по файлам (логи, конфиги, шеллы)
Быстрый просмотр файлов
cat file.log # вывести весь файл less file.log # пролистывать вверх/вниз, поиск по /строка head -n 50 file.log # первые 50 строк tail -n 50 file.log # последние 50 строк tail -f file.log # «онлайн» просмотр логаПоиск по тексту (ошибки, IP, подозрительные строки)
grep "ERROR" file.log # найти строки с ERROR grep -i "warning" file.log # регистронезависимый поиск grep -R "eval(base64_decode" . # рекурсивный поиск по проекту grep -R "site.ru" /var/log # где в логах фигурирует ваш доменКомбо для live‑мониторинга ошибок:
tail -f /var/log/nginx/error.log | grep --line-buffered "site.ru"
3. Права, владельцы, подозрительные файлы
Права и владельцы
ls -la # посмотреть права и владельца chown user:group file # сменить владельца chmod 644 file # стандартные права для файлов chmod 755 dir # стандартные права для директорийТипичные значения для PHP-проектов (без shared‑hosting‑извращений):
- директории:
755 - файлы:
644 - никакого
777в проде, если не хотите неожиданных «сюрпризов».
Поиск подозрительных файлов
find . -name "*.php" -mtime -1 # новые/изменённые за сутки find . -name "*.php" -size +1M # слишком «толстые» php-файлы find . -perm -o+w -type f # файлы, доступные на запись всем find . -name ".*" -type f # скрытые файлы (в т.ч. пассажи типа .something.php)
4. Сеть: кто подключён, какие порты, что слушает
Открытые порты и процессы
ss -tulpen # список слушающих портов и процессов ss -tnp # активные TCP‑подключенияКто подключён по SSH
who # кто в системе w # кто, откуда и что запускает last -n 20 # последние 20 входов в системуЗапросы к сайту в реальном времени (Nginx)
tail -f /var/log/nginx/access.log tail -f /var/log/nginx/access.log | grep "POST" tail -f /var/log/nginx/access.log | grep "wp-login" # поиск брут‑запросов к WP, как пример
5. Процессы, память, нагрузка
Общая картина
top # живой монитор ресурсов htop # более удобная версия (если установлена) uptime # load average и время работы сервера free -h # память df -h # диски и свободное место du -sh * # размер директорий в текущем каталогеКто ест CPU / RAM
ps aux --sort=-%cpu | head # топ по CPU ps aux --sort=-%mem | head # топ по памятиУбить зависший процесс
ps aux | grep php-fpm # найти PID kill 12345 # мягко завершить kill -9 12345 # жёстко (в крайнем случае)
6. Работа с архивами и бэкапами
Создать архив проекта
tar czf backup-`date +%F`.tar.gz /var/www/siteРаспаковать архив
tar xzf backup-2025-12-08.tar.gz -C /var/www/siteПолезно для:
- быстрых ручных бэкапов перед обновлениями;
- переносов проекта между серверами.
7. SSH и ключи: безопасность доступа к серверу
Создать SSH‑ключ
ssh-keygen -t ed25519 -C "your_email@example.com"Скопировать ключ на сервер
ssh-copy-id user@serverПодключиться с ключом
ssh user@serverБазовые практики:
- выключить парольный вход в
sshd_config(PasswordAuthentication no); - использовать нестандартный порт, если это допустимо инфраструктурно;
- ограничивать вход по IP, если есть возможность.
8. Мониторинг и анализ логов (Nginx, Apache, SSH)
Типичные места логов
/var/log/nginx/access.log /var/log/nginx/error.log /var/log/apache2/access.log /var/log/apache2/error.log /var/log/auth.log # попытки входа в систему (SSH и не только)Примеры команд
# 20 последних ошибок Nginx tail -n 20 /var/log/nginx/error.log # Подозрительные многократные попытки логина по SSH grep "Failed password" /var/log/auth.log | tail # Часто встречающиеся IP (грубый подсчёт) awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
9. Базовое взаимодействие с Git (деплой, код, аудит изменений)
Git напрямую про безопасность не отвечает, но помогает контролировать изменения в коде и ловить «левых редакторов».
git status # что изменилось git diff # посмотреть реальные изменения git log --oneline --decorate # история коммитов git blame file.php # кто и когда менял строки в файлеПодозрительные изменения можно быстрой командой просканировать и найти:
grep -R "base64_decode" .git grep -R "system(" .
10. Быстрые однострочники для безопасника и админа
Несколько «готовых» рецептов, которые можно брать и вставлять.
Показать топ‑10 IP по числу запросов к сайту:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | headПоиск всех PHP‑файлов, изменённых за последние 2 часа:
find /var/www/site -name "*.php" -mmin -120 -printПоиск сигнатур типичных веб-шеллов:
grep -R "eval(base64_decode" /var/www/site grep -R "passthru(" /var/www/site grep -R "shell_exec(" /var/www/site
11. Минимальный набор для «я не админ, но надо срочно глянуть»
Если совсем нет времени, а доступ к SSH есть, то хотя бы эти команды стоит держать под рукой:
# 1. Диски, память, нагрузка df -h free -h uptime # 2. Логи сайта tail -n 50 /var/log/nginx/error.log tail -n 50 /var/log/nginx/access.log # 3. Кто подключён по SSH w last -n 10 # 4. Изменённые PHP-файлы за сутки в проекте cd /var/www/site find . -name "*.php" -mtime -1 -printЭта шпаргалка не претендует на роль полноценного курса по администрированию, но закрывает рабочий минимум для:
- веб‑разработчика, которого внезапно сделали «ответственным за сервер»;
- кибербезопасности на уровне проверки логов, прав и подозрительных файлов;
- быстрой диагностики типичных проблем с сайтом.
-
Дополнение к предыдущей Unix‑шпаргалке, но специально для Node.js‑приложений. Здесь конкретные команды, примеры конфигов и típичные проблемы, которые встречаются при запуске и поддержке Node на боевом сервере.
1. Управление процессами Node.js
Базовый запуск (для разработки)
node app.js # простой запуск node --inspect app.js # с дебагером (слушает на 9229)Продакшн: процесс‑менеджер PM2
PM2 — это фактический стандарт для Node.js на Linux. Он обеспечивает автозапуск, рестарты и логирование.
Установка:
npm install -g pm2Запуск приложения через PM2:
pm2 start app.js --name "myapp" pm2 start app.js --name "myapp" --instances max # кластер на все ядра pm2 start app.js --name "myapp" --watch # перезапуск при изменении файлов (для dev)Управление:
pm2 list # список всех приложений pm2 status # статус (живо/мёртво) pm2 logs myapp # логи приложения в реальном времени pm2 logs myapp --err # только ошибки pm2 logs --lines 100 # последние 100 строк всех логов pm2 monit # живой мониторинг CPU/RAM по процессам pm2 stop myapp # остановить pm2 restart myapp # перезапустить pm2 delete myapp # удалить из управления pm2 kill # остановить PM2 и все процессыАвтозапуск при перезагрузке сервера
pm2 startup # сгенерирует команду для systemd/init.d pm2 save # сохранить текущий список процессовПосле этого PM2 автоматически запустит приложение при перезагрузке.
2. Конфиг PM2 (ecosystem.config.js)
Вместо множества флагов лучше использовать файл конфигурации. Создаёте
ecosystem.config.jsв корне проекта:module.exports = { apps: [ { name: "api-server", script: "./dist/main.js", // или src/main.js, если используете ts-node instances: "max", // число рабочих процессов exec_mode: "cluster", // кластерный режим env: { NODE_ENV: "production", PORT: 3000, }, env_development: { NODE_ENV: "development", PORT: 3000, }, // Перезапуск, если использование памяти > 500MB max_memory_restart: "500M", // Максимальное число перезапусков за час max_restarts: 10, min_uptime: "10s", // Логи error_file: "./logs/error.log", out_file: "./logs/out.log", log_date_format: "YYYY-MM-DD HH:mm:ss Z", }, ], };Запуск с этим конфигом:
pm2 start ecosystem.config.js pm2 start ecosystem.config.js --env development
3. Логирование приложения
Куда смотреть
PM2 пишет логи сюда:
~/.pm2/logs/ # основные логи приложенийЕсли вы указали свои пути в конфиге (см. выше):
tail -f ./logs/error.log tail -f ./logs/out.log tail -f ./logs/error.log | grep "ERR"Правильное логирование в коде
Не просто
console.log(), а структурированные логи. Популярные либы:winston,pino,bunyan.Пример с pino (просто и быстро):
import pino from "pino"; const logger = pino({ level: process.env.LOG_LEVEL || "info", transport: { target: "pino-pretty", }, }); logger.info({ userId: 123 }, "User logged in"); logger.error({ err: err }, "Something broke");В продакшене без
pino-pretty(для JSON-логов):const logger = pino({ level: "info", // transport убрать для чистого JSON в файл });Мониторинг в реальном времени
pm2 logs # все логи pm2 logs myapp # только приложения myapp pm2 logs myapp --err # только ошибки pm2 logs myapp --lines 50 # последние 50 строк tail -f ~/.pm2/logs/myapp-error.log | grep "500" # ошибки сервера
4. Базовая безопасность Node.js‑приложения
Переменные окружения (
.env)Никогда не коммитьте API‑ключи, пароли БД и токены в код.
Используйте
.envфайл:# .env DATABASE_URL=postgresql://user:pass@localhost/dbname API_SECRET=your_secret_key_here NODE_ENV=productionИ в коде:
import dotenv from "dotenv"; dotenv.config(); const dbUrl = process.env.DATABASE_URL;Проверка: нет ли в репо секретов
grep -R "password" . # поиск по слову password grep -R "secret" . # по слову secret grep -R "sk_" . # типичные Stripe ключи find . -name ".env*" -type f # .env файлы (не должны коммититься)Защита папки
node_modules# По умолчанию может быть доступна через веб, что плохо # В Nginx блокируйте: location /node_modules/ { deny all; }Обновление зависимостей (уязвимости)
npm audit # показать известные уязвимости npm audit fix # попытаться автоматически исправить npm outdated # показать устаревшие пакеты npm update # обновить в рамках семантики версий
5. Порты и сетевая безопасность
На каких портах слушит ваше приложение
ss -tulpen | grep node # процессы node и их порты lsof -i -P | grep node # альтернативный способХороший паттерн для продакшена
Node.js слушает на localhost:3000 Nginx сверху (порт 80/443) → проксирует на Node на localhost:3000Конфиг Nginx для проксирования:
upstream nodejs { server 127.0.0.1:3000; } server { listen 80; server_name your-site.ru; location / { proxy_pass http://nodejs; 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; } }Проверка прав на порты
# Node.js не должен запускаться от root (для портов < 1024 нужна привилегия) # Правильно: Node на 3000, Nginx как обратный прокси на 80 ps aux | grep node # под каким юзером запущен node
6. Работа с базами данных (Node.js + PostgreSQL/MySQL)
Типичные проблемы: вход на БД не установлен, утечка данных в логи, медленные квери.
Проверка подключения
# На сервере, если БД локальная psql -U postgres -d your_db # PostgreSQL mysql -u root -p your_db # MySQLУтечки в логи (секреты не должны попадать)
grep -R "password" ~/.pm2/logs/ grep -R "DATABASE_URL" ~/.pm2/logs/Убедитесь, что в логах не выводится полная строка подключения.
ORM и драйверы (NestJS примеры)
Если используется TypeORM:
import { DataSource } from 'typeorm'; export const AppDataSource = new DataSource({ type: 'postgres', host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT || '5432'), username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: ['src/**/*.entity.ts'], migrations: ['src/migrations/**/*.ts'], });Проверка количества активных подключений к БД
# PostgreSQL (на самой БД) psql -U postgres -d your_db -c "SELECT count(*) FROM pg_stat_activity;"
7. Логирование запросов (HTTP логи приложения)
В Express / Fastify / NestJS используйте middleware для логирования:
Express пример с morgan
import morgan from 'morgan'; import fs from 'fs'; // Логирование в файл const accessLogStream = fs.createWriteStream('./logs/access.log', { flags: 'a' }); app.use(morgan('combined', { stream: accessLogStream })); // В консоль (development) app.use(morgan('dev'));NestJS пример
import { Logger, Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class LoggerMiddleware implements NestMiddleware { private logger = new Logger('HTTP'); use(req: Request, res: Response, next: NextFunction) { const { method, originalUrl, ip } = req; const start = Date.now(); res.on('finish', () => { const duration = Date.now() - start; this.logger.log( `${method} ${originalUrl} ${res.statusCode} ${duration}ms from ${ip}`, ); }); next(); } }Поиск проблемных запросов
# Медленные запросы (>5 секунд) awk '$NF > 5 {print}' /var/log/nginx/access.log # POST запросы (обычно подозрительнее) tail -f /var/log/nginx/access.log | grep "POST" # 500 ошибки tail -f ~/.pm2/logs/myapp-error.log | grep "500"
8. Мониторинг производительности (CPU, память, утечки)
Live мониторинг PM2
pm2 monit # встроенный мониторХронометраж приложения (кластер)
pm2 describe myapp # детали о приложении и рабочих процессахУтечка памяти — основной враг Node.js
Признак утечки: приложение медленно ест RAM, потом падает.
Проверка в коде:
// Периодически логируем использование памяти setInterval(() => { const mem = process.memoryUsage(); console.log( `Memory: ${Math.round(mem.heapUsed / 1024 / 1024)}MB / ${Math.round(mem.heapTotal / 1024 / 1024)}MB` ); }, 5000);Если растёт без остановки — утечка. Ищите:
- забытые listener’ы (
EventEmitter); - не закрытые соединения с БД;
- циклические ссылки в объектах.
9. Типичные боевые ошибки и как их ловить
Запуск без базы данных
Приложение стартует, но падает при первом запросе. Решение:
// Проверка перед запуском async function checkConnections() { try { await db.ping(); logger.info('Database connected'); } catch (err) { logger.error('Database connection failed:', err); process.exit(1); } } await checkConnections(); app.listen(3000);Нестабильность (приложение рестартится сам по себе)
Причины: out of memory, exception, зависший процесс.
pm2 logs myapp --err # смотрим последние ошибки pm2 monit # жмём букву 'l' для логовEADDRINUSE: port already in use
Порт занят:
ss -tulpen | grep :3000 # кто занял порт kill -9 PID # убить процессИли PM2 уже не очистил:
pm2 kill # убить PM2 полностью pm2 start ecosystem.config.js # начать заново
10. Обновление и деплой приложения (с нулевым downtime)
Сценарий: новая версия в Git, нужно обновить в продакшене
# На сервере в директории с приложением cd /var/www/myapp # Забрать обновления git pull origin main # Установить зависимости (если были изменения в package.json) npm ci # предпочтительнее npm install для продакшена # Собрать (если есть TypeScript) npm run build # Перезапустить приложение с нулевым downtime (PM2 reload) pm2 reload myappАвтоматизация через GitHub Actions (push в main → автоматический деплой)
.github/workflows/deploy.yml:name: Deploy to production on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Deploy via SSH run: | mkdir -p ~/.ssh echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/key chmod 600 ~/.ssh/key ssh -i ~/.ssh/key deploy@your-server.com << 'EOF' cd /var/www/myapp git pull origin main npm ci npm run build pm2 reload myapp EOF
11. Безопасность: входящие запросы и injection‑атаки
Базовая валидация в Express / NestJS
import { IsString, IsEmail, MinLength } from 'class-validator'; export class CreateUserDto { @IsString() @MinLength(3) username: string; @IsEmail() email: string; @IsString() @MinLength(8) password: string; } // В контроллере @Post('/users') async create(@Body() dto: CreateUserDto) { // Валидация автоматическая, injection невозможна return this.usersService.create(dto); }SQL injection защита
Никогда не конкатенируйте SQL вручную:
// ❌ ПЛОХО const result = await db.query(`SELECT * FROM users WHERE id = ${userId}`); // ✅ ХОРОШО (parameterized query) const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);CORS и CSRF
import cors from 'cors'; import csrf from 'csurf'; // CORS (только свои домены) app.use(cors({ origin: ['https://your-site.ru'], credentials: true, })); // CSRF protection app.use(csrf({ cookie: false }));
12. Ротация логов и место на диске
Логи растут бесконечно. Нужна ротация.
PM2 + logrotate
Создайте
/etc/logrotate.d/pm2-app:/home/deploy/.pm2/logs/*.log { daily rotate 14 compress delaycompress notifempty missingok postrotate pm2 reload myapp > /dev/null 2>&1 || true endscript }Проверка:
logrotate -f /etc/logrotate.d/pm2-app # принудительная ротацияПроверка размера логов
du -sh ~/.pm2/logs/ ls -lh ~/.pm2/logs/
13. Быстрые однострочники для Node.js
Поиск всех GET запросов с кодом 404:
grep " 404 " ~/.pm2/logs/myapp-out.log | wc -lТоп IP-адресов, обращающихся к приложению (если логируете):
grep -oP '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' ~/.pm2/logs/myapp-out.log | sort | uniq -c | sort -nr | headПоиск ошибок за последний час:
tail -f ~/.pm2/logs/myapp-error.log | grep "$(date +'%H:%M')"Убить зависший процесс Node (перезапустится через PM2):
pkill -f "node dist/main.js"
14. Чек‑лист: запуск Node.js‑приложения в продакшене
- Переменные окружения:
.envс DATABASE_URL, API keys, NODE_ENV=production - PM2 конфиг:
ecosystem.config.jsс instances, памятью, логами - Nginx: обратный прокси на localhost:3000
- SSL/HTTPS: Let’s Encrypt + certbot
- Логирование: структурированные логи (pino/winston), ротация
- Валидация: DTO + class-validator для всех input’ов
- БД: миграции, проверка подключения при старте
- Мониторинг:
pm2 monit, периодическая проверка памяти - Бэкапы: регулярное копирование БД и важных файлов
- Обновления: планомерное обновление зависимостей, проверка уязвимостей (
npm audit)
Все это практический минимум для того, чтобы запустить и поддерживать Node.js на боевом сервере без паники. Мультипроцессность, логирование, мониторинг и безопасность — вот костяк.
Когда приложение начнёт падать на продакшене (а оно упадёт — это вопрос времени), эта шпаргалка должна помочь найти причину за 10 минут, а не за час.
- забытые listener’ы (
-
А как же самая главная команда?!
rm -rf -
Вопрос,сборку проекта лучше делать где? И как получить node_modules на проде?
-
@ArtemL хм, наверное стоит написать про деплой Некста - займусь на выходных
© 2024 - 2025 ExLends, Inc. Все права защищены.