Voglio fare alcune semplici regole iptables per negare tutte le connessioni in entrata e consentire l'uscita. Come posso fare ciò?
Voglio fare alcune semplici regole iptables per negare tutte le connessioni in entrata e consentire l'uscita. Come posso fare ciò?
Risposte:
Prova questo con accesso root:
# Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Accept on localhost
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established sessions to receive traffic
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Si noti che ciò taglierà brutalmente tutte le connessioni in esecuzione - questo include cose come la connessione SSH che è possibile utilizzare per amministrare il server. Utilizzalo solo se hai accesso a una console locale.
Vedi la risposta di Miphix per come aggiungere un'eccezione per SSH.
Se lavori in remoto tramite SSH, potresti voler aggiungere questo (lo -I
inserisce prima di tutte le altre regole in INPUT
):
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
Se il tuo servizio SSH è in ascolto su un'altra porta, dovrai usare quella porta invece di 22
.
Altrimenti, potresti perdere accidentalmente l'accesso.
Ricorda che le altre risposte non riguardano IPv6! Se il tuo sistema accetta il traffico IPv6, non verrà applicata una singola regola iptables al traffico ipv6.
invece di usare iptables / ip6tables direttamente, consiglio di usare iptables-restore e save. Questi strumenti consentono di specificare una configurazione iptables con più regole e caricarla facilmente con un solo comando.
creare un file (l'ho chiamato iptables.rules) con il seguente contenuto:
*filter
# drop forwarded traffic. you only need it of you are running a router
:FORWARD DROP [0:0]
# Accept all outgoing traffic
:OUTPUT ACCEPT [623107326:1392470726908]
# Block all incoming traffic, all protocols (tcp, udp, icmp, ...) everything.
# This is the base rule we can define exceptions from.
:INPUT DROP [11486:513044]
# do not block already running connections (important for outgoing)
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# do not block localhost
-A INPUT -i lo -j ACCEPT
# do not block icmp for ping and network diagnostics. Remove if you do not want this
# note that -p icmp has no effect on ipv6, so we need an extra ipv6 rule
-4 -A INPUT -p icmp -j ACCEPT
-6 -A INPUT -p ipv6-icmp -j ACCEPT
# allow some incoming ports for services that should be public available
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# commit changes
COMMIT
Nota che ho aggiunto qualche esempio in più se si desidera consentire ICMP e il traffico verso porte specifiche.
ora puoi caricarlo con questi comandi:
iptables-restore < iptables.rules
ip6tables-restore < iptables.rules
Ora le tue regole coprono anche ipv6 e sono facili da gestire.
Nota aggiuntiva per gli utenti Debian: se si è soddisfatti delle proprie regole, è possibile apt install iptables-persistent
ripristinarle dopo il riavvio. Le regole non vengono salvate automaticamente allo spegnimento, quindi esegui netfilter-persistent save
per aggiornare le regole permanenti.
Entrambe le risposte sopra riportate sono in qualche modo corrette, ma non sono abbastanza precise da dare una risposta. (Mi dispiace non ho abbastanza reputazione per aggiungere un commento, quindi scrivendo una risposta completa).
Nel mio caso ho incontrato un server Apache sovraccarico, sovraccarico di cron job, utilizzo eccessivo della CPU. I limiti dei thread sono stati memorizzati nel database SQL, ma ho incontrato il limite delle sue connessioni. Volevo limitare le connessioni Apache in arrivo dall'host locale (questa parte è facoltativa), ma mantenere tutte le altre connessioni possibili. Compresi quelli che sono stati effettivamente stabiliti.
L'ho fatto con comando
sudo iptables -I INPUT -p tcp --dport 80 -m state --state NEW -j REJECT
Significa: per ogni pacchetto tcp in entrata sulla porta 80, caricare il state
modulo e se questo è il primo pacchetto (connessione in entrata) rifiutarlo. Per localhost potresti semplicemente usare-s 127.0.0.0/8
E per un uso nel mondo reale, in alcuni casi potresti aggiungere "INVALID" agli stati NEW,INVALID
, perché puoi inviare pacchetti "dannosi", cercando di aggirare la tua regola. E sostituisci anche con -j DROP
per salvare il traffico in uscita (non invierà il segnale di rifiuto)