Tường lửa không biến chứng (UFW) không chặn bất cứ thứ gì khi sử dụng Docker


44

Đây là lần đầu tiên tôi thiết lập Máy chủ Ubuntu (14.04 LTS) và tôi gặp sự cố khi định cấu hình tường lửa (UFW).

Tôi chỉ cần sshhttpvì vậy tôi đang làm điều này:

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

Nhưng tôi vẫn có thể kết nối với cơ sở dữ liệu trên các cổng khác của máy này . Bất cứ ý tưởng về những gì tôi đang làm sai?

EDIT : các cơ sở dữ liệu này nằm trên các container Docker. Điều này có thể liên quan? nó có ghi đè lên cấu hình ufw của tôi không?

EDIT2 : đầu ra củasudo 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)

cơ sở dữ liệu gì? cổng nào Bạn có chắc đây là cùng một máy? đầu ra của ufw status
solsTiCe

@solsTiCe vâng, tôi chắc chắn đó là cùng một máy. Cơ sở dữ liệu là InfluxDB (trên một container docker) với các cổng 80838086. Tôi đã thêm ufw status verboseđầu ra trong câu hỏi. Cảm ơn.
ESala

Câu trả lời:


64

Vấn đề là sử dụng -pcờ trên container.

Nó chỉ ra rằng Docker thực hiện các thay đổi trực tiếp trên của bạn iptables, mà không được hiển thị với ufw status.

Các giải pháp có thể là:

  1. Ngừng sử dụng -pcờ. Sử dụng liên kết docker hoặc mạng docker thay thế.

  2. Ràng buộc các thùng chứa cục bộ để chúng không bị lộ ra ngoài máy của bạn:

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

  3. Nếu bạn khăng khăng sử dụng -pcờ, hãy yêu cầu docker không chạm vào bạn iptablesbằng cách vô hiệu hóa chúng /etc/docker/daemon.jsonvà khởi động lại:

    { "iptables" : false }

Tôi khuyên bạn nên tùy chọn 1 hoặc 2. Coi chừng tùy chọn 3 có tác dụng phụ , như các container không thể kết nối với internet.


8
Điều này rất hữu ích - tôi đã phát điên khi có thể truy cập các cổng mà tôi không cho phép ở ufw. Tuy nhiên, việc sử dụng iptables = false sẽ phá vỡ rất nhiều, như các container có thể truy cập được trên localhost, ví dụ như để ủy quyền ngược. Tốt hơn để đảm bảo rằng container nghe đúng, không sử dụng -p 80:80 mà sử dụng -p 127.0.0.1:80:80 hoặc các cổng khác nhau như 127.0.0.1:3000:80 để ủy quyền ngược với nginx hoặc apache và không có cổng đụng độ.
Andreas Reiff

2
@AndreasReiff bạn đúng, nhưng gần đây tôi thấy tốt nhất nên tránh -pcàng nhiều càng tốt. Ví dụ: trong trường hợp proxy ngược, tôi không ánh xạ bất kỳ cổng nào cho các thùng chứa công nhân, sau đó đặt nginx vào thùng chứa của chính nó -p 80:80và một --linkcho các cổng khác. Bằng cách này, không thể có bất kỳ xung đột cổng nào và điểm truy cập duy nhất là thông qua nginx.
ESala

1
Ngoài ra kiểm tra bài này để đề phòng thứ ba bạn phải thực hiện! svenv.nl/unixandlinux/dockerufw
Henk

1
Quan trọng : /etc/default/dockerlà một tệp cấu hình được sử dụng bởi cấu hình khởi động. Nếu bạn đã chuyển từ upstart sang systemd, tập tin này sẽ không được sử dụng.
orshachar

@ESala Bạn nên nghĩ về việc bỏ đánh dấu câu trả lời này là chính xác vì nó là ngày.
ctbrown

8

16.04 đưa ra những thách thức mới. Tôi đã thực hiện tất cả các bước như được hiển thị Running Docker đằng sau tường lửa ufw NHƯNG tôi KHÔNG thể lấy docker cộng với UFW để hoạt động vào ngày 16.04. Nói cách khác, bất kể tôi đã làm gì, tất cả các cổng docker đều được hiển thị trên toàn cầu với internet. Cho đến khi tôi tìm thấy điều này: Cách đặt Docker 1.12+ thành KHÔNG can thiệp vào IPTABLES / FirewallD

Tôi đã phải tạo tập tin /etc/docker/daemon.jsonvà đặt như sau:

{
    "iptables": false
}

Sau đó tôi đã ban hành sudo service docker stopthì sudo service docker startdocker FINALLY chỉ đơn giản là tuân theo các quy tắc phù hợp trong UFW.

Dữ liệu bổ sung: Docker ghi đè UFW!


Với Ubuntu 16.04 và Docker phiên bản 17.09, giải pháp này phá vỡ kết nối ra khỏi các container. Xem câu trả lời Askubfox.com/a/833363/262702askubfox.com/a/954041/262702
ctbrown

5

Nếu bạn đang sử dụng hệ thống init của systemd (Ubuntu 15.10 trở lên) chỉnh sửa /etc/docker/daemon.json(có thể cần phải tạo nó nếu nó không tồn tại), hãy đảm bảo rằng nó có iptableskhóa được cấu hình:

{   "iptables" : false }

EDIT : điều này có thể khiến bạn mất kết nối với internet từ bên trong các container

Nếu bạn đã bật UFW, hãy xác minh rằng bạn có thể truy cập internet từ bên trong các thùng chứa. nếu không - bạn phải xác định DEFAULT_FORWARD_POLICYnhư ACCEPTtrên /etc/default/ufwvà áp dụng mẹo được mô tả ở đây: https://stackoverflow.com/a/17498195/507564


2

Cách giải quyết nhanh là khi chạy Docker và thực hiện ánh xạ cổng. Bạn luôn có thể làm

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

để ngăn Docker của bạn khỏi bị truy cập từ bên ngoài.


2

Sử dụng /etc/docker/daemon.jsonvới nội dung

{
  "iptables": false
}

nghe có vẻ giống như một giải pháp nhưng nó chỉ hoạt động cho đến lần khởi động lại tiếp theo . Sau đó, bạn có thể nhận thấy rằng không có container nào của bạn có quyền truy cập Internet, do đó bạn không thể ping bất kỳ trang web nào. Nó có thể là hành vi không mong muốn.

Áp dụng tương tự để ràng buộc một container với IP cụ thể. Bạn có thể không muốn làm điều đó. Tùy chọn cuối cùng là tạo một thùng chứa và đặt nó phía sau UFW, không quan trọng chuyện gì xảy ra và cách bạn tạo thùng chứa này, vì vậy có một giải pháp:

Sau khi bạn tạo /etc/docker/daemon.jsontệp, hãy gọi:

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

để bạn thiết lập chính sách chuyển tiếp mặc định trong UFW để chấp nhận và sử dụng:

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

Nếu bạn sắp sử dụng docker-compose, thì nên thay thế IP từ lệnh trên bằng IP của docker-compose tạo mạng khi chạy nó docker-compose up.

Tôi đã mô tả vấn đề và giải pháp toàn diện hơn trong bài viết này

Hy vọng nó giúp!


1

Trong trường hợp của tôi, tôi đã kết thúc việc sửa đổi iptables để chỉ cho phép truy cập vào Docker từ các IP cụ thể.

Theo câu trả lời của ESala :

Nếu bạn sử dụng -pcờ trên container, Docker sẽ thay đổi trực tiếp thành iptables, bỏ qua ufw.

Ví dụ về các bản ghi được thêm vào iptables bởi Docker

Định tuyến đến chuỗi '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

Chuyển tiếp các gói từ chuỗi 'DOCKER' sang container:

-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

Bạn có thể sửa đổi iptables để chỉ cho phép truy cập vào chuỗi DOCKER từ IP nguồn được chỉ định (ví dụ 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

Bạn có thể muốn sử dụng iptables-save > /tmp/iptables.confiptables-restore < /tmp/iptables.confkết xuất, chỉnh sửa và khôi phục các quy tắc iptables.


0

Sử dụng --network = host khi bạn khởi động container để docker sẽ ánh xạ cổng tới mạng chỉ dành cho máy chủ bị cô lập thay vì mạng cầu mặc định. Tôi thấy không có cách hợp pháp để chặn mạng cầu. Ngoài ra, bạn có thể sử dụng mạng do người dùng xác định tùy chỉnh với sự cô lập.


0
  1. Đăng nhập vào bảng điều khiển docker của bạn:

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

  2. Và sau đó bên trong bảng điều khiển docker của bạn:

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. Thêm quy tắc ufw của bạn và kích hoạt ufw

    sudo ufw cho phép

    • Hình ảnh Docker của bạn cần được bắt đầu với --cap-add = NET_ADMIN

Để bật tùy chọn Docker "NET_ADMIN":

1.Stop Container:

docker dừng yourcontainer; 2.Nhận id container:

docker kiểm tra nhà cung cấp của bạn; 3.Modify hostconfig.json (đường dẫn docker mặc định: / var / lib / docker, bạn có thể thay đổi của bạn)

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

4. Tìm kiếm "CapAdd" và sửa đổi null thành ["NET_ADMIN"];

...., "VolumeFrom": null, "CapAdd": ["NET_ADMIN"], "CapDrop": null, .... 5. Khởi động lại docker trong máy chủ;

khởi động lại dịch vụ; 6. Bắt đầu yourconatiner;

docker bắt đầu liên lạc của bạn;


0

Tôi đã từng docker-composebắt đầu một số container và cũng có một vấn đề là một cổng bị phơi bày ra thế giới bỏ qua các quy tắc ufw.

Cách khắc phục để chỉ cung cấp cổng cho bộ chứa docker của tôi là thay đổi này trong docker-compose.ymltệp của tôi :

ports:
- "1234:1234"

đến đây:

ports:
- "1234"

Bây giờ các container-docker khác vẫn có thể sử dụng cổng, nhưng tôi không thể truy cập nó từ bên ngoài.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.