Docker Container Güvenliği Part-1

SWB
11 min readMar 21, 2021

Giriş

Bu yazı dizisine katkılarından dolayı sevgili dostum Altan Sirel ve sevgili padawan’ım Ahmet S. Külekçi’ye (özellikle ekran görüntüleri için) teşekkürlerimi borç bilirim.

Güvenlik bir yaşam biçimidir. Bu cümle aslında tüm yazılarımızın felsefesinin de merkezini oluşturuyor. Yazı dizimize başlamadan önce bir takım kavramlardan bahsetmek faydalı olacaktır. DevOps’u hiç durmaksızın yaşayan bir döngü olarak tanımlayacak olursak DevSecOps da güvenliğin yazılım ve operasyon süreçlerine bir yaşam biçimi olarak dahil olmasıdır diyebiliriz.

Docker Container Güvenliği yazı dizisi ile amacımız, sanallaştırma dünyasının “2.0” versiyonu olarak görülen ve yeni nesil sanallaştırma teknolojisi olarak bahsedilen container teknolojilerinin en ünlü ürünü olan Docker üzerinden güvenliğin nasıl sağlanacağını detaylı olarak incelemektir.

İlk olarak Container teknolojisinin genel mantığından bahsettikten sonra aslında güvenliğin her katmanda sağlanmasının nasıl bir yaklaşım olduğuna değineceğiz. Daha sonra Docker Security konumuzu üç ana bölüme ayırıp inceleyeceğiz. Birinci bölümde Docker Güvenlik Önerilerini inceledikten sonra ikinci bölümümüzde Docker Enterprise Güvenlik Önerilerine geçeceğiz. Ve son olarak üçüncü bölümümüzde tüm docker projelerinizde kullanabileceğiniz Docker Security Checklist’ini bir excel halinde içerisinde Gantt Table ile birlikte sizlerle paylaşacağız.

Her ne kadar yazının üç ana bölümü olacak olsa da yazı üç parttan daha fazla olacak. O yüzden yazının üç ana bölümü ile yayınlanan partları karıştırmayalım.

Docker ve Container Teknolojisine Bakış

Bu yazı dizisinde amacımız Docker’ın veya Container teknolojisinin ne olduğunu anlatmak değil. Bunun için İngilizce ve Türkçe yüzlerce harika makale bulabilirsiniz. Biz, Docker ve Container teknolojilerine güvenlik merkezi ile yaklaşacağız.

Teknolojinin emekleme dönemleri sayılabilecek zamanlarda yazılımlar direkt olarak fiziki sunucularda koşturulurdu. Sanallaştırma teknolojisinin gelişmesiyle birlikte bir fiziki sunucu içerisinde bulunan sanal makinelerde birden fazla yazılım kullanılabilir hale geldi. Sanal makineler (VM) pratikte üzerinde konak oldukları işletim sistemleri kadar güvenlidir. Bir VM üzerinde çalıştırılan yazılımdaki zafiyetten faydalanan kişi tüm sunucuya sızabilir. En kötü senaryo ne olabilir diye düşündüğümüzde VM Escape adı verilen ve sanal makine atlatılarak direkt olarak hipervizör üzerinde işlemlerin yapıldığı senaryo aklımıza gelebilir. Nitekim 2015 yılında CEN-2015–3456 kodu ile VENOM olarak adlandırılan zafiyet sömürü yöntemi ile ana bilgisayarda çalışan diğer sanal makinelere erişim sağlanmış oldu.

Bu durumda artık teknolojinin bir adım daha öteye gitmesi gerektiği zaten anlaşılmıştı ve “Container” denilen yapılar devreye girdi. Docker gibi sistemler sayesinde ana bilgisayar ile olan bağın diğer sanal makinelere erişilmesi problemi büyük ölçüde çözülmüş oldu.

