Docker daemon'ına başka bir makineden güvenli şekilde bağlanmanın iki resmî yolu vardır: SSH ve karşılıklı sertifika doğrulamalı TLS. SSH yönteminde daemon'da hiçbir ağ portu açmazsınız; istemci ssh://kullanici@sunucu adresli bir Docker context ya da DOCKER_HOST değişkeniyle sunucuya SSH üzerinden bağlanır. TLS yönteminde daemon TCP 2376 portunu dinler ve yalnızca sizin oluşturduğunuz CA tarafından imzalanmış istemci sertifikası sunan bağlantıları kabul eder. Kimlik doğrulamasız, şifresiz TCP 2375 erişimi ise belgelere göre önerilmez ve kullanımdan kaldırılmıştır.
Bu yazı Docker Engine'in Unix soketini neden bu kadar dikkatle korumanız gerektiğini, SSH ile bağlantıyı, OpenSSL ile CA, sunucu ve istemci sertifikası üretmeyi, daemon'ı systemd veya daemon.json ile ağdan dinletmeyi, güvenlik duvarı tarafını ve TLS modlarını anlatıyor. Docker context komutlarının kendisi (oluşturma, listeleme, dışa aktarma) docker context ile uzak sunucu yönetimi yazısının konusudur.
Varsayılan durum: yalnızca yerel Unix soketi
Docker daemon varsayılan olarak ağa açık olmayan bir Unix soketinden (/var/run/docker.sock) istek kabul eder. Sokete root kullanıcı ve docker grubunun üyeleri erişebilir. Docker Engine güvenlik sayfası bu tasarımın bir sebebi olduğunu anlatır: CLI ile daemon arasındaki REST API, Docker 0.5.2'de 127.0.0.1 üzerindeki bir TCP soketinden Unix soketine taşındı, çünkü yerel TCP soketi siteler arası istek sahteciliğine (CSRF) açıktı. Unix soketinde ise klasik dosya izinleriyle erişimi sınırlayabilirsiniz.
Daemon'a komut verebilen kişi sunucunun tamamını yönetebilir. Belgelerin verdiği örnek açıktır: bir container'a ana makinenin kök dizinini /host olarak bağlayabilir ve dosya sistemini kısıtlamasız değiştirebilirsiniz. Bu yüzden daemon API'sini ağa açmak, sunucuya root erişimi açmakla aynı ağırlıktadır. Güvenlik sayfası bir adım daha ileri gider: API uç noktasına diğer makinelerden erişimi güvenlik duvarıyla kısıtlasanız bile uç nokta container'lardan erişilebilir kalabilir ve bu kolayca yetki yükseltmeye dönüşebilir. Belgeler bu nedenle API'yi HTTP üzerinden açacaksanız HTTPS ve sertifikayla korumanın zorunlu olduğunu, ayrıca yalnızca güvenilen bir ağdan veya VPN'den erişilebilir tutulmasını önerir.
Yöntem 1: SSH ile bağlanmak
SSH yöntemi en az yapılandırma isteyen yoldur, çünkü sunucuda zaten çalışan SSH servisini kullanır ve daemon'da yeni bir port açmaz. Tek ön koşul, SSH ile bağlandığınız kullanıcının uzak makinedeki Docker soketine erişim yetkisinin olmasıdır. Bu genellikle kullanıcının docker grubunda olması anlamına gelir; bunun root düzeyinde yetki verdiğini unutmayın ve ayrıntılar için sudo olmadan Docker çalıştırma yazısına bakın.
Belgelerdeki örnek, host1.example.com üzerindeki daemon'a docker-user kullanıcısıyla bağlanan bir context oluşturur, ona geçer ve işiniz bitince yerel daemon'a döner:
docker context create \
--docker host=ssh://docker-user@host1.example.com \
--description="Remote engine" \
my-remote-engine
my-remote-engine
Successfully created context "my-remote-engine"
docker context use my-remote-engine
my-remote-engine
Current context is now "my-remote-engine"
docker context use default
default
Current context is now "default"Context oluşturmadan, tek seferlik bir bağlantı için DOCKER_HOST değişkeni de kullanılabilir. Bu değişken o kabukta çalıştırılan tüm docker komutlarını uzak daemon'a yönlendirir:
export DOCKER_HOST=ssh://docker-user@host1.example.com
docker infoHer docker komutu yeni bir SSH bağlantısı açtığı için art arda komutlar yavaşlayabilir. Belgeler aynı SSH bağlantısının birden çok çağrıda yeniden kullanılması için istemci tarafında ~/.ssh/config dosyasına şu ayarların eklenmesini önerir:
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yesGüvenlik sayfası SSH için bir seçenek daha anar: TLS yerine DOCKER_HOST=ssh://USER@HOST ya da ssh -L /path/to/docker.sock:/var/run/docker.sock ile soket yönlendirmesi. İkinci yolda uzak soket yerel bir dosya yoluna bağlanır. SSH anahtarlarıyla parola girişini kapatmak gibi genel sunucu sertleştirme adımları için VPS güvenlik sertleştirme yazısına bakabilirsiniz.
Yöntem 2: TLS ile korunan TCP soketi

