필요한 Docker 컨테이너에 액세스하기 위해 IP 주소를 화이트리스트에 어떻게 넣습니까?

9986 단어 linuxdockersecurity

모티프


최근에 가상 기기에서 실행되는 docker 설정을 보호해야 합니다. 이렇게 하면 특정한 포트 (또는 docker 용기) 만이 네트워크의 특정한 IP 주소를 통해 접근할 수 있습니다.현재, 이것은 간단한 작업인 것 같습니다. 이것은 간단한 작업이지만, iptables와 docker가 네트워크에 iptables를 설정하는 방법에 익숙하지 않으면, 그렇지 않습니다.나는 이 특수한 요구에 관한 어떤 강좌도 찾지 못했기 때문에, 나는 하나를 쓰기로 결정했다.
**면책 성명: * 전체적으로 Linux와 IPtables의 인터넷 세계에 대해 낯설습니다. 더 간단한 방법이 있거나 첨부된 정보가 정확하지 않으면 댓글로 알려주십시오.*

탐색


Docker는 Dockerhere를 사용하여 iptables를 설정하는 방법에 대한 문서 페이지를 가지고 있습니다.그것은 확실히 하나의 IP를 화이트 리스트에 넣는 방법을 열거했다.그래요?일을 다 끝냈습니까?완전히 그렇지는 않습니다.Docker 네트워크의 모든 포트에 단일 IP만 액세스할 수 있습니다.완전히 우리가 필요로 하는 것은 아니다.만약 이것이 당신의 사용 사례라면, 나는 당신이 더 이상 읽는 것을 멈추고, 문서를 자세히 읽고, 주어진 임무를 완성하는 것을 권장합니다. 포트 단계에 제한을 추가하는 방법을 알고 싶으면 돌아오십시오.

docker가 간단한 방화벽을 복잡하게 만들까?


UFW는 Linux에서 방화벽 규칙을 관리하는 더욱 간단하고 빠른 방법이다.우선, 그것은 이름으로 명명되었다 — 간단하다그러나 내가 docker에서 발견한 바와 같이 UFW는 CFW 같거나 더 통속적으로 말하면 TFW이다.나는 여기서 상세하게 소개하지 않겠지만, docker가 iptables를 조종하는 방식 때문에 정상적인 UFW 흐름은 작용하지 않을 것이며, 사실상 그것은 그것보다 더 많은 문제를 해결할 것이다 — 간고한 방식으로 이 점을 배웠다.이를 어떻게 실현하는지에 대한 강좌가 많고, 심지어는 github 프로젝트가 docker를 지원하기 위해 UFW를 확장하는 데 주력하고 있다.만약 대부분의 설정이 UFW에 의존한다면, 나는 네가 가서 보아야 한다고 건의한다. 왜냐하면 나의 용례에 있어서, 이것은 너무 심한 것 같아서, 나도 그것을 탐색하지 않았기 때문이다.

근데 iTables는 도대체 뭐야?


wikipedia page의 IPtables와 official documentation에 있는 아주 상세한 정보를 볼 수 있습니다. 내가 그것들이 무엇인지 설명하는 것이 아니라, 이것은 나쁜 일일 것입니다.이 글에 필요한 유일한 세부 사항은 다음과 같다.Iptables에는 주로 네 가지 종류의 표가 있는데 그것이 바로 raw, mangle,nat와 Filter이다.그것들은 이 순서에 따라 처리한 것이다.세분화에 대한 자세한 내용은 다음 그림을 참조하십시오.

docker가 iptables를 어떻게 조작하는지 이해하기


Docker는 필터 테이블에 Docker와 Docker-USER라는 두 개의 사용자 정의 iptables 체인을 만듭니다.모든 도커와의 소통은 이 규칙들을 통해 검증된다.DOCKER 네트워크 모듈로 채워져 있으므로 DOCKER 체인을 변경하지 않는 것이 좋습니다.추가가 아닌 DOCKER-USER 체인에 필요한 모든 사용자 정의 유효성 검사를 미리 전송합니다.docker의 문서 페이지에서 빠진 중요한 정보는 컨테이너의 모든 항구 전송 규칙이 iptables의nat표에 추가되는 것입니다. 이것은 큰 문제입니다.필터 테이블이 어떻게 설정되었는지 보려면 다음 명령을 실행하십시오.
sudo iptables -L -v
docker와 관련된 모든 전송 연결은 docker 네트워크 인터페이스로 연결되기 때문에 이 연결(또는 패키지)에 대한 모든 필터는 전방향 필터 체인에서 진행됩니다.따라서 전방향 체인을 확인하면 첫 번째 항목이 DOCKER-USER임을 알 수 있습니다.즉, 규칙에 제약이 추가되지 않았기 때문에 이 체인에 수신된 모든 패킷이 DOCKER-USER 체인에 전달됩니다.DOCKER-USER 체인으로 이동합니다. 기본적으로 제약이 없는 되돌아오는 규칙만 보일 것입니다. 이것은 필터가 부모 체인의 다음 규칙에서 다시 시작된다는 것을 의미합니다.만약 우리가 어떤 데이터 패키지를 처리하고 싶지 않다면, 우리는 규칙을 되돌리기 전에 그것을 필터해야 한다.

단도직입적으로


특정 IP만 특정 포트에서 실행되는 특정 서비스와 통신할 수 있도록 하는 우리의 목표를 되돌아봅시다.입력만 받고 출력을 생성하며 세부 사항을 공개하지 않는 블랙박스를 개발하면 필요할 수도 있습니다.입력과 출력 흐름을 제외하고는 이 상자에 대한 모든 접근을 막기를 원할 수도 있습니다.만약 우리가 두 개의 docker 용기가 실행 중이라면, django (8080) 와postgres (5432) 이다.우리는 8080의django 서버에 들어갈 수 있도록 허용하고 데이터베이스에 외부 연결을 허용하지 않으려고 합니다.

