Docker를 사용할 때 UFW (Uncomplicated Firewall)가 아무것도 차단하지 않습니다


44

이것은 Ubuntu Server (14.04 LTS)를 처음 설정 한 것으로 방화벽 (UFW) 구성에 문제가 있습니다.

난 단지 필요로 ssh하고 http내가이 일을하고, 그래서 :

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot

그러나 여전히이 컴퓨터의 다른 포트에있는 데이터베이스에 연결할 수 있습니다 . 내가 뭘 잘못하고 있는지에 대한 아이디어가 있습니까?

편집 :이 데이터베이스는 Docker 컨테이너에 있습니다. 관련이있을 수 있습니까? 내 ufw 구성을 재정의합니까?

EDIT2 : 출력sudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)

어떤 데이터베이스? 어느 포트? 이 기계가 같은 기계입니까? ufw status
solsTiCe

@ solsTiCe 예, 같은 컴퓨터라고 확신합니다. 데이터베이스는 포트 (A 고정 표시기 컨테이너) InfluxDB이다 8083하고 8086. ufw status verbose질문에 출력을 추가했습니다 . 감사.
ESala

답변:


63

문제는 -p컨테이너 에서 플래그를 사용하는 것 입니다.

Docker는로 iptables표시되지 않은을 (를) 직접 변경 하는 것으로 나타났습니다 ufw status.

가능한 해결책은 다음과 같습니다.

  1. -p플래그 사용을 중지하십시오 . 대신 도커 연결 또는 도커 네트워크를 사용하십시오.

  2. 컨테이너가 컴퓨터 외부에 노출되지 않도록 로컬로 바인딩하십시오.

    docker run -p 127.0.0.1:8080:8080 ...

  3. -p플래그 사용을 고집하는 경우 docker iptables가 비활성화 /etc/docker/daemon.json하고 다시 시작 하여 터치하지 않도록 지시하십시오 .

    { "iptables" : false }

옵션 1 또는 2를 권장합니다. 옵션 3 에는 컨테이너가 인터넷에 연결할 수 없게되는 것과 같은 부작용 이 있습니다.


8
이것은 매우 유용합니다-ufw에서 허용되지 않은 포트에 액세스 할 수 있다는 것에 열중했습니다. iptables = false를 사용하면 컨테이너가 로컬 호스트에서 액세스 가능해 지므로 (예 : 리버스 프록시 등) 크게 중단됩니다. 컨테이너가 올바르게 청취하는지 확인하는 것이 좋습니다. -p 80:80을 사용하지 말고 -p 127.0.0.1:80:80 또는 127.0.0.1:3000:80과 같은 다른 포트를 사용하여 nginx 또는 apache로 리버스 프록시하고 포트를 사용하지 마십시오. 충돌.
Andreas Reiff

2
@AndreasReiff 당신이 맞지만 요즘에는 -p가능한 한 피하는 것이 가장 좋습니다 . 예를 들어, 리버스 프록시의 경우 I는 작업자 컨테이너에 대한 모든 포트를 매핑하지 않는 한 다음의 자신과 용기에 nginx를 넣어 -p 80:80하고 --link다른 사람에. 이 방법으로 포트 충돌이 발생하지 않으며 유일한 액세스 지점은 nginx를 통한 것입니다.
ESala

1
또한이 게시물을 확인하여 세 번째 예방 조치를 취하십시오! svenv.nl/unixandlinux/dockerufw
Henk

1
중요 : /etc/default/dockerupstart 구성에 사용되는 구성 파일입니다. upstart에서 systemd로 이동 한 경우이 파일은 사용되지 않습니다.
orshachar

@ESala이 답변의 날짜가 표시되었으므로 정확한 답변을 취소하십시오.
ctbrown

8

16.04는 새로운 도전을 제시합니다. 나는 그림과 같이 모든 단계 한 UFW 방화벽 뒤에 도커 실행을 하지만 나는 16.04에 대한 작업에 고정 표시기 플러스 UFW를 가져올 수 없습니다. 즉, 내가 한 일에 관계없이 모든 도커 포트는 전 세계적으로 인터넷에 노출되었습니다. 내가 이것을 찾을 때까지 : Docker 1.12+를 IPTABLES / FirewallD를 방해하지 않도록 설정하는 방법

파일을 만들고 /etc/docker/daemon.json다음을 넣어야했습니다.

{
    "iptables": false
}

나는 그 발행 sudo service docker stopsudo service docker start마침내 고정 표시기 단순히 UFW에서 해당 규칙을 따르고있다.

추가 데이터 : Docker가 UFW를 능가합니다!


Ubuntu 16.04 및 Docker 버전 17.09에서는이 솔루션이 컨테이너에서 아웃 바운드 연결을 끊습니다. 응답 askubuntu.com/a/833363/262702askubuntu.com/a/954041/262702
ctbrown

4

systemd의 init 시스템 (Ubuntu 15.10 이상) /etc/docker/daemon.json을 사용하는 경우 (존재하지 않는 경우 만들어야 할 수도 있음 ) 편집 하십시오 iptables. 키가 구성 되어 있는지 확인하십시오 .

{   "iptables" : false }

편집 : 컨테이너 내부에서 인터넷 연결이 끊길 수 있습니다.

UFW를 사용하도록 설정 한 경우 컨테이너 내부에서 인터넷에 액세스 할 수 있는지 확인하십시오. 그렇지 않은 경우 on으로 정의 DEFAULT_FORWARD_POLICY하고 여기에 설명 된 트릭을 적용 해야합니다 . https://stackoverflow.com/a/17498195/507564ACCEPT/etc/default/ufw


2

Docker를 실행하고 포트 매핑을 수행 할 때 빠른 해결 방법이 있습니다. 당신은 항상 할 수 있습니다

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

Docker가 외부에서 액세스되지 않도록하십시오.


2

/etc/docker/daemon.json컨텐츠와 함께 사용

{
  "iptables": false
}

해결책처럼 들리 겠지만 다음에 다시 부팅 할 때까지만 작동합니다 . 그런 다음 컨테이너에 인터넷에 액세스 할 수있는 컨테이너가 없으므로 웹 사이트를 핑 (ping) 할 수 없습니다. 원하지 않는 동작 일 수 있습니다.

컨테이너를 특정 IP에 바인딩 할 때도 마찬가지입니다. 그렇게하고 싶지 않을 수도 있습니다. 궁극적 인 옵션은 컨테이너를 만들고 UFW 뒤에 컨테이너를 만드는 방법 과이 컨테이너를 만드는 방법에 관계없이 솔루션을 만드는 것입니다.

/etc/docker/daemon.json파일 을 작성한 후 다음을 호출하십시오.

sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload

따라서 UFW에서 기본 전달 정책을 설정하여 수락하고 다음을 사용하십시오.

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE

docker-compose를 사용하려는 경우 위의 명령에서 IP를로 실행할 때 네트워크 docker-compose 작성의 IP로 바꿔야합니다 docker-compose up.

이 기사에서 문제와 해결책을보다 포괄적 으로 설명했습니다.

그것이 도움이되기를 바랍니다!


1

필자의 경우 특정 IP에서만 Docker에 액세스 할 수 있도록 iptables를 수정했습니다.

당으로 ESala의 대답 :

-p컨테이너에서 플래그 를 사용 하면 Docker는 ufw를 무시하고 iptables를 직접 변경합니다.

Docker가 iptables에 추가 한 레코드의 예

'DOCKER'체인으로 라우팅 :

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

'DOCKER'체인에서 컨테이너로 패킷 전달 :

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

지정된 소스 IP (예 :)에서만 DOCKER 체인에 액세스 할 수 있도록 iptables를 수정할 수 있습니다 1.1.1.1.

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

iptables 규칙 을 사용 iptables-save > /tmp/iptables.conf하고 iptables-restore < /tmp/iptables.conf덤프, 편집 및 복원 할 수 있습니다 .


0

컨테이너를 시작할 때 --network = host를 사용하여 docker가 기본 브리지 네트워크 대신 격리 된 호스트 전용 네트워크에 포트를 매핑합니다. 브리지 된 네트워크를 차단할 법적 방법이 없습니다. 또는 격리 된 사용자 정의 사용자 정의 네트워크를 사용할 수 있습니다.


0
  1. 도커 콘솔에 로그인하십시오.

    sudo docker exec -i -t docker_image_name / bin / bash

  2. 그런 다음 도커 콘솔 내부에서

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. ufw 규칙을 추가하고 ufw를 활성화하십시오

    sudo ufw 활성화

    • Docker 이미지는 --cap-add = NET_ADMIN으로 시작해야합니다.

"NET_ADMIN"Docker 옵션을 활성화하려면 :

1. 컨테이너 정지 :

도 커가 컨테이너를 막습니다. 2. 컨테이너 ID 얻기 :

도커는 컨테이너를 검사합니다. 3. hostconfig.json 수정 (기본 도커 경로 : / var / lib / docker, 변경할 수 있음)

vim /var/lib/docker/containers/containerid/hostconfig.json

4. "CapAdd"를 검색하고 null을 [ "NET_ADMIN"]으로 수정하십시오.

...., "VolumesFrom": null, "CapAdd": [ "NET_ADMIN"], "CapDrop": null, .... 5. 호스트 컴퓨터에서 도커를 다시 시작하십시오.

서비스 도커 재시작; 6. 코너를 시작하십시오.

도 커가 컨테이너를 시작합니다.


0

나는 docker-compose여러 컨테이너를 시작했고 ufw 규칙을 무시하고 한 포트가 세계에 노출되었다는 문제가있었습니다.

내 docker 컨테이너에서만 포트를 사용할 수있게하는 수정은 내 docker-compose.yml파일 에서 다음과 같이 변경되었습니다 .

ports:
- "1234:1234"

이에:

ports:
- "1234"

이제 다른 도커 컨테이너는 여전히 포트를 사용할 수 있지만 외부에서 액세스 할 수는 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.