IPTables: permitir SSH de saída

4

Eu tentei escrever minhas regras para proteger um servidor web com apenas http / https, apt-get updates, enviando e-mails com acesso SSH. Até agora eu fiz isso:

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

Mas parece que perdi algo para o SSH de saída funcionar ( de este servidor para um controle remoto, o outro caminho funciona), mas não consigo encontrar o quê. Eu também tentei ssh o destino, digitando o IP no caso de algumas coisas DNS foi bloqueado, mas isso não funcionou.

Tenho certeza de que essas regras são a razão pela qual não funciona, porque funciona bem se eu tentar liberar e aceitar tudo.

Aqui está a saída 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
    
por user978548 05.07.2014 / 14:32

4 respostas

6

Quando você tem uma conexão de saída, a porta de destino será 22, então esta deve ser a regra:

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

Além disso, você deve ter uma regra para cobrir ESTABLISHED e RELATED além das cadeias INPUT e OUTPUT :

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

Espero que isso ajude.

    
por 05.07.2014 / 15:04
5

Sua regra para o tráfego SSH de saída não inclui a instrução NEW , necessária para iniciar as conexões de saída.

    
por 05.07.2014 / 14:38
4

Este é um erro clássico quando você não entende a arquitetura cliente-servidor e "firewalls com informações de estado"

Em uma arquitetura cliente-servidor, a única porta que é conhecida a priori é a porta de destino, porque o cliente escolhe uma porta efêmera 1 , exceto algumas exceções extremamente raras, como DHCP, por exemplo.

A partir do ponto de vista do firewall, cada pacote expulso do mesmo tem um estado NOVO, especialmente em conexões TCP. 2

Primeiro, vamos ver o que temos

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

Então, para mim, você precisa desse firewall

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

Espero que tenha sido útil. E desculpe pelo meu inglês, não é minha língua materna.

    
por 07.07.2014 / 18:31
0

Para as regras mais simples (por enquanto o estado ignorgin):

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

Isso deve fazer o truque. uma vez que você tentar e ter sucesso, você pode modificá-lo para incluir endereços IP de estado, de origem / destino, portas diferentes ..

    
por 06.07.2014 / 02:33

Tags