docker映射端口穿透內(nèi)置防火墻的實(shí)現(xiàn)
一、問(wèn)題現(xiàn)象
1、現(xiàn)象舉例
# 自制的springboot項(xiàng)目的dockerfile # springboot 其實(shí)就是一個(gè)簡(jiǎn)單的hello-world程序,寫(xiě)了一個(gè)HelloController 做測(cè)試 # dockerfile內(nèi)容: FROM java:8 MAINTAINER shan <test@qq2363581677@163.com> ADD ./demo.jar /demo.jar EXPOSE 8848 CMD java -jar /demo.jar # 構(gòu)建鏡像 docker build -f ./dockerfile -t demo . # 創(chuàng)建、映射端口、運(yùn)行容器 docker run -d --name=demo -p 8838:8848 demo
在阿里云服務(wù)器上外置的防火墻或安全組放行端口 8838 后,在瀏覽器發(fā)現(xiàn)可以直接訪問(wèn)到數(shù)據(jù)
----問(wèn)題在于咱還沒(méi)有開(kāi)啟內(nèi)置的防火墻firewalld,卻出現(xiàn)了端口可以直接被訪問(wèn)的情況
2、使用centos7 的防火墻firewalld查看放行端口情況


使用 docker 來(lái)部署項(xiàng)目,發(fā)現(xiàn)直接使用 -p 映射端口,會(huì)出現(xiàn)問(wèn)題:
導(dǎo)致docker直接透過(guò)系統(tǒng)本機(jī)的防火墻,不用開(kāi)端口可以直接外網(wǎng)訪問(wèn) 8838 端口。
二、問(wèn)題原因
1、docker無(wú)視防火墻firewalld 的原因
其實(shí)docker并不是繞過(guò)了防火墻,只是因?yàn)樗鵬ptables里寫(xiě)了規(guī)則,你在firewalld里看不到而已。(centos7系統(tǒng)既有iptables,也有firewalld)
在docker安裝完后,會(huì)接管iptables,只要你docker run的時(shí)候加入?yún)?shù),他會(huì)自動(dòng)向iptables里面添加規(guī)則。
所以使用 -p 容器端口:主機(jī)端口,最終會(huì)在iptables中添加上容器的端口。
防火墻 iptables 和 firewalld 的關(guān)系
- Iptables:是centos6自帶的防火墻工具,對(duì)服務(wù)器自身、網(wǎng)絡(luò)通信流量進(jìn)行控制,用于過(guò)濾數(shù)據(jù)包,屬于網(wǎng)絡(luò)層防火墻。
- FirewallD:是centos7自帶的防火墻工具,但是也同樣支持iptables。能夠允許哪些服務(wù)可用,哪些端口可用,屬于更高一層的防火墻。
iptables 與 firewalld 都不是真正的防火墻, 它們都只是用來(lái)定義防火墻策略的防火墻管理工具。
對(duì)于 centos7 系統(tǒng)既有iptables,也有firewalld
2、使用 iptables的命令可以查看到docker 容器的端口
iptables -L DOCKER

