devops/docker/readme_mtls.MD

251 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Настройка Docker с mTLS (mutual TLS)
> **mTLS** (mutual Transport Layer Security) обеспечивает двустороннюю аутентификацию: клиент и сервер проверяют друг друга с помощью сертификатов. Это повышает безопасность при удалённом управлении Docker.
---
### Требования
- ОС: Linux (например, CentOS/RHEL/Fedora)
- Права: `root` или `sudo`
- Установленный `docker`, `openssl`, `dnf` (или `yum`)
---
## Шаг 1: Подготовка директории для TLS-сертификатов
```bash
sudo mkdir -p /etc/docker/tls
cd /etc/docker/tls
```
---
## Шаг 2: Установка OpenSSL (если не установлен)
```bash
sudo dnf install -y openssl
```
---
## Шаг 3: Генерация CA (Certificate Authority)
CA будет подписывать все остальные сертификаты.
```bash
# Генерация закрытого ключа CA (с паролем)
sudo openssl genrsa -aes256 -out ca-key.pem 4096
```
> При выполнении команды будет запрошен **пароль**. Запомните его или сохраните в секрете.
```bash
# Генерация корневого сертификата CA (действует 1 год)
sudo openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
```
> При выполнении `req -new` будет предложено ввести данные (страна, организация и т.д.). Можно заполнить или оставить пустыми, **критичное поле — Common Name (CN)**. Например: `Docker CA`.
---
## Шаг 4: Генерация серверного сертификата (для Docker daemon)
```bash
# Генерация закрытого ключа сервера
sudo openssl genrsa -out server-key.pem 4096
# Создание CSR (Certificate Signing Request)
sudo openssl req -subj "/CN=dev01.tnt.local" -sha256 -new -key server-key.pem -out server.csr
```
> Убедитесь, что `CN` совпадает с DNS-именем или IP-адресом, по которому будут обращаться клиенты.
### Настройка расширений для серверного сертификата
```bash
echo "subjectAltName = DNS:dev01.tnt.local,IP:10.2.24.21,IP:127.0.0.1" | sudo tee extfile.cnf
echo "extendedKeyUsage = serverAuth" | sudo tee -a extfile.cnf
```
> Добавьте все IP и домены, по которым будет доступен Docker.
### Подписываем серверный сертификат с помощью CA
```bash
sudo openssl x509 -req -days 365 -sha256 -in server.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out server-cert.pem -extfile extfile.cnf
```
---
## Шаг 5: Генерация клиентского сертификата
Клиент (например, `docker` CLI с другого хоста) будет использовать эти файлы для аутентификации.
```bash
# Генерация ключа клиента
sudo openssl genrsa -out key.pem 4096
# Создание CSR для клиента
sudo openssl req -subj '/CN=client' -new -key key.pem -out client.csr
```
> Поле `CN=client` может быть любым, но лучше указать имя клиента.
### Расширение для клиентского сертификата
```bash
echo "extendedKeyUsage = clientAuth" | sudo tee extfile-client.cnf
```
### Подписываем клиентский сертификат
```bash
sudo openssl x509 -req -days 365 -sha256 -in client.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out cert.pem -extfile extfile-client.cnf
```
---
## Шаг 6: Очистка временных файлов
```bash
sudo rm -v client.csr server.csr extfile.cnf extfile-client.cnf
```
---
## Шаг 7: Установка прав доступа
```bash
# Закрытые ключи — только для чтения владельцем
sudo chmod 0400 ca-key.pem key.pem server-key.pem
# Сертификаты — чтение для всех
sudo chmod 0444 ca.pem server-cert.pem cert.pem
```
---
## Шаг 8: Настройка Docker демона
Отредактируем службу Docker:
```bash
sudo systemctl stop docker docker.socket
```
> Останавливаем, чтобы изменения вступили в силу.
Откройте файл службы:
```bash
sudo mcedit /lib/systemd/system/docker.service
```
Найдите строку `ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock` и **замените** её на:
```ini
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=/etc/docker/tls/ca.pem --tlscert=/etc/docker/tls/server-cert.pem --tlskey=/etc/docker/tls/server-key.pem -H=0.0.0.0:2376
```
> Важно:
> - `--tlsverify` включает TLS с проверкой клиента.
> - `--tlscacert`, `--tlscert`, `--tlskey` — пути к сертификатам.
> - `-H=fd://` — для работы с `systemd`
> - `-H=tcp://0.0.0.0:2376` — TCP-порт с TLS (стандартный порт для безопасного Docker)
---
## Шаг 9: Перезагрузка конфигурации и запуск Docker
```bash
sudo systemctl daemon-reload
sudo systemctl start docker
sudo systemctl status docker
```
> Убедитесь, что статус `active (running)` и нет ошибок.
---
## Шаг 10: Проверка сертификатов (опционально)
```bash
sudo cat /etc/docker/tls/ca.pem
sudo cat /etc/docker/tls/cert.pem
sudo cat /etc/docker/tls/key.pem
```
> Эти файлы нужно скопировать на клиентскую машину для подключения.
---
## Шаг 11: Клиентская настройка (на другой машине)
Скопируйте на клиент:
- `ca.pem``~/.docker/ca.pem`
- `cert.pem``~/.docker/cert.pem`
- `key.pem``~/.docker/key.pem`
Установите права:
```bash
chmod 0400 ~/.docker/key.pem
chmod 0444 ~/.docker/cert.pem ~/.docker/ca.pem
```
Подключение:
```bash
docker -H tcp://dev01.tnt.local:2376 --tlsverify ps
```
> Или установите переменные окружения:
```bash
export DOCKER_HOST=tcp://dev01.tnt.local:2376
export DOCKER_TLS_VERIFY=1
```
Теперь можно использовать `docker ps` и другие команды.
---
## Безопасность: Рекомендации
1. **Не используйте `--tlsverify` без клиентских сертификатов** — иначе любой, у кого есть сертификат от CA, может подключиться.
2. **Храните `ca-key.pem` в секрете** — он может подписывать новые сертификаты.
3. **Используйте брандмауэр** — открывайте порт `2376` только для доверенных IP.
4. **Обновляйте сертификаты** раз в год.
---
## Проверка подключения
На клиенте:
```bash
docker context create redos8-srv01 --description "redos8-srv01" --docker "host=tcp://dev01.tnt.local:2376,ca=ca.pem,cert=cert.pem,key=key.pem"
DOCKER_CONTEXT=redos8-srv01 docker info
```
Если видите информацию о хосте — mTLS настроен успешно.
---
## Откат
Чтобы вернуть стандартную конфигурацию:
1. Удалите параметры `--tls*` и `-H=tcp://...` из `ExecStart`.
2. Оставьте: `ExecStart=/usr/bin/dockerd -H fd:// ...`
3. Выполните: `systemctl daemon-reload && systemctl restart docker`
---