Безопасная передача файлов с помощью Nginx
Приветствую!

Пример настройки Nginx для передачи конкретного файла по https с базовой авторизацией по логину и паролю.

Предисловие

Недавно я решал одну задачку: требовалось передавать файлы, собранные с множества серверов из закрытого контура на внешний сервер для дальнейшей обработки👨‍💻.

Доступ из внутренней сети во внешнюю отсутствовал. Из внешней сети доступ к закрытому контуру был возможен только к одному из серверов по порту 443/tcp, где работал Nginx, обслуживающий прикладные сервисы. Протоколы SSH и FTP были недоступны, а остальные TCP-порты также были закрыты сетевым экраном🤷‍♂️.

При этом хосты внутри закрытого контура были доступны друг для друга по SSH.

Соответственно, с сервера, на котором работал Nginx, я организовал сбор необходимых файлов со всех остальных серверов. Настроить всё нужно было без прерывания работы прикладных сервисов🙄.

Поэтому… в конфигурацию Nginx был добавлен отдельный виртуальный хост с использованием самоподписанных сертификатов (хотя можно и обычные, если есть😑). Также был настроен доступ с авторизацией к конкретному файлу-архиву в файловой системе сервера по заранее определенному URL.

Таким образом удалось организовать безопасную доставку необходимых данных в ограниченных условиях.

О том, как именно я настраивал Nginx для решения такой задачи, мы сегодня и поговорим в этом небольшом HowTo.

Вводные данные

KeyValue
Система с NginxDebian 13
Клиентская машинаLMDE7
Виртуальный хостarchive.r4ven.me
Пользователь HTTP basic authivan
Пароль HTTP basic authsecretpassword

Создание тестового файла-архива

Создаём тестовую директорию и архив с данными, например с файлами в /etc/profile.d/:

BASH
sudo mkdir -vp /opt/data

sudo tar -v -c -z -f /opt/data/archive.tgz /etc/profile.d/
Нажмите, чтобы развернуть и увидеть больше

Создание файла с пользователями

На целевом сервере, откуда нужно забирать архив с файлами, создаём пользователя для HTTP basic auth:

BASH
sudo bash -c 'echo -n "ivan:" >> /etc/nginx/.htpasswd'

sudo bash -c 'openssl passwd -apr1 >> /etc/nginx/.htpasswd'

sudo chmod 600 /etc/nginx/.htpasswd

sudo chown www-data /etc/nginx/.htpasswd
Нажмите, чтобы развернуть и увидеть больше

Создание самоподписанных сертификатов для домена

Генерируем самоподписанный сертификат сроком действия 20 лет🙈:

BASH
sudo mkdir -vp /etc/nginx/ssl

sudo openssl req -x509 -nodes -days 7300 \
    -newkey rsa:4096 \
    -keyout /etc/nginx/ssl/archive.r4ven.me.key \
    -out /etc/nginx/ssl/archive.r4ven.me.crt \
    -subj "/C=RU/ST=Moscow/L=Moscow/O=IVAN/OU=TEST/CN=archive.r4ven.me"
Нажмите, чтобы развернуть и увидеть больше

Правка конфига

Добавляем дополнительный конфиг archive.conf Nginx в conf.d:

BASH
sudo nvim /etc/nginx/conf.d/archive.conf
Нажмите, чтобы развернуть и увидеть больше
BASH
server {
    listen                     443 ssl;
    server_name                archive.r4ven.me;
    ssl_certificate            /etc/nginx/ssl/archive.r4ven.me.crt;
    ssl_certificate_key        /etc/nginx/ssl/archive.r4ven.me.key;

    location /archive-file-url {
        auth_basic             "Secure Files Area";
        auth_basic_user_file   /etc/nginx/.htpasswd;
        alias                  /opt/data/archive.tgz;
    }
}
Нажмите, чтобы развернуть и увидеть больше

Где в параметре alias указывается путь к нужному файлу. В данном примере /opt/data/archive.tgz.

Проверяем и перечитываем конфигурацию:

BASH
sudo nginx -t

sudo nginx -s reload

systemctl status nginx
Нажмите, чтобы развернуть и увидеть больше

Проверка доступа с помощью curl

На клиентской машине скачиваем архив с помощью curl и проверяем его:

BASH
mkdir -vp ~/Nginx && cd ~/Nginx

curl -k -u ivan:secretpassword https://archive.r4ven.me/archive-file-url -o result_$(date '+%F').tgz

tar -v -t -f ./result_$(date '+%F').tgz
Нажмите, чтобы развернуть и увидеть больше

Чтобы не светить паролем в командной строке (и её истории) сохраните его, например, в файл .env в текущей директории:

BASH
echo 'ivan:secretpassword' > ./.env

chmod 600 ./.env

curl -k -u $(< ./.env) https://archive.r4ven.me/archive-file-url -o ./result_$(date '+%F').tgz
Нажмите, чтобы развернуть и увидеть больше

(Опционально) Добавление самоподписанного сертификата в список доверенных

При использовании самоподписанных сертификатов полезно будет добавить их публичную часть в хранилище на клиентской машине. А при обращении с помощью того же curl не использовать флаг -k (--insecure). Таким образом можно предотвратить небезопасное взаимодействие в случае компрометации сертификата.

Сохраняем публичный сертификат в файл:

BASH
echo | openssl s_client -connect archive.r4ven.me:443 -servername archive.r4ven.me 2> /dev/null | openssl x509 -outform PEM | tee ./archive.r4ven.me.crt
Нажмите, чтобы развернуть и увидеть больше

Копируем его в хранилище доверенных сертификатов и актуализируем данные:

BASH
sudo cp -v ./archive.r4ven.me.crt /usr/local/share/ca-certificates/archive.r4ven.me.crt

sudo update-ca-certificates
Нажмите, чтобы развернуть и увидеть больше

Проверяем доступ без флага --insecure:

BASH
curl -I -u $(< ./.env) https://archive.r4ven.me/archive-file-url
Нажмите, чтобы развернуть и увидеть больше

Всё работает😌. Теперь можно безопасно скачивать и обрабатывать файлы в своих скриптах📝.

Спасибо, что читаете. Успехов вам!

Авторские права

Автор: Иван Чёрный

Ссылка: https://r4ven.me/web/bezopasnaya-peredacha-faylov-s-pomoshchyu-nginx/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша