Ubuntu UFW Firewall Nasıl Yapılandırılır?
Merhaba sevgili okuyucu.
Linux bir cihazda kurulum yapmaya kalktığımız zaman makalelerde gelenek olduğu üzere önce apt-get update yapılır sonra firewall kapatılır 🙂 İlgili makaleler genelde test ortamı için yazıldığından bu konu atlanıyor diye düşünüyorum oysa ki firewall hepinizin malumu oldukça önemli bir konu. Bu yazıdan sonra umarım kendi firewall’unuzu kolaylıkla yönetebileceksiniz. Kullanım oranı yüksekliği açısından Ubuntu bi sistemte terminal üzerinden anlatmaya çalıştım. Umarım faydalı olur.
Öncelikle sistemim şu şekilde;
ccorbaci@websrv1:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.4 LTS
Release: 22.04
Codename: jammy
Ubuntu sistemlerde UFW olarak adlandırılan firewall servisi kurulum sonrası inaktif gelmekte yani servis var çaışıyor, ama inaktif durumda. Bunu aşağıdaki şekilde kontrol edebiliriz.
ccorbaci@websrv1:~$ sudo ufw status
[sudo] password for ccorbaci:
Status: inactive
ccorbaci@websrv1:~$ sudo systemctl status ufw
● ufw.service - Uncomplicated firewall
Loaded: loaded (/lib/systemd/system/ufw.service; enabled; vendor preset: enabled)
Active: active (exited) since Thu 2024-02-22 16:47:37 UTC; 10min ago
Docs: man:ufw(8)
Process: 508 ExecStart=/lib/ufw/ufw-init start quiet (code=exited, status=0/SUCCESS)
Main PID: 508 (code=exited, status=0/SUCCESS)
CPU: 1ms
ufw servisimizi aktif edelim;
NOT:
Eğer sisteminize uzak bir oturum ile bağlıysanız bu işlemleri cihaz yakınında iken yapmayı isteyebilirsiniz. Firewall etkinleştiğinde uzak oturumlarınız kapanabilir.
ccorbaci@websrv1:~$ sudo ufw enable
Firewall is active and enabled on system startup
ccorbaci@websrv1:~$ sudo ufw status
Status: active
Evet status durumu active oldu. Sonrasında disable etmek için sudo ufw disable
komutunu kullanabilirsiniz. Ek bilgi olarak; sisteminizde UFW kurulu değil ise kurulumu yapmak için sudo apt install ufw
komutunu kullanabilirsiniz.
IPv6 Konfigurasyonu
UFW oluşturduğunuz kuralları otomatik olarak IPv6 tarafında da uygulayacaktır. Bunu istemeyebilirsiniz. Bu durumla ilgili ayarlar /etc/default/ufw dosyasındadır. Dosyayı nano ile açarak duruma bakalım;
ccorbaci@websrv1:~$ sudo nano /etc/default/ufw
# /etc/default/ufw
#
# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6=yes
.
.
.
ufw dosyasındaki IPV6=yes satırı bu durumla ilgilidir. IPv6 kullanmıyorsanız ya da IPv6 için farklı bir yapılandırmaya gidecekseniz bu kısma no
diyerek dosyayı kaydedip kapatabilirsiniz. (Bunun için CTRL+X sonrasında Y ve enter girişi yapmamız yeterli.) Sonrasında ufw servisini disable ve tekrar enable yapınız.
ccorbaci@websrv1:~$ sudo ufw disable
[sudo] password for ccorbaci:
Firewall stopped and disabled on system startup
ccorbaci@websrv1:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
ccorbaci@websrv1:~$
Default Ayarlar
Yapacağımız ilk ayar cihaza gelen ve cihazdan dışarı giden ayarları yapılandırmak. Bir görselle anlatmak gerekirse;

