SonarQube ile DevSecOps İş Akışınızı Güçlendirin
SonarQube, kod kalitesini ve yazılım projelerinin genel sağlığını korumak için kritik bir araçtır. Açık kaynaklı bu güçlü Statik Uygulama Güvenlik Testi (SAST) aracı, kodun hatalarını, kod kokularını ve güvenlik açıklarını otomatik olarak inceleyerek kod kalitesi denetimleri gerçekleştirir. Bu entegrasyon, geliştirme yaşam döngüsü boyunca güvenlik önlemlerini artırmakla kalmaz, aynı zamanda ekiplerin kod tabanındaki ve dış modüllerdeki potansiyel açıkları proaktif bir şekilde çözmelerini sağlar. Güvenliği geliştirme sürecinin ayrılmaz bir parçası olarak (sola kaydırma) önceliklendirmek, daha dirençli ve güvenli yazılım uygulamaları geliştirilmesini sağlar.
Bir Statik Uygulama Güvenlik Testi (SAST) aracının temel işlevi, bir uygulamanın kaynak kodunu incelemek ve olası güvenlik açıklarını, kod verimsizliklerini, hataları veya diğer endişeleri tanımlamaktır. Bu araç, geliştiricilere kodları hakkında gerçek zamanlı geri bildirim sağlayarak güvenlik açıklarının erken tespitini ve çözümünü kolaylaştırır.
Neden SonarQube?
SonarQube’u kullanmaya karar verdiğimde, “sola kaydırma” konseptini araştırıyordum ve kaynak kodunda güvenlik açıklarını bulmamı sağlayacak bir araç arıyordum. O dönemde zaman ve bilgi yatırımı yapacak durumda değildim. Bu nedenle, güvenlikten en iyi uygulamalara kadar birçok kod alanını tarayan, açık kaynaklı bir versiyonu olan, işlevselliğini uzantılarla artırma seçeneği sunan ve ekiplerin günlük olarak kullanabileceği bir web arayüzüne sahip bu aracı seçtim.
DevSecOps’ta “sola kaydırma”, güvenlik uygulamalarını yazılım geliştirme yaşam döngüsünün daha erken aşamalarına entegre etmeyi ifade eder. Bu, güvenlik açıklarının daha sonraki aşamalarda ele alınmasını değil, başlangıçta ele alınmasını sağlayarak genel güvenlik ve verimliliği artırır.
Başlayalım!!
SonarQube Sunucusunu Eklentilerle Güncelleme
Sonar sunucusunu kurmaktan ziyade, sunucuyu ek pazar yerinden alınan ek eklentilerle güncellemek üzerine konuşacağım.
Bu belgede iki farklı eklentiyi ekleyeceğiz:
- Bağımlılık kontrolü
- Sonar YAML
Sonar Tarayıcı CLI’yi Hazırlama
Şimdi, pipeline’da kullanılacak bir konteyner imajı oluşturacağız. Teorik olarak her senaryoda çalışacak bir konteyner yaratacağız.
Dockerfile’da birçok araç kuracağız, böylece tarama yaparken hemen çalışacaktır.
Öncelikle, Docker’da en son etiketleri kullanmamayı bir en iyi uygulama olarak kabul ederiz. Daha sonra aşağıdaki araçları kurar ve yükleme paketlerini temizleriz:
# Gerekli paketleri kur
RUN apt-get update && \
apt-get install -y wget unzip openjdk-17-jdk curl python3-pip pkg-config python2 && \
apt-get clean && \
apt-get install -y zip apt-utils build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev awscli && \
rm -rf /var/lib/apt/lists/*
Java ortam değişkenlerini ayarlıyoruz:
# Java ortam değişkenlerini ayarla
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ENV PATH="${JAVA_HOME}/bin:${PATH}"
JavaScript kodunu bolca kullanıyorum, bu yüzden nvm (node sürümünü yükleyen bir paket) kurdum. Bir sonraki adımda bu ön yükleme daha net olacak.
# NVM kullanarak Node.js kur
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash \
&& export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" \
&& [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
&& nvm install node \
&& npm install -g yarn
SonarQube Tarayıcıyı kuruyoruz:
# SonarQube Tarayıcıyı kur
RUN wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip && \
unzip sonar-scanner-cli-5.0.1.3006-linux.zip -d /opt && \
mv /opt/sonar-scanner-5.0.1.3006-linux /opt/sonar-scanner && \
rm -f sonar-scanner-cli-5.0.1.3006-linux.zip
# Shell Ortamını Yapılandır
ENV PATH="/opt/sonar-scanner/bin:$PATH"
OWASP Bağımlılık Kontrolü, paketlerinizde bilinen güvenlik açıklarını kontrol etmek için önerilen bir araçtır:
# OWASP Bağımlılık Kontrolü kur
ENV owasp_dep_api=""
RUN export VERSION=$(curl -s https://jeremylong.github.io/DependencyCheck/current.txt) && \
curl -Ls "https://github.com/jeremylong/DependencyCheck/releases/download/v$VERSION/dependency-check-$VERSION-release.zip" -o dependency-check.zip && \
unzip dependency-check.zip && \
mv dependency-check /opt && \
mv /opt/dependency-check/bin/dependency-check.sh /opt/dependency-check/bin/dependency-check && \
chmod +x /opt/dependency-check/bin/dependency-check && \
sh /opt/dependency-check/bin/dependency-check -updateonly -nvdApiKey "$owasp_dep_api"
ENV PATH="/opt/dependency-check/bin:$PATH"
Trivy, Terraform, Kubernetes ve Cloud için bir güvenlik tarayıcısıdır:
# Trivy kur
RUN wget https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.tar.gz && \
tar zxvf trivy_0.50.1_Linux-64bit.tar.gz && \
mv trivy /usr/local/bin && \
rm trivy_0.50.1_Linux-64bit.tar.gz
TFLint, Terraform için bir linter’dır:
# TFLint kur
RUN wget https://github.com/terraform-linters/tflint/releases/download/v0.50.3/tflint_linux_amd64.zip && \
unzip tflint_linux_amd64.zip && \
mv tflint /usr/local/bin && \
rm tflint_linux_amd64.zip
Checkov, Terraform, CloudFormation, Kubernetes, Helm, ARM Şablonları ve Serverless çerçevelerini analiz eden bir araçtır:
# Checkov kur
RUN pip3 install checkov
Çalışma dizinini ayarlıyoruz ve bir entrypoint.sh oluşturuyoruz:
# Çalışma dizinini ayarla
WORKDIR /app
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# EntryPoint scriptini çalıştır
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Konteyneri başlatırken gerekli tüm işlemleri yapıyoruz:
# Konteyner başladığında çalıştırılacak komut
CMD ["/bin/bash"]
Konteyneri Çalıştırma ve Sonar Taramasını Yapma
Bu adımda bir script dosyasını çalıştıracağız ve ek adımlar ekleyebileceksiniz. Genellikle bu adımları her projede aynı şekilde pipeline’a koyarım, ancak diğer yöntemler de mümkündür.
GitHub reposunda bir execute.sh mevcut.
Öncelikle, Sonar tarayıcısının bellek limitini ayarlıyoruz:
# Sonar tarama bellek limitini ayarla
export SONAR_SCANNER_OPTS="-Xmx6048m"
JavaScript çerçeve dili ile çalışıyorsanız, node_modules paketini kurmanız gerekir. Bu adımda, proje kök klasöründe bir sonar-pre-execute.sh dosyası oluşturmalısınız:
# JavaScript için node_modules kur
file=sonar-pre-execute.sh
if [ -e $file ]; then
bash "$file"
else
echo "Kök klasörde PRE .sh dosyası bulunamadı."
fi
Terraform dizinindeyseniz, bazı dosyaları önceden hazırlamanız gerekir. Terraform planını çalıştırıp bir .plan uzantılı dosya oluşturmalısınız.
Kullanışlı Komutlar ve Sonuçlar
# Sonar taraması komutları
sonar-scanner \
-Dsonar.projectKey=<YOUR_PROJECT_KEY> \
-Dsonar.sources=. \
-Dsonar.host.url=<SONARQUBE_URL> \
-Dsonar.login=<YOUR_AUTH_TOKEN>
Sonuçların başarılı bir şekilde tamamlandığını doğrulamak için SonarQube arayüzüne gidin.
SonarQube Kurulumu ve Yapılandırılması
SonarQube’u DevSecOps süreçlerinize dahil etmenin ilk adımı, SonarQube sunucusunu kurmak ve bir proje ile entegre etmektir. Aşağıda SonarQube’un Docker ile nasıl kurulacağını ve Jenkins ile nasıl entegre edileceğini göstereceğiz.
Adım 1: SonarQube Docker Kurulumu
docker run -d --name sonarqube \
-p 9000:9000 \
sonarqube:latest
Bu komutla SonarQube sunucusunu Docker üzerinde çalıştırabilirsiniz. Ardından, web tarayıcınızda http://localhost:9000
adresine giderek SonarQube arayüzüne ulaşabilirsiniz.
Adım 2: Jenkins Entegrasyonu DevSecOps sürecinde sürekli entegrasyon ve dağıtım (CI/CD) araçları önemlidir. Jenkins ile SonarQube’u entegre ederek her kod değişikliğinde otomatik güvenlik ve kalite testleri gerçekleştirebilirsiniz.
Jenkins Pipeline Tanımı:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git 'https://github.com/kullanici/proje-repo.git'
}
}
stage('SonarQube Analysis') {
environment {
scannerHome = tool 'SonarQube Scanner'
}
steps {
script {
def sonarScanner = "${scannerHome}/bin/sonar-scanner"
sh "${sonarScanner} \
-Dsonar.projectKey=ProjeAnahtari \
-Dsonar.sources=. \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=token"
}
}
}
}
}
Bu basit pipeline, SonarQube taramasını bir Jenkins işine entegre eder. sonar.projectKey
, SonarQube üzerindeki projenizi tanımlar. sonar.login
kısmında ise SonarQube sunucusunda tanımladığınız kullanıcı token’ı kullanılır.
Güvenlik Analizi
SonarQube, OWASP Top 10 listesinde yer alan birçok güvenlik açığını tespit edebilir. Örneğin, aşağıdaki Python kodunda bir SQL enjeksiyon açığı bulunmaktadır:
def get_user_data(user_id):
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query)
return cursor.fetchall()
Bu kodda, user_id
parametresinin doğrudan SQL sorgusuna eklenmesi SQL enjeksiyonu riskine yol açar. SonarQube bu tarz güvenlik açıklarını tespit eder ve iyileştirme önerileri sunar. Örneğin, yukarıdaki kodun düzeltilmiş hali:
def get_user_data(user_id):
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))
return cursor.fetchall()
Bu şekilde, sorgu parametrelenmiş hale getirilir ve enjeksiyon riski ortadan kaldırılır.
Güvenlik Risklerini Önlemek için En İyi Uygulamalar
SonarQube’un sunduğu güvenlik analizlerini en iyi şekilde kullanmak için şu önerileri dikkate alabilirsiniz:
- Düzenli Tarama: Her yeni kod commit’inden sonra SonarQube taramaları yapılmalı.
- Otomatik Raporlama: Güvenlik açıkları raporlanmalı ve kritik sorunlar için uyarı sistemleri kurulmalı.
- Ekip Eğitimleri: Geliştiricilerin güvenlik konusunda farkındalık kazanması için düzenli eğitimler düzenlenmeli.
Sonuç SonarQube, DevSecOps süreçlerinin olmazsa olmaz bir parçasıdır. Kod kalitesini artırmanın yanı sıra, güvenlik açıklarını erkenden tespit ederek yazılımın güvenli bir şekilde geliştirilmesine katkı sağlar. Jenkins gibi CI/CD araçlarıyla entegre edildiğinde ise otomatik güvenlik taramaları ile her aşamada güvenliği sağlamak mümkün hale gelir.
DevSecOps sürecinizi optimize edebilirsiniz. Bu adımlar ve araçlar, yazılım geliştirme sürecinde güvenlik ve kaliteyi artırmanıza yardımcı olacaktır.