# 1-syslogpro: One-Way System Log Protection untuk Melindungi Log Sistem

Saat terjadi serangan siber ke dalam sistem, *Attacker* kemungkinan besar akan menghilangkan tanda atau bukti aktivitas mereka  di berbagai log pada sistem target. *Audit Trail* (log) adalah aset yang harus dilindungi oleh Perusahaan, tanpa log yang dapat diandalkan sumbernya dan dipercaya, proses investigasi dengan menggunakan alat bukti langsung (*direct evidence*) akan sulit untuk dibangun. Selain itu, proses rekonstruksi ulang untuk mengetahui dan menganalisa *Tactics, Techniques, and Procedures* (TTP) dari *Attacker* akan sulit untuk dibentuk, padahal proses tersebut juga termasuk cara untuk mendapatkan *lesson learned* dari suatu insiden agar insiden serupa tidak terjadi lagi dikemudian hari.

Apa yang terjadi apabila suatu serangan siber telah berhasil masuk dan mendapatkan akses root/administrator dari suatu sistem operasi? Bagaimana upaya pencegahan dan deteksi atas aktivitas yang dapat mengurangi atau bahkan menghilangkan integritas dari sistem pencatatan log kita?

Pada sistem operasi Linux, kita dapat memanfaatkan fungsi attribute *file*. Eksplorasi *file attribute* dari sebuah *file* ini dapat digunakan menjadi kunci dalam penyelamatan atau proteksi atas log sistem kita. Memang, sifat *file attribute* ini tidak sepenuhnya memberikan proteksi namun, penggunaan yang tepat dapat memberikan visibilitas atas perubahan major yang terjadi atas log sistem, dengan menggunakan kontrol deteksi dan pencegahan. Sistem operasi Linux memiliki kemampuan untuk mengatur atribut yang menempel pada suatu *file* dan/atau *folder*. Pada Linux anda dapat mengatur atribut yang menempel dengan menggunakan perintah `chattr`.

Perintah `chattr` di linux digunakan untuk mengubah *attribute* pada *file* di Linux untuk menghindari insiden salah *delete*, ataupun mencegah agar file maupun direktori penting di sistem tidak diubah. `chattr` sendiri juga berlaku untuk semua *user* termasuk *user* dengan hak akses root sekalipun. Pada tulisan ini, kami menggunakan perintah `chattr +a`, perintah ini digunakan untuk membuat attribute pada *file* agar bisa ditambah data baru, namun tidak bisa mengubah ataupun menghapus data lama atau lebih sering kita dengar dengan istilah *append*. Sistem ini memastikan bahwa semua operasi yang masuk dan diijinkan oleh *system administrator* adalah hanya satu operasi yaitu *append*, maka dari itu kita menamai teknik tersebut *One-Way System Log Protection* atau kita sebut *1-syslogpro.*

<figure><img src="https://2269273115-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqORrtdTgv9LCMJlHlnb%2Fuploads%2FutVKZ9V5WROWDfi3JEAz%2Fimage.png?alt=media&#x26;token=e90c54fb-4c3f-4623-a460-f099b3cc80e2" alt=""><figcaption><p>Gambar 1 - Contoh implementasi sederhana append atribut pada file di Linux.</p></figcaption></figure>

Kami akan berbagi bagaimana salah satu pemanfaatan command `` `lsattr` `` dan `` `chattr ` `` dapat membantu dalam pencegahan dan deteksi terhadap adanya perubahan pada log sistem Anda.

1. Untuk Menjalankan *Log Protection*, ada beberapa *software* yang harus di-*install* agar *software log protection* ini berjalan dengan lancar. Berikut adalah beberapa *software* yang perlu di-*install*:

{% code overflow="wrap" %}

```
yum install audit inotify-tools supervisor curl perl nano
```

{% endcode %}

2. Setelah *software* ter-*install*, *update* konfigurasi dari `auditd`. Edit beberapa konfigurasi berikut:

```apacheconf
"num_logs = 5" menjadi "num_logs = 2"
"max_log_file = 8" menjadi "max_log_file = 0"
"max_log_file_action = ROTATE" menjadi "max_log_file_action = IGNORE"
```

3. Lalu buat folder untuk meletakkan *source code log protection.*

```sh
mkdir -p /var/log-protect/db
```

