Docker Remote API без TLS-а даје практично root приступ — овако се затвара

|Аутор: Уредништво QUASA|6 мин читања
Docker Remote API без TLS-а даје практично root приступ — овако се затвара

Необезбеђен удаљени приступ Docker daemon-у може кориснику дати практично root контролу над хостом. Docker-ово упутство за удаљени приступ упозорава на ту последицу и наводи уобичајене портове: 2375 за везу без TLS-а и 2376 за TLS. Затворите неаутентификовани TCP приступ пре него што се ослоните на нови начин повезивања.

За администраторе који користе Docker CLI изаберите SSH и уклоните TCP слушалац daemon-а. Ако други алат мора директно да позива HTTPS API, укључите међусобни TLS (mTLS), ограничите порт на адресе овлашћених клијената и проверите да захтев без клијентског сертификата не успева. Обе путање захтевају проверу стварног стања на хосту и тест са друге машине.

Утврдите где daemon слуша

На Docker хосту покрените sudo ss -lntp и потражите dockerd и његове TCP адресе. Запис 0.0.0.0:2375 значи да процес слуша на свим IPv4 интерфејсима; проверите и IPv6, јер одвојен слушалац може остати доступан. Локална адреса 127.0.0.1 има другачији домет, али ни она није потребна за удаљени приступ преко SSH-а.

Затим погледајте systemctl cat docker.service, аргументе покренутог процеса dockerd и /etc/docker/daemon.json. Адреса може бити задата у systemd јединици или у конфигурационој датотеци. Ако је опција hosts постављена на оба места, Docker може одбити покретање; пре измене утврдите која конфигурација стварно управља сервисом. Забележите и постојећи начин локалног приступа сокету да га не изгубите при промени покретачке команде.

Провера слушаоца није исто што и провера доступности са интернета. Firewall или мрежа провајдера могу блокирати порт који dockerd слуша, док неочекивано правило може пропустити саобраћај. Зато почетни налаз упоредите са правилима и, ако имате приступ другој мрежи, покушајте да успоставите везу са 2375 са ње.

За Docker CLI користите SSH

Ако удаљени посао обавља Docker CLI, уклоните TCP адресу из конфигурације daemon-а и задржите локални Unix сокет. На клијентској машини направите контекст командом docker context create remote --docker host=ssh://[email protected], па проверите везу командом docker --context remote info. Корисник и име хоста су условни пример који треба заменити стварним вредностима.

SSH налог на удаљеној машини мора имати дозволу за Docker сокет. Та дозвола омогућава управљање daemon-ом, па приступ налогу и његовом SSH кључу дајте само овлашћеним администраторима. Успешан одговор на docker --context remote info потврђује да ова путања ради; после измене на хосту поновите sudo ss -lntp да утврдите да стари TCP слушалац више не постоји. Само прављење SSH контекста не искључује раније отворен порт.

За директан HTTPS API подесите mTLS

Када клијент мора непосредно да користи API, daemon-у су потребни CA сертификат, серверски сертификат и серверски приватни кључ, а овлашћеном клијенту његов сертификат и приватни кључ. Docker-ово упутство за заштиту сокета описује --tlsverify: daemon прихвата сертификате које је потписао поуздани CA, а клијент проверава сервер. Само --tls шифрује везу, али не захтева проверу идентитета клијента.

У серверски сертификат упишите DNS име преко којег ће се клијент повезивати у поље subjectAltName. Ако клијент користи IP адресу, додајте је као IP вредност у исто поље. За серверски сертификат задајте намену serverAuth, а за клијентски clientAuth. Пре инсталације можете прегледати издат сертификат командом openssl x509 -in server-cert.pem -noout -text и проверити име, намену и рок важења; исто урадите за клијентски сертификат.

CA приватни кључ чувајте одвојено од клијентских машина. Клијенту су потребни CA сертификат и његов сопствени сертификат и приватни кључ, а серверу одговарајући серверски кључ. Ограничите читање приватних кључева на налоге који их користе. Поседник важећег клијентског кључа може daemon-у слати привилеговане команде, па га треба чувати као root лозинку.