Aslında burada sadece bir teknoloji değil aynı zamanda bir felsefe de yatıyor. Bu felsefeyi anlamak konunun belki de teknik detayını öğrenmekten daha önemli. Çünkü teknik detaylara hâkim olunsa dahi yazılım geliştirme süreçlerine en başından dahil olmayan güvenlik yaklaşımları belirli bir süre sonra problem yaşamaya başlayacaktır.

Güvenliği merkezine alan DevSecOps, SSDLC gibi yaklaşımlardan önce yazılım geliştirme süreçleri aşağıdaki gibi ilerliyordu.

Yukarıda görmüş olduğunuz yaklaşımın adı Waterfall. Uzun yıllar yazılım dünyasında en çok kullanılan ve hatta günümüzde de halen kullanılan bir model. Peki güvenlik bunun neresinde? İşte sorun burada başlıyor. Bu yaklaşımda güvenliği her aşamaya implemente etmenin zorluğu akışın tamamen değişmesine sebep olmuştur.

DevOps olarak başlayan bu yeni felsefe günümüzde artık DevSecOps olarak da adını sıkça duyurmaya başladı. Yazılım geliştirme süreçlerindeki Continuous Integration ve Continuous Deployment/Delivery aşamasının sekteye uğramadan her bir adımda güvenliğin var olması bu felsefenin ana fikrini oluşturuyor.

Akademik dilimizi bir süre kenara bırakalım ve biraz daha basitleştirerek olayı izah etmeye çalışalım.

İkinci Dünya savaşı sonrasında ekonominin toparlanmaya çalıştığı dönemlerde ticaret küreselleşiyordu. Bu küreselleşmenin de etkisiyle taşımacılıkta bir rampa atlama zamanının geldiği hissedildi. Karanlık savaş zamanından çıkan insanlar ülkeler arası taşımacılıkta bir standarda ihtiyaç duymaya başladı. İşte tam bu aşamada Dünya Taşımacılık Konseyi (evet böyle bir konsey varmış ben de bilmiyordum) konteyner standardını duyurdu. Artık tüm taşımacılık yöntemlerinin tamamında ölçüleri tüm dünyaca kabul edilmiş ve farklı ölçülerde olan bu konteynerler kullanılacaktı. Bu sayede maliyetler düştü, taşımacılık çok daha kolay, esnek ve hızlı bir hale gelirken her şeyden önemlisi taşımacılık daha güvenli bir hale gelmişti.

Peki Docker da aslında taşımacılıkta yaşanan bu gelişmenin benzeri bir ürün değil midir?

VM ve Konteyner teknolojisi arasındaki farka aşağıdaki görselden bakabiliriz.

Sanal Makine ve Konteyner Farkları

Teoride hem hızlı hem daha az maliyetli hem de güvenli olacak olan konteyner teknolojisi düşünüldüğü kadar güvenli mi?

Bir sistemde çalışan konteynerlerin sayısı arttıkça, içerdiği uygulamalardan birinin container “breakout” adı verilen bir ihlale yol açma olasılığı da artar.

Docker, konteynerler arasında bir düzeyde kaynak ve işlem yalıtımı sağlarken, konteyner içinde root olarak çalışan bir işlemin, çekirdek alt sistemleri ve aygıtlarıyla doğrudan iletişim halinde ana bilgisayar sisteminde root olarak çalıştığı gerçeğini eklerseniz felaket senaryoları çizmenize neden olacak durumları görebilirsiniz.

Bu problemlerin önüne geçmek için birçok otomatize araç olsa da halen bir standart ve tam çözüm üretebilen bir aracın varlığı söz konusu değildir. Bu nedenle Docker konfigürasyonlarının A-Z’ye doğru (doğru kime göre neye göre dediğinizi duyar gibiyim) yapılması ve bunların kontrol edildiği bir mekanizmanın kurulması çok önemlidir.

Yukarıdaki iki paragrafın özeti ise şudur: Güvenlik sağlayalım derken önümüze gelen her şeyi root yetkisi ile çalıştırıp şirketimizin güvenlik ekibine kalp krizi geçirtmek üzereyiz. 😊