三、問(wèn)題的解決
1、依靠阿里云服務(wù)器提供的外置防火墻(推薦)
- 有的服務(wù)器叫防火墻,有的服務(wù)器叫安全組,都是一個(gè)東西,都是系統(tǒng)的外置防火墻。
- 防火墻就像一個(gè)門(mén),想象一下你的錢(qián)藏到你的房間,這時(shí)候有一個(gè)小偷想要來(lái)偷你的錢(qián),小偷需要先溜進(jìn)你家大門(mén)【外置防火墻(安全組/防火墻)】,然后再溜進(jìn)你的房間【內(nèi)置防火墻(iptables/firewalld)】。
解決方式1:依靠阿里云服務(wù)器提供的外置防火墻放行需要暴露給外界的端口
相當(dāng)于關(guān)閉了你家大門(mén)
雖然內(nèi)置防火墻和外置防火墻一起使用更加安全,但是影響了數(shù)據(jù)訪問(wèn)的效率了,為了速度,有時(shí)候確保安全即可,不用更加安全。
購(gòu)買(mǎi)了騰訊云服務(wù)的老鐵要注意一下:
配置安全組的時(shí)候,不要選擇放行所有端口,要選擇自定義,然后放行80、443、ping、ssh端口(ssh端口建議進(jìn)行修改,不使用默認(rèn)的22)
2、端口映射時(shí)指定監(jiān)聽(tīng)地址為本機(jī)
對(duì)于那些只需要在本地訪問(wèn),不需要向外暴露端口的服務(wù),在進(jìn)行端口映射的時(shí)候指定監(jiān)聽(tīng)地址為127.0.0.1。
# 創(chuàng)建、映射端口、運(yùn)行容器 docker run -d --name=demo -p 127.0.0.1:8838:8848 demo
- 這時(shí)候,外界(通過(guò)瀏覽器)就無(wú)法訪問(wèn)了到8838 端口了,即使在外置防火墻放行了端口。
3、禁用 docker 的 iptables 規(guī)則
原因就是docker 在iptables 加入規(guī)則,才導(dǎo)致內(nèi)置防火墻放行了docker容器的端口,現(xiàn)在咱就根治它,在docker配置文件禁止修改iptables 規(guī)則。
① docker 配置修改,禁止 iptables 規(guī)則
# 編輯/lib/systemd/system/docker.service文件 # 在ExecStart后添加 --iptables=false
② 重載 docker 配置 & 重啟 docker 服務(wù)
systemctl daemon-reload systemctl restart docker
完成上述兩步以及可以采用系統(tǒng) firewall 控制端口訪問(wèn),但會(huì)出現(xiàn) docker 容器間無(wú)法訪問(wèn),而且容器內(nèi)也無(wú)法訪問(wèn)外部網(wǎng)絡(luò)。
③ 使用類似 NAT 網(wǎng)絡(luò)方式使得 docker 可以訪問(wèn)外部網(wǎng)絡(luò)
firewall-cmd --permanent --zone=public --add-masquerade
使用該方法解決 docker 無(wú)視系統(tǒng)防火墻問(wèn)題所帶來(lái)的缺點(diǎn):容器內(nèi)無(wú)法獲取得到客戶端的真實(shí) IP,由于是類似 NAT 網(wǎng)絡(luò),常常 nginx 日志上記錄的是 docker0 網(wǎng)絡(luò)的子網(wǎng) IP,對(duì)于一些業(yè)務(wù)無(wú)法獲取真實(shí) IP 可能不能容忍,看個(gè)人的取舍吧。
4、使用 expose 方式暴露端口,然后采用 nginx 代理轉(zhuǎn)發(fā)(推薦)
(1) 使用dockerCompose 編排+nginx代理轉(zhuǎn)發(fā)
① dockerCompose 中編排內(nèi)容:
version: "3"
services:
app:
image: app
container_name: app
build: ..
expose:
- "8888"
depends_on:
- mysql
- redis
nginx:
image: nginx
container_name: nginx
ports:
- 80:80
- 443:443
volumes:
- /mnt/docker/nginx/:/etc/nginx/
links:
- app
depends_on:
- app② nginx 中的配置:
upstream appstream{
server app:8888; #dockerCompose編排之后,app服務(wù)名相當(dāng)于域名,可以通過(guò)app找到對(duì)應(yīng)的ip地址
}
server{
listen 80;
server_name blog.yilele.site;
location /api {
proxy_pass http://appstream;#nginx代理轉(zhuǎn)發(fā)
}
}(2) 上面例子的demo容器(使用dockerfile)+ nginx
server{
listen 80;
server_name blog.yilele.site;
location /hello {# 啟動(dòng)docker的demo容器后,可以通過(guò)命令:docker inspect demo 找到demo對(duì)應(yīng)的ip地址
proxy_pass http://demo的ip地址:8888; # nginx代理轉(zhuǎn)發(fā)
}
}ports 和 expose 區(qū)別
- ports: 暴露容器端口到主機(jī)的任意端口或指定端口。
不管是否指定主機(jī)端口,使用ports都會(huì)將端口 暴露給主機(jī)和其他容器。
- "9000:8080" # 綁定容器的8080端口到主機(jī)的9000端口 - "443" # 綁定容器的443端口到主機(jī)的任意端口,容器啟動(dòng)時(shí)隨機(jī)分配綁定的主機(jī)端口號(hào)
- expose: 暴露容器給
link到當(dāng)前容器的容器。
即暴露給處于同一個(gè)networks的容器。搭配link 進(jìn)行使用。
expose: - "8000"
參考文章:《docker無(wú)視防火墻問(wèn)題總結(jié)》 https://icharle.com/dockeriptables.html
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker?部署?Nexus?Maven私服的詳細(xì)過(guò)程
Nexus?是一個(gè)強(qiáng)大的倉(cāng)庫(kù)管理器,廣泛用于管理和組織軟件構(gòu)建過(guò)程中的依賴項(xiàng)和構(gòu)件,通過(guò)?Docker?部署?Nexus?私服,可以簡(jiǎn)化安裝和管理過(guò)程,并提供更高的靈活性和可擴(kuò)展性,這篇文章主要介紹了Docker?部署?Nexus?Maven私服的詳細(xì)過(guò)程,需要的朋友可以參考下2024-08-08
Idea通過(guò)docker compose?發(fā)布項(xiàng)目的過(guò)程
這篇文章主要介紹了Idea結(jié)合docker-compose發(fā)布項(xiàng)目,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
Docker容器簡(jiǎn)單部署nginx過(guò)程解析
這篇文章主要介紹了Docker容器簡(jiǎn)單部署nginx過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Docker容器網(wǎng)絡(luò)地址的創(chuàng)建修改
Docker提供了一個(gè)方便的方式來(lái)配置容器的網(wǎng)絡(luò)地址,在本文中,我們將介紹如何修改Docker容器的網(wǎng)絡(luò)地址,本文主要介紹了Docker容器網(wǎng)絡(luò)地址的創(chuàng)建修改,感興趣的可以了解一下2024-01-01
解決docker使用GDB,無(wú)法進(jìn)入斷點(diǎn)的問(wèn)題
這篇文章主要介紹了解決docker使用GDB,無(wú)法進(jìn)入斷點(diǎn)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
docker安裝opengauss數(shù)據(jù)庫(kù)配置過(guò)程詳解
這篇文章主要為大家介紹了docker安裝opengauss數(shù)據(jù)庫(kù)配置過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
Docker 無(wú)法停止或刪除容器服務(wù)問(wèn)題的解決方案
這篇文章主要介紹了Docker 無(wú)法停止或刪除容器服務(wù)問(wèn)題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
Docker中namespace隔離的實(shí)戰(zhàn)
Namespace是Linux內(nèi)核的一個(gè)功能,用于隔離和管理系統(tǒng)資源,如進(jìn)程、網(wǎng)絡(luò)和文件系統(tǒng)等,通過(guò)創(chuàng)建隔離的命名空間,系統(tǒng)可以實(shí)現(xiàn)容器化和資源隔離,提高系統(tǒng)的安全性和穩(wěn)定性,這種技術(shù)廣泛應(yīng)用于Docker等容器技術(shù)中,本文就來(lái)介紹一下Docker中namespace隔離的實(shí)戰(zhàn)2024-11-11

