Moim celem jest ograniczenie dostępu do kontenerów dokerów tylko do kilku publicznych adresów IP. Czy istnieje prosty, powtarzalny proces do osiągnięcia mojego celu? Zrozumienie tylko podstaw iptables podczas korzystania z domyślnych opcji Dockera jest dla mnie bardzo trudne.
Chciałbym uruchomić kontener, uczynić go widocznym dla publicznego Internetu, ale zezwalać tylko na połączenia z wybranych hostów. Spodziewałbym się ustawić domyślną zasadę WEJŚCIA REJECT, a następnie zezwolić tylko na połączenia z moich hostów. Ale reguły NAT i łańcuchy Dockera przeszkadzają, a moje reguły WEJŚCIE są ignorowane.
Czy ktoś może podać przykład realizacji mojego celu, biorąc pod uwagę następujące założenia?
- Hostuj publiczny adres IP 80.80.80.80 na eth0
- Hostuj prywatny adres IP 192.168.1.10 na eth1
docker run -d -p 3306:3306 mysql
- Zablokuj wszystkie połączenia z hostem / kontenerem 3306 oprócz hostów 4.4.4.4 i 8.8.8.8
Z przyjemnością powiążę kontener tylko z lokalnym adresem IP, ale potrzebuję instrukcji, jak poprawnie skonfigurować reguły przekazywania iptables, które przetrwają proces dokowania i host uruchomi się ponownie.
Dzięki!
--ctdir
? Używam-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
DOCKER-USER
tabela zawiera wpis:-A DOCKER-USER -j RETURN
który będzie działał przed powyższym, jeśli go użyjesz-A
. Rozwiązaniem jest wstawienie reguł w nagłówku w odwrotnej kolejności za pomocą-I
.FILTERS
łańcuchu i-I
wstaw nowe reguły (jak powiedziałeś), aby przejść do tego:-I INPUT -j FILTERS
i-I DOCKER-USER -i eth0 -j FILTERS
-I
, żeby być bezpiecznym.W Docker v.17.06 wprowadzono nowy łańcuch iptables o nazwie DOCKER-USER. Ten jest dla twoich niestandardowych reguł: https://docs.docker.com/network/iptables/
W przeciwieństwie do łańcucha DOCKER nie jest resetowany przy budowaniu / uruchamianiu kontenerów. Abyś mógł dodać te wiersze do skryptu config / skryptu iptables w celu obsługi serwera, nawet przed zainstalowaniem dokera i uruchomieniem kontenerów:
Teraz port dla MySQL jest zablokowany przed dostępem zewnętrznym (eth0), nawet jeśli myśl, że doker otwiera port dla świata. (Zasady te zakładają, że twój interfejs zewnętrzny to eth0.)
W końcu będziesz musiał najpierw wyczyścić iptables, zrestartuj usługę dokera, jeśli zbyt wiele pomieszałeś, próbując zablokować port, tak jak ja.
źródło
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION
dlatego niestandardowe instrukcje są wykonywane przed łańcuchem DOCKER.--dport
wewnątrz DOCKER-USER, musi to odpowiadać wewnętrznemu adresowi IP usługi kontenera, a nie odsłoniętemu portowi. Często się ze sobą zgadzają, ale nie zawsze, a to z łatwością może kolidować z innymi usługami, dlatego nadal twierdzę, że to rozwiązanie DOCKER-USER jest na wpół wypalone.AKTUALIZACJA : Choć jest ważne w 2015 roku, to rozwiązanie nie jest już właściwym sposobem na zrobienie tego.
Odpowiedź wydaje się znajdować w dokumentacji Dockera na https://docs.docker.com/articles/networking/#the-world
Skończyło się na tym, że:
Nie dotknąłem opcji
--iptables
lub--icc
.źródło
iptables -vnL DOCKER
, wszystkie porty docelowe to porty w kontenerze. Jeśli dobrze to zrozumiem, oznacza to, że powyższe reguły wpłynęłyby tylko na port3306
w kontenerze - to znaczy, gdybyś był w-p 12345:3306
swoim kontenerze, twoja reguła byłaby nadal wymagana do zablokowania dostępu (tj.--dport 12345
Nie działałaby) , ponieważ reguły ACCEPT łańcucha DOCKER są po NAT.--iptables=false
, ponieważ wydaje się, że jest to najgorszy z nich wszystkich.AKTUALIZACJA: Chociaż ta odpowiedź jest nadal aktualna, odpowiedź @SystemParadox
DOCKER-USER
w połączeniu z--ctorigdstport
jest lepsza.Oto rozwiązanie, które utrzymuje się między ponownymi uruchomieniami i pozwala wpływać na port odsłonięty, a nie port wewnętrzny .
iptables -t mangle -N DOCKER-mysql iptables -t mangle -A DOCKER-mysql -s 22.33.44.144/32 -j RETURN iptables -t mangle -A DOCKER-mysql -s 22.33.44.233/32 -j RETURN iptables -t mangle -A DOCKER-mysql -j DROP iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 3306 -j DOCKER-mysql
Zbudowałem obraz Dockera, który używa tej metody do automatycznego zarządzania iptables dla ciebie, używając zmiennych środowiskowych lub dynamicznie z etcd (lub z obydwoma):
https://hub.docker.com/r/colinmollenhour/confd-firewall/
źródło