Linux İptables Kullanımı ve Yapılandırılması

İptables linux işletim sistemlerine entegre bir şekilde gelen güvenlik duvarı yazılımıdır. İptables ile sunucuya gelen trafikleri kontrol edebilir veya başka bir adrese yönlendirebilirsiniz.

Bu yazıda sizinle ayrıca sunucunuza yapılan brute force atackları engelleyebilmeniz için küçük bir bash komutu paylaşacağım.

iptables yazılımı linuxt işletim sisteminize kurulu değil ise aşağıdaki şekilde kurabilir başlangıçta otomatik başlaması için ayarlama yapabilirsiniz.

# yum install iptables
veya
# apt install iptables

Başlangıçta otomatik başlaması veya başlamaması için aşağıdaki komutu çalıştırabilirsiniz.

Sunucu yeniden başladığında iptables otomatik başlar
# chkconfig iptables on
Sunucu yeniden başladığında iptables başlamaz
# chkconfig iptables off

İptables yazılımında gelen veya giden trafik ile ilgili tanımlara aşağıdaki şekilde bakabilirsiniz.

 # iptables -L
 Chain INPUT (policy ACCEPT)
 target     prot opt source        destination
 Chain FORWARD (policy ACCEPT)
 target     prot opt source        destination
 Chain OUTPUT (policy ACCEPT)
 target     prot opt source         destination

Bu listede INPUT gelen, OUTPUT giden ve FORWARD yönlendirilmiş tanımları ifade eder ve eğer bir kural varsa buradan görebilirsiniz.

Yeni bir kural eklendiğinde target ile ilgili aşağıdaki tanımlamaları yapabilirsiniz.

ACCEPT: Paketlerin geçisine izin verilir.
REJECT: Paketlerin erişimi reddedilir.
DROP: Paketlerin geçişine izin verilmez.
RETURN: Zincirin sonuna gönderilir.
QUEUE: Paketler kullanıcı alanına gönderilir.

Örnek olarak belirli bir ip den gelen paketlerin erişimini kısıtladığımızda liste aşağıdaki şekilde olacaktır.

# iptables -A INPUT -p tcp -s x.x.x.x -j DROP
# iptables-save  

Belirli bir ip nin sunucuya erişimini kısıtladığımızda bu kural aşağıdaki şekilde görünecektir. x.x.x.x ip’sinin sunucuya gönderdiği tüm TCP paketler sunucu tarafından kabul edilmeyecektir.

# iptables -L
 Chain INPUT (policy ACCEPT)
 target     prot opt source     destination
 DROP       tcp  --  x.x.x.x    anywhere
 Chain FORWARD (policy ACCEPT)
 target     prot opt source     destination
 Chain OUTPUT (policy ACCEPT)
 target     prot opt source     destination

Burada gönderilen paketler port farketmeksizin engellenecektir. Belirli bir port veya başka bir protokol belirterek gelen paketleri engellemekte mümkün. tcp, udp, udplite, icmp, icmpv6, esp, ah, sctp, mh protokolleri için tanımlama yapabilirsiniz. Örneğin belirli bir portu engellemek için aşağıdaki komutu kullanabilirsiniz.

# iptables -A INPUT -p tcp --dport 22 -s x.x.x.x -j DROP
# iptables-save 

Bu işlemin ardından x.x.x.x ip’si sunucuya 22 portundan erişemeyecektir.

Belirli bir subnet’i engellemek için aşağıdaki gibi ip adresin sonuna /subnet ekleyerek tanımlama yapabilirsiniz.

# iptables -A INPUT -p tcp --dport 22 -s x.x.0.0/16 -j DROP
# iptables -A INPUT -p tcp --dport 22 -s x.x.x.0/24 -j DROP
# iptables-save 

Örneğin belirli bir ip grubunu engelleyip engellenen ip grubu içerisinden tek bir ip’ye erişim vermek istersek bunu aşağıdaki şekilde yapabiliriz.

# iptables -A INPUT -p tcp --dport 22 -s x.x.0.0/16 -j DROP
# iptables -A INPUT -p tcp --dport 22 -s x.x.x.x -j ACCEPT
# iptables-save 

Bir kural tanımladıktan sonra mutlaka iptables-save komutunun çalıştırılması gerekmektedir. Varolan tüm kuralları temizlemek için iptables -F komutu kullanılabilir. Bu işlem sonrası tanımlanmış olan tüm kurallar silinecektir.

# iptables -F

İptables ile ilgili diğer parametreleri görmek kullanıcı kılavuzu sayfasını inceleyebilirsiniz.

# man iptables

SQL Tune Nasıl Yapılır

