Si të konfiguroni një mur zjarri Iptables për të mbrojtur trafikun midis serverëve tuaj


Prezantimi

Vendosja e komponentëve diskrete në konfigurimin e aplikacionit tuaj në nyje të ndryshme është një mënyrë e zakonshme për të ulur ngarkesën dhe për të filluar shkallëzimin horizontalisht. Një shembull tipik është konfigurimi i një baze të dhënash në një server të veçantë nga aplikacioni juaj. Ndërsa ka një sërë avantazhesh me këtë konfigurim, lidhja përmes një rrjeti përfshin një grup të ri shqetësimesh sigurie.

Në këtë udhëzues, ne do të demonstrojmë se si të vendosni një mur zjarri në secilin prej serverëve tuaj në një konfigurim të shpërndarë. Ne do të konfigurojmë politikën tonë për të lejuar trafikun e synuar midis komponentëve tanë, ndërkohë që mohojmë trafikun tjetër.

Ju gjithashtu mund të konfiguroni Firewall-et e Cloud të DigitalOcean të cilat funksionojnë si një shtresë shtesë, e jashtme në serverët tuaj në infrastrukturën DigitalOcean. Në këtë mënyrë, ju nuk keni nevojë të konfiguroni një mur zjarri në vetë serverët tuaj.

Për demonstrimin në këtë udhëzues, ne do të përdorim dy serverë Ubuntu 22.04. Njëri do të ketë një aplikacion në internet të shërbyer me Nginx dhe tjetri do të presë bazën e të dhënave MySQL për aplikacionin. Edhe pse ne do ta përdorim këtë konfigurim si shembull, ju duhet të jeni në gjendje të ekstrapoloni teknikat e përfshira për t'iu përshtatur kërkesave të serverit tuaj.

Parakushtet

Për të filluar, do të duhet të keni dy serverë të rinj Ubuntu 22.04. Shtoni një llogari të rregullt përdoruesi me privilegje sudo për secilën. Për ta bërë këtë, ndiqni udhëzuesin tonë fillestar të konfigurimit të serverit Ubuntu 22.04.

Konfigurimi i aplikacionit që do të sigurojmë bazohet në këtë udhëzues. Nëse dëshironi të ndiqni së bashku me atë shembull, konfiguroni aplikacionin tuaj dhe serverët e bazës së të dhënave siç tregohet nga ai tutorial. Përndryshe, mund ta përdorni këtë artikull si referencë të përgjithshme.

Hapi 1 - Vendosja e një muri zjarri

Do të filloni duke zbatuar një konfigurim bazë të murit të zjarrit për secilin prej serverëve tuaj. Politika që ne do të zbatojmë ka një qasje të parë të sigurisë. Ne do të mbyllim pothuajse gjithçka tjetër përveç trafikut SSH dhe më pas do të hapim vrima në murin e zjarrit për aplikacionin tonë specifik.

Ky udhëzues ndjek sintaksën iptables. iptables instalohet automatikisht në Ubuntu 22.04 duke përdorur një backend nftables, kështu që nuk duhet të instaloni asnjë paketë shtesë.

Duke përdorur nano ose redaktuesin tuaj të preferuar të tekstit, hapni skedarin /etc/iptables/rules.v4:

  1. sudo nano /etc/iptables/rules.v4

Ngjitni konfigurimin nga udhëzuesi i shabllonit të murit të zjarrit:

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# Commit the changes
COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Ruani dhe mbyllni skedarin. Nëse jeni duke përdorur nano, shtypni Ctrl+X për të dalë, më pas kur të kërkohet, Y dhe më pas Enter.

Nëse po e zbatoni këtë në një mjedis të drejtpërdrejtë, mos i rifreskoni ende rregullat e murit tuaj të zjarrit. Ngarkimi i rregullave të përshkruara këtu do të heqë menjëherë lidhjen midis aplikacionit tuaj dhe serverit të bazës së të dhënave. Do t'ju duhet të rregulloni rregullat për të pasqyruar nevojat tona operacionale përpara se t'i ngarkoni përsëri.