기본적으로 외부 연결은 허용되지 않습니다.


기본적으로 모든 전송과 전송의 연결을 삭제하지만, 이미 만들어진 연결과 모든 ssh 연결을 허용하려면 아래 명령을 실행하십시오.우리는 시스템에 외부 네트워크 인터페이스 (eth0)만 있다고 가정한다.
*# Allow loopback connections.*
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

*# Allow established and related incoming connections.*
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

*# Allow established outgoing connections.*
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT

*# Allow all incoming and outgoing SSH connections.*
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

*# Drop all incoming and forwarding connections by default.*
iptables -P INPUT DROP
iptables -P FORWARD DROP

*# Drop all forwarded connections from the external interface in the DOCKER-USER chain.*
iptables -I DOCKER-USER -i eth0 -j DROP
이러한 명령에 대한 자세한 내용은 Digital Ocean의 편리한 블로그this를 참조하십시오.
현재 sudo iptables-L-v의 출력을 다시 검사하면 입력과 전송 체인에 대한 기본 정책 (체인 이름 뒤에 있는 괄호에 표시) 이 DROP로 설정되어 있는 것을 볼 수 있습니다.
입력 체인은 이렇습니다.
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  555  416K ACCEPT     all  --  lo     any     anywhere             anywhere            
  147 11595 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
    1    44 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh ctstate NEW,ESTABLISHED
Docker-USER 체인은 이렇습니다.
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  eth0   any     anywhere             anywhere            
   16   864 RETURN     all  --  any    any     anywhere             anywhere
이제 **eth0 인터페이스에서 체인에 도달하는 모든 패킷이 삭제됩니다.**.

여기는 매우 적막하니, 누가 나에게 말해라


정적 IP (192.168.0.69) 가 있다면, 8080 포트를 실행하는django 서버에 요청을 보내고 싶습니다.이 요청을django 용기에 전송할 수 있도록 하려면 다음 명령을 실행하십시오.
*# Allow inbound and outbound traffic for 192.168.0.69 IP on 8080 port.*
iptables -I DOCKER-USER -i eth0 -s 192.168.0.69 -p tcp --dport 8080 -j RETURN
iptables -I DOCKER-USER -o eth0 -d 192.168.0.69 -p tcp --sport 8080 -j RETURN
상기 명령은 포트 8080에서 192.168.0.69로 전송되거나 전송된 모든 전송 tcp 데이터 패키지는 DOCKER-USER 체인에서 부모 체인(FORWARD)으로 되돌아와 진일보한 처리를 하고 이 체인의 그 어떠한 후속 규칙도 건너뛰어야 한다는 두 가지 규칙을 추가했다.따라서 이 패키지들은 버려진 규칙이 그 뒤에 있기 때문에 버려지지 않는다.현재,django 서버는 이 IP 주소로부터 요청을 받을 수 있을 것입니다.다른 IP 주소나 전체 서브넷을 허용하기 위해 미리 여러 규칙을 설정할 수 있습니다.작업이 완료되었습니다.

그런데 잠깐만, 누가 잡았어?


내가 docker도 iptables의nat표를 수정한다고 말한 거 기억나?Docker는 컨테이너에 노출된 모든 포트를 처리하는 데 사용합니다.다음 명령을 실행해서 그것이 도대체 무엇을 했는지 봅시다.
sudo iptables -t nat -L DOCKER
비슷한 출력을 보실 수 있을 것입니다.
Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            
DNAT       tcp  --  anywhere             anywhere             tcp dpt:5432 to:172.18.0.12:5432
DNAT       tcp  --  anywhere             anywhere             tcp dpt:8080 to:172.18.0.7:8080
DNAT       tcp  --  anywhere             anywhere             tcp
이것은 호스트 네트워크의 공개 포트에서 이루어진 모든 연결을 docker 네트워크와 그에 상응하는 용기로 전송할 수 있도록 합니다.
문제 보셨어요?설명 좀 할게요.iptables에서nat표는 필터 테이블 앞에서 처리되기 때문에, docker 용기에서 실행되는 프로세스 포트와 다른 공개 포트를 지정하면 필터 규칙을 작성할 때 문제가 발생합니다.
상기 예시에서 django 서버가 포트 8080에서 실행된다고 가정하지만, 개발 과정에서 다른 django 기반 서버와 어떠한 방해가 발생하지 않도록 공개(또는 비추기)합니다.이 예에서는 sudo iptables-t nat-L DOCKER를 실행하려면 비슷한 출력을 볼 수 있습니다.
Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            
DNAT       tcp  --  anywhere             anywhere             tcp dpt:5432 to:172.18.0.12:5432
DNAT       tcp  --  anywhere             anywhere             tcp dpt:8081 to:172.18.0.7:8080
DNAT       tcp  --  anywhere             anywhere             tcp
앞에서 설명한 대로 IP 화이트리스트 규칙을 작성할 때 포트 8081을 사용하고자 합니다.그러나 이 패키지는 이미 8080 포트로 전송되었고 화이트리스트 규칙의 제약을 위반할 수 있기 때문에 통하지 않는다.이 점을 알게 되어 나는 오랫동안 머리를 긁었다.따라서 위에서 언급한 IP 화이트리스트 규칙을 작성할 때 호스트 맵 포트가 아닌 밑바닥 docker 용기의 포트 번호를 사용해야 한다.백명단에 있는 IP의 8081 포트를 사용하여django 서버에 접근하더라도

내가 왜 이걸 신경 써야 돼?


안전하니까.
이것은 나의 원래 중편문장here의 복제판이다.

좋은 웹페이지 즐겨찾기