4. Buat file konfigurasi untuk *log protection*, *file* ini digunakan untuk mengatur log yang akan diproteksi.

```sh
nano /var/log-protect/log-protect-custom.conf
```

Edit dan masukkan variabel yang dibutuhkan untuk proses *alerting*, serta log-log yang akan diproteksi didalam sistem.

```apacheconf
BOT_TOKEN=<insert your bot token telegram here>
CHAT_ID=-<insert your chat ID telegram here>
TOPIC_ID=<insert your ID Topic Telegram here>
INET_IFACE=<insert your interface VM that used>
FILE_LOG= <insert the locations of your logs that must be protected>
  - /var/log/<service name>
  - /opt/log/<service name>
```

5. Lalu, buat satu *script* untuk memastikan bahwa *rules* dari `auditd` dan fungsi dari *log rotate* berjalan untuk log-log yang dilindungi.&#x20;

```sh
nano /var/log-protect/log-generation.sh
```

Lalu, buat *script* seperti dibawah ini, *script* di bawah berfungsi untuk memastikan log akan di *rotate* sesuai dengan jadwal yang telah diset, serta untuk memastikan *rules* dari `auditd` telah diaktifkan. Untuk referensi *rules* dari `auditd`, dapat menggunakan standar *baseline* dari CIS Benchmark Server.

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```bash
#!/bin/sh
file_log=`cat /var/log-protect/log-protect-custom.conf | grep -v "#" | grep -A1000 "FILE_LOG" | grep -v "FILE_LOG" | grep "-" | sed 's/  - //g' | tr '\n' ' '`
valid_file_log=""
############### Check file log is valid ###############
for file in ${file_log}; do
  if [[ ${file} != *".gz" ]] && [[ "${file##*.}" != +([0-9]) ]] && [ -f "$file" ]; then
    valid_file_log+=" "$file
  fi
done

############### Generate Audit Rules ###############
echo "" > /var/log-protect/db/list-attr-file

for file in ${valid_file_log}; do
  keywords="protect-"`echo $file | sed 's/\// /g' | awk 'END {print $(NF-1), $NF}'`
  keyword=`echo $keywords | sed -e 's/\s//g' | tr -d '*' | tr -d '.'`
  check_string=$(grep -c $keyword /etc/audit/audit.rules)
  if [ $check_string -eq 0 ]; then
    echo "-w "$file" -p rwa -k "$keyword >> /etc/audit/rules.d/log-protect.rules

    ############### add rule in auditd ###############
    auditctl -w $file -p rwa -k $keyword

    ############### change attribute of file ###############
    # if [[ $file != *"audit.log"* ]]; then
    chattr +a $file >> /var/log-protect/list-attr-file
    # fi

    ############### generate database list attribute file ###############
    attrfile=`lsattr -d $(readlink -f $file)`
    attrfile_name=`echo $attrfile | awk '{print $2}' | sed 's/\//-/g' | cut -c2-`
    echo $attrfile > /var/log-protect/db/`echo $attrfile_name`
  fi
done
echo "Successfully generated audit rules dan change attribute file"

############### Generate cron job file bash ###############
echo -e "#!/bin/sh\n" > /var/log-protect/cron.sh

for file in ${valid_file_log}; do
  # if [[ $file != *"audit.log"* ]]; then
  echo "chattr -a "$file >> /var/log-protect/cron.sh
  # fi
done

cat << EOF >> /var/log-protect/cron.sh

/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=\$?
if [ \$EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [\$EXITVALUE]"
fi

echo -e "Cron Successfully run at \`date\`\n"

EOF

for file in ${valid_file_log}; do
  # if [[ $file != *"audit.log"* ]]; then
  echo "chattr +a "$file >> /var/log-protect/cron.sh
  # fi
done
echo "Successfully generated cron file"

############### Add cronjob daily ###############
cron_count=`crontab -l | grep log-protect | wc -l`
if [ $cron_count -eq 0 ];then
  crontab -l | { cat; echo "0 0 * * * bash /var/log-protect/cron.sh > /var/log/cron-log-protection.log"; } | crontab -
  echo "Successfully generated cron job"
else
  echo "Cronjob for Log Protection already exist"
fi

############### Generate logrotate file ###############
echo "" > /var/logrotate.d/log-protect
for file in ${valid_file_log}; do
  # if [[ $file != *"audit.log"* ]]; then
  echo $file >> /etc/logrotate.d/log-protect
  # fi
done

if [[ $valid_file_log == *"nginx"* ]]; then
  cat << EOF >> /etc/logrotate.d/log-protect
{
    missingok
    compress
    dateext
    dateformat -%Y%m%d
    notifempty
    rotate 365
    sharedscripts
    postrotate
        /bin/kill -USR1 \`cat /run/nginx.pid 2>/dev/null\` 2>/dev/null || true
        /usr/bin/systemctl kill -s USR1 auditd.service >/dev/null 2>&1 || true
        /bin/kill -HUP \`cat /var/run/syslogd.pid 2> /dev/null\` 2> /dev/null || true
    endscript
}
EOF
else
 cat << EOF >> /etc/logrotate.d/log-protect
{
    missingok
    compress
    dateext
    dateformat -%Y%m%d
    notifempty
    rotate 365
    sharedscripts
    postrotate
        /usr/bin/systemctl kill -s USR1 auditd.service >/dev/null 2>&1 || true
        /bin/kill -HUP \`cat /var/run/syslogd.pid 2> /dev/null\` 2> /dev/null || true
    endscript
}
EOF
fi

echo "Successfully generated logrotate file"
```

{% endcode %}

Pada *script* di atas, terdapat perintah `chattr +a $file`. Perintah tersebutlah yang digunakan untuk memproteksi *file* agar tidak dapat diubah. Setelah itu jalankan *script* diatas, dengan baris perintah berikut

```sh
bash /var/log-protect/log-generation.sh
```

6. Selanjutnya buat *file* `check-input-out.sh`, *script* ini digunakan untuk memonitor aktivitas *create* *and delete file*/log dan sekaligus akan mengirimkan notifikasi telegram ke pemilik sistem.

```sh
nano /var/log-protect/check-input-out.sh
```

Edit *file* tersebut, sesuai dengan *script* dibawah ini:

{% code overflow="wrap" lineNumbers="true" %}

```bash
#!/bin/sh
folder_log=`cat /var/log-protect/log-protect-custom.conf | grep -v "#" | grep -A1000 "FILE_LOG" | grep -v "FILE_LOG" | sed 's/  - //g' | sed 's/\// /g' | sed 's/\(.*\)\./\1/' | tr -d '*' | sed 's/-//3' | sed 's/\w*$//' | sed 's/ /\//g' | xargs -n1 | sort -u | xargs`
file_log=`cat /var/log-protect/log-protect-custom.conf | grep -v "#" | grep -A1000 "FILE_LOG" | grep -v "FILE_LOG" | grep "-" | sed 's/  - //g' | tr '\n' ' '`
ip=`ifconfig $(grep INET_IFACE /var/log-protect/log-protect-custom.conf | sed 's/INET_IFACE=//' | grep -v '#') | grep -v inet6 | grep inet | awk '{print $2}'`
chat_id=`grep CHAT_ID /var/log-protect/log-protect-custom.conf | sed 's/CHAT_ID=//' | grep -v "#"`
topic_id=`grep TOPIC_ID /var/log-protect/log-protect-custom.conf | sed 's/TOPIC_ID=//' | grep -v "#"`
bot_token=`grep BOT_TOKEN /var/log-protect/log-protect-custom.conf | sed 's/BOT_TOKEN=//' | grep -v "#"`

valid_folder_log=""
valid_file_log=""
message=""

for folder in ${folder_log}; do
  if [ -d "$folder" ]; then
    valid_folder_log+=" "$folder
  fi
done

for file in ${file_log}; do
  if [ -f "$file" ]; then
    valid_file=`echo $file | sed 's/\// /g' | awk 'NF>1{print $NF}'`
    valid_file_log+=" "$valid_file
  fi
done

echo -e "\n\n\nFolder in monitoring    : "$valid_folder_log
echo -e "Filter for notification : "$valid_file_log"\n\n\n"

filter=`echo $valid_file_log | sed 's/ /\\\|/g'`

while read -r line
do
  if echo $line | grep "$filter";then
    message='<b>'`hostname`' - '$ip$'</b>'$'\n\n'$line
    if echo $line | grep "audit.log" | grep "CREATE" > /dev/null 2>&1; then
      echo -e "\nRestart audit"
      supervisorctl restart audit
    fi
    echo -n -e "\n`date` -- "
    curl -s --data "text=$message" --data "chat_id=$chat_id" --data "parse_mode=html" --data "message_thread_id=$topic_id" https://api.telegram.org/bot$bot_token/sendMessage
    echo -e "\n"
  fi
done < <(inotifywait -m -e create -e delete --timefmt '%a %b %d %T %Y %Z' --format '%T - %e %w%f' $valid_folder_log)
```

{% endcode %}

<figure><img src="https://2269273115-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqORrtdTgv9LCMJlHlnb%2Fuploads%2F66wTW0NTyHyOELcZlo3O%2Fimage.png?alt=media&#x26;token=390f0f88-fcfb-4a46-9c68-90078c6a73c2" alt=""><figcaption><p>Gambar 2 - Notifikasi Telegram untuk aktivitas CREATION and DELETION dalam folder atau file yang dimonitoring</p></figcaption></figure>

7. Selanjutnya buat *file* `check-audit.sh`, untuk memonitor log `auditd`, jika terdapat perubahan pada atribut *file* maka otomatis akan mengirimkan notifikasi ke telegram. *By default* sebelum *script* ini dijalankan semua *attribute* dalam *file* log yang kita lindungi hanya menjalankan fungsi *appends*

```sh
nano /var/code-script/log-protect/check-audit.sh
```

*Edit* file tersebut, sesuai *script* dibawah ini:

{% code overflow="wrap" lineNumbers="true" %}

```bash
#!/bin/sh
ip=`ifconfig $(grep INET_IFACE /var/log-protect/log-protect-custom.conf | sed 's/INET_IFACE=//' | grep -v '#') | grep -v inet6 | grep inet | awk '{print $2}'`
chat_id=`grep CHAT_ID /var/log-protect/log-protect-custom.conf | sed 's/CHAT_ID=//' | grep -v "#"`
topic_id=`grep TOPIC_ID /var/log-protect/log-protect-custom.conf | sed 's/TOPIC_ID=//' | grep -v "#"`
bot_token=`grep BOT_TOKEN /var/log-protect/log-protect-custom.conf | sed 's/BOT_TOKEN=//' | grep -v "#"`
id_audit=""

echo -e "\n\n\n`date` -- Starting Audit Log Protection\n\n"

while read -r line
do
  if echo $line | grep "chattr"; then
    # echo "id_audit before : "$id_audit
    id_audit_new=`echo "$line" | awk '{print $2}' | sed 's/msg=audit(//' | cut -f1 -d ":"`
    # echo "id_audit new : "$id_audit_new
    if [ "$id_audit" = "$id_audit_new" ]; then
      id_audit=`echo "$line" | awk '{print $2}' | sed 's/msg=audit(//' | cut -f1 -d ":"`
      # echo "id_audit after : "$id_audit
      id=`echo "$line" | awk '{print $2}'`
      datetime=`echo "$id" | sed 's/msg=audit(//' | cut -f1 -d "." | perl -pe 's/(\d+)/localtime/e'`
      file=`cat /var/log/audit/audit.log | grep $id | grep PATH | awk '{print $4}' | sed 's/name=//' | sed 's/"//g'`
      cwd=`cat /var/log/audit/audit.log | grep $id | grep CWD | awk '{print $3}' | sed 's/cwd=//' | sed 's/"//g'`

      cd $cwd

      attrfile=`lsattr -d $(readlink -f $file)`
      attrfile_name=`echo $attrfile | awk '{print $2}' | sed 's/\//-/g' | cut -c2-`
      message='<b>'`hostname`' - '$ip$'</b> -- '`echo -n $datetime" " && date +%Z`$'\n\nAda perubahan atrribute pada <b>'$file$'</b>\n\n'$attrfile
      if [ -f /opt/log-protect/db/`echo $attrfile_name` ];then
        message='<b>'`hostname`' - '$ip$'</b> -- '`echo -n $datetime" " && date +%Z`$'\n\nAda perubahan atrribute pada <b>'$file$'</b>\n\nBefore : '$(cat /opt/log-protect/db/`echo $attrfile_name`)$'\nAfter    : '$attrfile
      fi
      echo $attrfile > /opt/log-protect/db/`echo $attrfile_name`

      echo -n $'\n'`date` && echo -n " -- $attrfile_name -- "
      curl -s --data "text=$message" --data "chat_id=$chat_id" --data "parse_mode=html" --data "message_thread_id=$topic_id" https://api.telegram.org/bot$bot_token/sendMessage
      echo -e "\n"
    else
      id_audit=`echo "$line" | awk '{print $2}' | sed 's/msg=audit(//' | cut -f1 -d ":"`
    fi
  fi
done < <(tail -f /var/log/audit/audit.log)
```

{% endcode %}

<figure><img src="https://2269273115-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqORrtdTgv9LCMJlHlnb%2Fuploads%2FzY2IJwst2yMU8oL5YUWU%2Fimage.png?alt=media&#x26;token=3f5d840a-7f97-4442-bddf-6d698c197f02" alt=""><figcaption><p>Gambar 3 - Notifikasi Telegram untuk Perubahan Atribut yang terjadi pada file atau folder yang dimonitor.</p></figcaption></figure>

8. Selanjutnya adalah membuat konfigurasi untuk `supervisor`:

```bash
nano /etc/supervisord.d/log-protect.ini

[program:ino]
command=bash /opt/log-protect/check-input-out.sh
stderr_logfile = /var/log/supervisor/ino.log
stdout_logfile = /var/log/supervisor/ino.log

[program:audit]
command=bash /opt/log-protect/check-audit.sh
stderr_logfile = /var/log/supervisor/audit.log
stdout_logfile = /var/log/supervisor/audit.log
```

9. Lalu jalankan fungsi untuk *update service* yang ada didalam `supervisor`

{% code overflow="wrap" %}

```sh
supervisorctl reread && supervisorctl update && supervisorctl restart all
```

{% endcode %}

10. *Testing log protection* dengan perintah berikut, apabila notifikasi terkirim ke telegram maka secara otomatis *log protection* sudah aktif.

{% code overflow="wrap" %}

```sh
chattr -a /var/log/maillog && sleep 5 && chattr +a /var/log/maillog && touch /var/log/audit.log && sleep 5 && rm -rf /var/log/audit.log
```

{% endcode %}

Tantangan yang dihadapi dalam pembuatan *log protection* ini adalah:

1. Tidak seragamnya syarat *rotation* untuk masing-masing log, ada yang dirotasi atas ukuran *file*, ada yang dirotasi atas waktu.
2. Tidak seragamnya jadwal rotasi dari beberapa *file*.
3. Penyesuaian *naming format* dari log yang dirotasi oleh *hardening log protection*.
4. Penyesuaian lagi untuk konfigurasi di SIEM agar dapat mengambil log yang memang telah mendapatkan proteksi.
5. Penyesuaian lokasi dari log, agar seragam dalam implementasi *attribute*.

Pengembangan kedepan untuk fitur ini adalah:

1. Implementasi *secure log rotation*, dengan cara melakukan enkripsi atas log-log yang sudah dirotasi. Hal ini juga memastikan keamanan atas log-log yang telah dirotasi agar tidak ada modifikasi pada log-log yang sudah lampau.
2. Implementasi otomatisasi *backup* dan arsip, momentum ketika rotasi dapat juga disamakan dengan waktu ketika *backup* dan arsip dari log sistem terkait.
3. Implementasi *hashcheck* atau *digital signature* untuk memastikan *integritas* dari log sistem yang sudah dirotasi atau terarsip.

## Tentang Penulis

<div align="left"><figure><img src="https://2269273115-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqORrtdTgv9LCMJlHlnb%2Fuploads%2F9KztLssZkKwePBbtgQcw%2Fimage.png?alt=media&#x26;token=788bc5ad-e826-4466-9eab-0bea586c966c" alt="" width="276"><figcaption></figcaption></figure></div>

#### Rheno Sulistyo

Praktisi DevSecOps | Tertarik pada bidang *system administration* terutama Linux dan Devops

![](https://2269273115-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqORrtdTgv9LCMJlHlnb%2Fuploads%2FeWo0VwnYsDsJ1sr9QLi1%2Fimage.png?alt=media\&token=0b80cfd9-8dc4-4172-a74a-211ff6464fda)

#### Muhammad Fajar Masputra

Praktisi Keamanan Informasi | Tertarik pada bidang Cyber Security Operation, IT Audit, IT Governance dan Cloud Security


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cdef.gitbook.io/2023-2nd-cdef-bulletin/cyber-horizon/1-syslogpro-one-way-system-log-protection-untuk-melindungi-log-sistem.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