Bir CI sistemi veya SSH kullanamayan bir araç daemon'a HTTP üzerinden bağlanacaksa TLS gerekir. tlsverify bayrağı açık ve tlscacert güvenilen bir CA sertifikasını gösterdiğinde daemon yalnızca o CA tarafından imzalanmış sertifikayla gelen istemcileri kabul eder; istemci modunda ise yalnızca o CA'nın imzaladığı sertifikayı sunan sunuculara bağlanır. Belgeler TLS ve CA yönetiminin ileri düzey bir konu olduğunu, üretimde kullanmadan önce OpenSSL, x509 ve TLS konularına aşina olmanızı önerir. Aşağıdaki adımlarda $HOST değerini daemon sunucunuzun DNS adıyla değiştirin.
CA anahtarı ve sertifikası
Önce daemon sunucusunda CA'nın özel ve açık anahtarları üretilir. -aes256 CA anahtarını parolayla korur; sertifika oluştururken sorulan "Common Name" alanına sunucunun adını yazarsınız:
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pemSunucu anahtarı ve imzalı sertifika
Sunucu anahtarı ve sertifika imzalama isteği (CSR) oluşturulur. "CN" değeri Docker'a bağlanırken kullandığınız ana makine adıyla eşleşmelidir. TLS bağlantısı IP adresiyle de kurulabileceği için bağlanacağınız IP adresleri subjectAltName içinde listelenir; anahtarın yalnızca sunucu kimlik doğrulaması için kullanılması da extendedKeyUsage = serverAuth ile belirtilir:
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnfİstemci anahtarı ve sertifikası
İstemci kimlik doğrulaması için ayrı bir anahtar ve CSR oluşturulur, uzantı dosyasında extendedKeyUsage = clientAuth tanımlanır ve aynı CA ile imzalanır. Belgeler kolaylık için bu adımın da daemon sunucusunda yapılabileceğini not eder:
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem -extfile extfile-client.cnfSertifikalar üretildikten sonra CSR ve uzantı dosyaları silinebilir. Varsayılan umask 022 iken özel anahtarlar herkes tarafından okunabilir olduğu için izinleri daraltmak gerekir: anahtarlar yalnızca sahibine okunur (0400), sertifikalar ise yazmaya kapalı (0444) yapılır:
rm -v client.csr server.csr extfile.cnf extfile-client.cnf
chmod -v 0400 ca-key.pem key.pem server-key.pem
chmod -v 0444 ca.pem server-cert.pem cert.pemDaemon'ı ve istemciyi TLS ile çalıştırmak
Daemon yalnızca CA'nızın güvendiği sertifikayı sunan istemcileri kabul edecek şekilde şu bayraklarla başlatılır. İstemci tarafında ise CA sertifikası, istemci sertifikası ve istemci anahtarı verilir. Belgeler TLS üzerinden Docker'ın TCP 2376 portunda çalışması gerektiğini belirtir:
dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=$HOST:2376 versionEngine 29.0.0 sürüm notlarında bu konuyla ilgili iki değişiklik yer alır: istemci yapılandırmasından eski CBC şifre takımları kaldırıldı ve --tlscacert, --tlscert, --tlskey bayraklarında tırnaklı değerlere yönelik özel işleme son verildi. Eski betiklerde bu bayrakların değerlerini ayrıca tırnakla sarıyorsanız 29 sürümüne geçerken kontrol edin.
Daemon'ı kalıcı olarak ağdan dinletmek

