Docker
도 커와 함께 iptables
수색…
소개
이 주제는 iptables를 사용하여 외부에서 도커 컨테이너에 대한 액세스를 제한하는 방법에 관한 것입니다.
참을성이없는 사람들을 위해 예제를 확인할 수 있습니다. 다른 사람들은 새로운 규칙을 만드는 방법을 이해하기 위해 발언 섹션을 읽으십시오.
통사론
- iptables -I DOCKER [RULE ...] [ACCEPT | DROP] // DOCKER 테이블의 맨 위에 규칙을 추가하려면
- iptables -D DOCKER [RULE ...] [ACCEPT | DROP] // DOCKER 테이블에서 규칙을 제거하려면
- ipset restore </etc/ipfriends.conf // ipset ipfriends 를 재구성하려면
매개 변수
매개 변수 | 세부 |
---|---|
ext_if | Docker 호스트의 외부 인터페이스. |
XXX.XXX.XXX.XXX | Docker 컨테이너가 액세스하는 특정 IP를 제공해야합니다. |
YYY.YY.YYY.YYY | Docker 컨테이너가 액세스하는 또 다른 IP가 제공되어야합니다. |
친구 사귀기 | Docker 컨테이너에 액세스 할 수있는 IP를 정의하는 ipset 이름입니다. |
비고
문제
Docker 컨테이너에 대한 iptables 규칙을 구성하는 것은 약간 까다 롭습니다. 처음에는 "클래식"방화벽 규칙이 트릭을 수행해야한다고 생각할 것입니다.
예를 들어, nginx-proxy 컨테이너와 여러 서비스 컨테이너를 구성하여 HTTPS를 통해 일부 개인 웹 서비스를 노출한다고 가정 해 보겠습니다. 그런 다음 이와 같은 규칙은 IP XXX.XXX.XXX.XXX에 대해서만 웹 서비스에 대한 액세스 권한을 부여해야합니다.
$ iptables -A INPUT -i eth0 -p tcp -s XXX.XXX.XXX.XXX -j ACCEPT
$ iptables -P INPUT DROP
그것은 작동하지 않을 것이다, 당신의 콘테이너는 모두를 위해 아직도 접근 가능하다.
실제로 Docker 컨테이너는 호스트 서비스가 아닙니다. 호스트의 가상 네트워크에 의존하며 호스트는이 네트워크의 게이트웨이 역할을합니다. 그리고 게이트웨이와 관련하여 라우팅 된 트래픽은 INPUT 테이블에 의해 처리되지 않고 FORWARD 테이블에 의해 처리됩니다.
그러나 모든 것이 아닙니다. 사실 Docker 데몬은 컨테이너 네트워크 연결에 관한 마술을하기 시작할 때 많은 iptables 규칙을 만듭니다. 특히 FORWARD 테이블에서이 새 테이블로 트래픽을 전달하여 컨테이너 관련 규칙을 처리하는 DOCKER 테이블이 만들어집니다.
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:https
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:http
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
해결책
공식 문서 ( https://docs.docker.com/v1.5/articles/networking/) 를 확인하면 Docker 컨테이너 액세스를 하나의 특정 IP로 제한하는 첫 번째 해결책이 제공됩니다.
$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
실제로 DOCKER 테이블 맨 위에 규칙을 추가하는 것이 좋습니다. Docker에 의해 자동으로 구성된 규칙을 방해하지 않으며 간단합니다. 그러나 두 가지 주요 결함 :
- 먼저 두 IP 대신 액세스해야하는 경우 무엇입니까? 여기서 오직 하나의 src IP 만 수용 할 수 있고, 다른 IP IP는이를 막을 수 있습니다.
- 둘째, 부두 수리업자가 인터넷에 접속해야한다면? 서버 8.8.8.8 만 응답 할 수 있기 때문에 아무런 요청도 발생하지 않습니다.
- 마지막으로, 다른 논리를 추가하려면 어떻게해야할까요? 예를 들어, HTTP 프로토콜을 제공하는 웹 서버에 대한 모든 사용자에게 액세스 권한을 부여하고 다른 모든 것을 특정 IP로 제한하십시오.
첫 번째 관찰을 위해 ipset 을 사용할 수 있습니다. 위의 규칙에서 하나의 IP를 허용하는 대신 미리 정의 된 ipset에서 모든 IP를 허용합니다. 보너스로 iptable 규칙을 다시 정의 할 필요없이 ipset을 업데이트 할 수 있습니다.
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
두 번째 관찰에서는 방화벽에 대한 표준적인 문제입니다. 방화벽을 통해 서버에 연결할 수 있으면 방화벽이 서버가 사용자의 요청에 응답하도록 승인해야합니다. 이는 확립 된 연결과 관련이있는 패킷을 인증함으로써 수행 될 수 있습니다. 도커 로직의 경우 다음을 제공합니다.
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
마지막 관찰은 한 지점에 초점을 맞추고 있습니다 .iptables 규칙은 필수적입니다. 실제로, 일부 연결 (ESTABLISHED 연결에 관한 것 포함)을 수용하는 추가 논리는 IPSet과 일치하지 않는 나머지 모든 연결을 거부하는 DROP 규칙 앞에 DOCKER 테이블의 맨 위에 놓아야합니다.
테이블의 맨 위에 규칙을 삽입하는 iptable의 -I 옵션을 사용하기 때문에 이전 iptables 규칙을 역순으로 삽입해야합니다.
// Drop rule for non matching IPs
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
// Then Accept rules for established connections
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 3rd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 2nd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 1st custom accept rule
이 모든 것을 염두에두고이 구성을 보여주는 예제를 확인할 수 있습니다.
Docker 컨테이너에 대한 IP 액세스 제한
먼저 ipset을 설치 하십시오 . 그것을하는 방법을 알기 위해서는 배포판을 참조하십시오. 예를 들어, 다음은 데비안과 같은 배포판에 대한 명령입니다.
$ apt-get update
$ apt-get install ipset
그런 다음 Docker 컨테이너에 대한 액세스를 열려고하는 IP가 포함 된 ipset을 정의하는 구성 파일을 만듭니다.
$ vi /etc/ipfriends.conf
# Recreate the ipset if needed, and flush all entries
create -exist ipfriends hash:ip family inet hashsize 1024 maxelem 65536
flush
# Give access to specific ips
add ipfriends XXX.XXX.XXX.XXX
add ipfriends YYY.YYY.YYY.YYY
이 ipset을로드하십시오.
$ ipset restore < /etc/ipfriends.conf
Docker 데몬이 실행 중인지 확인하십시오. 다음 명령을 입력 한 후에 오류가 나타나지 않아야합니다.
$ docker ps
iptables 규칙을 삽입 할 준비가되었습니다. 주문을 존중 해야합니다 .
// All requests of src ips not matching the ones from ipset ipfriends will be dropped.
$ iptables -I DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
// Except for requests coming from a connection already established.
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
새 규칙을 만들려면 새 규칙을 삽입하기 전에 추가 한 모든 맞춤 규칙을 제거해야합니다.
$ iptables -D DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
$ iptables -D DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT
Docker 데몬이 시작될 때 제한 액세스 구성
진행중인 작업
일부 맞춤 iptables 규칙
진행중인 작업