miałem ostatnio interesującą sytuację w firmie.
jeden z pracowników miał na swoim komputerze wersję demo nowego serwisu www. i trzeba było wystawić to dla klienta na zewnątrz.
teoretycznie trywiał – jak się okazało, nie do końca.
najpierw ogólnie.
sieć wygląda w uproszczeniu tak:
aplikacja była odpalona na komputerze “pracownik a".
na firewallu/routerze regułki były skomplikowane, ale dla uproszczenia przyjmijmy, że było tylko:
iptables -P INPUT DROP<br /> iptables -P FORWARD DROP<br /> iptables -F<br /> iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT<br /> iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT<br /> iptables -A INPUT -p icmp -j ACCEPT<br /> iptables -A FORWARD -p icmp -j ACCEPT<br /> iptables -A INPUT -i lo -j ACCEPT<br /> iptables -A FORWARD -i lo -j ACCEPT<br /> iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT # eth0 to sieć lokalna, eth1 - internet<br /> iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
jak widać nic skomplikowanego.
no więc pojawia się zadanie – klient ma mieć wystawiony serwis z “pracownik a" (port 80) na dowolnym porcie.
ok. robimy:
iptables -t nat -A PREROUTING -s 243.65.193.17 -p tcp --dport 82 -j DNAT --to-destination 172.30.0.2:80
i … działa. zero zdziwień. proste i miłe.
ale jak wyżej napisałem – trywiał, ale nie do końca. jaki więc haczyk?
no cóż. następnego dnia pojawił się drugi request:
tak jak klient wchodzi na http://192.0.2.94:82/ to pracownicy z sieci (np. pracownik b) też mają móc.
i tu zaczęły się schody.
pierwszy strzał:
iptables -t nat -A PREROUTING -s 172.30.0.0/24 -d 192.0.2.94 -p tcp --dport 82 -j DNAT --to-destination 172.30.0.2:80<br /> iptables -A FORWARD -i eth0 -o eth0 -j ACCEPT
i nie działa.
chwila zastanowienia – nic prostego się nie okazuje.
tak więc rozrysowaliśmy sobie sytuację:
- “pracownik b" wysyła pakiet do 192.0.2.94:82. adres źródłowy pakietu: 172.30.0.3:1031 (jakiś losowy, wysoki port)
- ponieważ pakiet jest do innej sieci niż 172.30.0.0/24, zostaje przekazany do routera
- router ma regułkę która pakiet dnatuje, więc dane pakietu zmieniają się na:
źródło: 172.30.0.3:1031, cel: 172.30.0.2:80 - pakiet przechodzi przez firewalla zaakceptowany i wchodzi z powrotem do lanu.
- pakiet trafia do komputera “pracownik a". super! ale tu zaczynają się kłopoty.
- “pracownik a" odpowiada. zamienia miejscami nadawcę i odbiorcę pakietu, otrzymując:
źródło: 172.30.0.2:80, cel: 172.30.0.3:1031 - ponieważ cel jest w sieci 172.30.0.0/24 – wysyła pakiet bezpośrednio do odbiorcy – z pominięciem routera.
- do komputera “pracownik b" trafia pakiet (ack/syn), na dobry port, ale od złego ip?! “pracownik b" chciał “rozmawiać" z 192.0.2.94:82, a tu dostaje pakiet od 172.30.0.2:80 – czyli jakaś pomyłka. pakiet zostaje olany.
- nie bangla.
po rozrysowaniu sprawa stała się jasna.
pozostaje naprawić. pojawił się pomysł by robić DNAT'a, na “pracownik a" (przekazując pakiet do routera), ale to było brzydkie.
co finalnie zrobiliśmy?
na routerze dodaliśmy jedną regułkę:
iptables -t nat -A POSTROUTING -s 172.30.0.0/24 -d 172.30.0.2 -p tcp --dport 80 -j SNAT --to-source 172.30.0.1
i działa!
pełny przesył wygląda teraz tak:
- “pracownik b" wysyła pakiet do 192.0.2.94:82. adres źródłowy pakietu: 172.30.0.3:1031 (jakiś losowy, wysoki port)
- ponieważ pakiet jest do innej sieci niż 172.30.0.0/24, zostaje przekazany do routera
- router ma regułkę która pakiet dnatuje, więc dane pakietu zmieniają się na:
źródło: 172.30.0.3:1031, cel: 172.30.0.2:80 - pakiet przechodzi przez firewalla zaakceptowany
- przed wyjściem do lanu pakiej jest snatowany, więc dane pakietu zmieniają się na:
źródło: 172.30.0.1:1031, cel: 172.30.0.2:80 - pakiet trafia do komputera “pracownik a".
- “pracownik a" odpowiada. zamienia miejscami nadawcę i odbiorcę pakietu, otrzymując:
źródło: 172.30.0.2:80, cel: 172.30.0.1:1031 - ponieważ cel jest w sieci 172.30.0.0/24 – wysyła pakiet bezpośrednio do odbiorcy – ale w tym przypadku odbiorcą jest router
- mechanizm conntracka na routerze dokonuje odpowiednich (odwrotnych) translacji adresów, tak, że pakiet powrotny przyjmuje postać:
źródło: 192.0.2.94:82, cel: 172.30.0.3:1031 - do komputera “pracownik b" trafia pakiet (ack/syn), na dobry port, i od słusznego ip.
- bangla.
po zapisaniu tego wszystkiego sprawa staje się jasna i oczywista. ale nie zmienia to faktu, że kilka razy słychać było – “nie da się".
powyższy pomysł/regułki dedykuję wszystkim zdającym test na pracownika do nas 🙂 tam jest mocno podobne pytanie 🙂