Hapi 2 - Zbuloni portet që përdoren nga shërbimet tuaja

Për të lejuar komunikimin midis komponentëve tuaj, duhet të dini portat e rrjetit që përdoren. Ju mund të gjeni portat e duhura të rrjetit duke ekzaminuar skedarët tuaj të konfigurimit, por një metodë agnostike e aplikimit për të gjetur portat e duhura është thjesht të kontrolloni se cilat shërbime po dëgjojnë për lidhje në secilën nga makinat tona.

Ju mund të përdorni mjetin netstat për ta zbuluar këtë. Meqenëse aplikacioni juaj komunikon vetëm përmes IPv4, ne do të shtojmë argumentin -4 por ju mund ta hiqni atë nëse po përdorni gjithashtu IPv6. Argumentet e tjera që ju nevojiten për të gjetur shërbimet tuaja në funksion janë -p, -l, -u, -n , dhe -t, të cilat mund t'i jepni si -plunt.

Këto argumente mund të zbërthehen si më poshtë:

  • p: Trego PID-in dhe emrin e programit të cilit i përket secila fole.
  • l: Shfaq vetëm bazat e dëgjimit.
  • u: Shfaq trafikun UDP.
  • n: Shfaq daljen numerike në vend të emrave të shërbimeve.
  • t: Shfaq trafikun TCP.

  1. sudo netstat -4plunt

Në serverin tuaj të internetit, dalja juaj mund të duket kështu:

Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1058/sshd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4187/nginx

Kolona e parë e theksuar tregon adresën IP dhe portin që po dëgjon shërbimi i theksuar në fund të rreshtit. Adresa speciale 0.0.0.0 do të thotë që shërbimi në fjalë po dëgjon në të gjitha adresat e disponueshme.

Në serverin tuaj të bazës së të dhënave, dalja juaj mund të duket kështu:

  1. sudo netstat -4plunt
Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1097/sshd tcp 0 0 192.0.2.30:3306 0.0.0.0:* LISTEN 3112/mysqld

Ju mund t'i lexoni këto kolona saktësisht njësoj. Në këtë shembull, adresa 192.0.2.30 përfaqëson adresën IP private të serverit të bazës së të dhënave. Në tutorialin parakusht, ju e keni kufizuar MySQL në ndërfaqen private për arsye sigurie.

Merrni parasysh vlerat që gjeni në këtë hap. Këto janë detajet e rrjetit që do t'ju nevojiten për të rregulluar konfigurimin e murit të zjarrit.

Në serverin tuaj të internetit, duhet të siguroheni që portat e mëposhtme janë të aksesueshme:

  • Port 80 në të gjitha adresat
  • Port 22 në të gjitha adresat (tashmë është llogaritur në rregullat e murit të zjarrit)

Serveri juaj i bazës së të dhënave duhet të sigurojë që portat e mëposhtme janë të aksesueshme:

  • Port 3306 në adresën 192.0.2.30 (ose ndërfaqen e lidhur me të)
  • Port 22 në të gjitha adresat (tashmë është llogaritur në rregullat e murit të zjarrit)

Hapi 3 - Rregulloni rregullat e murit të zjarrit të serverit të uebit

Tani që keni informacionin e portit që ju nevojitet, do të rregulloni grupin e rregullave të murit të zjarrit të serverit tuaj të internetit. Hapni skedarin e rregullave në redaktorin tuaj me privilegjet sudo:

  1. sudo nano /etc/iptables/rules.v4

Në serverin në internet, duhet të shtoni portin 80 në listën tuaj të trafikut të pranueshëm. Meqenëse serveri po dëgjon në të gjitha adresat e disponueshme - serverët e uebit në përgjithësi presin të jenë të aksesueshëm nga kudo - ju nuk do ta kufizoni rregullin sipas ndërfaqes ose adresës së destinacionit.

Vizitorët tuaj të internetit do të përdorin protokollin TCP për t'u lidhur. Korniza juaj tashmë ka një zinxhir të personalizuar të quajtur TCP për përjashtimet e aplikacioneve TCP. Ju mund të shtoni portën 80 në atë zinxhir, pikërisht poshtë përjashtimit për portën tuaj SSH:

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 80 -j ACCEPT

. . .

Serveri juaj i uebit do të fillojë lidhjen me serverin tuaj të bazës së të dhënave. Trafiku juaj në dalje nuk është i kufizuar në murin tuaj të zjarrit dhe trafiku hyrës i lidhur me lidhjet e vendosura është i lejuar, kështu që ne nuk kemi nevojë të hapim asnjë portë shtesë në këtë server për të lejuar këtë lidhje.

Ruani dhe mbyllni skedarin kur të keni mbaruar. Serveri juaj i uebit tani ka një politikë të murit të zjarrit që do të lejojë të gjithë trafikun legjitim ndërsa bllokon gjithçka tjetër.

Testoni skedarin tuaj të rregullave për gabime sintaksore:

  1. sudo iptables-restore -t < /etc/iptables/rules.v4

Nëse nuk shfaqen gabime sintaksore, ringarkoni murin e zjarrit për të zbatuar grupin e ri të rregullave:

  1. sudo service iptables-persistent reload

Hapi 4 - Rregulloni rregullat e murit të zjarrit të serverit të bazës së të dhënave

Në serverin tuaj të bazës së të dhënave, duhet të lejoni hyrjen në portin 3306 në adresën IP private të serverit tuaj. Në këtë rast, ajo adresë ishte 192.0.2.30. Ju mund të kufizoni aksesin e destinuar për këtë adresë në mënyrë specifike, ose mund të kufizoni aksesin duke u përshtatur me ndërfaqen që i është caktuar asaj adrese.

Për të gjetur ndërfaqen e rrjetit të lidhur me atë adresë, ekzekutoni ip -4 adr show scope global:

  1. ip -4 addr show scope global
Output
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0 valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1 valid_lft forever preferred_lft forever

Zonat e theksuara tregojnë se ndërfaqja eth1 është e lidhur me atë adresë.

Më pas, ju do të rregulloni rregullat e murit të zjarrit në serverin e bazës së të dhënave. Hapni skedarin e rregullave me privilegjet sudo në serverin tuaj të bazës së të dhënave:

  1. sudo nano /etc/iptables/rules.v4

Përsëri, ju do të shtoni një rregull në zinxhirin tonë TCP për të formuar një përjashtim për lidhjen midis serverëve tuaj të uebit dhe bazës së të dhënave.

Për të kufizuar aksesin bazuar në adresën aktuale në fjalë, do të shtoni rregullin si ky:

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -d 192.0.2.30 -j ACCEPT

. . .

Nëse preferoni të lejoni përjashtimin bazuar në ndërfaqen që strehon atë adresë, mund të shtoni një rregull të ngjashëm me këtë:

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -i eth1 -j ACCEPT

. . .

Ruani dhe mbyllni skedarin kur të keni mbaruar.

Kontrolloni për gabime sintaksore me këtë komandë:

  1. sudo iptables-restore -t < /etc/iptables/rules.v4

Kur të jeni gati, ringarkoni rregullat e murit të zjarrit:

  1. sudo service iptables-persistent reload

Të dy serverët tuaj tani duhet të mbrohen pa kufizuar rrjedhën e nevojshme të të dhënave ndërmjet tyre.

konkluzioni

Zbatimi i një muri zjarri të duhur duhet të jetë gjithmonë pjesë e planit tuaj të vendosjes kur vendosni një aplikacion. Megjithëse e demonstruam këtë konfigurim duke përdorur dy serverë që ekzekutojnë Nginx dhe MySQL, teknikat e demonstruara më sipër janë të zbatueshme pavarësisht nga zgjedhjet tuaja specifike të teknologjisë.

Për të mësuar më shumë rreth mureve të zjarrit dhe iptables në mënyrë specifike, hidhini një sy udhëzuesve të mëposhtëm:

  • Si të zgjidhni një politikë efektive të murit të zjarrit për të siguruar serverët tuaj
  • Një zhytje e thellë në arkitekturën e Iptables dhe Netfilter
  • Si të testoni konfigurimin e murit të zjarrit me Nmap dhe Tcpdump