Uzak erişimi kalıcı yapmanın iki yolu vardır: systemd kullanan dağıtımlarda docker.service için bir override dosyası, systemd kullanmayanlarda daemon.json içindeki hosts dizisi. Belgeler önemli bir uyarı yapar: dinleme adresini hem systemd birim dosyasında hem de daemon.json içinde tanımlamak bir çakışmaya yol açar ve Docker başlamaz. Yalnızca birini seçin.
systemd yolunda sudo systemctl edit docker.service bir override dosyası açar. Belgelerdeki örnek daemon'ı yalnızca yerel döngü adresinde dinletir; boş ExecStart= satırı, paketin tanımladığı komutu temizleyip yerine yenisini koymak için gereklidir. Uzak istemcilerin bağlanacağı bir kurulumda adresi TLS bayraklarıyla ve 2376 portuyla birlikte kullanmanız gerekir:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375sudo systemctl daemon-reload
sudo systemctl restart docker.service
sudo netstat -lntp | grep dockerd
tcp 0 0 127.0.0.1:2375 0.0.0.0:* LISTEN 3758/dockerdsystemd kullanmayan sistemlerde aynı sonuç /etc/docker/daemon.json içindeki hosts dizisiyle elde edilir; dizi hem Unix soketini hem TCP adresini içerir. Belgeler bu anahtarın Windows ve Mac için Docker Desktop'ta desteklenmediğini belirtir. daemon.json dosyasının genel kuralları için daemon.json yapılandırma yazısına bakabilirsiniz:
{
"hosts": ["unix:///var/run/docker.sock", "tcp://127.0.0.1:2375"]
}Güvenlik duvarı tarafı
Docker ile aynı makinede bir güvenlik duvarı çalışıyorsa ve API'ye başka bir makineden erişilecekse Docker portuna gelen bağlantılara izin vermeniz gerekir. Belgelere göre varsayılan port TLS kullanılıyorsa 2376, değilse 2375'tir. Belgeler Ubuntu'da sık kullanılan ufw ve RPM tabanlı sistemlerde sık kullanılan firewalld için başlangıç notları verir ve bu ayarların izin verici olduğunu, sistemi daha sıkı kilitleyen bir yapılandırma isteyebileceğinizi ekler. Kuralı yalnızca istemcinizin IP adresine veya VPN aralığına açmak bu tavsiyenin doğal uygulamasıdır. UFW'nin kendisi için UFW güvenlik duvarı rehberi, Docker'ın iptables ile etkileşimi için Docker iptables ve UFW yazısına bakabilirsiniz.
İstemcide TLS'i varsayılan yapmak
Her komutta sertifika yollarını yazmamak için istemci dosyalarını ev dizininizdeki ~/.docker klasörüne taşıyıp DOCKER_HOST ve DOCKER_TLS_VERIFY değişkenlerini tanımlayabilirsiniz. İstemci bu klasörde ca.pem, cert.pem ve key.pem dosyalarını bulursa istemci sertifikasını kendiliğinden gönderir. Anahtarları başka bir yerde tutuyorsanız konumu DOCKER_CERT_PATH ile belirtirsiniz:
mkdir -pv ~/.docker
cp -v {ca,cert,key}.pem ~/.docker
export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
docker ps
export DOCKER_CERT_PATH=~/.docker/zone1/
docker --tlsverify psAPI'yi curl ile denemek isterseniz üç ek bayrak gerekir: istemci sertifikası, istemci anahtarı ve CA sertifikası:
curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \
--cacert ~/.docker/ca.pemTLS modları

