Ritual verifikasi berlalu hijau semua, tetapi satu pertanyaan masih menggantung dari chapter instalasi: dari mana daemon tahu Budi boleh bicara tanpa sudo? Jawabannya tidak berada di dalam Docker sama sekali, melainkan pada izin berkas Unix biasa di /var/run/docker.sock — socket yang menjadi satu-satunya pintu masuk ke daemon. Memahami pintu ini berarti memahami siapa yang boleh masuk, kenapa grup docker jauh lebih berkuasa dari namanya, dan bagaimana membuka pintu tersebut ke jaringan tanpa menyerahkan kunci kerajaan. Chapter ini membedah ketiganya: izin socket di lokal, opsi koneksi remote dengan segala jebakannya, dan jalur yang paling layak direkomendasikan.

Socket Docker dan Izin Berkasnya #

Setiap interaksi klien-daemon yang kita lakukan sepanjang Course ini — dari docker ps sampai docker run hello-world — melewati satu berkas socket unix. Mari kita lihat wujudnya beserta izinnya:

bash
$ ls -l /var/run/docker.sock

Output yang Dihasilkan:

text
srw-rw---- 1 root docker 0 Okt 13 09:41 /var/run/docker.sock

Sepuluh karakter pertama pada baris tersebut memuat seluruh kebijakan akses daemon. Mari kita telaah karakter demi karakter:

  1. s di kolom pertama — tipe berkas berupa socket: endpoint komunikasi di dalam kernel Unix, bukan berkas data biasa; proses menulis ke socket dan pembaca di sisi lain menerima pesannya.
  2. rw- untuk pemiliknya root — pengguna root dapat membaca dan menulis ke socket ini; dialah pemiliknya, seperti tercantum pada kolom sebelum ukuran berkas.
  3. rw- untuk grupnya docker — seluruh anggota grup docker boleh membaca dan menulis ke socket yang sama; inilah satu-satunya jalur akses tanpa sudo, dan izinnya setara pemilik.
  4. --- untuk pihak lain — pengguna lain tidak memiliki hak apa pun; tanpa sudo dan tanpa keanggotaan grup docker, pintu ini tertutup rapat.
  5. Angka 0 dan tanggal di belakangnya — socket tidak menyimpan data sehingga ukurannya selalu nol; tanggal menandai kapan daemon membuatnya saat menyala.

Kombinasi root:docker dengan izin rw-rw---- — sering ditulis singkat 660 — adalah desain yang disengaja: sistem operasi yang menjadi penjaga pintu, bukan Docker. Mendaftarkan seseorang ke grup docker sama artinya dengan memberinya kunci socket, dan penjaga berkas Unix yang memutuskan kunci itu sah atau tidak.

Grup docker dan Pendaftaran Anggotanya #

Mekanisme pendaftarannya sudah kita pakai pada Chapter Instalasi Docker di Linux, dan sekarang saatnya membedah isi perintahnya:

bash
$ sudo usermod -aG docker $USER
$ newgrp docker
$ groups

Output yang Dihasilkan:

text
budi docker sudo

Mari kita telaah tiga perintah tersebut:

  1. usermod -aG docker $USER — flag -a berarti append dan -G menambah grup sekunder; tanpa -a, daftar grup lama pengguna justru tertimpa dan keanggotaan lain hilang — kesalahan klasik yang berbahaya.
  2. newgrp docker — membuka sub-shell yang langsung memakai keanggotaan baru, jembatan sementara sebelum logout; keanggotaan grup dari usermod baru berlaku penuh pada sesi login berikutnya.
  3. groups — mencetak daftar grup milik sesi saat ini; munculnya docker di samping budi dan sudo membuktikan kini ada kunci socket di saku Budi.

Membuka Koneksi Remote tanpa TLS #

Pintu socket lokal memenuhi satu mesin; kadang kita butuh CLI dari mesin lain bicara dengan daemon — misalnya laptop yang menarget server kantor. Docker mendukung daemon mendengarkan TCP lewat flag -H, dan bentuk paling naifnya tampak menggoda:

bash
$ sudo dockerd -H tcp://0.0.0.0:2375

Perintah tersebut memerintahkan daemon mendengarkan semua antarmuka jaringan pada port 2375 — dan di situlah letak masalahnya. Port 2375 melayani HTTP tanpa enkripsi dan tanpa autentikasi: siapa pun yang dapat menjangkau port itu dapat menjalankan container apa pun, mem-mount folder host, dan pada praktiknya menjadi root di server. Port ini layak dipahami sebagai referensi sejarah, bukan sebagai konfigurasi yang boleh dipasang di jaringan nyata.