Unutulmaması gereken altın cümle: “Docker bir güvenlik ürünü değildir.”

Yazı dizimizde tamamen CIS tarafından yayınlanan CIS Docker Benchmark v1.2.0'ı baz aldık. Ayrıca eklemeler yaptığımız kısımlar için ilgili yazının ilgili part’ına kaynaklar kısmına eklemeler yaptık. Daha fazla bilgiye ihtiyacı olanlar kaynaklar kısmını inceleyebilir.

NOT: Kaynaklar kısmında birçok önemli ve değerli makaleyi sizlerle paylaşıyoruz. İlgili tavsiyelerin içeriği hakkında daha derine girmek isteyenler kaynakları inceleyebilirler.

1.1. Genel Konfigürasyonlar

Spesifik konfigürasyonlara geçmeden önce özellikle belirtilmesi gereken bir konu var. Yazılım geliştiricisi olmak bazı (iyi veya kötü) alışkanlıkların kazanılmasına sebep oluyor. Bunlardan birisi de eğer bir şey çalışıyorsa onun versiyonunun güncellenmesinden çekinilmesidir. Ancak güncellemelerin sadece fonksiyonel iyileştirmeler, bugfixler veya yeni feature’lar olmadığını aynı zamanda o güncellemelerin güvenlik iyileştirmeleri içerebileceğini unutmamak gerekiyor.

Kısacası mümkün olan her senaryoda en güncel (en stabil olan) versiyonu kullanmak güvenlik için bir ön şarttır.

Bir diğer konu ise Docker’ın üzerinde koştuğu işletim sisteminde gerekli güncellemelerin ve doğru güvenlik konfigürasyonlarının yapılmasıdır. Docker, üzerinde koştuğu işletim sisteminin güvenli olduğu kadar güvenli olacaktır.

Bu iki konudan da bahsettikten sonra artık yolculuğumuza başlayabiliriz.

1.2. Linux Hostlar için Spesifik Konfigürasyonlar

Docker’ın hostu olarak en çok kullanılan işletim sistemlerinden biri olan Linux konfigürasyonlarını inceleyelim.

1.2.1. Her bir konteyner için ayrı partition ayrılması

Varsayılan olarak tüm Docker konteynerları ve onların verileri ile meta verileri linuxta /var/lib/docker dizininde bulunur. Eğer varsayılan olarak bunu bu şekilde bırakırsanız tüm konteynarların verilerine tek bir noktadan erişilmesi tehlikesi ile karşı karşıya kalırsınız. Aynı zamanda yine varsayılan olarak Docker imajlarının da burada depolandığını düşünürsek bu dizin sizin storage kapasitenize bağlı olarak hızlı bir şekilde dolabilir ve hem ana makinenin hem de Docker’ın kullanılamaz hale gelmesine sebep olabilir.

Hem güvenlik hem de storage optimizasyonu için Docker dosyalarını ayrı bir mantıksal birimde oluşturmalısınız.

Nasıl kontrol ederim?

grep ‘/var/lib/docker\s’ /proc/mounts

Yukarıdaki komutu Docker’ı kurduğunuz ana makinenizin terminalinde çalıştırdığınızda size /var/lib/docker mount noktası için partition detaylarını verecektir.

Kontrol için bir diğer komut ise şudur:

mountpoint — “$(docker info -f ‘{{ .DockerRootDir }}’)”

Bu komut ise size root dizininin yapılandırılmış bir mount noktası olup olmadığını gösterecektir.

Eğer ilk kurulum aşamasında bunu yapmak istiyorsanız /var/lib/docker mount noktası için ayrı bir partition oluşturmalısınız. Ancak hali hazırda çalışan bir sistemde bunu yapmak istiyorsanız Linux LVM’i kullanarak bunu gerçekleştirebilirsiniz.

1.2.2. Docker Daemon kontrolünün belirli kullanıcılara verilmesi

