Categories
Berita PDSI

Unsecret Tai Chi Techniques on Apache2 and PHP FPM: UNISA Yogyakarta Style

Mungkin Anda pernah menonton film kungfu dengan jurus Tai Chi, bagaimana seorang pendekar menggunakan kekuatan lawan untuk melakukan serangan balik. Kita bisa menerapkan trik yang sama untuk memperkuat keamanan server berbasis Apache2 dan PHP FPM.

Catatan:

  • Artikel ini dibagi ke dalam dua bagian. Bagian pertama dalam bahasa Inggris dan bagian kedua dalam bahasa Indonesia.
  • Artikel ini berdasarkan pengalaman UNISA Yogyakarta pada server Ubuntu

Daftar Isi

Jurus Tai Chi

Kehampaan adalah awal dari Tai Chi dan sinkronisasi adalah gerakan dasar Tai Chi. Kita akan menggunakan keduanya untuk memperkuat keamanan server berbasis Apache2 dan PHP FPM

— Unsecret Tai Chi Techniques on Apache2 and PHP FPM: UNISA Yogyakarta Style
https://bptsi.unisayogya.ac.id/unsecret-tai-chi-techniques-on-apache2-and-php-fpm-unisa-yogyakarta-style/ 2022-04-18 13:51:53

Jurus Pertama: Kuda-kuda

Tulis kode yang bersih dan aman

Kode yang bersih dapat dibaca, dan disempurnakan oleh pengembang selain penulis aslinya. Memiliki unit dan tes penerimaan. Memiliki nama yang bermakna. Menyediakan satu cara daripada banyak cara untuk melakukan satu hal. Memiliki ketergantungan (dependensi) dan API sekecil-kecilnya yang didefinisikan secara eksplisit. Kode harus dapat dibaca/dipahami dengan bahasa manusia, meskipun tidak semua informasi dapat diungkapkan dengan jelas dalam kode (dapat diberikan komentar).

— “Big” Dave Thomas, penemu OTI, godfather dari Eclipse strategy
dari Clean Code A Handbook of Agile Software Craftsmanship (Robert C. Martin)

Untuk menulis kode yang aman, Anda dapat mengikuti prinsip menulis kode yang dijelaskan dalam Panduan Menulis Kode yang Aman oleh OWASP:

  1. Validasi Input
  2. Pengkodean Output
  3. Manajemen otentikasi dan kata sandi (termasuk penanganan kata kunci yang aman yang diberikan oleh layanan atau kode dari eksternal)
  4. Manajemen sesi
  5. Kontrol akses
  6. Kriptografi
  7. Penanganan dan pencatatan Error
  8. Proteksi data
  9. Keamanan komunikasi
  10. Pengaturan sistem
  11. Keamanan basis data
  12. Manajemen file
  13. Manajemen memory
  14. Praktik umum menulis kode

Jurus Kedua: Menjadi Hampa

Sembunyikan sebanyak-banyaknya seolah-olah hanya dapat melakukan sedikit hal

  1. Buat zonasi untuk area publik dan area privat
    • Buat pengguna dan grup di mana Apache2 tidak termasuk di dalam grup tersebut
    • Berikan izin minimum untuk area pribadi
      Ijin berkas publik: 0644
      Ijin direktori publik: 0711, or 0755 (WordPress membutuhkan 0755)
      Ijin semua berkas konfigurasi/indeks PHP: 0400
      Ijin semua berkas PHP: 0600
      Ijin folder privat: 0711
  2. Buat isolasi direktori
    • Pemilik dari root directory adalah root dengan ijin 0755
    • Pemilik dari web root directory (di bawah root directory) adalah pengguna dan grup di mana Apache2 tidak termasuk di dalam grup tersebut dengan ijin 0711
    • Pindah root directory dari www-data ke direktori baru di bawah direktori bawaan dengan pemiliknya adalah root dan ijinnya adalah 0755
    • Aktifkan penjara
      • Apache2: DocumentRoot
      • PHP: open_basedir
  3. Non aktifkan allow_url_include di php.ini
    allow_url_include = Off
  4. Hilangkan kemampuan untuk melakukan eksekusi di folder temporary, unggah, dan folder rentan lainnya
    • Buat sebuah image untuk temporary PHP
    • Mount temporary folder dari PHP, folder unggah, dan folder rentan lainnya dengan opsi noexec, /etc/fstab
      #mount PHP's temporary image
      /var/imagetmp.img /temporaryphp tmpfs nosuid,nodev,noatime,noexec,mode=1777 0 0
      #mount other folders
      #...
    • Ubah pengaturan folder temporary di php.ini menunjuk ke folder baru
    • Tambahkan hal ini di berkas konfigurasi apache:
      Alias "/var/www/rootdir/webrootdir/uploads" "/temporaryphp"
      #... other risky folders
      <Directory "/temporaryphp">
      Options -ExecCGI
      AddHandler cgi-script .php .pl .py .jsp .asp .htm .html
      </Directory>

Contoh

#Buat pengguna dan grup di mana Apache2 tidak termasuk di dalam grup tersebut
 addgroup newgroup
 adduser --no-create-home --ingroup newgroup newuser
#setelah memasukkan password
usermod -a -G newgroup newuser

#Buat isolasi direktori: Pemilik dari root directory adalah root dengan ijin 0755
mkdir /var/www/rootdir
chown root:root /var/www/rootdir
chmod 0755 /var/www/rootdir

#Buat isolasi direktori: Pemilik dari web root directory (di bawah root directory) adalah pengguna dan grup di mana Apache2 tidak termasuk di dalam grup tersebut dengan ijin 0711
mkdir /var/www/rootdir/webrootdir
chown newgroup:newuser -R /var/www/rootdir/webrootdir
chmod 0711 /var/www/rootdir/webrootdir

#Buat isolasi direktori: Pindah root directory dari www-data ke direktori baru di bawah direktori bawaan dengan pemiliknya adalah root dan ijinnya adalah 0755
mkdir /var/www/000-default
chown root:root /var/www/000-default
chmod 0755 /var/www/000-default
#then you can change /var/www to /var/www/000-default in /etc/apache2/sites-enabled/000-default.conf file configuration

#Ijin berkas publik: 0644
find /var/www/rootdir/webrootdir -type f -exec chmod 0644 {} +

#Ijin folder privat: 0711
find /var/www/rootdir/webrootdir/* -type d -exec chmod 0711 {} +

#Ijin direktori publik: 0711, or 0755 (WordPress membutuhkan 0755)
chmod 0755 /var/www/rootdir/webrootdir/uploads && chmod 0755 /var/www/rootdir/webrootdir/cache
find /var/www/rootdir/webrootdir/uploads -type d -exec chmod 0755 {} + && find /var/www/rootdir/webrootdir/cache -type d -exec chmod 0755 {} +

#Ijin semua berkas konfigurasi/indeks PHP: 0400
chmod 0400 db.php && chmod 0400 config.php && chmod 0400 index.php

#Ijin semua berkas PHP: 0600
find /var/www/rootdir/webrootdir -type f -name ""*.php"" -exec chmod 0600 {} +
#pengaturan website di /etc/php/x.y/fpm/pool.d/example-site.conf
[newsubdomain]
user = newuser
group = newgroup
listen = /run/php/phpx.y-fpm-wp1.sock
listen.owner = newuser
listen.group = www-data
listen.mode = 0660
php_admin_value[open_basedir] = /var/www/rootdir/webrootdir:/temporaryphp

Jurus Ketiga: Sinkronisasi dengan Serangan

Pahami serangan, gunakan usaha (sumber daya) minimal untuk mengalihkan serangan ke ruang hampa

  1. Gunakan pengalaman atau catatan (log) untuk memahami serangan
    • Gunakan RewriteCond %{REQUEST_URI} and RewriteCond %{QUERY_STRING} untuk mengalihkan serangan dan memberi respon secara langsung
    • Pengalihan method yang tidak digunakan ke halaman Forbidden
  2. Jangan menahan serangan, tetapi buang serangan atau alihkan serangan ke sumber daya dummy (void)
    • Matikan PHP pada Apache
      a2dismod phpx.y
    • Kirimkan skrip PHP dengan ekstensi .php yang berada di direktori publik ke soket PHP-FPM yang tidak didengar (unlistened) tanpa waktu tunggu (timeout 1ms)
    • Kirimkan skrip PHP dengan ekstensi .php ke soket PHP-FPM yang didengar (listened)

Contoh

#pengaturan website di /etc/apache2/sites-enabled/example-site.conf
#sebagai contoh: serangan path traversal tercatat di log
<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    ServerAdmin webmaster@localhost
    #Isolasi
    DocumentRoot /var/www/rootdir/webrootdir
    ServerName newsubdomain.example.org
    ErrorLog ${APACHE_LOG_DIR}/newsubdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/newsubdomain_access.log combined
    <Directory "/var/www/rootdir/webrootdir">
      #pengalihan path traversal
      RewriteCond %{REQUEST_URI} (?:%252E%252E%252F) [OR]
      RewriteCond %{QUERY_STRING} (?:%252E%252E%252F) [OR]
      RewriteCond %{REQUEST_URI} (?:\.\./) [OR]
      RewriteCond %{QUERY_STRING} (?:\.\./)
      RewriteRule .* trap.html [L]
      #pengalihan method yang tidak digunakan ke halaman Forbidden
      RewriteCond %{REQUEST_METHOD} ^(PUT|DELETE|PATCH|TRACK|OPTIONS) 
      RewriteRule .* - [F]
      #pengaturan lain
    </Directory>
    #Kirimkan skrip PHP dengan ekstensi .php yang berada di direktori publik ke soket PHP-FPM yang tidak didengar (unlistened) tanpa waktu tunggu (timeout 1ms)
    ProxyPassMatch ^(.*((/temporaryphp)|(uploads/)|(cache/)))(.*\.php(/.*)?)*$ unix:/run/php/phpx.y-fpm-newsubdomain-forbid.sock|fcgi://localhostnewsubdomain_forbid timeout=1ms
    #Kirimkan skrip PHP dengan ekstensi .php ke soket PHP-FPM yang didengar (listened)
    <FilesMatch "\.php$">
        <If "-f %{REQUEST_FILENAME}">
            SetHandler "proxy:unix:/run/php/phpx.y-fpm-newsubdomain.sock|fcgi://localhost/"
        </If>
    </FilesMatch>
    #pengaturan lain
  </VirtualHost>
</IfModule>

Demikian, semoga bermanfaat. [bst]

Sources/Sumber:

By basit

Biro Pengembangan Teknologi Dan Sistem Informasi

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.