Membungkus Koneksi Remote dengan TLS #

Jalur aman pertama tetap memakai TCP, tetapi dengan port 2376 yang dibungkus TLS: daemon dan klien saling memverifikasi sertifikat, dan seluruh lalu lintas terenkripsi. Seluruh pengaturan sisi daemon berada — sesuai tradisi section ini — di daemon.json:

json
{
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
  "tlsverify": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert": "/etc/docker/server-cert.pem",
  "tlskey": "/etc/docker/server-key.pem"
}

Mari kita telaah kunci-kunci TLS pada blok di atas:

  1. hosts dengan dua pendengar — socket unix tetap terbuka untuk klien lokal, sementara tcp://0.0.0.0:2376 membuka pintu jaringan; ingat bahwa kunci ini menuntut drop-in systemd seperti yang kita pasang pada Chapter Konfigurasi Docker Engine agar tidak bentrok dengan argumen -H fd://.
  2. tlsverify — mode TLS dua arah: daemon memverifikasi sertifikat klien, dan klien memverifikasi sertifikat daemon; tanpa sertifikat yang ditandatangani certificate authority kita, koneksi ditolak dua-duanya.
  3. tlscacert — sertifikat certificate authority yang menjadi hakim kepercayaan; hanya sertifikat bertanda tangan CA inilah yang diterima.
  4. tlscert dan tlskey — pasangan sertifikat dan kunci privat milik daemon sendiri; inilah identitas yang diperiksa klien saat koneksi dibuka.

Di sisi klien, dua environment variable dari Chapter Konfigurasi Docker CLI mengaktifkan verifikasi serupa — DOCKER_TLS_VERIFY=1 memerintahkan CLI memverifikasi server, dan DOCKER_CERT_PATH menunjuk folder berisi ca.pem, cert.pem, dan key.pem milik klien:

bash
$ export DOCKER_TLS_VERIFY=1
$ export DOCKER_CERT_PATH=$HOME/.docker
$ docker -H tcp://server.example.com:2376 version

Perintah terakhir pada blok di atas kini berjalan di atas jalur yang terlindungi: klien membuktikan dirinya ke daemon, daemon membuktikan dirinya ke klien, dan REST API mengalir terenkripsi di antara keduanya. Harganya adalah urusan pemeliharaan sertifikat — membuat CA, menandatangani sertifikat server dan klien, memutarnya saat kedaluwarsa — yang dokumentasinya tersedia pada halaman keamanan Docker di bagian Referensi.

Jalur yang Direkomendasikan adalah SSH #

Untuk mayoritas kasus, ada jalur ketiga yang jauh lebih sederhana: SSH. Docker CLI dapat berbicara ke daemon lewat sesi SSH yang sudah kita punya, tanpa membuka port TCP apa pun dan tanpa mengelola satu sertifikat pun. Kita sudah membuatnya pada Chapter Konfigurasi Docker CLI; mengingat kembali bentuknya:

bash
$ docker context create server-latihan --docker "host=ssh://[email protected]"
$ docker context use server-latihan

Autentikasi mengikuti kunci SSH yang biasa kita pakai untuk login ke server — berarti tanpa password tambahan, tanpa sertifikat baru, dan tanpa permukaan serangan port terbuka; daemon tetap mendengarkan socket unix-nya saja. Satu syarat yang perlu diingat: pengguna ssh di server — budi pada contoh kita — tetap harus menjadi anggota grup docker di sana, karena penjaga pintunya tetap izin berkas socket, bukan SSH itu sendiri. Inilah alasan jalur ssh menjadi rekomendasi bawaan section ini: keamanan mewarisi infrastruktur yang sudah teruji, dan konfigurasi tambahan di sisi server mendekati nol.

Akses kini teratur: Budi masuk lewat grup docker di laptopnya, tim masuk lewat context ssh ke server latihan, dan jalur TLS tersedia untuk kebutuhan skala lebih besar. Namun dunia nyata tidak selalu semulus dokumentasi — daemon kadang menolak menyala, socket menolak diakses padahal perintahnya sudah benar, dan disk mendadak penuh tanpa kabar. Delapan gejala paling umum beserta ritual diagnosisnya menanti pada chapter penutup section ini: Troubleshooting Instalasi.

Referensi #