Docker, konteynerın erişim haklarını sınırlamadan ana makine ile guest konteyner arasında dizin paylaşmamıza olanak sağlar. Bu aynı zamanda direkt olarak bir konteyner oluşturup ana makinenin / dizinini konteyner ile eşleştirebileceğimiz anlamına gelir. Docker Daemon varsayılan olarak root ve docker grubuna ait kullanıcılar tarafından kontrol edilebilir durumdadır.

Bu durumda konteyner herhangi bir kısıtlama olmadan ana makinemizin dosya sisteminde değişiklikler yapabilir. Eğer docker grubunun bir üyesi olan kullanıcıysanız hak yükseltme yapabilir ve ana makinede root dizini ile eşleşen bir konteyner başlatabilirsiniz. Aslında ne kadar korkutucu bir senaryo değil mi?

Aşağıdaki komut ile docker grubunda olan kullanıcıları görüntüleyebilirsiniz. Burada sadece olması gereken kullanıcıların olmasına çok dikkat etmelisiniz.

getent group docker

Bu komutu çalıştırdıktan sonra incelediğiniz kullanıcılar arasında trusted olmayanları silmelisiniz. Ayrıca hassas veri içerdiğini bildiğiniz dizinleri ana makine ile konteyner arasında eşleştirmemelisiniz.

1.2.3. Docker Daemon için denetim konfigürasyonu

Ana makinenin Linux dosya sistemi ve sistem çağrılarını monitör etmek ve denetlemek önemlidir. Bununla birlikte aynı öneme sahip bir diğer konu da Docker Daemon’ın denetlenmesidir. Docker Daemon root ayrıcalıklarıyla çalıştığı için faaliyetlerini vekullanımını denetlemek çok büyük öneme sahiptir. Varsayılan olarak Docker daemon’ın audit logu tutmuyor. Bunu bizim ayarlamamız gerekecek.

/etc/audit/audit.rules dosyasına aşağıdaki satırı ekleyelim:

-w /usr/bin/dockerd -k docker

Bu işlemi gerçekleştirdikten sonra audit daemon’ı yeniden başlatmamız gerekiyor:

service auditd restart

Peki audit kuralının olup olmadığını nasıl doğrulayabiliriz? Aşağıdaki komut da bunun için:

auditctl -l | grep /usr/bin/dockerd

Burada dikkat edilmesi gereken önemli bir husus daha var. Bu şekilde audit logları tutmak çok büyük dosyaların oluşmasına ve sistemin şişmesine neden olabilir. Bu nedenle periyodik olarak bu logların rotate edilmesini sağlayarak arşivlemelisiniz. Ayrıca diğer kritik bölümlerin dolmaması için de audit loglarına ayrı bir bölüm oluşturulmalıdır.

1.2.4. Docker dizinleri ve dosyaları için denetim konfigürasyonu

Linux sistem çağrılarını denetliyoruz. Linux dosya sistemini de mutlaka denetliyoruz. Peki ya Docker ile ilgili tüm dosya ve dizinleri de denetliyor muyuz? Eğer tüm sistemi denetliyorsak mantıken denetliyoruz diyebiliriz ancak burada ayrı parantez açmanın ve bu konuyu ayrıca kontrol etmenin de faydası olacağını düşünüyoruz.

Docker arka plandaki çalışmalarını root ayrıcalıklarıyla gerçekleştirir. Bu çalışmaları gerçekleştirmesi bazı dizinlere bağlıdır. Örneğin /var/lib/docker dizini gibi. Bu kısımda hangi dizin ve dosyaları denetlememiz gerektiğine ve bunu nasıl gerçekleştireceğimize bakalım. Ayrıca Docker’ın varsayılan birçok denetimi denetimi yapmadığını da ekleyelim.

NOT: Bu bölümde audit.rules dosyasına eklenen satırlar sonrası Audit Daemon’ı yeniden başlatmamız gerekiyor. Eklemeniz gereken tüm satırları ekledikten sonra aşağıdaki komut ile Audit Daemon’ı yeniden başlatabilirsiniz:

service auditd restart

/var/lib/docker

