Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Системное Администрирование
  4. Bash | Shell
  5. Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов

Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов

Запланировано Прикреплена Закрыта Перенесена Bash | Shell
5 Сообщения 5 Постеры 108 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • MugiwaraM Не в сети
    MugiwaraM Не в сети
    Mugiwara
    написал в отредактировано
    #1

    Материал ориентирован на разработчиков и тех, кто не живёт в терминале 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
    

    Эта шпаргалка не претендует на роль полноценного курса по администрированию, но закрывает рабочий минимум для:

    • веб‑разработчика, которого внезапно сделали «ответственным за сервер»;
    • кибербезопасности на уровне проверки логов, прав и подозрительных файлов;
    • быстрой диагностики типичных проблем с сайтом.
    1 ответ Последний ответ
    3
    • AladdinA Не в сети
      AladdinA Не в сети
      Aladdin
      js
      написал в отредактировано
      #2

      Дополнение к предыдущей 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‑приложения в продакшене

      1. Переменные окружения: .env с DATABASE_URL, API keys, NODE_ENV=production
      2. PM2 конфиг: ecosystem.config.js с instances, памятью, логами
      3. Nginx: обратный прокси на localhost:3000
      4. SSL/HTTPS: Let’s Encrypt + certbot
      5. Логирование: структурированные логи (pino/winston), ротация
      6. Валидация: DTO + class-validator для всех input’ов
      7. БД: миграции, проверка подключения при старте
      8. Мониторинг: pm2 monit, периодическая проверка памяти
      9. Бэкапы: регулярное копирование БД и важных файлов
      10. Обновления: планомерное обновление зависимостей, проверка уязвимостей (npm audit)

      Все это практический минимум для того, чтобы запустить и поддерживать Node.js на боевом сервере без паники. Мультипроцессность, логирование, мониторинг и безопасность — вот костяк.

      Когда приложение начнёт падать на продакшене (а оно упадёт — это вопрос времени), эта шпаргалка должна помочь найти причину за 10 минут, а не за час.

      1 ответ Последний ответ
      1
      • hannadevH Не в сети
        hannadevH Не в сети
        hannadev
        написал в отредактировано
        #3

        А как же самая главная команда?!

        rm -rf
        
        1 ответ Последний ответ
        🤡
        -1
        • ArtemLA Не в сети
          ArtemLA Не в сети
          ArtemL
          написал в отредактировано
          #4

          Вопрос,сборку проекта лучше делать где? И как получить node_modules на проде?

          kirilljsxK 1 ответ Последний ответ
          0
          • ArtemLA ArtemL

            Вопрос,сборку проекта лучше делать где? И как получить node_modules на проде?

            kirilljsxK Не в сети
            kirilljsxK Не в сети
            kirilljsx
            js
            написал в отредактировано
            #5

            @ArtemL хм, наверное стоит написать про деплой Некста - займусь на выходных

            1 ответ Последний ответ
            1

            Категории

            • Главная
            • Новости
            • Фронтенд
            • Бекенд
            • Языки программирования

            Контакты

            • Сотрудничество
            • info@exlends.com
            • Наш чат
            • Наш ТГ канал

            © 2024 - 2025 ExLends, Inc. Все права защищены.

            Политика конфиденциальности
            • Войти

            • Нет учётной записи? Зарегистрироваться

            • Войдите или зарегистрируйтесь для поиска.
            • Первое сообщение
              Последнее сообщение
            0
            • Лента
            • Категории
            • Последние
            • Метки
            • Популярные
            • Пользователи
            • Группы