Rockylinux(OracleLinux) 8.x 에서 Docker 는 run/start/stop 을 할때
Docker-proxy 가 iptables 를 이용해서 DOCKER, DOCKER-USER, DOCKER-ISOLATION-STAGE-1, DOCKER-ISOLATION-STAGE-2 등의 Chain을
만들어 관리 하기 때문에 기존에 설정된 firewall 설정을 무시하고 호출이 가능한 상태가 된다.
OCI 에서는 인스턴스에 시큐리티 리스트에서 아이피/포트를 관리할 수 있으나
스위치의 access_list 처럼 같은 서브넷에 속한 모든 서버가 영향을 받기 때문에 firewall 에서
설정한 포트만 오픈을 하고자 할때 사용할 수 있는 방법이다.(OCI 안에서 여러 인스턴스를 운영하거나 로컬에서 Docker 서버를 운영할때..)
AWS 의 보안 그룹은 각 인스턴스 별로 작동하기 때문에 불필요 하다.
- 먼저 도커의 iptables 사용 옵션을 끄고 docker 를 재시작 한다.
12~]# echo '{ "iptables": false }' > /etc/docker/daemon.json~]# systemctl restart docker.service docker.socket - firewalld 에서 설정된 값을 모두 초기화 한다.
1~]# iptables -F && iptables -X - Docker 의 네트워크 정보를 확인 한다.
12~]# docker network inspect bridge -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'172.17.0.0/16 - Container 에서 호스트롤 통해 outbound 를 위한 설정을 추가 한다. (첫번째줄에 Docker의 네트워크 정보를 입력해서 실행 해야 한다.)
123456~]# firewall-cmd --permanent --zone docker --add-source 172.17.0.1/16~]# firewall-cmd --permanent --new-policy dockerToWorld~]# firewall-cmd --permanent --policy dockerToWorld --add-ingress-zone docker~]# firewall-cmd --permanent --policy dockerToWorld --add-egress-zone ANY~]# firewall-cmd --permanent --policy dockerToWorld --set-target ACCEPT~]# firewall-cmd --permanent --policy dockerToWorld --add-masquerade - inbound 를 위한 설정을 추가 한다.
123~]# firewall-cmd --permanent --new-policy dockerFwdPort~]# firewall-cmd --permanent --policy dockerFwdPort --add-ingress-zone ANY~]# firewall-cmd --permanent --policy dockerFwdPort --add-egress-zone HOST - 필요에 따라 아래와 같이 inbound 설정을 추가 한다. (nginx-docker 를 위한 80(tcp), 443(tcp/udp) 을 연다.)
123~]# firewall-cmd --permanent --policy dockerFwdPort --add-forward-port port=443:proto=tcp:toport=443:toaddr=172.17.0.2~]# firewall-cmd --permanent --policy dockerFwdPort --add-forward-port port=443:proto=udp:toport=443:toaddr=172.17.0.2~]# firewall-cmd --permanent --policy dockerFwdPort --add-forward-port port=80:proto=tcp:toport=80:toaddr=172.17.0.2
마지막에 여는 명령어를 보면 알겠지만 열려고 하는 컨테이너의 IP를 알아야 한다.
때문에 Container 으로 진입해서 ifconfig 를 보면 알 수 있겠지만 매우 귀찬은 관계로 스크립트를 작성 하였다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#!/bin/bash Chain_inbound=dockerFwdPort iptables_inbound=$(iptables -nL $Chain_inbound 2>/dev/null) Container_list=$(docker ps --format 'table {{.Names}}\t{{.Ports}}') echo -e "\e[35;1m===================================================================================\e[0m" echo "$Container_list" echo -e "\e[35;1m===================================================================================\e[0m" echo -e "\e[32;1m*** Run manually what Container open to out of world. ***\e[0m" echo -e "\e[35;1m-----------------------------------------------------------------------------------\e[0m" for a in $(awk '!/NAMES/{print $1}' <<< "$Container_list") do Container_data=$(docker inspect $a --format '{{.NetworkSettings.IPAddress}} {{.HostConfig.PortBindings}}' | sed 's/map\[//g;s/\]//g;s/\[//g;s/[{}]//g;s/: /:/g') Container_IP=$(awk '{print $1}' <<< $Container_data) echo -e "\e[34;1m### $a ###\e[0m" for b in $(awk '{$1="";print $0}' <<< $Container_data) do to_port=$(cut -d'/' -f1 <<< $b) proto=$(cut -d'/' -f2 <<< $b | cut -d":" -f1) from_port=$(cut -d':' -f2 <<< $b) if [ $(grep -w $Container_IP <<< "$iptables_inbound"|grep -w $to_port|grep -w $proto|wc|awk '{print $1}') -eq 0 ];then echo " firewall-cmd --permanent --policy $Chain_inbound --add-forward-port port=$from_port:proto=$proto:toport=$to_port:toaddr=$Container_IP" ((COUNT++)) fi done echo done if [[ $COUNT -ge 1 ]];then echo -e "\e[34;1m### restart firewalld ###\e[0m" echo " firewall-cmd --reload" fi echo -e "\e[35;1m===================================================================================\e[0m" exit 0 |
실행하면 아래와 같이 나오는데 필요한 Container 부분만 실행을 해서 사용하면 된다.
출처: https://firewalld.org/2024/04/strictly-filtering-docker-containers