زمانی که با استفاده از docker یا docker-compose یک پورتی رو expose میکنید، دیگه شاید به راحتی نتونید اون ها رو با firewall های لینوکس مثل iptables محدودش کنید و هرکسی میتونه بهشون وصل بشه. با دوتا کامند خیلی ساده روی Iptables میتونید پورت های داکر رو محدود کنید.
سعی کنید در مورد iptables بخونید و ازش نترسید. هدف من آموزش iptables نیست و پیشنهاد میکنم حتما کمی در موردش سرچ کنید.
فرض کنید که با داکر کامپوز یک دیتابیس postgres اجرا کردید و پورتش رو به 9999 مپ کردید
postgres: image: 'postgres:13' ports: - "9999:5432"
حالا میخواید که پورت ۹۹۹۹ رو برای یک یا چند آی پی خاص محدود کنید. اگر سعی کنید که پورت ۹۹۹۹ یا ۵۴۳۲ رو به روش های معمول iptable ببندید عملا موفق نخواهید شد. دلیلش رو پایین تر توضیح دادم.
برای این کار دوتا مرحله داریم:
۱- ابتدا آی پی هایی که اجازه دارند به پورت شما وصل بشن رو مشخص کنید
۲-کلا اون پورت رو برای هر آی پی دیگه ای ببندید
این کامند به آی پی 8.8.8.8 اجازه میده که به پورت 9999 شما متصل بشه
iptables -I DOCKER-USER -i eth0 -s 8.8.8.8 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j ACCEPT
شما میتونید برای آی پی های مختلف و پورت های مختلف هر چند بار این دستور رو وارد کنید
توضحیات:
داکر یک سری chain درست میکنه که رول های خودش رو داخل اون قرار میده ولی با هر بار ریست شدن داکر اون ها تغییر میکنن. برای همین DOCKER-USER رو درست کرده که شما دستورات خودتون که مربوط به داکر هستند رو داخل اون ست کنید تا داکر اون ها رو خراب نکنه
این آپشن میگه هرکس از اینترفیس eth0 اومد این رول رو براش اجرا کن. پس دقت کنید اگر اسم اینترفیس شما چیز دیگه ای هست این مقدار رو تغییر بدید. ما کاری با اینترفیس های دیگه نداریم و در واقع هدفمون محدود کردن ورودی های خارج از ماشینمون هست
مقدار آی پی مورد نظر ما رو نشون میده که باید با مقدار خودتون عوضش کنید. اینجا میتونید حالت های دیگه مثل رنج و چند آی پی و .. هم بدید
این یعنی داریم در مورد پروتکل tcp صحبت میکنیم
خب اینم اصل داستان که داره پورت ۹۹۹۹ رو مشخص میکنه. شاید بگید که چرا --dport رو استفاده نکردم. دلیلش مکانزیم مپ کردن پورت های داکر هست که اگر از این آپشن استفاده کنید مجبورید پورت ۵۴۳۲ رو محدود کنید. اون وقت اگر دوتا پسترگس داشته باشید دسترسی به هردو محدود میشه
خب این هم که مشخص داره کانکشن رو قبول میکنه
این کامند پورت شما رو برای همه میبنده ولی چون کامند قبلی رو زودتر وارد کردید اگر آی پی شما با قبلی مچ بشه اجازه ورود داره.
iptables -A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j DROP
تفاوتش با بالایی اینه که میگه: هرکس از اینترفیس eth0 اومد و خواست از طریق tcp به پورت 9999 متصل بشه رو drop کن. پس اگر قبل از این رولی داشته باشید که اجازه ورود رو بده، آی پی شما با این رول مواجه نمیشه. کسی به این رول میرسه که رول های دیگه رو رد کرده باشه و باهاشون مچ نشده باشه.
دقت کنید که این دوتا رول باید بالای DOCKER-USER قرار بگیرند! پایین تر توضیح دادم چطوری این کار رو بکنید.
شما باید حتما از دستورات خودتون بکاپ بگیرید. اونم به روش خیلی خیلی ساده. من حتی از این روش برای ادیت رول ها هم استفاده میکنم.
با دستور زیر میتونید لیست تمام رول های خودتون رو داخل یک فایل بریزید:
sudo iptables-save > iptables.txt
شما میتونید این فایل رو باز کنید و تغییرات خودتون رو داخلش وارد کنید یا ترتیب اون ها رو تغییر بدید.
با دستور زیر هم میتونید رول های ذخیره شده رو لود کنید:
sudo iptables-restore < iptables.txt
دقت کنید که خود داکر داخل DOCKER-USER یک رول داره و دو رول شما باید بالای اون قرار بگیره. میتونید با ویرایش فایلی که درست کردید ترتیب اون رو تغییر بدید:
-A DOCKER-USER -s 8.8.8.8/32 -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j ACCEPT
-A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 9999 --ctdir ORIGINAL -j DROP
-A DOCKER-USER -j RETURN