Ringkasan penguraian log
Dokumen ini memberikan ringkasan tentang cara Google Security Operations mengurai log mentah ke format Unified Data Model (UDM).
Google Security Operations dapat menerima data log yang berasal dari sumber penyerapan berikut:
- Pengirim Google Security Operations
- Feed Google Security Operations API
- Google Security Operations Ingestion API
- Partner teknologi pihak ketiga
Secara umum, pelanggan mengirimkan data sebagai log mentah asli. Google Security Operations secara unik mengidentifikasi perangkat yang menghasilkan log menggunakan LogType. LogType mengidentifikasi keduanya:
- vendor dan perangkat yang membuat log, seperti Cisco Firewall, Server DHCP Linux, atau Bro DNS.
- yang mengonversi log mentah menjadi Unified Data Model (UDM) terstruktur. Ada hubungan one-to-one antara parser dan LogType. Setiap parser mengonversi data yang diterima oleh satu LogType.
Google Security Operations menyediakan serangkaian parser default yang membaca log mentah asli dan membuat data UDM terstruktur menggunakan data dalam log mentah asli. Google Security Operations mengelola parser ini. Pelanggan juga dapat menentukan petunjuk pemetaan data kustom dengan membuat parser khusus pelanggan. Hubungi perwakilan Google Security Operations Anda untuk mengetahui informasi tentang cara membuat parser khusus pelanggan.
Parser berisi petunjuk pemetaan data. Ini menentukan cara data dipetakan dari log mentah asli ke satu atau beberapa kolom dalam struktur data UDM.
Jika tidak ada error penguraian, Google Security Operations akan membuat data terstruktur UDM menggunakan data dari log mentah. Proses mengonversi log mentah menjadi data UDM disebut normalisasi.
Parser default dapat memetakan subset nilai inti dari log mentah. Biasanya, kolom inti ini adalah yang paling penting untuk memberikan insight keamanan di Google Security Operations. Nilai yang tidak dipetakan tetap ada dalam log mentah, tetapi tidak disimpan dalam data UDM.
Pelanggan juga dapat menggunakan Ingestion API, untuk mengirim data dalam format Unified Data Model (UDM) terstruktur.
Menyesuaikan cara penguraian data yang diserap
Google Security Operations menyediakan kemampuan berikut yang memungkinkan pelanggan menyesuaikan penguraian data pada data log asli yang masuk.
- Parser khusus pelanggan: pelanggan membuat konfigurasi parser kustom untuk jenis log tertentu yang memenuhi persyaratan khusus mereka. Parser khusus pelanggan akan menggantikan parser default untuk LogType tertentu. Hubungi perwakilan Google Security Operations Anda untuk mengetahui informasi tentang cara membuat parser khusus pelanggan.
- Ekstensi parser: Pelanggan dapat menambahkan petunjuk pemetaan kustom selain konfigurasi parser default. Setiap pelanggan dapat membuat kumpulan petunjuk pemetaan kustom unik mereka sendiri. Petunjuk pemetaan ini menentukan cara mengekstrak dan mengubah kolom tambahan dari log mentah asli ke kolom UDM. Ekstensi parser tidak menggantikan parser default atau khusus pelanggan.
Contoh penggunaan log proxy web Squid
Bagian ini memberikan contoh log proxy web Squid dan menjelaskan cara nilai dipetakan ke data UDM. Untuk deskripsi semua kolom dalam skema UDM, lihat Daftar kolom Model Data Terpadu.
Contoh log proxy web Squid berisi nilai yang dipisahkan spasi. Setiap data mewakili satu peristiwa dan menyimpan data berikut: stempel waktu, durasi, klien, kode hasil/status hasil, byte yang dikirim, metode permintaan, URL, pengguna, kode hierarki, dan jenis konten. Dalam contoh ini, kolom berikut diekstrak dan dipetakan ke dalam data UDM: waktu, klien, status hasil, byte, metode permintaan, dan URL.
1588059648.129 23 192.168.23.4 TCP_HIT/200 904 GET www.google.com/images/sunlogo.png - HIER_DIRECT/203.0.113.52 image/jpeg
Saat Anda membandingkan struktur ini, perhatikan bahwa hanya sebagian data log asli yang disertakan dalam kumpulan data UDM. Kolom tertentu wajib diisi dan kolom lainnya bersifat opsional. Selain itu, hanya sebagian bagian dalam data UDM yang berisi data. Jika parser tidak memetakan data dari log asli ke data UDM, Anda tidak akan melihat bagian data UDM tersebut di Google Security Operations.
Bagian metadata
menyimpan stempel waktu peristiwa. Perhatikan bahwa nilai dikonversi
dari format EPOCH ke RFC 3339. Konversi ini bersifat opsional. Stempel waktu dapat
disimpan sebagai format EPOCH, dengan prapemrosesan untuk memisahkan bagian detik dan
milidetik ke dalam kolom terpisah.
Kolom metadata.event_type
menyimpan nilai NETWORK_HTTP
yang merupakan nilai yang dihitung
yang mengidentifikasi jenis peristiwa. Nilai metadata.event_type
menentukan kolom UDM tambahan yang diperlukan atau opsional. Nilai product_name
dan
vendor_name
berisi deskripsi perangkat yang mudah digunakan dan
mencatat log asli.
metadata.event_type
dalam data Peristiwa UDM tidak sama dengan log_type
yang ditentukan saat menyerap data menggunakan Ingestion API. Kedua atribut ini menyimpan
informasi yang berbeda.
Bagian network
berisi nilai dari peristiwa log asli. Perhatikan dalam contoh
ini bahwa nilai status dari log asli diuraikan dari kolom 'result
code/status' sebelum ditulis ke data UDM. Hanya result_code
yang disertakan dalam data UDM.
Bagian principal
menyimpan informasi klien dari log asli. Bagian
target
menyimpan URL yang sepenuhnya memenuhi syarat dan alamat IP.
Bagian security_result
menyimpan salah satu nilai enum untuk mewakili tindakan yang dicatat dalam log asli.
Ini adalah kumpulan data UDM yang diformat sebagai JSON. Perhatikan bahwa hanya bagian yang
berisi data yang disertakan. Bagian src
, observer
, intermediary
, about
,
dan extensions
tidak disertakan.
{
"metadata": {
"event_timestamp": "2020-04-28T07:40:48.129Z",
"event_type": "NETWORK_HTTP",
"product_name": "Squid Proxy",
"vendor_name": "Squid"
},
"principal": {
"ip": "192.168.23.4"
},
"target": {
"url": "www.google.com/images/sunlogo.png",
"ip": "203.0.113.52"
},
"network": {
"http": {
"method": "GET",
"response_code": 200,
"received_bytes": 904
}
},
"security_result": {
"action": "UNKNOWN_ACTION"
}
}
Langkah-langkah dalam petunjuk parser
Petunjuk pemetaan data dalam parser mengikuti pola umum, seperti berikut:
- Mengurai dan mengekstrak data dari log asli.
- Memanipulasi data yang diekstrak. Hal ini mencakup penggunaan logika kondisional untuk menguraikan nilai secara selektif, mengonversi jenis data, mengganti substring dalam nilai, mengonversi ke huruf besar atau huruf kecil, dll.
- Tetapkan nilai ke kolom UDM.
- Menampilkan data UDM yang dipetakan ke kunci @output.
Mengurai dan mengekstrak data dari log asli
Menetapkan pernyataan filter
Pernyataan filter
adalah pernyataan pertama dalam kumpulan petunjuk penguraian.
Semua petunjuk penguraian tambahan terdapat dalam pernyataan filter
.
filter {
}
Melakukan inisialisasi variabel yang akan menyimpan nilai yang diekstrak
Dalam pernyataan filter
, lakukan inisialisasi variabel perantara yang akan digunakan
parser untuk menyimpan nilai yang diekstrak dari log.
Variabel ini digunakan setiap kali setiap log diuraikan. Nilai di setiap variabel perantara akan ditetapkan ke satu atau beberapa kolom UDM nanti dalam petunjuk penguraian.
mutate {
replace => {
"event.idm.read_only_udm.metadata.product_name" => "Webproxy"
"event.idm.read_only_udm.metadata.vendor_name" => "Squid"
"not_valid_log" => "false"
"when" => ""
"srcip" => ""
"action" => ""
"username" => ""
"url" => ""
"tgtip" => ""
"method" => ""
}
}
Mengekstrak setiap nilai dari log
Google Security Operations menyediakan serangkaian filter, berdasarkan Logstash, untuk mengekstrak kolom dari file log asli. Bergantung pada format log, Anda menggunakan satu atau beberapa filter ekstraksi untuk mengekstrak semua data dari log. Jika string adalah:
- JSON native, sintaksis parser mirip dengan filter JSON yang mendukung log berformat JSON. JSON bertingkat tidak didukung.
- Format XML, sintaksis parser mirip dengan filter XML yang mendukung log berformat XML.
- pasangan nilai kunci, sintaksis parser mirip dengan filter Kv yang mendukung pesan berformat nilai kunci.
- Format CSV, sintaksis parser mirip dengan filter Csv yang mendukung pesan berformat csv.
- semua format lainnya, sintaksis parser mirip dengan filter GROK dengan pola bawaan GROK . Ini menggunakan petunjuk ekstraksi gaya Regex.
Google Security Operations menyediakan sebagian kemampuan yang tersedia di setiap filter. Google Security Operations juga menyediakan sintaksis pemetaan data kustom yang tidak tersedia di filter. Lihat Referensi sintaksis parser untuk mengetahui deskripsi fitur yang didukung dan fungsi kustom.
Melanjutkan contoh log proxy web Squid, petunjuk ekstraksi data berikut menyertakan kombinasi sintaksis Logstash Grok dan ekspresi reguler.
Pernyataan ekstraksi berikut menyimpan nilai dalam variabel perantara berikut:
when
srcip
action
returnCode
size
method
username
url
tgtip
Contoh pernyataan ini juga menggunakan kata kunci overwrite
untuk menyimpan nilai yang diekstrak
di setiap variabel. Jika proses ekstraksi menampilkan error, pernyataan on_error
akan menetapkan not_valid_log
ke True
.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
overwrite => ["when","srcip","action","returnCode","size","method","url","username","tgtip"]
on_error => "not_valid_log"
}
Melakukan manipulasi dan transformasi pada nilai yang diekstrak
Google Security Operations memanfaatkan kemampuan plugin filter mutasi Logstash untuk memungkinkan manipulasi nilai yang diekstrak dari log asli. Google Security Operations menyediakan sebagian kemampuan yang tersedia di plugin. Lihat Sintaksis parser untuk deskripsi fitur yang didukung dan fungsi kustom, seperti:
- mentransmisikan nilai ke jenis data yang berbeda
- mengganti nilai dalam string
- menggabungkan dua array atau menambahkan string ke array. Nilai string dikonversi ke array sebelum penggabungan.
- mengonversi ke huruf kecil atau huruf besar
Bagian ini memberikan contoh transformasi data yang dibuat berdasarkan log proxy web Squid yang telah disajikan sebelumnya.
Mengubah stempel waktu peristiwa
Semua peristiwa yang disimpan sebagai data UDM harus memiliki stempel waktu peristiwa. Contoh ini memeriksa apakah nilai untuk data diekstrak dari log. Kemudian, fungsi ini menggunakan
fungsi tanggal
Grok untuk mencocokkan nilai dengan format waktu UNIX
.
if [when] != "" {
date {
match => [
"when", "UNIX"
]
}
}
Mengubah nilai username
Contoh pernyataan berikut mengonversi nilai dalam variabel username
menjadi huruf kecil.
mutate {
lowercase => [ "username"]
}
Mengubah nilai action
Contoh berikut mengevaluasi nilai dalam variabel perantara action
dan mengubah nilai menjadi ALLOW, BLOCK, atau UNKNOWN_ACTION yang merupakan nilai yang valid untuk kolom UDM security_result.action
. Kolom UDM security_result.action
adalah jenis yang dihitung yang hanya menyimpan nilai tertentu.
if ([action] == "TCP_DENIED" or [action] == "TCP_MISS" or [action] == "Denied" or [action] == "denied" or [action] == "Dropped") {
mutate {
replace => {
"action" => "BLOCK"
}
}
} else if ([action] == "TCP_TUNNEL" or [action] == "Accessed" or [action] == "Built" or [action] == "Retrieved" or [action] == "Stored") {
mutate {
replace => {
"action" => "ALLOW"
}
}
} else {
mutate {
replace => {
"action" => "UNKNOWN_ACTION" }
}
}
Mengubah alamat IP target
Contoh berikut memeriksa nilai dalam variabel perantara tgtip
.
Jika ditemukan, nilai akan dicocokkan dengan pola alamat IP menggunakan pola Grok
yang telah ditentukan sebelumnya. Jika ada error yang mencocokkan nilai dengan pola alamat IP, fungsi on_error
akan menetapkan properti not_valid_tgtip
ke True
. Jika pencocokan berhasil, properti not_valid_tgtip
tidak akan ditetapkan.
if [tgtip] not in [ "","-" ] {
grok {
match => {
"tgtip" => [ "%{IP:tgtip}" ]
}
overwrite => ["tgtip"]
on_error => "not_valid_tgtip"
}
Mengubah jenis data returnCode dan size
Contoh berikut mentransmisikan nilai dalam variabel size
ke
uinteger
dan nilai dalam variabel returnCode
ke integer
. Hal ini
diperlukan karena variabel size
akan disimpan ke
kolom UDM network.received_bytes
yang menyimpan jenis data int64
. Variabel
returnCode
akan disimpan ke kolom UDM network.http.response_code
yang menyimpan jenis data int32
.
mutate {
convert => {
"returnCode" => "integer"
"size" => "uinteger"
}
}
Menetapkan nilai ke kolom UDM dalam peristiwa
Setelah nilai diekstrak dan dipraproses, tetapkan nilai tersebut ke kolom dalam data peristiwa UDM. Anda dapat menetapkan nilai yang diekstrak dan nilai statis ke kolom UDM.
Jika Anda mengisi event.disambiguation_key
, pastikan kolom ini unik untuk setiap peristiwa yang dihasilkan untuk log yang diberikan. Jika dua peristiwa yang berbeda memiliki disambiguation_key
yang sama, hal ini akan menyebabkan perilaku yang tidak terduga dalam sistem.
Contoh parser di bagian ini dibuat berdasarkan contoh log proxy web Squid di atas.
Menyimpan stempel waktu peristiwa
Setiap data peristiwa UDM harus memiliki nilai yang ditetapkan untuk kolom UDM metadata.event_timestamp
. Contoh berikut menyimpan stempel waktu peristiwa yang diekstrak dari log ke
variabel bawaan @timestamp
. Google Security Operations menyimpannya ke
kolom UDM metadata.event_timestamp
secara default.
mutate {
rename => {
"when" => "timestamp"
}
}
Menetapkan jenis peristiwa
Setiap kumpulan data peristiwa UDM harus memiliki nilai yang ditetapkan untuk kolom UDM metadata.event_type
. Kolom ini adalah jenis yang dihitung. Nilai kolom ini menentukan
kolom UDM tambahan yang harus diisi agar data UDM dapat disimpan.
Proses penguraian dan normalisasi akan gagal jika salah satu kolom wajib diisi tidak
berisi data yang valid.
replace => {
"event.idm.read_only_udm.metadata.event_type" => "NETWORK_HTTP"
}
}
Simpan nilai username
dan method
menggunakan pernyataan replace
Nilai di kolom perantara username
dan method
adalah string. Contoh
berikut memeriksa apakah ada nilai yang valid dan, jika ada, menyimpan
nilai username
ke kolom UDM principal.user.userid
dan nilai method
ke kolom UDM network.http.method
.
if [username] not in [ "-" ,"" ] {
mutate {
replace => {
"event.idm.read_only_udm.principal.user.userid" => "%{username}"
}
}
}
if [method] != "" {
mutate {
replace => {
"event.idm.read_only_udm.network.http.method" => "%{method}"
}
}
}
Simpan action
ke kolom UDM security_result.action
Di bagian sebelumnya, nilai dalam variabel perantara action
dievaluasi dan diubah menjadi salah satu nilai standar untuk kolom UDM security_result.action
.
Kolom UDM security_result
dan action
menyimpan array item,
yang berarti Anda harus mengikuti pendekatan yang sedikit berbeda saat menyimpan nilai ini.
Pertama, simpan nilai yang ditransformasi ke kolom security_result.action
perantara. Kolom security_result
adalah induk dari kolom action
.
mutate {
merge => {
"security_result.action" => "action"
}
}
Selanjutnya, simpan kolom perantara security_result.action
perantara ke
kolom UDM security_result
. Kolom UDM security_result
menyimpan array item, sehingga nilai ditambahkan ke kolom ini.
# save the security_result field
mutate {
merge => {
"event.idm.read_only_udm.security_result" => "security_result"
}
}
Menyimpan alamat IP target dan alamat IP sumber menggunakan pernyataan merge
Simpan nilai berikut ke data peristiwa UDM:
- Nilai di variabel perantara
srcip
ke kolom UDMprincipal.ip
. - Nilai di variabel perantara
tgtip
ke kolom UDMtarget.ip
.
Kolom UDM principal.ip
dan target.ip
menyimpan array item, sehingga
nilai ditambahkan ke setiap kolom.
Contoh di bawah menunjukkan berbagai pendekatan untuk menyimpan nilai ini.
Selama langkah transformasi, variabel perantara tgtip
dicocokkan dengan alamat IP menggunakan pola Grok yang telah ditentukan. Contoh pernyataan berikut
memeriksa apakah properti not_valid_tgtip
bernilai benar yang menunjukkan bahwa nilai tgtip
tidak dapat dicocokkan dengan pola alamat IP. Jika salah, nilai tersebut akan menyimpan nilai tgtip
ke kolom UDM target.ip
.
if ![not_valid_tgtip] {
mutate {
merge => {
"event.idm.read_only_udm.target.ip" => "tgtip"
}
}
}
Variabel perantara srcip
tidak ditransformasikan. Pernyataan berikut
memeriksa apakah nilai diekstrak dari log asli, dan jika ya, menyimpan
nilai ke kolom UDM principal.ip
.
if [srcip] != "" {
mutate {
merge => {
"event.idm.read_only_udm.principal.ip" => "srcip"
}
}
}
Simpan url
, returnCode
, dan size
menggunakan pernyataan rename
Contoh pernyataan di bawah menyimpan nilai berikut menggunakan pernyataan rename
.
- Variabel
url
disimpan ke kolom UDMtarget.url
. - Variabel perantara
returnCode
yang disimpan ke kolom UDMnetwork.http.response_code
. - Variabel perantara
size
disimpan ke kolom UDMnetwork.received_bytes
.
mutate {
rename => {
"url" => "event.idm.read_only_udm.target.url"
"returnCode" => "event.idm.read_only_udm.network.http.response_code"
"size" => "event.idm.read_only_udm.network.received_bytes"
}
}
Mengikat data UDM ke output
Pernyataan terakhir dalam petunjuk pemetaan data menghasilkan output data yang diproses ke data peristiwa UDM.
mutate {
merge => {
"@output" => "event"
}
}
Kode parser lengkap
Ini adalah contoh kode parser lengkap. Urutan petunjuk tidak mengikuti urutan yang sama dengan bagian sebelumnya dalam dokumen ini, tetapi menghasilkan output yang sama.
filter {
# initialize variables
mutate {
replace => {
"event.idm.read_only_udm.metadata.product_name" => "Webproxy"
"event.idm.read_only_udm.metadata.vendor_name" => "Squid"
"not_valid_log" => "false"
"when" => ""
"srcip" => ""
"action" => ""
"username" => ""
"url" => ""
"tgtip" => ""
"method" => ""
}
}
# Extract fields from the raw log.
grok {
match => {
"message" => [
"%{NUMBER:when}\\s+\\d+\\s%{SYSLOGHOST:srcip} %{WORD:action}\\/%{NUMBER:returnCode} %{NUMBER:size} %{WORD:method} (?P<url>\\S+) (?P<username>.*?) %{WORD}\\/(?P<tgtip>\\S+).*"
]
}
overwrite => ["when","srcip","action","returnCode","size","method","url","username","tgtip"]
on_error => "not_valid_log"
}
# Parse event timestamp
if [when] != "" {
date {
match => [
"when", "UNIX"
]
}
}
# Save the value in "when" to the event timestamp
mutate {
rename => {
"when" => "timestamp"
}
}
# Transform and save username
if [username] not in [ "-" ,"" ] {
mutate {
lowercase => [ "username"]
}
}
mutate {
replace => {
"event.idm.read_only_udm.principal.user.userid" => "%{username}"
}
}
if ([action] == "TCP_DENIED" or [action] == "TCP_MISS" or [action] == "Denied" or [action] == "denied" or [action] == "Dropped") {
mutate {
replace => {
"action" => "BLOCK"
}
}
} else if ([action] == "TCP_TUNNEL" or [action] == "Accessed" or [action] == "Built" or [action] == "Retrieved" or [action] == "Stored") {
mutate {
replace => {
"action" => "ALLOW"
}
}
} else {
mutate {
replace => {
"action" => "UNKNOWN_ACTION" }
}
}
# save transformed value to an intermediary field
mutate {
merge => {
"security_result.action" => "action"
}
}
# save the security_result field
mutate {
merge => {
"event.idm.read_only_udm.security_result" => "security_result"
}
}
# check for presence of target ip. Extract and store target IP address.
if [tgtip] not in [ "","-" ] {
grok {
match => {
"tgtip" => [ "%{IP:tgtip}" ]
}
overwrite => ["tgtip"]
on_error => "not_valid_tgtip"
}
# store target IP address
if ![not_valid_tgtip] {
mutate {
merge => {
"event.idm.read_only_udm.target.ip" => "tgtip"
}
}
}
}
# convert the returnCode and size to integer data type
mutate {
convert => {
"returnCode" => "integer"
"size" => "uinteger"
}
}
# save url, returnCode, and size
mutate {
rename => {
"url" => "event.idm.read_only_udm.target.url"
"returnCode" => "event.idm.read_only_udm.network.http.response_code"
"size" => "event.idm.read_only_udm.network.received_bytes"
}
# set the event type to NETWORK_HTTP
replace => {
"event.idm.read_only_udm.metadata.event_type" => "NETWORK_HTTP"
}
}
# validate and set source IP address
if [srcip] != "" {
mutate {
merge => {
"event.idm.read_only_udm.principal.ip" => "srcip"
}
}
}
# save event to @output
mutate {
merge => {
"@output" => "event"
}
}
} #end of filter