|
|
|
@ -0,0 +1,450 @@
|
|
|
|
|
# Защита хоста Docker
|
|
|
|
|
|
|
|
|
|
Первая категория охватывает все, что вы можете сделать для защиты вашего хоста докеров.
|
|
|
|
|
|
|
|
|
|
## 1. Поддерживайте актуальность Docker Host
|
|
|
|
|
|
|
|
|
|
Здесь действительно не нужно никаких объяснений. Это самая простая из лучших практик безопасности Docker, и она буквально занимает секунды.
|
|
|
|
|
|
|
|
|
|
Держите свою хост-систему Docker в курсе обновлений безопасности. В моем стеке Docker Traefik на базе Linux я часто обновляю пакеты и обновляю систему, используя следующие команды:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
sudo apt-get update
|
|
|
|
|
sudo apt-get upgrade
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 2. Используйте обратный прокси
|
|
|
|
|
|
|
|
|
|
Лучший способ — не открывать какие-либо порты для Интернета, а вместо этого использовать VPN в вашей частной сети и получать локальный доступ к приложениям. Но это слишком громоздко, и размещение приложений за обратным прокси-сервером — удобная, но худшая альтернатива.
|
|
|
|
|
|
|
|
|
|
Вам нужно будет настроить переадресацию портов на вашем интернет-шлюзе, чтобы перенаправить определенные порты на хост Docker.
|
|
|
|
|
|
|
|
|
|
Я настоятельно рекомендую не выставлять все приложения Docker в Интернет. Вместо этого поместите их за обратным прокси. Я использую Traefik и выставляю в Интернет только порты **80** и **443**. Даже приборная панель traefik, использующая порт **8080**, находится за обратным прокси-сервером.
|
|
|
|
|
|
|
|
|
|
# Защита Докера
|
|
|
|
|
|
|
|
|
|
Следующая большая категория: Docker. Давайте рассмотрим, как я считаю, контрольный список безопасности Docker , чтобы убедиться, что ваша установка защищена.
|
|
|
|
|
|
|
|
|
|
## 3. Не меняйте владельца сокета Docker
|
|
|
|
|
|
|
|
|
|
Не связывайтесь с владением Docker Socket (`/var/run/docker.sock` в Linux). По умолчанию сокет принадлежит пользователю **root** и группе **docker** .
|
|
|
|
|
|
|
|
|
|
Для удобства я рекомендовал добавить себя (ваше имя пользователя) в группу докеров в прошлом.
|
|
|
|
|
|
|
|
|
|
Преимущество заключается в том, что вы можете запускать команды docker без использования sudo. Но это угроза безопасности. Я отошел от него и не рекомендую.
|
|
|
|
|
|
|
|
|
|
## 4. Не запускайте контейнеры Docker от имени root
|
|
|
|
|
|
|
|
|
|
По умолчанию контейнеры запускаются от имени пользователя root внутри контейнера, что дает привилегии root. Это угроза безопасности.
|
|
|
|
|
|
|
|
|
|
Одна из лучших практик безопасности Docker — запускать контейнер от имени пользователя без полномочий root (UID не 0). Известные и надежные образы используют эту передовую практику безопасности при создании образов. Например, LinuxServer.io предоставляет образы докеров для нескольких приложений домашнего сервера. Их образы позволяют явно указать UID и GID в качестве переменных окружения.
|
|
|
|
|
|
|
|
|
|
В идеале, это должно выглядеть так, как показано в блоке кода ниже.
|
|
|
|
|
```yaml
|
|
|
|
|
environment:
|
|
|
|
|
- PUID=$PUID
|
|
|
|
|
- PGID=$PGID
|
|
|
|
|
```
|
|
|
|
|
## 5. Осторожно используйте привилегированный режим
|
|
|
|
|
|
|
|
|
|
По умолчанию контейнеры Docker работают в «непривилегированном» режиме. Это означает, что эти контейнеры не могут запускать демон Docker внутри себя. Это также запрещает использование хост-устройств или определенных функций ядра.
|
|
|
|
|
|
|
|
|
|
Обычно это делается путем добавления следующей строки в services:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
privileged: true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Для некоторых служб требуется привилегированный режим. Например, только четыре службы в моем файле компоновки Docker используют привилегированный режим:
|
|
|
|
|
|
|
|
|
|
1. Home Assistant — для доступа к USB-контроллеру Z-wave.
|
|
|
|
|
2. Socket Proxy — требование для Socket proxy, повышающее безопасность.
|
|
|
|
|
3. Glances – для мониторинга системы
|
|
|
|
|
4. APCUPSD — для связи демона ИБП APC с ИБП через USB.
|
|
|
|
|
|
|
|
|
|
В таких ситуациях используйте образы докеров только из надежных источников (подробнее об этом позже). Еще лучший подход — использовать возможности докеров .
|
|
|
|
|
|
|
|
|
|
Кроме того, добавление следующей строки гарантирует, что контейнеры не получат дополнительных привилегий:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
security_opt:
|
|
|
|
|
- no-new-privileges:true
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 6. Используйте доверенные образы Docker
|
|
|
|
|
|
|
|
|
|
По возможности всегда используйте изображения от проверенных издателей или официальных источников.
|
|
|
|
|
|
|
|
|
|
Это дает немедленное доверие и обеспечивает безопасность контейнера Docker.
|
|
|
|
|
|
|
|
|
|
С непопулярными образами трудно предсказать или предположить, были ли соблюдены/реализованы передовые методы безопасности Docker.
|
|
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
|
К сожалению, для многих приложений для домашних серверов, таких как Sonarr, Radarr и т. д., нет «официальных» или «проверенных» издателей. Поэтому вам придется ориентироваться на популярность изображения (количество загрузок/звезд).
|
|
|
|
|
|
|
|
|
|
## 7. Используйте секреты Docker
|
|
|
|
|
|
|
|
|
|
Указание всей вашей конфиденциальной информации (например, ключей API) в файле `.env`, `/etc/environment` или файле `docker-compose.yml` может представлять угрозу безопасности.
|
|
|
|
|
|
|
|
|
|
Именно поэтому были введены [секреты Docker](https://www.docker.com/blog/docker-secrets-management/): для управления конфиденциальными данными.
|
|
|
|
|
|
|
|
|
|
Реализация секретов Docker для вашего стека — это многоэтапный процесс.
|
|
|
|
|
|
|
|
|
|
### А. Создать папку секретов
|
|
|
|
|
|
|
|
|
|
Сначала создайте папку secrets внутри корневой папки docker .
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
sudo mkdir secrets
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Установите для этой папки права доступа 600 , принадлежащие пользователю root и группе root .
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
sudo chown root:root ~/docker/secrets
|
|
|
|
|
sudo chmod 600 ~/docker/secrets
|
|
|
|
|
```
|
|
|
|
|
Это делает эту папку доступной только для пользователя *root*, добавляя уровень безопасности при доступе к конфиденциальной информации.
|
|
|
|
|
|
|
|
|
|
### B. Создайте секретные файлы
|
|
|
|
|
|
|
|
|
|
Затем вам нужно будет поместить вашу конфиденциальную информацию в файл. В качестве примера давайте определим секрет для электронной почты учетной записи Cloudflare.
|
|
|
|
|
|
|
|
|
|
Давайте создадим файл внутри папки секретов с именем **cloudflare_email** . Помните, что для создания файла вам потребуются root-права. В моей системе Ubuntu я использую:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
sudo su
|
|
|
|
|
nano cloudflare_email
|
|
|
|
|
```
|
|
|
|
|
Вы можете использовать любой другой текстовый редактор.
|
|
|
|
|
|
|
|
|
|
Единственное, что нужно добавить в файл, — это адрес электронной почты вашей учетной записи Cloudflare.
|
|
|
|
|
|
|
|
|
|
Сохранить и выйти.
|
|
|
|
|
|
|
|
|
|
### C. Определите секреты в файле Docker Compose
|
|
|
|
|
|
|
|
|
|
Теперь, когда секрет Docker создан, давайте определим его в файле компоновки Docker. Делается это с помощью блока: secrets.
|
|
|
|
|
|
|
|
|
|
В приведенном ниже примере показаны два секрета: `cloudflare_email` и `cloudflare_api_key`.
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
########################### SECRETS
|
|
|
|
|
|
|
|
|
|
secrets:
|
|
|
|
|
cloudflare_email:
|
|
|
|
|
file: $SECRETSDIR/cloudflare_email
|
|
|
|
|
cloudflare_api_key:
|
|
|
|
|
file: $SECRETSDIR/cloudflare_api_key
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`$SECRETSDIR` — это переменная окружения, содержащая путь к папке секретов Docker.
|
|
|
|
|
|
|
|
|
|
### D. Используйте секреты в службах Docker
|
|
|
|
|
|
|
|
|
|
После глобального определения мы можем использовать секреты в сниппетах docker-compose для отдельных сервисов. Поскольку мы добавили данные учетной записи Cloudflare в качестве секретов Docker, давайте посмотрим, как их использовать во фрагменте кода docker-compose для Traefik.
|
|
|
|
|
|
|
|
|
|
Во-первых, мы должны сделать секреты доступными внутри контейнера Traefik. Для этого вам нужно добавить следующий блок в сниппет docker-compose для Traefik:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
secrets:
|
|
|
|
|
- cloudflare_email
|
|
|
|
|
- cloudflare_api_key
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Это делает секретный файл доступным в папке `/run/secrets` внутри контейнера.
|
|
|
|
|
|
|
|
|
|
Затем мы можем установить переменные среды для чтения конфиденциальных данных из этих секретных файлов с помощью блока `environment:` как показано ниже:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
environment:
|
|
|
|
|
- CF_API_EMAIL_FILE=/run/secrets/cloudflare_email
|
|
|
|
|
- CF_API_KEY_FILE=/run/secrets/cloudflare_api_key
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Обратите внимание, что к переменным окружения теперь добавляется **_FILE** в конце. Не пропустите это, иначе это не сработает.
|
|
|
|
|
|
|
|
|
|
Сохраните и заново создайте службу и проверьте журналы на наличие ошибок. Если контейнер не сможет правильно прочитать секреты, вы увидите это как ошибку в журналах.
|
|
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
|
Чтобы секреты Docker работали правильно, базовый образ контейнера должен их поддерживать. Если образ имеет репутацию/надежный образ, очень высока вероятность того, что разработчики внедрили передовые методы обеспечения безопасности Docker , включая секреты Docker.
|
|
|
|
|
|
|
|
|
|
## 8. Используйте прокси-сервер Docker Socket
|
|
|
|
|
|
|
|
|
|
Каждый раз, когда вы предоставляете сокет Docker службе, вы упрощаете для контейнера получение root-доступа в хост-системе.
|
|
|
|
|
|
|
|
|
|
Но некоторым приложениям требуется доступ к сокету Docker и API (например, Traefik, Glances, Dozzle, Watchtower и т. д.).
|
|
|
|
|
|
|
|
|
|
Если Traefik будет скомпрометирован, ваша хост-система может быть скомпрометирована. Собственная документация Traefik перечисляет использование Socket Proxy в качестве решения.
|
|
|
|
|
|
|
|
|
|
Прокси-сервер сокета похож на брандмауэр для сокета/API докера. Вы можете разрешить или запретить доступ к определенному API.
|
|
|
|
|
|
|
|
|
|
Я начал с [Socket Proxy от Tecnativa](https://hub.docker.com/r/tecnativa/docker-socket-proxy), но недавно перешел на [Socket Proxy от FluenceLab](https://hub.docker.com/r/fluencelabs/docker-socket-proxy), так как он обеспечивает более детальный контроль .
|
|
|
|
|
|
|
|
|
|
Добавьте сеть в свой файл compose (игнорируйте первую строку, если у вас уже есть блок network:):
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
networks:
|
|
|
|
|
socket_proxy:
|
|
|
|
|
name: socket_proxy
|
|
|
|
|
driver: bridge
|
|
|
|
|
ipam:
|
|
|
|
|
config:
|
|
|
|
|
- subnet: 192.168.91.0/24
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
И, наконец, вот фрагмент кода docker-compose для добавления прокси-сервера сокета для повышения безопасности докера:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
# Docker Socket Proxy - Security Enchanced Proxy for Docker Socket
|
|
|
|
|
socket-proxy:
|
|
|
|
|
container_name: socket-proxy
|
|
|
|
|
image: tecnativa/docker-socket-proxy
|
|
|
|
|
restart: always
|
|
|
|
|
networks:
|
|
|
|
|
socket_proxy:
|
|
|
|
|
ipv4_address: 192.168.91.254 # You can specify a static IP
|
|
|
|
|
# privileged: true # true for VM. False for unprivileged LXC container.
|
|
|
|
|
ports:
|
|
|
|
|
- "127.0.0.1:2375:2375" # Port 2375 should only ever get exposed to the internal network. When possible use this line.
|
|
|
|
|
# I use the next line instead, as I want portainer to manage multiple docker endpoints within my home network.
|
|
|
|
|
# - "2375:2375"
|
|
|
|
|
volumes:
|
|
|
|
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
|
|
|
|
environment:
|
|
|
|
|
- LOG_LEVEL=info # debug,info,notice,warning,err,crit,alert,emerg
|
|
|
|
|
## Variables match the URL prefix (i.e. AUTH blocks access to /auth/* parts of the API, etc.).
|
|
|
|
|
# 0 to revoke access.
|
|
|
|
|
# 1 to grant access.
|
|
|
|
|
## Granted by Default
|
|
|
|
|
- EVENTS=1
|
|
|
|
|
- PING=1
|
|
|
|
|
- VERSION=1
|
|
|
|
|
## Revoked by Default
|
|
|
|
|
# Security critical
|
|
|
|
|
- AUTH=0
|
|
|
|
|
- SECRETS=0
|
|
|
|
|
- POST=1 # Watchtower
|
|
|
|
|
# Not always needed
|
|
|
|
|
- BUILD=0
|
|
|
|
|
- COMMIT=0
|
|
|
|
|
- CONFIGS=0
|
|
|
|
|
- CONTAINERS=1 # Traefik, portainer, etc.
|
|
|
|
|
- DISTRIBUTION=0
|
|
|
|
|
- EXEC=0
|
|
|
|
|
- IMAGES=1 # Portainer
|
|
|
|
|
- INFO=1 # Portainer
|
|
|
|
|
- NETWORKS=1 # Portainer
|
|
|
|
|
- NODES=0
|
|
|
|
|
- PLUGINS=0
|
|
|
|
|
- SERVICES=1 # Portainer
|
|
|
|
|
- SESSION=0
|
|
|
|
|
- SWARM=0
|
|
|
|
|
- SYSTEM=0
|
|
|
|
|
- TASKS=1 # Portainer
|
|
|
|
|
- VOLUMES=1 # Portainer
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!!! warning "Внимание"
|
|
|
|
|
никогда не открывайте порт 2375 для доступа в Интернет. Вас взломают/ Это еще более важно для виртуальных частных серверов, которые обычно предоставляют доступ ко всем портам. Включите брандмауэр, чтобы разрешить только порты 80 и 443 (и заблокировать остальные) для прохождения на ваш сервер, а также реализовать обходной путь Docker IP Tables, описанный далее в этом руководстве.
|
|
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
|
Кроме того, порт `2375` должен быть открыт только для внутренней сети (*127.0.0.1:2375*).
|
|
|
|
|
|
|
|
|
|
В блоке **environment:** указываем раздел Docker API, который хотим открыть или закрыть. Я добавил комментарии, чтобы описать, какие службы требуют каких разделов API. Например, если вы не используете WatchTower, вы можете ввести **0** для нескольких разделов API.
|
|
|
|
|
|
|
|
|
|
После запуска контейнера прокси-сервера Socket вы можете заменить прямой доступ к сокету Docker прокси-сервером Socket для всех служб, которые в нем нуждаются. Это можно сделать несколькими способами, в зависимости от того, как это поддерживает образ контейнера.
|
|
|
|
|
|
|
|
|
|
Для Traefik замените следующий аргумент CLI (если вы используете аргументы CLI вместо статических конфигураций):
|
|
|
|
|
|
|
|
|
|
`- --providers.docker.endpoint=unix:///var/run/docker.sock`
|
|
|
|
|
|
|
|
|
|
на
|
|
|
|
|
|
|
|
|
|
`- --providers.docker.endpoint=tcp://socket-proxy:2375`
|
|
|
|
|
|
|
|
|
|
Для других служб вы можете удалить указание Docker Socket в качестве тома (следующая строка под томами: ):
|
|
|
|
|
|
|
|
|
|
`- /var/run/docker.sock:/var/run/docker.sock:ro`
|
|
|
|
|
|
|
|
|
|
и добавьте переменную окружения DOCKER_HOST , как показано ниже:
|
|
|
|
|
|
|
|
|
|
`DOCKER_HOST: tcp://socket-proxy:2375`
|
|
|
|
|
|
|
|
|
|
Это то, что я делаю для Portainer и WatchTower.
|
|
|
|
|
|
|
|
|
|
Воссоздайте свой стек, и ваши службы должны использовать защищенный прокси-сервер сокета Docker вместо сокета Docker.
|
|
|
|
|
|
|
|
|
|
## 9. Измените DOCKER_OPTS на Respect IP Table Firewall
|
|
|
|
|
|
|
|
|
|
Случайно наткнулся на эту тему. Я включил UFW, как всегда делаю на своем VPS Digital Ocean, и заблокировал все, кроме 80 и 443. Я непреднамеренно попытался получить доступ к одной из служб, используя номер порта, и был шокирован тем, что я был подключен.
|
|
|
|
|
|
|
|
|
|
Покопавшись дальше, я наткнулся на этот открытый вопрос на GitHub . Почему это было открыто больше года, несмотря на огромное количество людей, запрашивающих исправление, мне не понятно.
|
|
|
|
|
|
|
|
|
|
Поэтому, если у вас включен прокси-сервер сокета и включен брандмауэр, из-за недостатка безопасности в докере хакеры все равно могут взломать вашу систему, используя порт прокси-сервера сокета (2375).
|
|
|
|
|
|
|
|
|
|
К счастью, есть обходной путь. В системах на базе Ubuntu/Debian отредактируйте **/etc/default/docker** и добавьте следующую строку:
|
|
|
|
|
|
|
|
|
|
`DOCKER_OPTS="--iptables=false"`
|
|
|
|
|
|
|
|
|
|
Сохраните файл и перезапустите службу Docker.
|
|
|
|
|
|
|
|
|
|
Попробуйте подтвердить исправление, обратившись к одной из ваших служб с помощью WAN-IP:PORT.
|
|
|
|
|
|
|
|
|
|
## 10. Контролируйте использование ресурсов Docker
|
|
|
|
|
|
|
|
|
|
Мне понравилось, что я могу устанавливать ресурсы для сервисов Docker. К сожалению, это возможно только с [Docker-Compose версии 2](https://docs.docker.com/compose/compose-file/compose-file-v2/#cpu-and-other-resources) или режимом Docker Swarm.
|
|
|
|
|
|
|
|
|
|
Если вы используете любой из них, вы можете установить [ограничения ресурсов для служб Docker](https://docs.docker.com/config/containers/resource_constraints/) .
|
|
|
|
|
|
|
|
|
|
Вот пример docker-compose для установки ограничений ресурсов в режиме Docker Swarm:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
deploy:
|
|
|
|
|
resources:
|
|
|
|
|
limits:
|
|
|
|
|
cpus: '0.50'
|
|
|
|
|
memory: 50M
|
|
|
|
|
reservations:
|
|
|
|
|
cpus: '0.25'
|
|
|
|
|
memory: 20M
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Установив ограничения ресурсов, вы можете ограничить любую службу, которая становится мошеннической и потребляет ваши системные ресурсы.
|
|
|
|
|
|
|
|
|
|
**Защита приложений Docker с помощью Traefik**
|
|
|
|
|
|
|
|
|
|
Есть вещи, которые можно сделать на стороне Traefik, чтобы защитить ваш стек от вредоносных атак. Давайте рассмотрим некоторые меры безопасности Traefik, которые можно реализовать.
|
|
|
|
|
|
|
|
|
|
## 11. Ограничение скорости
|
|
|
|
|
|
|
|
|
|
Ограничение скорости довольно распространено для смягчения атак методом грубой силы или отказа в обслуживании. В моем стеке Traefik Docker есть промежуточное ПО для определения ограничения скорости .
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
middlewares-rate-limit:
|
|
|
|
|
rateLimit:
|
|
|
|
|
average: 100
|
|
|
|
|
burst: 50
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Приведенный выше общий набор чисел отлично работает для меня. Его можно настроить в соответствии с вашей ситуацией, используя документацию Traefik по ограничению скорости .
|
|
|
|
|
|
|
|
|
|
## 12. Заголовки безопасности Traefik
|
|
|
|
|
|
|
|
|
|
Заголовки безопасности — это основные требования к безопасности веб-сайта. Они защищают от различных атак, включая XSS, кликджекинг, внедрение кода и многое другое.
|
|
|
|
|
|
|
|
|
|
Вот заголовки безопасности Traefik, которые я определил как промежуточное ПО:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
middlewares-secure-headers:
|
|
|
|
|
headers:
|
|
|
|
|
accessControlAllowMethods:
|
|
|
|
|
- GET
|
|
|
|
|
- OPTIONS
|
|
|
|
|
- PUT
|
|
|
|
|
accessControlMaxAge: 100
|
|
|
|
|
hostsProxyHeaders:
|
|
|
|
|
- "X-Forwarded-Host"
|
|
|
|
|
sslRedirect: true
|
|
|
|
|
stsSeconds: 63072000
|
|
|
|
|
stsIncludeSubdomains: true
|
|
|
|
|
stsPreload: true
|
|
|
|
|
forceSTSHeader: true
|
|
|
|
|
# frameDeny: true #overwritten by customFrameOptionsValue
|
|
|
|
|
customFrameOptionsValue: "allow-from https:example.com" #CSP takes care of this but may be needed for organizr.
|
|
|
|
|
contentTypeNosniff: true
|
|
|
|
|
browserXssFilter: true
|
|
|
|
|
# sslForceHost: true # add sslHost to all of the services
|
|
|
|
|
# sslHost: "example.com"
|
|
|
|
|
referrerPolicy: "same-origin"
|
|
|
|
|
# Setting contentSecurityPolicy is more secure but it can break things. Proper auth will reduce the risk.
|
|
|
|
|
# the below line also breaks some apps due to 'none' - sonarr, radarr, etc.
|
|
|
|
|
# contentSecurityPolicy: "frame-ancestors '*.example.com:*';object-src 'none';script-src 'none';"
|
|
|
|
|
featurePolicy: "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
|
|
|
|
|
customResponseHeaders:
|
|
|
|
|
X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex,"
|
|
|
|
|
server: ""
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
В Traefik была ошибка, из-за которой нельзя было определить заголовки безопасности как в динамической, так и в статической конфигурации. Это с тех пор было закрыто.
|
|
|
|
|
|
|
|
|
|
Так что теперь можно добавить **sslForceHost** и **sslHost** к отдельным службам, если хотите, для дополнительной безопасности.
|
|
|
|
|
|
|
|
|
|
## 13. Параметры TLS
|
|
|
|
|
|
|
|
|
|
Параметры TLS позволяют настраивать соединения TLS для защиты соединения между клиентом и вашей службой. Дополнительные пояснения можно найти в [документации TLS от Traefik](https://doc.traefik.io/traefik/https/tls/).
|
|
|
|
|
|
|
|
|
|
В моей настройке я определил следующие параметры TLS для Traefik:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
tls:
|
|
|
|
|
options:
|
|
|
|
|
default:
|
|
|
|
|
minVersion: VersionTLS12
|
|
|
|
|
sniStrict: true
|
|
|
|
|
cipherSuites:
|
|
|
|
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
|
|
|
|
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
|
|
|
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
|
|
|
|
|
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|
|
|
|
|
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
|
|
|
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
|
|
|
|
- TLS_AES_128_GCM_SHA256
|
|
|
|
|
- TLS_AES_256_GCM_SHA384
|
|
|
|
|
- TLS_CHACHA20_POLY1305_SHA256
|
|
|
|
|
curvePreferences:
|
|
|
|
|
- CurveP521
|
|
|
|
|
- CurveP384
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 14. Многофакторная аутентификация
|
|
|
|
|
|
|
|
|
|
Это становится все более и более очевидным / обязательным. Если вы еще не защитили свои приложения Docker с помощью многофакторной аутентификации, сделайте это прямо сейчас. Я тестировал и использовал три системы аутентификации: Google OAuth, Authelia и Keycloak.
|
|
|
|
|
|
|
|
|
|
## 15. Защитите контейнеры Docker с помощью Cloudflare
|
|
|
|
|
|
|
|
|
|
Вот краткое изложение ключевых настроек Cloudflare для повышения безопасности контейнеров Docker при подключении к Интернету.
|
|
|
|
|
|
|
|
|
|
- **Cloudflare Proxy** — позволяет использовать улучшения безопасности и производительности Cloudflare.
|
|
|
|
|
- **Режим SSL** — полный или строгий. Это шифрует соединение между исходным сервером и Cloudflare и между Cloudflare и клиентом.
|
|
|
|
|
- **Пограничные сертификаты**:
|
|
|
|
|
- **Всегда использовать HTTPS**: ВКЛ.
|
|
|
|
|
- **HTTP Strict Transport Security (HSTS)**: Включить (будьте осторожны)
|
|
|
|
|
- **Минимальная версия TLS**: 1.2
|
|
|
|
|
- **Оппортунистическое шифрование**: ВКЛ.
|
|
|
|
|
- **TLS 1.3**: ВКЛ.
|
|
|
|
|
- **Автоматическая перезапись HTTPS**: ВКЛ.
|
|
|
|
|
- **Мониторинг прозрачности сертификата**: ВКЛ.
|
|
|
|
|
- Правила брандмауэра. Создайте правила для разрешения или запрета определенного трафика (например, я разрешаю трафик только из РФ в мои частные приложения, так как я получаю к нему доступ только из РФ).
|
|
|
|
|
- **Настройки брандмауэра**:
|
|
|
|
|
- **Уровень безопасности**: Высокий
|
|
|
|
|
- **Режим боя с ботом**: ВКЛ.
|
|
|
|
|
- **Прохождение испытания**: 30 минут
|
|
|
|
|
- **Проверка целостности браузера**: ВКЛ.
|
|
|
|
|
|
|
|
|
|
Это настройки Cloudflare, связанные с безопасностью Docker.
|
|
|
|
|
|
|
|
|
|
**Другие улучшения безопасности для стека Docker Traefik**
|
|
|
|
|
|
|
|
|
|
Все вышеперечисленные рекомендации по безопасности докеров — это то, что я реализовал до сих пор. Но есть и другие, и я настоятельно рекомендую изучить следующее для дополнительной безопасности.
|
|
|
|
|
|
|
|
|
|
## 16. Fail2ban
|
|
|
|
|
|
|
|
|
|
Fail2ban сканирует ваши лог-файлы и блокирует IP-адреса, которые показывают злонамеренные намерения (например, поиск эксплойтов, неудачных паролей и т. д.). При обнаружении подозрительной активности он обновляет правила брандмауэра, чтобы заблокировать IP-адрес на указанный период времени.
|
|
|
|
|
|
|
|
|
|
## 17. Безопасность Docker Bench
|
|
|
|
|
|
|
|
|
|
Docker Bench for Security — это скрипт, который проверяет десятки распространенных передовых методов развертывания контейнеров Docker в рабочей среде .
|
|
|
|
|
|
|
|
|
|
## 18. RBAC
|
|
|
|
|
|
|
|
|
|
RBAC — это управление доступом на основе ролей. Если вы представляете предприятие или имеете несколько пользователей, это обязательно. Это может быть довольно дорого реализовать, но [portainer делает это очень простым](https://www.funkypenguin.co.nz/note/docker-rbac-with-portainer/) (поскольку кулинарная книга FunkyPenguin потрясающая … проверьте ее, если вы этого не сделали) за символическую плату.
|
|
|
|
|
|
|
|
|
|
## 19. Сканер уязвимостей контейнеров
|
|
|
|
|
|
|
|
|
|
Последним в списке лучших практик для безопасности докеров является сканер уязвимостей. Здесь есть несколько примеров, но я перечислю только один: Clair.
|
|
|
|
|
|
|
|
|
|
Clair — проект с открытым исходным кодом для статического анализа уязвимостей в контейнерах приложений.
|
|
|
|
|
|
|
|
|
|
Он использует Clair API для индексации образов контейнеров, а затем сопоставляет их с известными уязвимостями безопасности Docker.
|