MAATRIX / Блог / Как установить и настроить PrivateBin на VPS

Как установить и настроить PrivateBin на VPS

MAATRIX

Обычный pastebin — это доверие вслепую: вы вставляете текст, а сервер хранит его в открытом виде, и любой, у кого есть доступ к базе или логам, может его прочитать. PrivateBin решает эту проблему иначе: шифрование происходит в браузере до отправки на сервер, а сам сервер получает только зашифрованный блоб и никогда не видит ни пароль, ни содержимое. Дальше — рабочая установка на собственном VPS, от Docker-контейнера до нюансов настройки, на которые обычно натыкаются на третий день.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Как устроено шифрование в PrivateBin

Прежде чем ставить, стоит понимать модель безопасности — иначе легко настроить систему так, что смысл теряется.

Когда вы создаёть вставку (paste), браузер генерирует случайный ключ AES-256, шифрует текст локально через WebCrypto API и отправляет на сервер уже зашифрованные байты. Ключ никогда не покидает браузер — он попадает в URL после символа # (fragment identifier), а всё, что идёт после #, браузер по стандарту не отправляет на сервер при HTTP-запросе. Именно поэтому ссылка вида https://paste.example.com/?abc123#XyZ... безопасна: серверная часть до # уходит на сервер как идентификатор записи, а часть после # остаётся только у получателя.

