Uzun süredir idari yönetim süreçleri nedeniyle teknik operasyonlardan uzak kaldığım için, teknik detay içeren yazılar yazmıyordum.
Yakın zamanda bazı değişimler ve ihtiyaçlar nedeniyle 365 tarafında güvenlik farkındalığı amacıyla ihtiyaç olan Azure notification metodları ile ilgili çok işe yarayacak ve AI ile de işinizi çözemeyeceğiniz bir paylaşım yapmak istedim.
Özellikle Azure üzerinde Sanal sunucu kullananlar için çok uygun maliyette ve anlaşılır bir notification metodu geliştirmek isterseniz. Aşağıdaki yöntemi kullanabilirsiniz.
Bu yapı sizi Azure’da aylık yaklaşık 10 dolar gibi bir maliyetle tüm sunucularınızın CPU – RAM – Disk uyarılarının bilgilerini istediğiniz eşikte mail olarak almayı, sunucularınız kapanırsa açılırsa ya da restart olursa yine aynı şekilde bu bilgileri almayı ve yine sunucularınıza linux windows farketmeksizin her success loginde mail ile bildirim alabileceğiniz ve farkındalığınızı arttırabilecek bir yapı sunacaktır. Azure’un normal bildirim yöntemleri ile oluşturacağınız alertler anlaşılabilir içerikler sağlamadığı gibi gereksiz oldukça fazla veri barındırıyor. Sade, anlaşılır ve amaca yönelik özel optimize edilmiş bir yönteme ihtiyacınız var ise AI’lar ile bile ulaşamayacağınız veri setini paylaşıyorum.
I haven’t been writing about technical details for a long time because I’ve been away from technical operations due to administrative processes.
Recently, due to some changes and needs, I wanted to share a very useful method for security awareness on the 365 side: Azure notification methods. This method is something you can’t achieve with AI alone.
Especially for those using virtual servers on Azure, if you want to develop a very cost-effective and understandable notification method, you can use the following method.
This structure will allow you to receive information about CPU, RAM, and disk alerts for all your servers via email at your desired thresholds, for approximately $10 per month on Azure. You can also receive information about server shutdowns, restarts, or other server issues, and receive email notifications for every successful login, regardless of whether your servers are Linux or Windows, increasing your awareness. Azure’s standard notification methods don’t provide understandable content and contain a lot of unnecessary data. If you need a simple, understandable, and purpose-optimized method, I’m sharing a dataset you can’t achieve with AI.
Amaç
Azure VM sunuculari icin özel mail bildirimleri kurmak. Azure Monitor Alert kurallari, Logic App ve SMTP baglantisi kullanilarak sunucu olaylarinda özellestirilmis mail gönderimi sağlanmaktadır.
Mimari
- Azure Monitor, VM metriklerini, Activity Log ve Event Log’lari izler
- Belirlenen esik degeri asildiginda veya olay gerceklestiginde Alert Rule tetiklenir
- Alert Rule, Action Group’u calistirir
- Action Group, Logic App’i tetikler (HTTP webhook)
- Logic App, SMTP uzerinden ozel formatta mail gonderir
Kapsam
– CPU kullanimi %80 uzerinde
– RAM kullanimi %80 uzerinde
– Disk kullanimi %80 uzerinde (C:, /, /data)
– Sunucu Reboot (Azure Portal uzerinden)
– Sunucu Start/Stop (acilma/kapanma)
– RDP ve SSH uzak baglanti bildirimi
AŞAMA 1: Logic App Olusturma
Mail gonderecek olan Logic App’i olusturuyoruz.
1.1 – Logic App Kaynak Olusturma
- Azure Portal ust arama cubuguna Logic Apps yaz ve tikla
- + Add butonuna tikla
- Bilgileri doldur:
Subscription: Mevcut subscription
Resource Group: rg-monitor
Logic App name: lg-xx-monitoring
Region: VM’lere yakin bolge
Plan type: Consumption
- Review + Create > Create
- Go to resource tikla
1.2 – HTTP Trigger Ekleme
- Logic App Designer’da When a HTTP request is received trigger’ini sec
- Sample payload eklemeye gerek yok, direkt devam et
1.3 – SMTP Mail Gonderme Adimi
- + New step > SMTP ara > Send Email (V3) seç
SMTP Baglanti Bilgileri:
SMTP Server: smtp.office365.com (veya kendi SMTP sunucunuz)
User Name: xx@şirketadiniz.com
Password: Hesap sifresi veya App Password (MFA varsa)
Port: 587
SSL: Evet
NOT: MFA aktifse App Password kullanin veya Office 365 Outlook connector kullanin.
1.4 – Mail Icerigini Yapilandirma
From:
xx@şirketadiniz.com
To:
xxx@şirketadiniz.com
Subject (Expression):
concat(‘⚠️ ALARM: ‘,
triggerBody()?[‘data’]?[‘essentials’]?[‘alertRule’],
‘ | Sunucu: ‘,
last(split(first(triggerBody()?[‘data’]
?[‘essentials’]?[‘alertTargetIDs’]), ‘/’)))
Body – Satirlar (Is HTML: Yes):
Her Expression icin Body alanina tikla > Expression sekmesine gec > yapistir > OK tikla.
Satir 1 – Baslik (duz yazi): Sunucu Alarm Bildirimi
Satir 2 – Alarm Adi:
Duz yazi: Alarm Adi: + Expression:
triggerBody()?[‘data’]?[‘essentials’]?[‘alertRule’]
Satir 3 – Onem Derecesi (duz yazi): Onem Derecesi: Yuksek
Satir 4 – Tetiklenme Zamani: (Bu bölüm hatalı gelen timezone’u düzeltir.)
Duz yazi: Tetiklenme Zamani: + Expression:
convertTimeZone(triggerBody()?[‘data’]?[‘essentials’]
?[‘firedDateTime’], ‘UTC’, ‘Turkey Standard Time’,
‘dd.MM.yyyy HH:mm:ss’)
Satir 5 – Etkilenen Kaynak:
Duz yazi: Etkilenen Kaynak: + Expression:
last(split(first(triggerBody()?[‘data’]?[‘essentials’]
?[‘alertTargetIDs’]), ‘/’))
Satir 6 – Durum:
Duz yazi: Durum: + Expression:
triggerBody()?[‘data’]?[‘essentials’]?[‘description’]
Satir 7 – Detay Bilgisi (Disk/Login – tek Expression):
Bu expression alert turune gore otomatik farkli bilgi gosterir:
Disk Alert -> Disk: C: | Kullanim: % xx
Login Alert -> Kullanici: jonedoe | IP: 1.2.3.4 | Protokol: RDP
Diger alertlar -> Bos (hicbir sey gostermez)
Expression:
if(equals(triggerBody()?[‘data’]?[‘essentials’]
?[‘alertRule’], ‘Login Alert’),
concat(‘Kullanici: ‘,
coalesce(triggerBody()?[‘data’]?[‘alertContext’]
?[‘condition’]?[‘allOf’][0]?[‘dimensions’][2]
?[‘value’], ”),
‘ | IP: ‘,
coalesce(triggerBody()?[‘data’]?[‘alertContext’]
?[‘condition’]?[‘allOf’][0]?[‘dimensions’][3]
?[‘value’], ”),
‘ | Protokol: ‘,
coalesce(triggerBody()?[‘data’]?[‘alertContext’]
?[‘condition’]?[‘allOf’][0]?[‘dimensions’][1]
?[‘value’], ”)),
if(equals(triggerBody()?[‘data’]?[‘essentials’]
?[‘alertRule’], ‘Disk Alert’),
concat(‘Disk: ‘,
coalesce(triggerBody()?[‘data’]?[‘alertContext’]
?[‘condition’]?[‘allOf’][0]?[‘dimensions’][1]
?[‘value’], ”),
‘ | Kullanim: %’,
coalesce(string(triggerBody()?[‘data’]
?[‘alertContext’]?[‘condition’]?[‘allOf’][0]
?[‘metricValue’]), ”)),
”))
NOT: ONEMLI: Alert rule isimleri ‘Login Alert’ ve ‘Disk Alert’ olarak tanimlanmalidir. Farkli isim kullanilirsa expression calismaz.
Satir 8 – Alt Bilgi (duz yazi): Bu mail otomatik olarak Azure Monitor tarafindan gonderilmistir.
Satir 9 – Imza (duz yazi): Sirket BT Ekibi
. Save tikla
ASAMA 2: Action Group Olusturma
Tum alert rule’lar icin tek bir Action Group kullanilacak.
- Azure Monitor > Alerts > Action groups > + Create
Basics:
Action group name: AG-VM-Monitoring
Display name: VM-Monitor
Actions:
- Action type: Logic App > lg-xx-monitoring sec
- Enable common alert schema: Yes
- Name: SendAlertEmail
- Review + Create > Create
ASAMA 3: VM Detailed Metrics Etkinlestirme
RAM ve Disk alert’lari icin VM’lerde detayli metriklerin toplanmasi gerekir. Bu adimi HER VM icin tekrarlayın.
- VM’e git > sol menuden Monitor tikla
- Memory kisminda configure detailed metrics linkine tikla
- Iki checkbox’u da isaretle (OpenTelemetry + Log-based)
- Review + enable > Enable
NOT: Memory verisi toplanmaya baslamasi 15-30 dakika surebilir.
ASAMA 4: Data Collection Rules (DCR) Olusturma
RDP/SSH login bildirimleri ve sunucu ici reboot tespiti icin Windows Event Log ve Linux Syslog verilerinin toplanmasi gerekir.
4.1 – Windows DCR
- Ust arama cubuguna Data collection rules yaz > + Create
Basics:
Rule name: DCR-Login-Windows
Resource Group: rg-monitor
Region: Sweden Central (Burası uygun fiyatlı bir region 🙂 )
Platform Type: Windows
Resources:
- + Add resources > Tum Windows VM’leri sec > Apply
Collect and deliver:
- + Add data source
Data source type: Windows Event Logs
Log level: Security kategorisini isaretle
Destination: Mevcut Log Analytics workspace
- Add > Review + Create > Create
4.2 – Linux DCR
- Data collection rules > + Create
Basics:
Rule name: DCR-Login-Linux
Resource Group: rg-monitor
Region: Sweden Central
Platform Type: Linux
Resources:
- + Add resources > Tum Linux VM’leri sec > Apply
Collect and deliver:
- + Add data source
Data source type: Linux Syslog
auth: LOG_INFO
authpriv: LOG_INFO
Diger facility’ler: LOG_NONE
Destination: Ayni Log Analytics workspace
- Add > Review + Create > Create
NOT: Veri toplanmaya baslamasi 15-30 dakika surebilir. Sonradan yeni sunucu eklemek icin ilgili DCR’ye gidip Resources kisminda VM ekleyin.
ASAMA 5: VM Reboot Alert Rule
Azure Portal uzerinden yapilan restart islemlerini yakalar.
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- VM’leri sec
Condition:
- Signal: Restart Virtual Machine | Status: Succeeded
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Alert-VM-Reboot
Description: Sunucu yeniden baslatildi (Reboot)
- Review + Create > Create
NOT: Sadece Azure Portal/CLI/PowerShell uzerinden yapilan restart’lari yakalar.
ASAMA 6: Sunucu Start/Stop Alert Rules
Sunucu acildiginda veya kapatildiginda bildirim gonderir. Iki ayri alert rule gereklidir.
6.1 – Sunucu Kapanma (Deallocate) Alert
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- VM’leri sec
Condition:
- Signal: Deallocate Virtual Machine | Status: Succeeded
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Alert-VM-Stop
Description: Sunucu kapatildi (Deallocate)
- Review + Create > Create
6.2 – Sunucu Acilma (Start) Alert
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- Ayni VM’leri sec
Condition:
- Signal: Start Virtual Machine | Status: Succeeded
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Alert-VM-Start
Description: Sunucu baslatildi
- Review + Create > Create
ASAMA 7: CPU %80 Alert Rule
CPU kullanimi %80’i gectiginde bildirim gonderir.
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- VM’leri sec
Condition:
- Signal: Percentage CPU
Operator: Greater than
Threshold: 80
Check every: 5 minutes
Lookback period: 5 minutes
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Alert-CPU-80
Description: CPU kullanimi %80 esigini asti
- Review + Create > Create
ASAMA 8: RAM %80 Alert Rule
RAM kullanimi %80’i gectiginde bildirim gonderir. Log Search Alert olarak olusturulur.
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- Resource type: Log Analytics workspaces > workspace sec
Condition:
- Signal: Custom log search > KQL sorgusu:
InsightsMetrics
| where Origin == “vm.azm.ms”
| where Namespace == “Memory” and Name == “AvailableMB”
| extend TotalMemory = toreal(todynamic(Tags)
[“vm.azm.ms/memorySizeMB”])
| extend MemoryUsagePercent = ((TotalMemory
– toreal(Val)) / TotalMemory) * 100
| summarize avg(MemoryUsagePercent) by
bin(TimeGenerated, 5m), Computer, _ResourceId
Measurement:
Measure: avg_MemoryUsagePercent
Aggregation type: Average
Aggregation granularity: 5 minutes
Alert logic:
Operator: Greater than
Threshold: 80
Frequency: 5 minutes
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: RAM Alert
Description: RAM kullanimi %80 eşigini aştı
- Review + Create > Create
ASAMA 9: Disk %80 Alert Rule
Disk kullanimi %80’i gectiginde bildirim gonderir. Windows C:, Linux / ve /data disklerini izler.
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- Resource type: Log Analytics workspaces > ayni workspace sec
Condition:
- Signal: Custom log search > KQL sorgusu:
InsightsMetrics
| where Origin == “vm.azm.ms”
| where Namespace == “LogicalDisk”
and Name == “FreeSpacePercentage”
| extend Disk = tostring(todynamic(Tags)
[“vm.azm.ms/mountId”])
| where Disk == “C:” or Disk == “/”
or Disk == “/data”
| extend DiskUsedPercent = 100 – Val
| where DiskUsedPercent > 80
| summarize AggregatedValue = max(DiskUsedPercent)
by bin(TimeGenerated, 5m), Disk, Computer,
_ResourceId
NOT: Summarize sirasinda Disk, Computer’dan once gelmeli.
Split by dimensions:
Disk: Include all values
Computer: Include all values
Measurement:
Measure: AggregatedValue
Aggregation type: Maximum
Aggregation granularity: 5 minutes
Alert logic:
Operator: Greater than
Threshold: 0
Frequency: 5 minutes
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Disk Alert
Description: Disk kullanimi %80 esigini asti
- Review + Create > Create
ASAMA 10: RDP/SSH Login Alert Rule
Sunuculara RDP veya SSH ile baglanti yapildiginda bildirim gonderir. Tek bir alert rule ile hem Windows hem Linux sunucular izlenir.
NOT: Oncelikle ASAMA 4’teki DCR’lerin olusturulmus ve veri toplamaya baslamis olmasi gerekir.
- Azure Monitor > Alerts > + Create > Alert rule
Scope:
- Resource type: Log Analytics workspaces > ayni workspace sec
Condition:
- Signal: Custom log search > KQL sorgusu:
let rdp = Event
| where EventLog == “Security” and EventID == 4624
| parse EventData with * ‘<Data Name=”LogonType”>’
LogonType ‘</Data>’ *
| where LogonType == “10”
| parse EventData with * ‘<Data Name=”TargetUserName”>’
RemoteUser ‘</Data>’ *
| parse EventData with * ‘<Data Name=”IpAddress”>’
SourceIP ‘</Data>’ *
| project TimeGenerated, Computer, RemoteUser,
SourceIP, Protokol = “RDP”, _ResourceId;
let ssh = Syslog
| where Facility == “auth” or Facility == “authpriv”
| where SyslogMessage contains “Accepted”
| parse SyslogMessage with * “for ” RemoteUser
” from ” SourceIP ” ” *
| project TimeGenerated, Computer = HostName,
RemoteUser, SourceIP, Protokol = “SSH”,
_ResourceId;
union rdp, ssh
| summarize AggregatedValue = count() by
bin(TimeGenerated, 5m), Computer, RemoteUser,
SourceIP, Protokol, _ResourceId
Split by dimensions:
Computer: Include all values
Protokol: Include all values
RemoteUser: Include all values
SourceIP: Include all values
NOT: Dimensions sirasi: D0=Computer, D1=Protokol, D2=RemoteUser, D3=SourceIP. Logic App expression’i bu siraya gore ayarlanmistir.
Measurement:
Measure: AggregatedValue
Aggregation type: Total
Aggregation granularity: 5 minutes
Alert logic:
Operator: Greater than
Threshold: 0
Frequency: 5 minutes
Actions:
- Select action group > AG-VM-Monitoring
Details:
Alert rule name: Login Alert
Description: Uzak baglanti tespit edildi (RDP/SSH)
- Review + Create > Create
TEST YONTEMLERI
Action Group Testi (Hizli Test)
- Azure Monitor > Alerts > Action groups > group sec > Test
Reboot/Start/Stop: Activity log – Administrative
CPU/Disk: Metric alert – Static threshold
RAM/Login: Log alert V2
Gercek Testler
Reboot:
Azure Portal > VM > Restart butonu (2-5 dk bekle)
Start/Stop:
Azure Portal > VM > Stop butonu, sonra Start (2-5 dk bekle)
CPU (Linux):
sudo apt install stress -y
stress –cpu 4 –timeout 360
RAM (Linux):
free -m
stress –vm 1 –vm-bytes 5500M –timeout 360
Disk:
Threshold’u gecici 10’a düşürr, 5-10 dk bekle, sonra 80’e geri çevir.
RDP/SSH Login:
Windows sunucuya RDP ile baglan veya Linux sunucuya SSH ile baglan. 5-10 dk içinde mail gelir.
YENI SUNUCU EKLEME
Yeni bir sunucu eklemek icin asagidaki adimlari izleyin:
- Detailed Metrics etkinlestir: ASAMA 3’u yeni VM icin tekrarla
- DCR’ye ekle: Windows ise DCR-Login-Windows, Linux ise DCR-Login-Linux > Resources > + Add
- Activity Log alert’lari: Scope subscription veya resource group ise otomatik dahil olur. Degilse scope’u genislet veya VM’i ekle
- CPU Metric alert: Scope resource group ise otomatik dahil olur
- RAM/Disk/Login alert: Workspace scope’unda oldugu icin, DCR’ye eklenen VM otomatik dahil olur
NOT: En az iş gerektiren yontem: Activity Log ve Metric alert’larinin scope’unu subscription veya resource group seviyesine cekmektir.( Bazı alertlerde subs ya da resource seçilince alertler çalışmıyor en güvenli yöntem direkt resource seçmek. )
ÖZET: Tum Alert Rule’lar
| Alert | Tip | Signal | Kosul | Scope | Maliyet | |
| Alert-VM-Reboot | Activity Log | Restart VM | Succeeded | VM’ler | Ucretsiz | Temel |
| Alert-VM-Stop | Activity Log | Deallocate VM | Succeeded | VM’ler | Ucretsiz | Temel |
| Alert-VM-Start | Activity Log | Start VM | Succeeded | VM’ler | Ucretsiz | Temel |
| Alert-CPU-80 | Metric | Percentage CPU | > 80 | VM’ler | ~$0.10/ay | Temel |
| RAM Alert | Log Search | KQL Memory | > 80% | Workspace | ~$1.50/ay | Temel |
| Disk Alert | Log Search | KQL LogicalDisk | Used>80% | Workspace | ~$1.50/ay | +Disk |
| Login Alert | Log Search | KQL Event+Syslog | Login>0 | Workspace | ~$1.50/ay | +Login |
Eylemlerimiz sürecek 🙂