Aşağıdaki komut seti ile bunu yapıyorum;
ccorbaci@websrv1:~$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
ccorbaci@websrv1:~$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
ccorbaci@websrv1:~$ sudo ufw reload
Firewall reloaded
Bu şekilde cihaza gelen tüm trafiği kapattım ve cihazdan dışarı giden tüm trafiği açtım. Peki bunu nasıl kontrol ederiz? Bundan sonra denediğiniz de göreceksiniz ki cihaza ping atılabiliyor. Bunu birazdan açıklayacağım. Fakat cihaza ssh yapamadığınızı göreceksiniz.
İlk İzinler
O halde ilk iznimizi ssh olarak verelim.
ccorbaci@websrv1:~$ sudo ufw allow ssh
[sudo] password for ccorbaci:
Rule added
ccorbaci@websrv1:~$
Kontrol edelim;
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
ccorbaci@websrv1:~$
Artık 22 port (ssh) tarafından gelen bağlantılara izin vermiş bulunuyoruz. (Herhangi bir yerden gelen isteklere izin ver)
Bu işlemleri yaptığım sunucu üzerinde apache web server kurulu olduğundan ben örnek olması açısından 80 ve 443 portuna da izin veriyorum.
ccorbaci@websrv1:~$ sudo ufw allow http
Rule added
ccorbaci@websrv1:~$ sudo ufw allow https
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443 ALLOW IN Anywhere
ccorbaci@websrv1:~$
İzin verdiğiniz anda bağlantıların açıldığını göreceksiniz.
Kuralları Silmek
Tanımladığınız kuralları silmek te esasen kolaydır. Bunu aşağıdaki şekilde yapabilirsiniz;
ccorbaci@websrv1:~$ sudo ufw allow 10000
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 10000 ALLOW IN Anywhere
[ 4] 22/tcp ALLOW IN Anywhere
ccorbaci@websrv1:~$ sudo ufw delete 3
Deleting:
allow 10000
Proceed with operation (y|n)? y
Rule deleted
ccorbaci@websrv1:~$
Belirli Bir Yerden Erişim Ayarları
Şimdiye kadar izin verdiğimiz durumlar hep “anywhere” yani herhangi bir yerden. Yani bağlantının nereden geldiği ile ilgilenmedik. Bağlantının o port için sadece tek bir yerden gelmesini istediğiniz durumda bunu nasıl yaparız? örnek olarak bu sunucuya sadece tek bir IP üzerinden ssh bağlantısı yapılabilsin istediğimi varsayalım;
ccorbaci@websrv1:~$ sudo ufw allow from 192.168.1.145 to any port ssh
Rule added
ccorbaci@websrv1:~$
192.168.1.145 üzerinden gelen ssh isteklerine herhangi bir port üzerinden izin verdim. Kontrol ettiğimizde 4 numaralı kuralımız artık devrede. 3 numaralı daha önce tanımladığımız kuralı sildiğimiz gerekiyor ayrıca.
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 22/tcp ALLOW IN 192.168.1.145
ccorbaci@websrv1:~$sudo ufw delete 3
Deleting:
allow 22/tcp
Proceed with operation (y|n)? y
Rule deleted
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN 192.168.1.145
ccorbaci@websrv1:~$
Belirli bir yerden belirli bir kaynak için erişim ise şu şekilde yapılabilir.
ccorbaci@websrv1:~$ sudo ufw allow from 192.168.1.145 to any port 22 proto tcp
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 53/tcp ALLOW IN Anywhere
[ 4] 53/udp ALLOW IN Anywhere
[ 5] 22/tcp ALLOW IN 192.168.1.145
ccorbaci@websrv1:~$
Bu tanımlama ile dışarıdan gelen tcp 22 isteklerini 192.168.1.145 üzerinden geliyor ise kabul et demiş olduk. Burada proto protokol anlamındadır.
Belirli Bir Port Aralığına İzin Vermek
10000 ile 15000 arasındaki tüm partlara izin vermek istediğimizi varsayalım.
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 53/tcp ALLOW IN Anywhere
[ 5] 53/udp ALLOW IN Anywhere
ccorbaci@websrv1:~$ sudo ufw allow 10000:15000/tcp
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 53/tcp ALLOW IN Anywhere
[ 5] 53/udp ALLOW IN Anywhere
[ 6] 10000:15000/tcp ALLOW IN Anywhere
ccorbaci@websrv1:~$
Bu şekilde 10000 ve 15000 aralığındaki tüm tcp paketlerine izin vermiş olduk.
sudo ufw allow from 192.168.1.145 to any port 10000:15000 proto tcp
şeklinde kaynak ta belirtebilirsiniz.
İçeriden Dışarı Erişim İzinleri
Farklı durumlarda cihazdan dışarı giden bağlantılarda izin vermek isteyebilirsiniz.
ccorbaci@websrv1:~$ sudo ufw status numbered
[sudo] password for ccorbaci:
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
ccorbaci@websrv1:~$ sudo ufw allow out ssh
[sudo] password for ccorbaci:
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 22/tcp ALLOW OUT Anywhere (out)
ccorbaci@websrv1:~$
4 numaralı kuralda bunu tanımlamış oldum. Tabi ilk başta sudo ufw default allow outgoing diyerek bütün bağlantılara izin verdiğimiz unutulmamalıdır. Cihaz içeriden dışarı sadece ssh üzerinden çıksın isterseniz bunu deny yapmanız gerekecektir.
PING
Tüm bunlara rağmen bilgisayara ping atılabildiğini farketmişsinizdir. Başta da belirttiğim gibi bu durumun sebebi, /etc/ufw/before.rules dosyasında varsayılan olarak gelen ICMP isteklerini kabul eden bir varsayılan olmasıdır. Bunu kapatmak isteyebilirsiniz. İlgili dosyaya gidelim ve yine nano ile açalım.
ccorbaci@websrv1:~$ sudo nano /etc/ufw/before.rules
ccorbaci@websrv1:~$
.
.
# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
.
.
eğer içeriden giden PING paketleri için tanımlama yapacaksanız. Bu satırları aynen bir alta kopyalayarak aşağıdaki şekide değişiklik yapmalısınız.
.
.
# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
# ok icmp codes for OUTPUT
-A ufw-before-output -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-output -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-output -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-output -p icmp --icmp-type echo-request -j ACCEPT
.
.
Bu şekilde içeriden dışarıya ping atılabilmesine izin verdik. (Sonrasında sudo ufw reload
yapmalısınız)
Dışarıdan gelen PING(icmp) isteklerini kapatmak için ise ilgilil satırları yorum satırı olarak işaretleyip dosyayı kaydetmeniz yeterlidir. Şu şekilde;
.
.
# ok icmp codes for INPUT
#-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
#-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
#-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
#-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT
.
.
sudo ufw reload
yapmayı unutmayın.
Belirli Bir Şeyi Engellemek
Bazı durumlarda herkes-herşey erişsin fakat tek bir şey erişmesin istediğimiz durumlar olabilir. Bunu yapmak için aşağıdaki şekilde kural tanımlaması yapabilirsiniz.
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 53/tcp ALLOW IN Anywhere
[ 5] 53/udp ALLOW IN Anywhere
ccorbaci@websrv1:~$ sudo ufw deny from 192.168.1.145 to any port 22 proto tcp
Rule added
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp ALLOW IN Anywhere
[ 4] 53/tcp ALLOW IN Anywhere
[ 5] 53/udp ALLOW IN Anywhere
[ 6] 22/tcp DENY IN 192.168.1.145
ccorbaci@websrv1:~$
status kısmına baktığımızda 22/tcp istekleri herkese açık. Sonrasında 6. kuralda göreceğiniz üzere sadece 192.168.1.145 üzerinden gelen 22/tcp isteklerini reddet dedim.
Fakat bu gibi durumlarda kurallar 1 den itibaren uygulandığından, önce 3 numaralı kuralı uygulayarak herkese izin verecek, sonra 6 kuralda 192.168.1.145 e izin vermeyecek, bu şekilde istediğim yapılandırma olmayacaktır. Dolayısıyla 6. kuralı benim üste almam gerekmekte.
ccorbaci@websrv1:~$ sudo ufw insert 3 deny from 192.168.1.145 to any port 22 proto tcp
Rule inserted
ccorbaci@websrv1:~$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 80/tcp ALLOW IN Anywhere
[ 2] 443 ALLOW IN Anywhere
[ 3] 22/tcp DENY IN 192.168.1.145
[ 4] 22/tcp ALLOW IN Anywhere
[ 5] 53/tcp ALLOW IN Anywhere
[ 6] 53/udp ALLOW IN Anywhere
ccorbaci@websrv1:~$
Gördüğünüz gibi insert parametresi ile kuralımı yukarıya taşıyarak istediğimiz durumu elde etmiş olduk.
Bu kısımlara aşina olduğunuzda aklınıza şu gelecektir. Peki ben bloklanan ya da izin verilen istekleri nasıl görüntüleyebilir ya da loglayabilirim. Bununla ilgili ayrı bir yazı yazmayı planlıyorum. Buraları kontrol etmeyi unutmayın 🙂