Bu dizin konteynerlar hakkındaki tüm bilgileri içerir. Bu nedenle bu dizin ve dosyaları denetlemek gerekir.

Bu denetimi gerçekleştirmek için /etc/audit/audit.rules dosyasına aşağıdaki satırı eklememiz yeterli olacaktır.

-w /var/lib/docker -k docker

Eğer /var/lib/docker dizini için denetim yapıp yapmadığımızı kontrol etmek istersek aşağıdaki komut ile bunu gerçekleştirebiliriz:

auditctl -l | grep /var/lib/docker

/etc/docker ve /etc/default/docker

Bu dizin Docker Daemon ile Docker Client arasındaki TLS iletişimi için kullanılan çeşitli sertifika ve key’leri içeriyor. Bu nedenle denetleme listemize bu dizini de eklemeliyiz.

Bu denetimi gerçekleştirmek için /etc/audit/audit.rules dosyasına aşağıdaki satırı eklememiz yeterli olacaktır.

-w /etc/docker -k docker

/etc/default/docker dosyasını denetlemek için:

-w /etc/default/docker -k docker

/usr/lib/systemd/system/docker.service

Docker Daemon parametreleri bir kullanıcı tarafından değiştirildiğinde docker.service dosyası oluşur ve içerisinde çeşitli parametreleri barındırır. Bu dosyayı denetlemek yapılmış olan değişiklikleri kontrol etmek açısından önemlidir.

Bu denetimi gerçekleştirmek için /etc/audit/audit.rules dosyasına aşağıdaki satırı eklememiz yeterli olacaktır.

-w /usr/lib/systemd/system/docker.service -k docker

Burada yapacağımız kontrolde iki aşama düşünebiliriz. Birincisi için aşağıdaki komutu yazalım:

systemctl show -p FragmentPath docker.service

Bu komut sonucunda eğer docker.service dosyası diye bir dosya yoksa iki seçenek var demektir. Ya herhangi bir değişiklik yapılmadığı için böyle bir dosya oluşmamıştır ya da audit rule çalışmıyordur. Bundan emin olmak için admin haklarıyla bir Docker Daemon parametrelerinde bir değişiklik yaparak tekrar yukarıdaki komutu yazabiliriz.

Veya ikinci yöntem olarak audit rule kontrolü yapabiliriz:

auditctl -l | grep docker.service

docker.socket

Docker Daemon için önemli parametrelere sahip bir diğer dosya da docker.socket dosyası. Tıpkı docker.service’de olduğu gibi bu dosyayı da denetlememiz faydalı olacaktır. Docker ilk kurulduğunda bu dosya ortalarda olmayacağı için yine varsayılan olarak denetimi yapılmamakta.

Bu denetimi gerçekleştirmek için /etc/audit/audit.rules dosyasına aşağıdaki satırı eklememiz yeterli olacaktır.

-w /usr/lib/systemd/system/docker.socket -k docker

Docker.service için bahsettiğimiz kontrol konusu burada da aynı şekilde geçerli. Bazen docker.socket diye bir dosya olmayabilir. Bu nedenle yine aynı mantıkla aşağıdaki komutları docker.service’de olduğu gibi kullanabilirsiniz.

systemctl show -p FragmentPath docker.socketauditctl -l | grep docker.socket

Bu bölümde denetlememiz gereken üç farklı dosya/klasörümüz daha kaldı. Bunlara da göz atalım:

/etc/docker/daemon.json

/usr/bin/containerd

/etc/sbin/runc

Daemon.json dosyası docker daemon konfigürasyon dosyamız oluyor. Containerd runc v.b. metaları kontrol etmek için kullanılan daemon’dır. Runc ise OCI spesifikasyonuna göre konteynerleri spawn ve run etmek için kullanılan bir CLI aracıdır. Bu 3 cümle direkt olarak neden denetleme yapmamız gerektiğiniz bize anlatıyor.

Bu üç dosyamızız da denetim listemize almak için /etc/audit /audit.rules dosyasına aşağıdaki satırları eklememiz yeterli olacaktır.

