SSL и открытые порты в Docker — как защитить соединение?
В случае, когда за SSL сертификаты для докеризированных приложений отвечает внешний веб-сервер (например, Caddy), нужно очень внимательно отнестись к тому, как вы открываете порты в своем docker-compose.
Обычная практика такая:
nginx:
build: ./nginx
ports:
- 8888:80
volumes:
- static_sp2:/code/static
- media_sp2:/code/media
depends_on:
- web
restart: "on-failure"
Но здесь есть серьезная проблема. Ваш nginx теперь доступен не только по адресу localhost или 127.0.0.1, но и всему миру, если у сервера есть публичный адрес.
Мы же выпускаем сертификат с помощью Caddy, значит доступ к сайту будет защищен только если пользователь придет по доменному имени. А что если он забьет ip адрес и добавить в конце порт 8888? Так он получит доступ к сайту без SSL, и может воспользоваться данной возможностью множеством неприятных способов.
Поэтому мы будем создавать контейнеры правильно, мы будем их показывать только приложениям, которые крутятся на нашем сервере:
nginx:
build: ./nginx
ports:
- "127.0.0.1:8888:80"
volumes:
- static_sp2:/code/static
- media_sp2:/code/media
depends_on:
- web
restart: "on-failure"
Обратите внимание, что с появлением локального айпи адреса нам пришлось взять все выражение в кавычки, иначе докер не сможет достойно распарсить данную строку.
Смотрим, что показывает нам nmap:
user@server:~$ nmap 127.0.0.1
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-24 06:42 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00011s latency).
Not shown: 993 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
5000/tcp open upnp
5432/tcp open postgresql
8000/tcp open http-alt
8888/tcp open sun-answerbook
Видим, что внутри порт 888 открыт. Сканируем порты по внешнему доменному имени:
matakov@matacoder:~$ nmap site.ru
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-24 06:44 UTC
Nmap scan report for site.ru (178.154.254.176)
Host is up (0.0011s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
Все, уязвимость ушла, наружу смотрит только SSH, HTTP и HTTPS.