Bu yazıda bir sql’i tune edip sorgu sonucunun hızlandırılması konusunda index ekleme yöntemini açıklayacağım. Burada anlatacağım yöntemi oracle, postgresql, mysql ve diğer veritabanlarında kullanabilirsiniz.

İlk olarak index nedir ve neden eklenmesi gerektiğini açıklamak istiyorum. İndex oluşturulmuş bir ağaç yapısıdır ve birden çok index türü vardır. B-tree index yapısını aşağıdaki şekilde inceleyebilirsiniz. Leaf block dediğimiz yerde ilgili tablonun içerisindeki rowların id leri bulunmaktadır. Bunu adres olarak düşünebiliriz. Branch blocks dediğimiz yer ise datanın belirli bir düzene göre gruplandığı yerdir. Aşağıdaki resimde görebileceğiniz gibi job_id kolonunda 2 değerine sahip satırların id numaraları bir blokta tutulmuş. Bu da job_id = 2 koşulu istendiğinde tabloyu full okumak yerine sadece ilgili bloklara gidip okuma yapacağı anlamına gelmektedir.

Tablo full okunmadığı için ilgili sql daha hızlı sonuç üretecektir. Daha hızlı sonuç üretmesi veritabanının fazla efor harcamamasına ve daha performanslı çalışmasına neden olacaktır.

Çok fazla transaction alan veritabanlarında sql’lerin sorgu sonuç süreleri kritik bir öneme sahiptir. Şu şekilde bir hesap yapacak olursak daha anlaşılır olacaktır. Elimizde çalışması 1 sn süren bir sql olsun ve bu sql uygulamadan veritabanına 10 bin kez gönderilsin. Bu işlem veritabanında 1 sn* 10 bin kez çalışacaktır ve veritabanını toplamda 10 bin saniye / 60 = 166 dakika meşgul edecektir. Tabi cpu’nun saniye de milyarlarca işlem yapabildiği için gerçek hayatta bu işlem 166 dakikada sürmeyecektir.

İlgili sql’e index ekleyip çalışma süresini yarıya düşürdüğümüzü varsayarsak toplamda 83 dakika kazanmış olacağız ki bu muazzam bir süre. Bu örnekte saniyeler üzerinden gidiyorum fakat sql’lerin veritabanında çalışma süreleri mili saniyeleri geçmemesi gerekiyor. 0.5 saniye bile bir sorgu için aşırı büyük bir değer.

Şimdi veritabanının bir sorguyu çalıştırırken sonucu getirmek için izlediği yolu göstereceğim. Örnek olarak elimizde aşağıdaki gibi bir sql sorgusu olsun.

select firts_name, last_name from hr.employee where job_id = 2;

Bu sql’i veritabanı şu şekilde yorumlayacaktır:

– job_id kolonunda değeri 2 olan
– hr.employee tablosundaki
– first_name ve last_name kolonundaki tüm verileri getir.

Sorgu bizim aksimize tersten okunarak istenilen dataları getirmek için işlenmeye başlandı. Bu kısımda job_id kolonunda 2 değerine sahip satırlar için tabloyu satır satır okuyup eşleşen kayıtları bulmaya çalışacaktır. İlgili kolonda eğer bir index yok ise explain plan da aşağıda da görebileceğiniz gibi “full table access” yöntemi kullanılacaktır.

OPERATIONOPTIONSOBJECT_NAMEPOSITION
SELECT STATEMENT2
..TABLE ACCESSTABLE ACCESS FULLEMPLOYEES1

Eğer employees tablosunun job_id kolonunda bir index olmuş olsaydı tabloyu full okumak zorunda kalmayacak ve explain plan’ı aşağıdaki gibi olacaktı.

OPERATIONOPTIONSOBJECT_NAMEPOSITION
SELECT STATEMENT2
..TABLE ACCESSINDEX RANGE SCANEMPLOYEES1

Şekilde görüldüğü gibi index range scan yöntemi ile tabloya yapılan erişim sorgu maliyetini düşürmektedir. Elinizdeki sql’leri bu doğrultuda inceleyerek gerekli olabilecek indexleri oluşturabilirsiniz.

Son olarak aşağıdaki gibi bir sql’i ele alalım.

select firts_name, last_name from hr.employee where job_id = 2 and first_name = 'Emrah';

Bu sqli çalıştırırken job_id kolonunda index olmasına rağmen sorgu çalıştırıldığında ilgili index kullanılmayabilir. Bu durumda bileşik index oluşturulması gerekir. İlk oluşturulan basit index tipini ifade etmekteydi. Bu durumda bileşik index oluşturmak zorunda kalınabilirdi. Oracle veritabanında basit ve bileşik index aşağıdaki gibi oluşturulabilir.

# basit index
create index [index_name] on [table_name] (column);
# bileşik index
create index [index_name] on [table_name] (column1,column2);