-w /etc/docker/daemon.json -k docker-w /usr/bin/containerd -k docker-w /usr/sbin/runc -k docker

Kontrol etmek için ise:

auditctl -l | grep /etc/docker/daemon.jsonauditctl -l | grep /usr/bin/containerdauditctl -l | grep /usr/sbin/runc

Bu komutları kullanabilirsiniz.

Bir önceki konuda bahsettiğimiz gibi audit logları çok büyük dosyaların oluşmasına ve sistemin şişmesine neden olabileceği için periyodik olarak bu logların rotate edilmesini sağlayarak arşivlemeyi unutmamalıyız.

Tüm bunları gerçekleştirdiğimize göre bir sonraki yazımızda Docker Daemon konfigürasyonlarına geçebiliriz demektir.

Sorularınız ve düzeltme önerileriniz için iletişim: serhanw@pm.me

Kaynaklar:

CIS Docker Benchmark v1.2.0–07–29–2019

http://12factor.net/config

http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

http://blog.docker.com/2014/10/docker-1-3-signed-images-process-injection-security-options-mac-shared-directories/

http://blog.scalock.com/new-docker-security-features-and-what-they-mean-seccomp-profiles

http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf

http://craiccomputing.blogspot.in/2014/09/clean-up-unused-docker-containers-and.html

http://daviddaeschler.com/2014/12/14/centos-7rhel-7-and-docker-containers-on-boot/

http://docs.docker.com/reference/commandline/cli/#run

http://docs.fedoraproject.org/en-US/Fedora/13/html/Security-Enhanced_Linux/

http://events.linuxfoundation.org/sites/events/files/slides/User%20Namespaces%20-%20ContainerCon%202015%20-%2016-9-final_0.pdf

http://jpetazzo.github.io/assets/2015-03-05-deep-dive-into-docker-storage-drivers.html#1

http://man7.org/linux/man-pages/man2/setgid.2.html

http://man7.org/linux/man-pages/man2/setuid.2.html

http://man7.org/linux/man-pages/man7/namespaces.7.html

http://man7.org/linux/man-pages/man7/pid_namespaces.7.html

http://man7.org/linux/man-pages/man7/user_namespaces.7.html

http://muehe.org/posts/switching-docker-from-aufs-to-devicemapper/

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/ch01.html

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Security_Guide/chap-system_auditing.html

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux_atomic_host/7/html/container_security_guide/docker_selinux_security_policy

https://access.redhat.com/security/team/key

https://arxiv.org/pdf/1501.02967

https://avicoder.me/2016/07/22/Twitter-Vine-Source-code-dump/

https://blog.docker.com/2015/11/docker-trusted-registry-1-4/

https://blog.docker.com/2016/05/docker-security-scanning/

https://containerd.tools/

https://docs.docker.com/datacenter/ucp/2.2/guides/admin/configure/external-auth/

https://docs.docker.com/datacenter/ucp/2.2/guides/admin/configure/external-auth/enable-ldap-config-file/

https://docs.docker.com/datacenter/ucp/2.2/guides/admin/configure/run-only-the-images-you-trust/

https://docs.docker.com/datacenter/ucp/2.2/guides/admin/configure/use-your-own-tls-certificates/

https://docs.docker.com/datacenter/ucp/2.2/guides/admin/install/plan-installation/#use-an-external-certificate-authority

https://docs.docker.com/datacenter/ucp/2.2/reference/cli/install/#description

https://docs.docker.com/develop/develop-images/build_enhancements/

https://docs.docker.com/docker-cloud/builds/image-scan/

https://docs.docker.com/edge/engine/reference/commandline/dockerd/

https://docs.docker.com/edge/engine/reference/commandline/dockerd/#default-ulimits

https://docs.docker.com/edge/engine/reference/commandline/dockerd/#options

https://docs.docker.com/ee/dtr/admin/configure/set-up-vulnerability-scans/

