IPTables: zezwalaj na wychodzące SSH

4

Próbowałem napisać zasady zabezpieczania serwera WWW za pomocą protokołu http / https, aktualizacji apt-get, wysyłania poczty SSH. Do tej pory zrobiłem to:

IPT=/sbin/iptables
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
#
$IPT -A INPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT
#
# Allow All for SSH
$IPT -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --dport 22 -j ACCEPT
#
# Allow all for HTTP / HTTPS
$IPT -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
#
# Allow loopback traffic
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
#    
# Allow to be pinged ( Outside => srv )
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
#
# Allow outgoing DNS connections
$IPT -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
$IPT -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
#
# Apt-get
$IPT -A OUTPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT
#
# SMTP Outgoing
$IPT -A OUTPUT -p tcp --sport 1024:65535 -d 0/0 --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp -s 0/0 --sport 25 --dport 1024:65535 -m state --state ESTABLISHED-j ACCEPT
#
# Prevent DoS
#$IPT -A INPUT -p tcp --dport 80 -m limit --limit 60/minute --limit-burst 150 -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 100 --connlimit-mask 32     -j REJECT --reject-with tcp-reset
#
# Log dropped packets
$IPT -N LOGGING
$IPT -A INPUT -j LOGGING
$IPT -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: "     --log-level 7
$IPT -A LOGGING -j DROP
#
$IPT -L

Ale wygląda na to, że coś przeoczyłem dla wychodzącego SSH do pracy ( od tego serwera do pilota, w inny sposób działa), ale nie mogę znaleźć co. Próbowałem także ssh miejsca docelowego, wpisując adres IP na wypadek, gdyby niektóre elementy DNS zostały zablokowane, ale to też nie działało.

Jestem prawie pewien, że te reguły są przyczyną, dla której nie działa, ponieważ działa dobrze, jeśli spróbuję spłukać i zaakceptować wszystko.

Oto wyjście iptables -L -n:

Chain INPUT (policy DROP)
 target     prot opt source               destination
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 state NEW,ESTABLISHED
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:443 state ESTABLISHED
 ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
 ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 8
 ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp spt:53
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spts:32786:61000 dpt:80
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:80 dpts:32786:61000
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:25 dpts:1024:65535 state ESTABLISHED
 REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 #conn/32 > 100 reject-with tcp-reset
 LOGGING    all  --  0.0.0.0/0            0.0.0.0/0

 Chain FORWARD (policy DROP)
 target     prot opt source               destination

 Chain OUTPUT (policy DROP)
 target     prot opt source               destination
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:22
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:80 state ESTABLISHED
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:443 state NEW,ESTABLISHED
 ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
 ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 0
 ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:53
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spts:32786:61000 dpt:80
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spt:80 dpts:32786:61000
 ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp spts:1024:65535 dpt:25 state NEW,ESTABLISHED

 Chain LOGGING (1 references)
 target     prot opt source               destination
 LOG        all  --  0.0.0.0/0            0.0.0.0/0           limit: avg 2/min burst 5 LOG flags 0 level 7 prefix `IPTables Packet Dropped: '
 DROP       all  --  0.0.0.0/0            0.0.0.0/0
użytkownik978548
źródło
Czy istnieje powód, dla którego próbujesz uwzględnić stany w każdej regule zamiast jednej reguły u góry łańcucha dla ustanowionych i powiązanych połączeń? Jest to uważane za standardową praktykę.
Belmin Fernandez
@BelminFernandez Przeczytał zły poradnik w Internecie. Niestety jest ich wiele.
Michael Hampton
Bez powodu. Rzeczywiście, właśnie czytałem (oczywiście złe) rzeczy w Internecie. Po prostu nie wiedziałem, że mogę zrobić inaczej. Dzięki.
user978548,

Odpowiedzi:

6

Gdy masz połączenie wychodzące, port docelowy będzie wynosił 22, więc powinna to być reguła:

$IPT -A OUTPUT -o eth0 -p tcp --dport 22 -j ACCEPT

Ponadto powinieneś mieć jedną regułę do zakrycia ESTABLISHEDi RELATEDna łańcuchach INPUTi OUTPUT:

$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Mam nadzieję że to pomoże.

Belmin Fernandez
źródło
Dziękuję Ci. Próbowałem edytować reguły za pomocą twoich uwag (jak również w moim pytaniu powyżej). Ponownie, niestety, to nie wystarczyło.
user978548,
Czy możesz odświeżyć iptables -L -ni opublikować pytanie?
Belmin Fernandez
Nie wygląda na to, żeby nowe zasady weszły w życie. Wyczyść reguły (uważaj, aby się nie zablokować, jeśli robisz to przez ssh) i uruchom ponownie skrypt, którego używasz dla reguł.
Belmin Fernandez
Tak, są, zrobiłem to ponownie i sprawdziłem. Na przykład po wierszach spt / dpt: 22 nie ma już „stanu NOWOŚĆ, USTANOWIONO”. Co widziałeś, żeby ssh zadziałało? (i dzięki za ostrzeżenie! Regularnie się
zamykam
Pierwsza zasada mocy INPUTi OUTPUTłańcuchy powinny być ESTABLISHED,RELATEDzasady, ale nie widzę go tam. Mogłem bardzo coś przeoczyć (jeszcze nie jadłem śniadania!).
Belmin Fernandez
5

Reguła dotycząca wychodzącego ruchu SSH nie zawiera NEWinstrukcji wymaganej do inicjowania połączeń wychodzących.

HBruijn
źródło
Dziękuję Ci ! Zrozumiałem i dodałem to. Niestety, to nadal nie działa (nadal „upłynął limit czasu połączenia”, a działa, jeśli opróżnię i zaakceptuję wszystko). Myślę, że przegapiłem też inną rzecz. Nie napisałem tego, ponieważ uważam, że to nie ma znaczenia, ale połączenie odbywa się między 2 różnymi portami (port 22 na serwerze, wtedy jest router, który kieruje 22 do 24 na miejscu). Nie ma znaczenia prawda?
user978548
1
Piszesz, że host docelowy ma SSH obsługujący nasłuch na porcie 24 za routerem przekierowującym z 22 na 24. Czy to możliwe, że router punkt blokujący jest źle skonfigurowany? Na podstawie przekierowania masz prawo połączyć się z portem 22, ponieważ powinieneś dbać tylko o port publiczny celu.
DevOps,
4

Jest to klasyczny błąd, gdy nie rozumiesz architektury klient-serwer i „stanowych zapór ogniowych”

W architekturze klient-serwer jedynym znanym a priori portem jest port docelowy, ponieważ klient wybiera efemeryczne porty 1 , z wyjątkiem bardzo rzadkich wyjątków, takich jak na przykład DHCP.

Z punktu widzenia zapory ogniowej każdy wyrzucony z niej pakiet ma stan NOWOŚĆ, szczególnie w połączeniach TCP. 2)

Najpierw zobaczmy, co mamy

IPT=/sbin/iptables
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# Excellent!! because always we need to accept this kind of states because
# always are response packets, remember we can be client or server
$IPT -A INPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT

# Allow All for SSH
# this accept ssh connections from outside, and the response for this input
# is a outgoing packet with the state ESTABLISHED. (four lines above)
$IPT -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

# this rule are meaningless because you never start a ssh connection from
# source port 22, this because the source ports are choose randomly
$IPT -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPT

# this one let start a ssh connection from within to the outside and the response
# enter in state ESTABLISHED, 13 lines above
$IPT -A OUTPUT -o eth0 -p tcp --dport 22 -j ACCEPT

# Allow all for HTTP / HTTPS
# http servers are very basic if we think on client-server, they only respond a
# client request, except if some web software try to establish a network connection
# to the outside, for this block the only rule with meaning is the first, the rest are
# meaningless
$IPT -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# Allow loopback traffic
# this are obligatory rules avoiding the firewall block himself
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# Allow to be pinged ( Outside => srv )
# always the interpretation depends from the point of view
# with this rules you can accept ping request from outside and despond the request
# but you cannot ping from inside to outside because in that scenario you send the request (OUTPUT)
# and receive a reply from outside (INPUT) 
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT


# Allow outgoing DNS connections
# this allow send dns queries to the DNS server that you have registered in the file
# /etc/resolv.conf
$IPT -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
# this one are meaningless because the response from the DNS server is ESTABLISHED and is 
# accepted in the very beginning in the firewall 
$IPT -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

# Apt-get
# AFAIK apt use http or ftp, they can use https but is less common
# the specification of a range on source port are meaningless
$IPT -A OUTPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 --sport 32786:61000 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT
$IPT -A INPUT -p tcp --dport 32786:61000 --sport 80 -j ACCEPT

# SMTP Outgoing
# I don't known why you start adding more criteria without meaning 
# maybe you start surfing on the net and starting copy&paste code without see what you are doing
# always when yo need to learn something go to the root, or in this case to www.netfilter.org
$IPT -A OUTPUT -p tcp --sport 1024:65535 -d 0/0 --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp -s 0/0 --sport 25 --dport 1024:65535 -m state --state ESTABLISHED-j ACCEPT


# the rules below are.... copy&paste from somewhere

# Prevent DoS
#$IPT -A INPUT -p tcp --dport 80 -m limit --limit 60/minute --limit-burst 150 -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 100 --connlimit-mask 32     -j REJECT --reject-with tcp-reset
#
# Log dropped packets
$IPT -N LOGGING
$IPT -A INPUT -j LOGGING
$IPT -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: "     --log-level 7
$IPT -A LOGGING -j DROP

Więc dla mnie potrzebujesz tej zapory ogniowej

IPT=/sbin/iptables
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# accept a priori all the responses
$IPT -A INPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m state --STATE ESTABLISHED,RELATED -j ACCEPT

# Allow All for SSH 
# allow ssh connections from outside to inside
$IPT -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

# allow ssh connections from inside to outside
$IPT -A OUTPUT -o eth0 -p tcp --dport 22 -j ACCEPT

# Allow all for HTTP / HTTPS
$IPT -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
$IPT -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT

# Allow loopback traffic
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# Allow to be pinged ( Outside => srv )
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
# from srv to outside
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT

# Allow outgoing DNS connections
$IPT -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT

# Apt-get
$IPT -A OUTPUT -p tcp --dport 80 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 21 -j ACCEPT

# SMTP Outgoing
$IPT -A OUTPUT -p tcp --dport 25 -j ACCEPT

Mam nadzieję, że było to pomocne. I przepraszam za mój angielski, to nie jest mój język ojczysty.

fbs
źródło
0

Dla najprostszych reguł (na razie stan ignorowania):

iptables -A INPUT -p tcp --sport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

To powinno załatwić sprawę. gdy spróbujesz i odniesiesz sukces, możesz go zmodyfikować, aby zawierał stan, źródłowe / docelowe adresy IP, różne porty.

melsayed
źródło