На Linux хосту са одговарајућом systemd поставком отворите override командом sudo systemctl edit docker.service. У секцији [Service] поништите стару команду редом ExecStart=, а затим задајте ExecStart=/usr/bin/dockerd -H fd:// -H tcp://10.0.0.5:2376 --tlsverify --tlscacert=/etc/docker/tls/ca.pem --tlscert=/etc/docker/tls/server-cert.pem --tlskey=/etc/docker/tls/server-key.pem. Ово је условни пример: приватну адресу, путање и употребу fd:// ускладите са постојећом јединицом и socket активацијом. Потом покрените sudo systemctl daemon-reload и sudo systemctl restart docker.service; ако покретање не успе, проверите журнал сервиса и могући сукоб са hosts у daemon.json.

На клијенту испробајте docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=tcp://docker.example.net:2376 version. Име у адреси мора одговарати серверском сертификату, а сертификат клијента мора потицати од CA коме daemon верује. Успешна команда показује да је проверена веза успостављена, али још не показује ко све може да дође до порта.

Ограничите порт и тестирајте приступ

Docker хост прихвата везу ка TLS порту 2376 само са дозвољене клијентске адресе.

За mTLS вежите daemon за приватну адресу кад год је могуће и дозволите долазни саобраћај на 2376 само са адреса овлашћених клијената. На хосту са активним UFW-ом, условни пример је sudo ufw allow proto tcp from 198.51.100.10 to any port 2376; Ubuntu-ова документација за UFW описује овај облик правила са изворном адресом, протоколом и одредишним портом. Пример адресу замените стварном адресом клијента.

Проверите sudo ufw status verbose: UFW мора бити активан, подразумевана политика или друга правила морају блокирати преостале изворе, а старије широко правило за исти порт не сме остати. Ако UFW тек укључујете преко SSH-а, прво обезбедите правило за постојећи SSH приступ. Проверите и правила провајдерског firewall-а, као и IPv6 ако хост има IPv6 адресу. Порт 2375 не треба оставити отворен ни за једну удаљену мрежу.

Са овлашћене клијентске машине покрените curl --cacert ca.pem --cert cert.pem --key key.pem https://docker.example.net:2376/_ping. Одговор OK показује да клијентски сертификат пролази и да curl верује серверском сертификату за наведено име. Поновите позив без --cert и --key: тај захтев не сме добити успешан API одговор. Поновите и са непоузданим CA сертификатом; провера сервера треба да падне, без опције -k која би је заобишла.

Са мреже која није на листи дозвола проверите да 2376 није доступан, а са спољне мреже да захтев ка 2375 не пролази. На самом хосту sudo ss -lntp треба да покаже само планирану приватну TCP адресу за mTLS, односно да не покаже Docker TCP слушаоца ако сте изабрали SSH. Тиме одвојено проверавате конфигурацију daemon-а, аутентификацију клијента и мрежно ограничење.

Ротирајте клијентске кључеве без прекида приступа

За редовну замену издајте клијенту нов приватни кључ и сертификат, проверите везу новим паром, па уклоните старе копије са машина и из аутоматизације. Бележите коме је који сертификат издат и када истиче, тако да замену можете припремити пре истека. Одвојени кључеви по клијенту олакшавају утврђивање који приступ треба мењати.

Ако је стари кључ компромитован, његово брисање са једне машине не укида поверење daemon-а у сертификат који је потписао исти CA. У једноставној mTLS поставци зато планирајте замену CA и поновно издавање потребних сертификата или механизам ауторизације који може укинути приступ конкретном клијенту. После промене поновите позитиван тест са важећим кључем и негативан тест са старим.

Прочитајте и:

Подели:

Претплатите се на наш билтен

Добијајте најновије вести о Web3, AI-у и криптовалутама директно у пријемно сандуче.

0