https://docs.docker.com/ee/ucp/admin/configure/set-session-timeout/

https://docs.docker.com/ee/ucp/authorization/

https://docs.docker.com/ee/ucp/user-access/cli/

https://docs.docker.com/engine/admin/configuring/

https://docs.docker.com/engine/admin/live-restore/

https://docs.docker.com/engine/admin/logging/overview/

https://docs.docker.com/engine/admin/runmetrics/

https://docs.docker.com/engine/admin/systemd/

https://docs.docker.com/engine/extend/plugins_authorization/

https://docs.docker.com/engine/installation/

https://docs.docker.com/engine/reference/builder/#healthcheck

https://docs.docker.com/engine/reference/builder/#/onbuild

https://docs.docker.com/engine/reference/commandline/cli/#environment-variables

https://docs.docker.com/engine/reference/commandline/cli/#notary

https://docs.docker.com/engine/reference/commandline/dockerd/#access-authorization

https://docs.docker.com/engine/reference/commandline/dockerd/#bind-docker-to-another-hostport-or-a-unix-socket

https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file

https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-socket-option

https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-user-namespace-options

https://docs.docker.com/engine/reference/commandline/dockerd/#default-cgroup-parent

https://docs.docker.com/engine/reference/commandline/dockerd/#storage-driver-options

https://docs.docker.com/engine/reference/commandline/exec/

https://docs.docker.com/engine/reference/commandline/pull/

https://docs.docker.com/engine/reference/commandline/rmi/

https://docs.docker.com/engine/reference/commandline/run/#mount-tmpfs-tmpfs

https://docs.docker.com/engine/reference/commandline/run/#options

https://docs.docker.com/engine/reference/commandline/run/#restart-policies-restart

https://docs.docker.com/engine/reference/commandline/secret/

https://docs.docker.com/engine/reference/commandline/swarm_init/

https://docs.docker.com/engine/reference/commandline/swarm_init/#--data-path-addr

https://docs.docker.com/engine/reference/commandline/swarm_init/#--listen-addr

https://docs.docker.com/engine/reference/commandline/swarm_unlock-key/

https://docs.docker.com/engine/reference/commandline/swarm_update/#examples

https://docs.docker.com/engine/reference/run/#ipc-settings-ipc

https://docs.docker.com/engine/reference/run/#network-settings

https://docs.docker.com/engine/reference/run/#pid-settings-pid

https://docs.docker.com/engine/reference/run/#security-configuration

https://docs.docker.com/engine/reference/run/#specify-custom-cgroups

https://docs.docker.com/engine/reference/run/#uts-settings-uts

https://docs.docker.com/engine/reference/run/#volume-shared-filesystems

https://docs.docker.com/engine/security/apparmor/

https://docs.docker.com/engine/security/https/

https://docs.docker.com/engine/security/seccomp/

https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface

https://docs.docker.com/engine/security/security/#other-kernel-security-features

https://docs.docker.com/engine/security/trust/content_trust/

https://docs.docker.com/engine/security/userns-remap/

https://docs.docker.com/engine/swarm/admin_guide/#/add-manager-nodes-for-fault-tolerance

https://docs.docker.com/engine/swarm/admin_guide/#recover-from-disaster

https://docs.docker.com/engine/swarm/how-swarm-mode-works/pki/#rotating-the-ca-certificate

https://docs.docker.com/engine/swarm/manage-nodes/

https://docs.docker.com/engine/swarm/swarm_manager_locking/

https://docs.docker.com/engine/tutorials/dockervolumes/

https://docs.docker.com/engine/tutorials/dockervolumes/#creating-and-mounting-a-data-volume-container

https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#run

https://docs.docker.com/engine/userguide/networking/

https://docs.docker.com/engine/userguide/networking/default_network/binding/

https://docs.docker.com/engine/userguide/networking/default_network/container-communication/#communication-between-containers

https://docs.docker.com/engine/userguide/networking/overlay-security-model/

https://docs.docker.com/engine/userguide/storagedriver/

https://docs.docker.com/engine/userguide/storagedriver/selectadriver/#supported-backing-filesystems

https://docs.docker.com/registry/insecure/

https://docs.docker.com/storage/bind-mounts/#configure-bind-propagation

https://docs.docker.com/userguide/dockerimages/

http://searchsdn.techtarget.com/feature/Docker-networking-How-Linux-containers-will-change-your-network

https://events.linuxfoundation.org/sites/events/files/slides/User%20Namespaces%20-%20ContainerCon%202015%20-%2016-9-final_0.pdf

https://forums.docker.com/t/command-to-remove-all-unused-images/20/8

https://forums.docker.com/t/docker-in-docker-vs-mounting-var-run-docker-sock/9450/2

https://fralef.me/docker-and-iptables.html

https://github.com/docker/docker/blob/master/profiles/seccomp/default.json

https://github.com/docker/docker-ce/blob/master/components/packaging/deb/systemd/docker.socket

https://github.com/docker/docker-ce/releases/latest

https://github.com/docker/docker/issues/14856

https://github.com/docker/docker/issues/21109

https://github.com/docker/docker/issues/22741

https://github.com/docker/docker/issues/22870

https://github.com/docker/docker/issues/24253

https://github.com/docker/docker/issues/2918

https://github.com/docker/docker/issues/3313

https://github.com/docker/docker/issues/7906

https://github.com/docker/docker/issues/8093

https://github.com/docker/docker/issues/9054

https://github.com/docker/docker/pull/11109

https://github.com/docker/docker/pull/12648

https://github.com/docker/docker/pull/16609

https://github.com/docker/docker/pull/18697

https://github.com/docker/docker/pull/20662

https://github.com/docker/docker/pull/20727

https://github.com/docker/docker/pull/26276

https://github.com/docker/docker/pull/4572

https://github.com/docker-library/httpd/blob/12bf8c8883340c98b3988a7bade8ef2d0d6dcf8a/2.4/Dockerfile

https://github.com/docker-library/php/blob/d8a4ccf4d620ec866d5b42335b699742df08c5f0/7.0/alpine/Dockerfile

https://github.com/moby/moby/issues/33938

https://github.com/moby/moby/pull/20727

https://github.com/moby/moby/pull/29984

https://github.com/moby/moby/pull/32717

https://github.com/moby/moby/releases/latest

https://github.com/nyantec/narwhal

https://github.com/opencontainers/runc

https://github.com/progrium/busybox

https://github.com/projectatomic/atomic-site/issues/269

https://github.com/twistlock/authz

https://github.com/YungSang/fedora-atomic-packer/blob/master/oem/docker.socket

https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/

https://lwn.net/Articles/475362/

https://lwn.net/Articles/475678/

https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/

https://registry.hub.docker.com/

https://success.docker.com/article/Docker_Reference_Architecture-_Securing_Docker_EE_and_Security_Best_Practices#ucpsecurity

https://titanous.com/posts/docker-insecurity

http://success.docker.com/article/Docker_Reference_Architecture-_Securing_Docker_EE_and_Security_Best_Practices

https://www.andreas-jung.com/contents/on-docker-security-docker-group-considered-harmful

https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt

https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt

https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

https://www.projectatomic.io/docs/docker-storage-recommendation/

https://zeltser.com/security-risks-and-benefits-of-docker-application/

http://windsock.io/the-docker-proxy/

http://www.livewyer.com/blog/2015/02/24/slimming-down-your-docker-containers-alpine-linux

http://www.oreilly.com/webops-perf/free/files/docker-security.pdf

http://www.projectatomic.io/blog/2015/08/why-we-dont-let-non-root-users-run-docker-in-centos-fedora-or-rhel/

http://www.projectatomic.io/blog/2015/12/making-docker-images-write-only-in-production/

--

--

SWB

Some Kind of Security Guy | Defender of Digital Privacy & Security 🫡 | #Cybersecurity | #Blockchain Security | Safeguarding the Decentralized Web 🌐