Tam iki yönlü kimlik doğrulama istemiyorsanız bayrakları karıştırarak farklı modlar elde edebilirsiniz. Belgelerin listelediği modlar şunlardır:
| Taraf | Bayraklar | Davranış |
|---|---|---|
| Daemon | tlsverify, tlscacert, tlscert, tlskey | İstemcileri doğrular |
| Daemon | tls, tlscert, tlskey | İstemcileri doğrulamaz |
| İstemci | tls | Sunucuyu genel veya varsayılan CA havuzuna göre doğrular |
| İstemci | tlsverify, tlscacert | Sunucuyu verilen CA'ya göre doğrular |
| İstemci | tls, tlscert, tlskey | İstemci sertifikasıyla kimlik doğrular, sunucuyu verilen CA'ya göre doğrulamaz |
| İstemci | tlsverify, tlscacert, tlscert, tlskey | İstemci sertifikasıyla kimlik doğrular ve sunucuyu verilen CA'ya göre doğrular |
Sunucu yönetimi için tavsiye edilecek kombinasyon tablonun ilk ve son satırıdır: daemon istemcileri doğrular, istemci de sunucuyu kendi CA'nıza göre doğrular. Daemon'ın istemcileri doğrulamadığı mod, sertifikası olmayan herkesin bağlanabilmesi anlamına gelir ve yukarıdaki "API erişimi root erişimidir" uyarısını geçersiz kılmaz.
Rootless daemon için uzak erişim
Rootless modda daemon bir kullanıcı ad alanında çalıştığından soketi TCP üzerinden açmak için dockerd-rootless.sh komutunu DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" değişkeniyle ve TLS bayraklarıyla başlatmanız gerekir. SSH ile erişimde ise uzak sunucuda $DOCKER_HOST değişkeninin tanımlı olması gerekir. Ayrıntılar Docker rootless mod yazısında.
Sık yapılan hatalar
- 2375 portunu internete açmak: Kimlik doğrulamasız API, ağdaki herkese root erişimi demektir. Belgeler TLS'siz uzak erişimi önermez.
- Dinleme adresini iki yerde tanımlamak: systemd override ile
daemon.jsoniçindekihostsbirlikte kullanılırsa daemon başlamaz. - Sertifikada IP adresini unutmak: IP ile bağlanacaksanız adresin
subjectAltNameiçinde olması gerekir; "Common Name" bağlandığınız ana makine adıyla eşleşmelidir. - Anahtar izinlerini açık bırakmak: Varsayılan
umaskile özel anahtarlar herkesçe okunabilir;chmod 0400uygulayın. - SSH kullanıcısının sokete erişimi olmaması: SSH context'i, uzak kullanıcının Docker soketine erişebilmesini gerektirir.
- Sertifikaların süresini takip etmemek: Belgelerdeki örnek sertifikalar
-days 365ile bir yıllıktır; süre dolmadan yenilemeyi planlayın.
Sık Sorulan Sorular
SSH mi TLS mi kullanmalıyım?
Kendi sunucunuzu yönetiyorsanız SSH daha az parça içerir: yeni port açmaz, sertifika yönetimi gerektirmez ve mevcut SSH anahtarlarınızı kullanır. TLS, SSH kullanamayan ya da HTTPS üzerinden API çağrısı yapması gereken araçlar için uygundur. İki yöntem de belgelerde soketi korumanın resmî yolu olarak anlatılır.
Docker API'sini yalnızca 127.0.0.1 üzerinde açmak güvenli mi?
Belgelerdeki örnekler bu adresi kullanır ve dışarıdan gelen bağlantıyı engeller. Ancak güvenlik sayfası, bir API uç noktasının güvenlik duvarıyla kısıtlansa bile container'lardan erişilebilir kalabileceği ve yetki yükseltmeye yol açabileceği konusunda uyarır. TCP gerçekten gerekmiyorsa Unix soketinde kalmak en güvenli seçenektir.
Join token veya TLS anahtarı sızarsa ne yapmalıyım?
Belgelere göre anahtara sahip olan herkes daemon'a komut verebilir. Daemon tlscacert ile verilen CA'nın imzaladığı her istemci sertifikasını kabul ettiği için, sızan bir sertifikayı devre dışı bırakmanın bu kurulumdaki yolu yeni bir CA ile sunucu ve istemci sertifikalarını yeniden üretmek ve daemon'ı yeni CA ile başlatmaktır. Swarm join token'ları ayrı bir konudur ve docker swarm join-token --rotate ile yenilenir; bunu Docker Swarm kurulumu yazısında anlatıyoruz.
Docker soketini bir container'a bağlamak neden riskli?
Soket daemon'ın API'sidir. Soketi gören bir container, ya da o container'ı ele geçiren biri, daemon'a yeni container başlatma dahil her komutu verebilir; güvenlik sayfasının anlattığı gibi bu da ana makinede root erişimine eşdeğerdir. Yönetim panelleri bağlamında bu riskin ayrıntısı Portainer kurulumu yazısında ele alınıyor.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Docker öğrenme rehberi · docker context ile uzak sunucu · Docker permission denied çözümü · Docker rootless mod · Docker iptables ve UFW · UFW güvenlik duvarı