Tujuan saya adalah membatasi akses ke kontainer buruh pelabuhan hanya ke beberapa alamat IP publik. Apakah ada proses sederhana dan berulang untuk mencapai tujuan saya? Memahami hanya dasar-dasar iptables saat menggunakan opsi default Docker, saya merasa sangat sulit.
Saya ingin menjalankan wadah, membuatnya terlihat oleh Internet publik, tetapi hanya mengizinkan koneksi dari host tertentu. Saya berharap untuk menetapkan kebijakan INPUT standar dari REJECT dan kemudian hanya mengizinkan koneksi dari host saya. Tapi aturan dan rantai Docker menghalangi dan aturan INPUT saya diabaikan.
Adakah yang bisa memberikan contoh bagaimana mencapai tujuan saya dengan asumsi berikut?
- Host IP publik 80.80.80.80 di eth0
- Host IP pribadi 192.168.1.10 pada eth1
docker run -d -p 3306:3306 mysql
- Blokir semua koneksi ke host / wadah 3306 kecuali dari host 4.4.4.4 dan 8.8.8.8
Saya senang untuk mengikat wadah hanya ke alamat ip lokal tetapi akan membutuhkan instruksi tentang cara mengatur aturan penerusan iptables dengan benar yang selamat dari proses buruh pelabuhan dan host restart.
Terima kasih!
--ctdir
? Saya menggunakan-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
DOCKER-USER
tabel default berisi entri:-A DOCKER-USER -j RETURN
yang akan berjalan sebelum di atas jika Anda gunakan-A
. Solusinya adalah dengan memasukkan aturan di kepala dalam urutan terbalik-I
.FILTERS
rantai baru , dan-I
masukkan aturan baru (seperti yang Anda katakan), untuk melompat ke sana:-I INPUT -j FILTERS
dan-I DOCKER-USER -i eth0 -j FILTERS
-I
, hanya untuk aman.Dengan Docker v.17.06 ada rantai iptables baru yang disebut DOCKER-USER. Yang ini untuk aturan khusus Anda: https://docs.docker.com/network/iptables/
Tidak seperti rantai DOCKER itu tidak diatur ulang pada membangun / memulai wadah. Jadi Anda bisa menambahkan baris-baris ini ke konfigurasi / skrip iptables Anda untuk menyediakan server bahkan sebelum menginstal buruh pelabuhan dan memulai wadah:
Sekarang port untuk MySQL diblokir dari akses eksternal (eth0) bahkan berpikir buruh pelabuhan membuka port untuk dunia. (Aturan ini menganggap, antarmuka eksternal Anda adalah eth0.)
Akhirnya, Anda harus membersihkan iptables untuk me-restart layanan buruh pelabuhan terlebih dahulu, jika Anda mengacaukannya terlalu banyak mencoba untuk mengunci port seperti yang saya lakukan.
sumber
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION
Itulah sebabnya, instruksi khusus dijalankan sebelum rantai DOCKER.--dport
di dalam DOCKER-USER ini harus cocok dengan IP internal layanan kontainer, bukan port yang terbuka. Ini sering cocok tetapi tidak selalu dan ini dapat dengan mudah bertentangan dengan layanan lain jadi saya masih berpendapat bahwa solusi DOCKER-USER ini setengah matang.MEMPERBARUI : Meskipun valid pada tahun 2015, solusi ini tidak lagi merupakan cara yang tepat untuk melakukannya.
Jawabannya tampaknya ada dalam dokumentasi Docker di https://docs.docker.com/articles/networking/#the-world
Apa yang akhirnya saya lakukan adalah:
Saya tidak menyentuh opsi
--iptables
atau--icc
.sumber
iptables -vnL DOCKER
, port tujuan adalah semua port di dalam wadah. Jika saya benar, itu berarti aturan di atas hanya akan mempengaruhi port3306
di dalam wadah - yaitu, jika Anda ke-p 12345:3306
wadah Anda, aturan Anda masih akan menjadi yang diperlukan untuk mengunci akses (yaitu--dport 12345
tidak akan berfungsi) , karena aturan ACCEPT rantai DOCKER bersifat post-NAT.--iptables=false
, karena ini tampaknya menjadi pilihan terburuk dari semuanya.UPDATE: Meskipun jawaban ini masih valid, jawaban yang digunakan oleh @SystemParadox
DOCKER-USER
dalam kombinasi dengan--ctorigdstport
lebih baik.Berikut ini adalah solusi yang bertahan dengan baik di antara restart dan memungkinkan Anda untuk memengaruhi port yang terbuka daripada port internal .
iptables -t mangle -N DOCKER-mysql iptables -t mangle -A DOCKER-mysql -s 22.33.44.144/32 -j RETURN iptables -t mangle -A DOCKER-mysql -s 22.33.44.233/32 -j RETURN iptables -t mangle -A DOCKER-mysql -j DROP iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 3306 -j DOCKER-mysql
Saya telah membangun gambar Docker yang menggunakan metode ini untuk secara otomatis mengelola iptables untuk Anda, menggunakan variabel lingkungan atau secara dinamis dengan etcd (atau keduanya):
https://hub.docker.com/r/colinmollenhour/confd-firewall/
sumber