Отсюда следствия:

  • Владелец сервера физически не может прочитать содержимое, даже если получит root-доступ к базе.
  • Если вы отправите ссылку без фрагмента (#...) — например, обрезав её при пересылке — получатель не сможет расшифровать данные и это не баг, а корректное поведение.
  • PrivateBin поддерживает необязательный пароль на вставку — он подмешивается к ключу через PBKDF2, добавляя защиту, даже если ссылка утечёт целиком.

Это отличает PrivateBin от связки самопального pastebin + сервер, где шифрование, если оно вообще есть, делает бэкенд — то есть по определению видит открытый текст хотя бы на миг.

Требования и выбор сервера

PrivateBin — лёгкое PHP-приложение, ему не нужны серьёзные ресурсы:

ПараметрМинимумКомфортно
CPU1 vCPU1-2 vCPU
RAM512 МБ1 ГБ
Диск10 ГБ20 ГБ SSD
ОСUbuntu 24.04 / Debian 12Ubuntu 24.04

Хранилище по умолчанию — файловая система (данные лежат в виде зашифрованных JSON-файлов), поэтому отдельная СУБД не нужна, хотя PrivateBin умеет работать и с базой данных, если вставок много и нужна выборка по критериям. Для личного или командного использования хватит младшего тарифа VPS — узкое место здесь не производительность, а диск под накопление файлов и корректный HTTPS.

Если сервер разворачиваете с нуля, для базовой подготовки пригодятся статьи про настройку домена и DNS на Ubuntu 24.04 и про установку Docker с нуля — дальше вся установка PrivateBin строится поверх этого.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка через Docker Compose

Официальный образ privatebin/privatebin — самый быстрый и предсказуемый путь: не нужно вручную ставить PHP, настраивать расширения и следить за версиями.

Создайте директорию проекта и структуру:

mkdir -p ~/privatebin/{data,config}
cd ~/privatebin

Файл docker-compose.yml:

services:
  privatebin:
    image: privatebin/privatebin:latest
    container_name: privatebin
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./data:/srv/data
      - ./config/conf.php:/srv/cfg/conf.php:ro
    environment:
      - PHP_TZ=Europe/Moscow

Обратите внимание: порт пробрасывается только на 127.0.0.1 — наружу контейнер не смотрит, весь внешний трафик пойдёт через реверс-прокси с HTTPS, который добавим следующим шагом. Это стандартная практика для любого self-hosted сервиса с чувствительными данными.

Скачайте образец конфигурации и подправьте под себя:

docker run --rm privatebin/privatebin:latest cat /srv/cfg/conf.php > config/conf.php

Запуск:

docker compose up -d
docker compose logs -f privatebin

Проверить, что контейнер поднялся и слушает локально:

curl -I http://127.0.0.1:8080

Должен вернуться HTTP/1.1 200 OK. Если контейнер падает в рестарт-луп — почти всегда причина в правах на директорию data: процесс в контейнере работает не от root, и каталог должен быть доступен на запись:

sudo chown -R 33:33 ./data   # UID www-data внутри образа

Настройка conf.php: ключевые параметры

Файл conf.php — сердце конфигурации, секции разбиты понятно по назначению.

Раздел [main] — общее:

[main]
name = "PrivateBin"
basepath = "https://paste.example.com/"
discussion = false
opendiscussion = false
password = true
fileupload = true
burnafterreadingselected = false
defaultformatter = "plaintext"
sizelimit = 10485760
template = "bootstrap-dark"
languageselection = true

Важные флаги:

  • discussion / opendiscussion — комментарии к вставкам. Для приватного sharing-инструмента обычно выключают.
  • password — разрешить пользователю задавать дополнительный пароль на вставку (рекомендуется оставить true).
  • burnafterreadingselected — сделать «сгорание после прочтения» опцией по умолчанию в UI. Полезно, если сервис используется для передачи одноразовых секретов (паролей, токенов).
  • sizelimit — лимит в байтах на одну вставку, здесь 10 МБ.

Раздел [expire] задаёт варианты времени жизни:

[expire]
default = "1week"

[expire_options]
5min = 300
30min = 1800
1hour = 3600
1day = 86400
1week = 604800
1month = 2592000
never = 0

Опцию never стоит убирать или ограничивать отдельной ролью — вечные вставки на диске накапливаются бесконечно и их некому чистить, если вы не настроите отдельный cron.

Раздел [traffic] защищает от спама:

[traffic]
limit = 10
exempted = "127.0.0.1"
header = "X-Forwarded-For"

limit — сколько вставок можно создать с одного IP за период (по умолчанию 10 минут). Ключевой момент: если PrivateBin стоит за реверс-прокси (а он у нас стоит), нужно явно указать header = "X-Forwarded-For", иначе все запросы будут выглядеть как пришедшие с IP самого прокси и либо все банятся разом, либо лимит не работает вообще.

Nginx как реверс-прокси и HTTPS

Ставим Nginx (если ещё не установлен) и настраиваем проксирование на локальный порт контейнера:

sudo apt update && sudo apt install -y nginx

Конфиг /etc/nginx/sites-available/privatebin:

server {
    listen 80;
    server_name paste.example.com;

    location / {
        proxy_pass http://127.0.0.1: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;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 12m;
    }
}

client_max_body_size должен быть чуть больше, чем sizelimit в conf.php — иначе Nginx отрежет крупные вставки раньше, чем до них дойдёт очередь PrivateBin, с невнятной ошибкой 413.

Активируем сайт и получаем сертификат через Certbot:

sudo ln -s /etc/nginx/sites-available/privatebin /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d paste.example.com

Certbot сам допишет блок listen 443 ssl и настроит редирект с 80 на 443. Если предпочитаете более простой автоматический TLS без отдельных cron-задач на продление, есть смысл сравнить подход в статье Caddy или Nginx: что выбрать для сервера и обзоре Certbot или acme.sh: что выбрать — для одного маленького сервиса как PrivateBin Caddy с авто-HTTPS часто оказывается меньше возни.

Без HTTPS PrivateBin разворачивать бессмысленно: WebCrypto API, на котором держится шифрование, в большинстве браузеров попросту не работает в незащищённом контексте (кроме localhost), так что без сертификата вы получите либо ошибку в консоли, либо предупреждение о небезопасном источнике.

Очистка истёкших вставок и бэкап

PrivateBin не удаляет истёкшие записи автоматически «по расписанию» — они помечаются как просроченные и не отдаются по запросу, но физически файлы остаются на диске, пока их не подчистит garbage collector. Штатный способ — дёргать ?gc при обращении к сервису; проще всего — форсировать это отдельным cron:

# /etc/cron.d/privatebin-gc
0 3 * * * root curl -s https://paste.example.com/?gc > /dev/null

Для бэкапа достаточно директории data — это плоские зашифрованные JSON-файлы, восстанавливаются простым копированием:

tar czf privatebin-backup-$(date +%F).tar.gz -C ~/privatebin data config/conf.php

Отдельно шифровать бэкап уже не обязательно (данные внутри и так зашифрованы клиентом), но conf.php может содержать чувствительные настройки доступа, если вы включали интеграцию с S3 или базой — тогда бэкап всё же стоит держать в защищённом месте. Общие практики про надёжные бэкапы на сервере разобраны в материале про BorgBackup на Ubuntu 24.04, если хотите версионирование и дедупликацию вместо простого tar.

Защита от брутфорса и злоупотреблений

PrivateBin не имеет системы аккаунтов — это его фича, но и слабое место: нет встроенного разграничения, кто и что может публиковать. Практические меры:

  • Fail2Ban на Nginx-логи, если вы хотите банить IP за агрессивное сканирование или попытки перебора паролей на вставках через прямые запросы к API. Настройка правил разобрана в статье Fail2Ban для Nginx: настройка правил, а базовая установка — в Fail2Ban на Ubuntu 24.04.
  • UFW для ограничения доступа к серверу в целом — оставить открытыми только 80/443/22, остальное закрыть. См. настройку UFW на Ubuntu 24.04.
  • Basic Auth перед прокси, если сервис не публичный, а для узкого круга людей — самый простой способ отсечь ботов и сканеры ещё до того, как запрос дойдёт до PrivateBin:
location / {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://127.0.0.1:8080;
    # ... остальные proxy_set_header как выше
}

Учтите: Basic Auth добавляет ещё один слой доступа поверх шифрования содержимого, но сам по себе не заменяет TLS и не защищает содержимое вставок — это разные уровни модели угроз, и путать их не стоит.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли восстановить содержимое вставки, если потеряна ссылка с ключом?

Нет, и это принципиально: ключ шифрования не хранится на сервере ни в каком виде, только в фрагменте URL у того, кто открывал ссылку. Потеря ссылки с #... равносильна потере данных.

PrivateBin можно использовать вместо облачных пастбинов для рабочих секретов?

Да, это одно из основных применений — временная передача паролей, токенов, конфигов с опцией «сгорает после прочтения». Для регулярной командной работы с секретами всё же присмотритесь к специализированным решениям (Vault, secrets-менеджеры), но для разовой передачи PrivateBin избыточен по сложности в хорошем смысле — прост и достаточен.

Нужна ли база данных для PrivateBin?

Нет, по умолчанию используется файловое хранилище, и для большинства сценариев его достаточно. БД (MySQL/PostgreSQL/SQLite) имеет смысл подключать, если вставок очень много и нужна эффективная выборка или запуск нескольких инстансов PrivateBin с общим хранилищем.

Что будет, если сервер взломают — можно ли прочитать старые вставки?

Не имея ключей, которые никогда не отправлялись на сервер — нет, если только сама реализация WebCrypto на клиенте не была скомпрометирована заранее (например, подменённым JS-файлом). Именно поэтому важно держать сам PrivateBin в актуальной версии и следить за целостностью статики.

Как перенести PrivateBin на другой сервер?

Достаточно скопировать директории data и config, поднять тот же docker-compose на новом сервере и перевести DNS — ключи шифрования данных от переноса не зависят, они не хранятся на сервере вовсе.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →