ProHoster > blog > administrasi > Pengantar Kebijakan Jaringan Kubernetes untuk Profesional Keamanan
Pengantar Kebijakan Jaringan Kubernetes untuk Profesional Keamanan
Catatan. terjemahan: Penulis artikel, Reuven Harrison, memiliki pengalaman lebih dari 20 tahun dalam pengembangan perangkat lunak, dan saat ini menjabat sebagai CTO dan salah satu pendiri Tufin, sebuah perusahaan yang menciptakan solusi manajemen kebijakan keamanan. Meskipun ia memandang kebijakan jaringan Kubernetes sebagai alat yang cukup ampuh untuk mensegmentasi jaringan dalam sebuah cluster, ia juga yakin bahwa kebijakan tersebut tidak mudah diterapkan dalam praktiknya. Materi ini (cukup banyak) dimaksudkan untuk meningkatkan kesadaran para spesialis mengenai masalah ini dan membantu mereka membuat konfigurasi yang diperlukan.
Saat ini, semakin banyak perusahaan yang memilih Kubernetes untuk menjalankan aplikasi mereka. Minat terhadap perangkat lunak ini begitu tinggi sehingga beberapa orang menyebut Kubernetes sebagai βsistem operasi baru untuk pusat data.β Secara bertahap, Kubernetes (atau k8s) mulai dianggap sebagai bagian penting dari bisnis, yang memerlukan pengorganisasian proses bisnis yang matang, termasuk keamanan jaringan.
Bagi para profesional keamanan yang bingung bekerja dengan Kubernetes, hal yang mungkin terjadi adalah kebijakan default platform ini: izinkan semuanya.
Panduan ini akan membantu Anda memahami struktur internal kebijakan jaringan; memahami perbedaannya dengan aturan firewall biasa. Panduan ini juga akan membahas beberapa kendala dan memberikan rekomendasi untuk membantu mengamankan aplikasi di Kubernetes.
Kebijakan jaringan Kubernetes
Mekanisme kebijakan jaringan Kubernetes memungkinkan Anda untuk mengelola interaksi aplikasi yang diterapkan pada platform di lapisan jaringan (lapisan ketiga dalam model OSI). Kebijakan jaringan tidak memiliki beberapa fitur lanjutan dari firewall modern, seperti penegakan OSI Layer 7 dan deteksi ancaman, namun kebijakan tersebut memberikan tingkat keamanan jaringan dasar yang merupakan titik awal yang baik.
Kebijakan jaringan mengontrol komunikasi antar pod
Beban kerja di Kubernetes didistribusikan ke seluruh pod, yang terdiri dari satu atau lebih container yang di-deploy secara bersamaan. Kubernetes memberikan setiap pod alamat IP yang dapat diakses dari pod lain. Kebijakan jaringan Kubernetes menetapkan hak akses untuk grup pod dengan cara yang sama seperti grup keamanan di cloud digunakan untuk mengontrol akses ke instance mesin virtual.
Mendefinisikan Kebijakan Jaringan
Seperti sumber daya Kubernetes lainnya, kebijakan jaringan ditentukan di YAML. Pada contoh di bawah ini, aplikasi balance akses ke postgres:
(Catatan. terjemahan: tangkapan layar ini, seperti semua tangkapan layar serupa berikutnya, dibuat bukan menggunakan alat Kubernetes asli, tetapi menggunakan alat Tufin Orca, yang dikembangkan oleh perusahaan penulis artikel asli dan disebutkan di akhir materi.)
Untuk menentukan kebijakan jaringan Anda sendiri, Anda memerlukan pengetahuan dasar tentang YAML. Bahasa ini didasarkan pada indentasi (ditentukan dengan spasi, bukan tab). Elemen berindentasi adalah milik elemen berindentasi terdekat di atasnya. Elemen daftar baru dimulai dengan tanda hubung, semua elemen lainnya memiliki bentuk nilai kunci.
Setelah menjelaskan kebijakan di YAML, gunakan kubectluntuk membuatnya di cluster:
kubectl create -f policy.yaml
Spesifikasi Kebijakan Jaringan
Spesifikasi kebijakan jaringan Kubernetes mencakup empat elemen:
podSelector: mendefinisikan pod yang terpengaruh oleh kebijakan ini (target) - wajib diisi;
policyTypes: menunjukkan jenis kebijakan apa saja yang termasuk di dalamnya: ingress dan/atau egress - opsional, namun saya sarankan untuk menentukannya secara eksplisit di semua kasus;
ingress: mendefinisikan diperbolehkan masuk lalu lintas ke pod target - opsional;
egress: mendefinisikan diperbolehkan keluar lalu lintas dari pod target bersifat opsional.
Contoh diambil dari website Kubernetes (saya ganti role pada app), menunjukkan bagaimana keempat elemen digunakan:
Harap dicatat bahwa keempat elemen tidak harus disertakan. Itu hanya wajib podSelector, parameter lain dapat digunakan sesuai keinginan.
Jika Anda menghilangkan policyTypes, kebijakan tersebut akan diartikan sebagai berikut:
Secara default, diasumsikan bahwa ini mendefinisikan sisi masuknya. Jika kebijakan tidak secara eksplisit menyatakan hal ini, sistem akan berasumsi bahwa semua lalu lintas dilarang.
Perilaku pada sisi jalan keluar akan ditentukan oleh ada tidaknya parameter jalan keluar yang bersangkutan.
Untuk menghindari kesalahan saya sarankan selalu membuatnya eksplisit policyTypes.
Menurut logika di atas, jika parameternya ingress dan / atau egress dihilangkan, kebijakan akan menolak semua lalu lintas (lihat "Peraturan Pengupasan" di bawah).
Kebijakan default adalah Izinkan
Jika tidak ada kebijakan yang ditentukan, Kubernetes mengizinkan semua lalu lintas secara default. Semua pod dapat dengan bebas bertukar informasi satu sama lain. Hal ini mungkin tampak berlawanan dengan intuisi dari sudut pandang keamanan, namun perlu diingat bahwa Kubernetes pada awalnya dirancang oleh pengembang untuk memungkinkan interoperabilitas aplikasi. Kebijakan jaringan ditambahkan kemudian.
Ruang nama
Namespace adalah mekanisme kolaborasi Kubernetes. Mereka dirancang untuk mengisolasi lingkungan logis satu sama lain, sementara komunikasi antar ruang diperbolehkan secara default.
Seperti kebanyakan komponen Kubernetes, kebijakan jaringan berada dalam namespace tertentu. Di blok metadata Anda dapat menentukan di ruang mana kebijakan tersebut berada:
Jika namespace tidak ditentukan secara eksplisit dalam metadata, sistem akan menggunakan namespace yang ditentukan dalam kubectl (secara default namespace=default):
kubectl apply -n my-namespace -f namespace.yaml
Saya merekomendasikan tentukan namespace secara eksplisit, kecuali Anda membuat kebijakan yang menargetkan beberapa namespace sekaligus.
Primer elemen podSelector dalam kebijakan tersebut akan memilih pod dari namespace tempat kebijakan tersebut berada (akses ke pod dari namespace lain ditolak).
Demikian pula dengan podSelectors di blok masuk dan keluar hanya dapat memilih pod dari namespacenya sendiri, kecuali tentu saja Anda menggabungkannya namespaceSelector (ini akan dibahas di bagian βFilter berdasarkan namespace dan podβ).
Aturan Penamaan Kebijakan
Nama kebijakan bersifat unik dalam namespace yang sama. Tidak boleh ada dua kebijakan dengan nama yang sama di ruang yang sama, namun bisa ada kebijakan dengan nama yang sama di ruang berbeda. Hal ini berguna ketika Anda ingin menerapkan kembali kebijakan yang sama di beberapa ruang.
Saya terutama menyukai salah satu metode penamaan. Ini terdiri dari menggabungkan nama namespace dengan pod target. Misalnya:
Anda dapat melampirkan label khusus ke objek Kubernetes, seperti pod dan namespace. Label (label - tag) setara dengan tag di cloud. Kebijakan jaringan Kubernetes menggunakan label untuk memilih polongyang mereka terapkan:
podSelector:
matchLabels:
role: db
β¦ atau ruang namayang mereka terapkan. Contoh ini memilih semua pod di namespace dengan label yang sesuai:
Satu peringatan: saat menggunakan namespaceSelectorpastikan namespace yang Anda pilih berisi label yang benar. Sadarilah bahwa namespace bawaan seperti default ΠΈ kube-system, secara default tidak mengandung label.
Anda dapat menambahkan label ke spasi seperti ini:
kubectl label namespace default namespace=default
Pada saat yang sama, namespace di bagian tersebut metadata harus mengacu pada nama ruang sebenarnya, bukan label:
Kebijakan firewall terdiri dari aturan dengan sumber dan tujuan. Kebijakan jaringan Kubernetes ditentukan untuk suatu target - sekumpulan pod yang menerapkannya - dan kemudian menetapkan aturan untuk lalu lintas masuk dan/atau keluar. Dalam contoh kita, target kebijakannya adalah semua pod di namespace default dengan label dengan kunci app dan artinya db:
Ayat ingress dalam kebijakan ini, membuka lalu lintas masuk ke pod target. Dengan kata lain, ingress adalah sumber dan target adalah tujuan yang sesuai. Demikian pula jalan keluar adalah tujuan dan target adalah sumbernya.
Ini setara dengan dua aturan firewall: Ingress β Target; Sasaran β Jalan Keluar.
Jalan keluar dan DNS (penting!)
Dengan membatasi lalu lintas keluar, berikan perhatian khusus pada DNS - Kubernetes menggunakan layanan ini untuk memetakan layanan ke alamat IP. Misalnya, kebijakan berikut tidak akan berfungsi karena Anda belum mengizinkan aplikasi tersebut balance akses DNS:
Elemen terakhir to kosong, dan oleh karena itu ia memilih secara tidak langsung semua pod di semua namespace, mengizinkan balance mengirim kueri DNS ke layanan Kubernetes yang sesuai (biasanya berjalan di luar angkasa kube-system).
Pendekatan ini berhasil, bagaimanapun caranya terlalu permisif dan tidak aman, karena memungkinkan kueri DNS diarahkan ke luar cluster.
Anda dapat memperbaikinya dalam tiga langkah berturut-turut.
1. Izinkan permintaan DNS saja dalam cluster dengan menambahkan namespaceSelector:
2. Izinkan kueri DNS hanya dalam namespace kube-system.
Untuk melakukan ini, Anda perlu menambahkan label ke namespace kube-system: kubectl label namespace kube-system namespace=kube-system - dan menuliskannya dalam kebijakan menggunakan namespaceSelector:
3. Orang paranoid dapat melangkah lebih jauh dan membatasi permintaan DNS ke layanan DNS tertentu kube-system. Bagian βFilter berdasarkan namespace DAN podβ akan memberi tahu Anda cara mencapainya.
Pilihan lainnya adalah menyelesaikan DNS di tingkat namespace. Dalam hal ini, tidak perlu dibuka untuk setiap layanan:
Kosong podSelector memilih semua pod di namespace.
Pertandingan pertama dan urutan aturan
Dalam firewall konvensional, tindakan (Izinkan atau Tolak) pada sebuah paket ditentukan oleh aturan pertama yang dipenuhinya. Di Kubernetes, urutan kebijakan tidak menjadi masalah.
Secara default, ketika tidak ada kebijakan yang ditetapkan, komunikasi antar pod diperbolehkan dan mereka dapat dengan bebas bertukar informasi. Setelah Anda mulai merumuskan kebijakan, setiap pod yang terpengaruh oleh setidaknya salah satu dari kebijakan tersebut akan diisolasi sesuai dengan disjungsi (logis OR) dari semua kebijakan yang memilihnya. Pod yang tidak terpengaruh oleh kebijakan apa pun tetap terbuka.
Anda dapat mengubah perilaku ini menggunakan aturan pengupasan.
Aturan pengupasan (βTolakβ)
Kebijakan firewall biasanya menolak lalu lintas apa pun yang tidak diizinkan secara eksplisit.
Tidak ada tindakan penolakan di Kubernetes, namun efek serupa dapat dicapai dengan kebijakan reguler (permisif) dengan memilih grup pod sumber yang kosong (ingress):
Harap dicatat itu kebijakan tambahan apa pun yang mengizinkan lalu lintas ke pod di namespace akan diutamakan daripada aturan ini (mirip dengan menambahkan aturan izinkan sebelum aturan penolakan dalam konfigurasi firewall).
Izinkan semuanya (Apa pun-apa pun-izinkan)
Untuk membuat kebijakan Izinkan Semua, Anda perlu melengkapi kebijakan Tolak di atas dengan elemen kosong ingress:
Ini memungkinkan akses dari semua pod di semua namespace (dan semua IP) ke pod mana pun di namespace default. Perilaku ini diaktifkan secara default, sehingga biasanya tidak perlu didefinisikan lebih lanjut. Namun, terkadang Anda mungkin perlu menonaktifkan sementara beberapa izin tertentu untuk mendiagnosis masalah.
Aturannya dapat dipersempit untuk mengizinkan akses saja satu set pod tertentu (app:balance) di ruang nama default:
2. Di dalam bagian kebijakan ingress dapat memiliki banyak elemen from (dikombinasikan dengan logika OR). Demikian pula bagian egress mungkin mencakup banyak elemen to (juga digabungkan dengan disjungsi):
3. Kebijakan yang berbeda juga digabungkan dengan logika OR
Namun saat menggabungkannya, ada satu batasannya ditunjukkanChris Cooney: Kubernetes hanya dapat menggabungkan kebijakan dengan kebijakan yang berbeda policyTypes (Ingress ΠΈΠ»ΠΈ Egress). Kebijakan yang mendefinisikan ingress (atau egress) akan saling menimpa.
Hubungan antar namespace
Secara default, berbagi informasi antar namespace diperbolehkan. Hal ini dapat diubah dengan menggunakan kebijakan penolakan yang akan membatasi lalu lintas keluar dan/atau masuk ke dalam namespace (lihat "Aturan Pengupasan" di atas).
Setelah Anda memblokir akses ke namespace (lihat "Aturan Pengupasan" di atas), Anda dapat membuat pengecualian terhadap kebijakan penolakan dengan mengizinkan koneksi dari namespace tertentu menggunakan namespaceSelector:
Hasilnya, semua pod di namespace default akan memiliki akses ke pod postgres di ruang nama database. Namun bagaimana jika Anda ingin membuka aksesnya postgres hanya pod tertentu di namespace default?
Filter berdasarkan namespace dan pod
Kubernetes versi 1.11 dan lebih tinggi memungkinkan Anda menggabungkan operator namespaceSelector ΠΈ podSelector menggunakan logika AND, tampilannya seperti ini:
Mengapa ini diartikan sebagai AND dan bukan OR yang biasa?
Harap dicatat bahwa podSelector tidak dimulai dengan tanda hubung. Di YAML, ini artinya podSelector dan berdiri di depannya namespaceSelector merujuk ke elemen daftar yang sama. Oleh karena itu, mereka digabungkan dengan logika AND.
Menambahkan tanda hubung sebelumnya podSelector akan mengakibatkan munculnya elemen daftar baru, yang akan digabungkan dengan elemen sebelumnya namespaceSelector menggunakan logika OR.
Untuk memilih pod dengan label tertentu di semua namespace, masukkan kosong namespaceSelector:
Aturan untuk firewall dengan banyak objek (host, jaringan, grup) digabungkan menggunakan logika OR. Aturan berikut akan berfungsi jika sumber paket cocok Host_1 OR Host_2:
Sebaliknya, di Kubernetes berbagai label masuk podSelector ΠΈΠ»ΠΈ namespaceSelector digabungkan dengan logika AND. Misalnya, aturan berikut akan memilih pod yang memiliki kedua label, role=db Π version=v2:
podSelector:
matchLabels:
role: db
version: v2
Logika yang sama berlaku untuk semua jenis operator: penyeleksi target kebijakan, penyeleksi pod, dan penyeleksi namespace.
Subnet dan alamat IP (IPBlocks)
Firewall menggunakan VLAN, alamat IP, dan subnet untuk mensegmentasi jaringan.
Di Kubernetes, alamat IP ditetapkan ke pod secara otomatis dan dapat sering berubah, sehingga label digunakan untuk memilih pod dan namespace dalam kebijakan jaringan.
Subnet (ipBlocks) digunakan saat mengelola koneksi eksternal (Utara-Selatan) masuk (ingress) atau keluar (egress). Misalnya, kebijakan ini terbuka untuk semua pod dari namespace default akses ke layanan DNS Google:
Pemilih pod kosong dalam contoh ini berarti βpilih semua pod di namespace.β
Kebijakan ini hanya mengizinkan akses ke 8.8.8.8; akses ke IP lain dilarang. Jadi, intinya, Anda telah memblokir akses ke layanan DNS internal Kubernetes. Jika Anda masih ingin membukanya, tunjukkan secara eksplisit.
Biasanya ipBlocks ΠΈ podSelectors bersifat eksklusif satu sama lain, karena alamat IP internal pod tidak digunakan ipBlocks. Dengan menunjukkan pod IP internal, Anda sebenarnya akan mengizinkan koneksi ke/dari pod dengan alamat ini. Dalam praktiknya, Anda tidak akan mengetahui alamat IP mana yang akan digunakan, itulah sebabnya alamat IP tersebut tidak boleh digunakan untuk memilih pod.
Sebagai contoh tandingan, kebijakan berikut mencakup semua IP dan oleh karena itu mengizinkan akses ke semua pod lainnya:
Biasanya pod mendengarkan satu port. Ini berarti Anda tidak bisa menentukan nomor port dalam kebijakan dan membiarkan semuanya sebagai default. Namun, disarankan untuk membuat kebijakan seketat mungkin, sehingga dalam beberapa kasus Anda masih dapat menentukan port:
Perhatikan bahwa pemilih ports berlaku untuk semua elemen di blok to ΠΈΠ»ΠΈ from, yang mengandung. Untuk menentukan port berbeda untuk kumpulan elemen berbeda, pisahkan ingress ΠΈΠ»ΠΈ egress menjadi beberapa subbagian dengan to ΠΈΠ»ΠΈ from dan di setiap daftarkan port Anda:
Jika Anda menghilangkan definisi port sepenuhnya (ports), ini berarti semua protokol dan semua port;
Jika Anda menghilangkan definisi protokol (protocol), ini berarti TCP;
Jika Anda menghilangkan definisi port (port), ini berarti semua port.
Praktik terbaik: Jangan mengandalkan nilai default, tentukan apa yang Anda perlukan secara eksplisit.
Harap dicatat bahwa Anda harus menggunakan port pod, bukan port layanan (lebih lanjut tentang ini di paragraf berikutnya).
Apakah kebijakan ditentukan untuk pod atau layanan?
Biasanya, pod-pod di Kubernetes saling mengakses melalui layanan - penyeimbang beban virtual yang mengalihkan lalu lintas ke pod-pod yang mengimplementasikan layanan tersebut. Anda mungkin berpikir bahwa kebijakan jaringan mengontrol akses ke layanan, namun kenyataannya tidak demikian. Kebijakan jaringan Kubernetes berfungsi pada port pod, bukan port layanan.
Misalnya, jika suatu layanan mendengarkan port 80, tetapi mengalihkan lalu lintas ke port 8080 pada podnya, Anda harus menentukan 8080 secara tepat dalam kebijakan jaringan.
Mekanisme seperti itu harus dianggap kurang optimal: jika struktur internal layanan (port tempat pod mendengarkan) berubah, kebijakan jaringan harus diperbarui.
Pendekatan arsitektur baru menggunakan Service Mesh (misalnya, lihat tentang Istio di bawah - kira-kira terjemahan) memungkinkan Anda untuk mengatasi masalah ini.
Apakah perlu mendaftarkan Ingress dan Egress?
Jawaban singkatnya adalah ya, agar pod A dapat berkomunikasi dengan pod B, pod A harus diizinkan untuk membuat koneksi keluar (untuk ini Anda perlu mengonfigurasi kebijakan jalan keluar), dan pod B harus dapat menerima koneksi masuk ( untuk ini, oleh karena itu, Anda memerlukan kebijakan ingress).
Namun, dalam praktiknya, Anda dapat mengandalkan kebijakan default untuk mengizinkan koneksi dalam satu atau kedua arah.
Jika beberapa pod-sumber akan dipilih oleh satu atau lebih jalan keluar-politisi, pembatasan yang dikenakan padanya akan ditentukan oleh disjungsi mereka. Dalam hal ini, Anda harus secara eksplisit mengizinkan koneksi ke pod -kepada penerima. Jika sebuah pod tidak dipilih berdasarkan kebijakan apa pun, lalu lintas keluarnya (keluar) diperbolehkan secara default.
Demikian pula nasib podnyapenerima, dipilih oleh satu atau lebih masuk-politisi, akan ditentukan oleh disjungsi mereka. Dalam hal ini, Anda harus secara eksplisit mengizinkannya untuk menerima lalu lintas dari pod sumber. Jika sebuah pod tidak dipilih berdasarkan kebijakan apa pun, semua lalu lintas masuknya akan diizinkan secara default.
Lihat Stateful atau Stateless di bawah.
Log
Kebijakan jaringan Kubernetes tidak dapat mencatat lalu lintas. Hal ini mempersulit penentuan apakah suatu kebijakan berfungsi sebagaimana mestinya dan sangat mempersulit analisis keamanan.
Kontrol lalu lintas ke layanan eksternal
Kebijakan jaringan Kubernetes tidak mengizinkan Anda menentukan nama domain yang sepenuhnya memenuhi syarat (DNS) di bagian jalan keluar. Fakta ini menyebabkan ketidaknyamanan yang signifikan ketika mencoba membatasi lalu lintas ke tujuan eksternal yang tidak memiliki alamat IP tetap (seperti aws.com).
Pemeriksaan Kebijakan
Firewall akan memperingatkan Anda atau bahkan menolak menerima kebijakan yang salah. Kubernetes juga melakukan beberapa verifikasi. Saat menetapkan kebijakan jaringan melalui kubectl, Kubernetes mungkin menyatakan bahwa kebijakan tersebut salah dan menolak untuk menerimanya. Dalam kasus lain, Kubernetes akan mengambil kebijakan tersebut dan mengisinya dengan detail yang hilang. Mereka dapat dilihat menggunakan perintah:
kubernetes get networkpolicy <policy-name> -o yaml
Perlu diingat bahwa sistem validasi Kubernetes tidak sempurna dan mungkin melewatkan beberapa jenis kesalahan.
Eksekusi
Kubernetes tidak mengimplementasikan kebijakan jaringan itu sendiri, namun hanyalah sebuah gateway API yang mendelegasikan beban kendali ke sistem dasar yang disebut Container Networking Interface (CNI). Menetapkan kebijakan pada cluster Kubernetes tanpa menetapkan CNI yang sesuai sama dengan membuat kebijakan pada server manajemen firewall tanpa kemudian menginstalnya pada firewall. Terserah pada Anda untuk memastikan bahwa Anda memiliki CNI yang layak atau, dalam kasus platform Kubernetes, dihosting di cloud (Anda dapat melihat daftar penyedia di sini β kira-kira. trans.), aktifkan kebijakan jaringan yang akan menetapkan CNI untuk Anda.
Perhatikan bahwa Kubernetes tidak akan memperingatkan Anda jika Anda menetapkan kebijakan jaringan tanpa bantuan CNI yang sesuai.
Berstatus atau Tanpa Kewarganegaraan?
Semua CNI Kubernetes yang saya temui bersifat stateful (misalnya, Calico menggunakan koneksi Linux). Hal ini memungkinkan pod untuk menerima respons pada koneksi TCP yang dimulainya tanpa harus membangunnya kembali. Namun, saya tidak mengetahui standar Kubernetes yang dapat menjamin status.
Manajemen Kebijakan Keamanan Tingkat Lanjut
Berikut beberapa cara untuk meningkatkan penegakan kebijakan keamanan di Kubernetes:
Pola arsitektur Service Mesh menggunakan kontainer sespan untuk menyediakan telemetri terperinci dan kontrol lalu lintas di tingkat layanan. Sebagai contoh bisa kita ambil Istio.
Beberapa vendor CNI telah memperluas alat mereka untuk melampaui kebijakan jaringan Kubernetes.
Tufin Orca Memberikan visibilitas dan otomatisasi kebijakan jaringan Kubernetes.
Paket Tufin Orca mengelola kebijakan jaringan Kubernetes (dan merupakan sumber dari tangkapan layar di atas).
Kebijakan jaringan Kubernetes menawarkan seperangkat alat yang bagus untuk melakukan segmentasi klaster, namun kebijakan tersebut tidak intuitif dan memiliki banyak kehalusan. Karena kerumitan ini, saya yakin banyak kebijakan klaster yang ada bermasalah. Solusi yang mungkin untuk masalah ini termasuk mengotomatiskan definisi kebijakan atau menggunakan alat segmentasi lainnya.
Saya harap panduan ini membantu menjernihkan beberapa pertanyaan dan menyelesaikan masalah yang mungkin Anda temui.