Named pipe dalam praktik — IPC andalan Windows, dari desain sampai keamanan

· Diperbarui pada: · · Windows, IPC, Pengembangan Windows, C#, C++, Keamanan, Win32 API

Riwayat revisi (1 pembaruan, terakhir pada 31 Aug 2026)

Catatan perubahan yang dilakukan pada artikel ini. Jika versi sebelumnya telah diarsipkan, versi itu tetap dapat dibaca melalui tautan permanen dengan DOI.

Diterjemahkan ulang sebagai terjemahan lengkap dari naskah Jepang. Versi bahasa Indonesia sebelumnya adalah ringkasan yang hanya memindahkan sebagian naskah, sehingga bagian, tabel, gambar Mermaid, keterangan gambar, dan FAQ tidak ada. Semuanya dipulihkan sesuai naskah Jepang, dan klaim teknisnya sama dengan versi Jepang.
Publikasi pertama
Mengutip artikel ini(DOI (arsip terdaftar): 10.5281/zenodo.22176773)

DOI di bawah mengarah ke versi yang telah diarsipkan sebelumnya dan mungkin berbeda dari teks saat ini. Gunakan URL halaman ini untuk merujuk teks saat ini.

Go Komura (2026). Named pipe dalam praktik — IPC andalan Windows, dari desain sampai keamanan. KomuraSoft LLC. https://comcomponent.com/id/blog/windows-named-pipes-practical-guide/

DOI (arsip terdaftar)
10.5281/zenodo.22176773
DOI (versi terakhir yang didaftarkan)
10.5281/zenodo.22176774

Ingin bertukar perintah antara layanan yang selalu berjalan dan aplikasi UI pengaturan. Ingin memisahkan ke proses lain hanya pekerjaan yang membutuhkan hak administrator. Ingin saling mengirim data antar tool di PC yang sama. Ketika komunikasi antarproses (IPC) semacam ini diperlukan di Windows, standar yang patut ditimbang lebih dulu adalah named pipe.

Artikel tabel keputusan komunikasi antarproses menempatkan named pipe sebagai “kandidat pertama IPC di mesin yang sama”. Artikel ini adalah pembahasan rincinya. Mengapa kandidat pertama, bagaimana memilih mode dan konfigurasi server, dan apa yang harus dilindungi ketika layanan berhak istimewa memakainya. Untuk pengembang yang menulis aplikasi bisnis dan layanan di Windows, bahan keputusan desain disusun berdasarkan sumber primer.

1. Kesimpulan lebih dulu

  • Named pipe adalah saluran komunikasi antarproses dua arah dengan ruang nama \\.\pipe\nama. Beberapa instance dapat dibuat dengan nama yang sama, sehingga beberapa klien dapat diterima sekaligus.1
  • Alasan menjadi kandidat pertama untuk IPC di mesin yang sama adalah model keamanannya. ACL dapat mengontrol siapa yang terhubung, dan server dapat memeriksa serta meminjam (meng-impersonate) akun Windows klien. TCP localhost tidak punya keduanya.2
  • Jika ingin memperlakukan “satu penulisan = satu pesan”, pakai mode pesan; jika sudah punya framing sendiri, pakai mode byte. Bahkan dalam mode pesan, pembacaan terpecah saat buffer kurang (ERROR_MORE_DATA) tetap harus ditangani.3
  • Beberapa klien ditangani dengan “beberapa instance + overlapped I/O” atau “.NET async/await”. Sampel resmi menunjukkan bentuk yang memproses beberapa instance di satu thread.4
  • Garis minimum keamanan adalah empat poin: tolak jarak jauh (PIPE_REJECT_REMOTE_CLIENTS), ACL eksplisit, deteksi pembajakan lewat FILE_FLAG_FIRST_PIPE_INSTANCE, dan minimalkan tingkat impersonation di sisi klien.56
  • Untuk ImpersonateNamedPipeClient, memeriksa nilai kembalian adalah nyawa. Jika kegagalan diabaikan, pemrosesan berjalan dengan hak server.6

2. Apa itu named pipe — ruang nama, instance, dan bentuk koneksi

Named pipe adalah saluran yang dikenali dengan nama seperti \\.\pipe\MyCompany.MyApp.Control. Server membuatnya dengan CreateNamedPipe, dan klien membuka nama yang sama dengan CreateFile. Setelah terbuka, kedua sisi membaca dan menulis dengan ReadFile / WriteFile — ciri khasnya adalah dapat dipakai dalam bentuk yang sama seperti I/O berkas.1

Konsep penting adalah instance. Pipe dengan nama yang sama dapat dibuat dalam beberapa instance, dan satu instance adalah satu saluran dengan satu klien. Panggilan CreateNamedPipe pertama menentukan jumlah instance maksimum (atau tanpa batas).3

Koneksi di sisi klien punya tata cara yang sudah umum. Ketika semua instance sedang dipakai, CreateFile gagal dengan ERROR_PIPE_BUSY, jadi tunggu yang kosong dengan WaitNamedPipe lalu coba lagi. Selain itu, akses yang ditentukan saat membuka harus cocok dengan arah yang dibuat server — pipe dua arah dapat dibuka dengan spesifikasi baca maupun tulis, tetapi outbound yang hanya ditulis server harus dibuka hanya-baca, dan inbound yang hanya dibaca server harus dibuka hanya-tulis, atau CreateFile gagal.7

Arah pipe dan spesifikasi akses klienPipe dua arah dapat dibuka klien dengan spesifikasi baca maupun tulis, tetapi outbound yang hanya ditulis server harus dibuka hanya-baca, dan inbound yang hanya dibaca server harus dibuka hanya-tulisDua arahOutboundInboundArah yang dibuat server?Baca maupun tulis bolehBuka hanya-bacaBuka hanya-tulis

Gambar 1: Ketidakcocokan arah dan spesifikasi akses berujung pada kegagalan CreateFile. Saat menelusuri kesalahan koneksi, periksa ini lebih dulu.

Struktur dasar named pipeServer membuat beberapa instance pipe dengan nama yang sama dan menunggu koneksi dengan ConnectNamedPipe; setiap klien membuka nama itu dengan CreateFile dan memiliki saluran dua arah satu-ke-satu dengan satu instanceServerInstance 1Instance 2Instance 3Klien AKlien BKlien C

Gambar 2: Dengan beberapa instance bernama sama, satu server dapat berkomunikasi satu-ke-satu dengan beberapa klien sekaligus.

Named pipe juga dapat dibuka dari jarak jauh lewat SMB (\\server\pipe\nama), tetapi dalam desain modern hampir tidak ada alasan untuk memakainya secara aktif. Yang jadi isu justru jangan biarkan tetap terbuka jika tidak dipakai (Bab 5).

3. Mode byte dan mode pesan

Pipe punya dua mode transfer.3

  • Mode byte (PIPE_TYPE_BYTE): “aliran byte tanpa potongan” seperti TCP. Di mana satu pesan berakhir harus ditentukan sendiri (merancang framing seperti prefix panjang).
  • Mode pesan (PIPE_TYPE_MESSAGE + PIPE_READMODE_MESSAGE): satu penulisan diperlakukan sebagai satu pesan, dan sisi baca menerimanya dalam satuan itu. Untuk pertukaran permintaan-respons, ini lebih mudah.

Mode pesan punya pendamping yang berguna: TransactNamedPipe, yang mengirim permintaan dan menerima respons dalam satu kali panggilan.8 Ada juga jebakannya. Jika buffer terima lebih kecil dari seluruh pesan, pembacaan mengembalikan ERROR_MORE_DATA dan menjadi pembacaan terpecah. Jangan berasumsi bahwa mode pesan berarti “satu Read selalu membawa keseluruhan”; loop untuk membaca sisanya tetap perlu ditulis. Mode baca adalah pengaturan per handle; yang diputuskan CreateNamedPipe hanya sisi server. Klien menentukannya dengan SetNamedPipeHandleState setelah CreateFile (ReadMode setelah terhubung di .NET).7

Loop pembacaan terpecah pada mode pesanJika ReadFile berhasil, pesan selesai; jika ERROR_MORE_DATA, sisa yang tidak muat di buffer dibaca lagi lalu digabung; error lain diperlakukan sebagai putus koneksiBerhasilERROR_MORE_DATAError lainBaca dengan ReadFileHasilnya?Pesan selesaiBaca sisa lalu gabungkanPerlakukan sebagai putus koneksi

Gambar 3: Bahkan dalam mode pesan, loop “baca sisanya” tetap diperlukan. Tanpa itu, hanya pesan besar yang rusak.

Perbedaan mode byte dan mode pesanPada mode byte, tiga penulisan menjadi aliran byte tanpa potongan dan penerima harus memotongnya sendiri; pada mode pesan, satuan tiap penulisan dipertahankan dan sampai ke penerima apa adanyaMode byte: tulis AAA, BB, CCCCYang diterima: aliran byte AAABBCCCCBatas (framing) dirancang sendiriMode pesan: tiga penulisan yang samaYang diterima: tiga pesan AAA, BB, CCCCSatuan penulisan dipertahankan

Gambar 4: Mode pesan mempertahankan “satuan penulisan” sampai ke penerima. Framing tidak perlu dirancang, tetapi penanganan pembacaan terpecah jangan dilupakan.

Petunjuk praktis memilihnya sederhana. Jika pertukarannya berbentuk permintaan dan respons, pakai mode pesan. Jika yang dialirkan sudah format yang membawa framing (data serialisasi berpanjang atau transfer stream), pakai mode byte. Di .NET, menentukan PipeTransmissionMode.Message sesuai dengan yang pertama.9

4. Desain server — tipe thread sinkron atau tipe overlapped

Operasi dasar server adalah pengulangan “buat instance → tunggu klien dengan ConnectNamedPipe → baca/tulis → putuskan lalu ke klien berikutnya”. Ada dua bentuk untuk melayani beberapa klien sekaligus.

Tipe thread sinkron. Satu thread dialokasikan per instance, masing-masing melayani kliennya sendiri dengan I/O sinkron. Kodenya lugas, tetapi mengonsumsi thread sebanyak jumlah klien, dan saat berhenti secara keseluruhan (shutdown) perlu cara untuk keluar dari I/O yang memblokir.

Tipe overlapped (asinkron). Instance dibuat dengan FILE_FLAG_OVERLAPPED, lalu ConnectNamedPipe / ReadFile / WriteFile dikeluarkan secara asinkron, dan sejumlah kecil thread menangani penyelesaian semua instance. Sampel resmi Microsoft menunjukkan server yang menunggu array event dengan WaitForMultipleObjects dan memproses beberapa instance di satu thread.4 Pembahasan umum I/O asinkron sudah dijelaskan di artikel serial I/O; jika skalanya besar, koneksi ke IOCP atau I/O thread pool juga bisa dipilih.

Struktur server tipe overlappedPenyelesaian operasi asinkron tiap instance diterima lewat array event; sejumlah kecil thread menunggu dengan WaitForMultipleObjects lalu memajukan pemrosesan instance yang selesai, sehingga jumlah thread dipisahkan dari jumlah klienOperasi asinkron instance 1Array eventOperasi asinkron instance 2Operasi asinkron instance 3Tunggu penyelesaian dengan WaitForMultipleObjectsMajukan pemrosesan instance yang selesai

Gambar 5: Tipe overlapped memisahkan jumlah thread dari jumlah klien. Sampel resmi memutar siklus ini di satu thread.

Di .NET, pilihan ini hampir tidak perlu dirisaukan. Dengan WaitForConnectionAsync / ReadAsync / WriteAsync pada NamedPipeServerStream plus async/await, efisiensi tipe overlapped didapat dengan kode yang hampir sama lugasnya seperti tipe sinkron.9

// C#: kerangka server yang menerima beberapa klien
while (!token.IsCancellationRequested)
{
    var server = new NamedPipeServerStream(
        "MyCompany.MyApp.Control",
        PipeDirection.InOut,
        NamedPipeServerStream.MaxAllowedServerInstances,
        PipeTransmissionMode.Message,
        PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly);

    try
    {
        await server.WaitForConnectionAsync(token);
    }
    catch
    {
        await server.DisposeAsync();        // jika keluar sebelum terhubung, dispose sendiri
        throw;
    }
    _ = HandleClientAsync(server, token);   // setelah terhubung, kepemilikan pindah ke handler
}

PipeOptions.CurrentUserOnly berarti “hanya izinkan koneksi dari proses pengguna yang sama” — default yang mudah dan aman tanpa menulis ACL sendiri.10 Tidak dapat dipakai pada konfigurasi lintas pengguna (layanan ↔ aplikasi sesi pengguna, dan semacamnya); dalam kasus itu lanjut ke desain ACL di bab berikutnya.

Loop penerimaan server asinkron .NETLoop penerimaan membuat NamedPipeServerStream, menunggu koneksi dengan WaitForConnectionAsync, lalu melepaskan penanganan klien secara asinkron dan segera kembali menerima berikutnya, sehingga koneksi simultan ditangani dengan kode yang lugasBuat stream serverTunggu dengan WaitForConnectionAsyncKoneksi tibaLepaskan penanganan klien secara asinkron

Gambar 6: Loop penerimaan hanya berputar “tunggu → lepas → berikutnya”; penanganan tiap klien berjalan secara paralel.

5. Keamanan — empat poin wajib jika dipakai layanan berhak istimewa

Alasan terbesar named pipe menjadi kandidat pertama IPC di mesin yang sama adalah model keamanannya, tetapi itu jika dikonfigurasi dengan benar. Terutama pada konfigurasi broker “layanan berhak administrator + aplikasi UI berhak rendah”, pipe itu sendiri menjadi batas hak. Ada empat poin yang harus dipegang.

(1) Tolak jarak jauh. Pipe yang dimaksudkan sebagai IPC lokal tetapi dapat dibuka dari jaringan sudah merupakan permukaan serangan. Jika PIPE_REJECT_REMOTE_CLIENTS ditentukan pada CreateNamedPipe, koneksi klien jarak jauh ditolak secara otomatis.5

(2) Buat ACL eksplisit. Serahkan security descriptor lewat SECURITY_ATTRIBUTES dan persempit pengguna serta grup yang diizinkan terhubung. Jangan memberi GENERIC_WRITE kepada klien — hak FILE_CREATE_PIPE_INSTANCE yang terkandung di dalamnya memungkinkan klien yang diizinkan membuat instance server bernama sama dan merebut koneksi berikutnya. Berikan baca dan tulis sebagai hak terpisah, dan jangan menyerahkan hak membuat instance.11

(3) Cegah pembajakan nama. Nama pipe adalah siapa cepat dia dapat. Jika proses jahat membuat pipe bernama sama lebih dulu dan menunggu, klien terhubung ke server palsu. Server menentukan FILE_FLAG_FIRST_PIPE_INSTANCE saat membuat instance pertama, menjamin “dirinyalah yang pertama”, dan jika gagal, curigai pembajakan lalu berhenti. Flag ini khusus untuk instance pertama yang mengamankan nama; jika dipasang pada yang kedua dan seterusnya, pembuatan gagal.3

(4) Klien meminimalkan tingkat impersonation sesuai kebutuhan. Ini persiapan jika tujuan koneksi ternyata server palsu. Jika klien menentukan **SECURITY_SQOS_PRESENT SECURITY_IDENTIFICATION** pada CreateFile, sisi server masih dapat mengidentifikasi klien, tetapi tidak dapat meminjam haknya untuk bertindak.2 Namun ini trade-off dengan alur impersonation — pada konfigurasi broker di mana server melakukan akses sungguhan dengan hak klien, tingkat identifikasi tidak cukup untuk impersonation, dan izin SECURITY_IMPERSONATION diperlukan. Izin itu bersyarat pada kepastian terhubung ke server yang sah. Perlindungan pembajakan di sisi server hanyalah mekanisme yang membuat startup gagal sehingga ketahuan; jika penyerang membuat pipe bernama sama lebih dulu saat layanan sah tidak ada, klien tetap bisa terhubung ke server palsu. Izinkan hanya jika tujuan koneksi dapat dipastikan lewat jaminan startup layanan atau autentikasi timbal balik setelah terhubung.

Identifikasi dan peminjaman hak di sisi server adalah ImpersonateNamedPipeClient. Memanggilnya setelah membaca permintaan dari pipe membuat thread pemanggil mulai bergerak dalam konteks keamanan pengirim pesan yang terakhir dibaca. Jika berkas dibuka dengan hak klien, keputusan akses mengikuti klien — mekanisme agar layanan berhak istimewa menjalankan “operasi yang diminta, dengan hak orang yang meminta”.6 Syarat mutlak pemakaiannya adalah memeriksa nilai kembalian. Jika pemrosesan dilanjutkan padahal impersonation gagal, operasi berikutnya berjalan dengan hak tinggi server sendiri. Dokumentasi resmi menyatakan secara eksplisit: “saat gagal, permintaan klien tidak boleh dijalankan”. Bersama RevertToSelf setelah pekerjaan selesai, tata cara di artikel token impersonation berlaku apa adanya.

Alur pemrosesan permintaan dengan impersonationServer membaca permintaan dari pipe, mengonfirmasi keberhasilan ImpersonateNamedPipeClient, lalu beroperasi dengan hak klien, dan kembali ke konteksnya sendiri dengan RevertToSelf. Jika impersonation gagal, permintaan ditolak tanpa dijalankanServerKlienServerKlienJika gagal, tolak tanpa menjalankan permintaanKirim permintaanBaca permintaanImpersonateNamedPipeClientJalankan operasi dengan hak klienKembalikan dengan RevertToSelfBalas hasil

Gambar 7: Konfirmasi keberhasilan impersonation dan RevertToSelf yang andal adalah satu paket. Jika dilanjutkan saat gagal, eksekusi berjalan dengan hak server.

Empat poin menjaga pipe layanan berhak istimewaSisi server mengunci pintu masuk dengan menolak jarak jauh, ACL eksplisit, dan jaminan instance pertama; sisi klien menentukan tingkat impersonation seminimal mungkin agar hak tidak dipinjam server palsu (jika desainnya tidak membiarkan server meminjam hak, batasi ke tingkat identifikasi)Sisi klienTentukan tingkat impersonation seminimal mungkinSisi serverPIPE_REJECT_REMOTE_CLIENTSBatasi yang terhubung dengan ACLFIRST_PIPE_INSTANCE (hanya yang pertama)Pipe sebagai batas hak

Gambar 8: Pada konfigurasi di mana pipe menjadi batas hak, implementasikan 3 poin sisi server + 1 poin sisi klien sebagai satu set.

6. Jebakan praktis

Balapan urutan startup. Jika klien datang terhubung sebelum server membuat pipe, hasilnya error “pipe tidak ada”. Sisi klien menyertakan “tidak ada → tunggu sebentar lalu coba lagi”. Sebaliknya, prinsip sisi server adalah mulai menunggu dengan ConnectNamedPipe sebelum klien start.8

Alur coba ulang koneksi klienBuka pipe dengan CreateFile; jika pipe tidak ada, tunggu sebentar lalu coba lagi; jika ERROR_PIPE_BUSY karena semua instance terpakai, tunggu yang kosong dengan WaitNamedPipe lalu coba lagi; jika berhasil, masuk ke komunikasiBerhasilPipe tidak adaERROR_PIPE_BUSYBuka dengan CreateFileHasilnya?Mulai komunikasiTunggu sebentar (server belum start)Tunggu yang kosong dengan WaitNamedPipe

Gambar 9: Penanganan koneksi klien membedakan dua jenis kegagalan, “tidak ada” dan “penuh”, lalu keduanya kembali ke coba ulang.

Mendeteksi putus koneksi. Ketika rekan berakhir, Read/Write gagal dengan ERROR_BROKEN_PIPE dan semacamnya. Itu bukan anomali, melainkan keseharian komunikasi. Server yang mendeteksi putus memanggil DisconnectNamedPipe pada instance dan bersiap untuk koneksi berikutnya; klien terhubung kembali — gagasan “rekoneksi idempoten” di artikel sleep/resume berlaku di sini juga.

Asumsi ukuran pesan. Selain pembacaan terpecah mode pesan (Bab 3), jika “maksimal berapa byte satu pesan” tidak diputuskan sebagai protokol, pesan raksasa dari rekan yang jahat (atau yang bug) dapat menghamburkan memori. Tetapkan batas atas, dan putuskan jika terlampaui; itu yang aman.

Selesainya penulisan dan diterimanya data oleh rekan adalah hal berbeda. Keberhasilan WriteFile tidak berarti aplikasi rekan telah memproses data. Operasi yang membutuhkan kepastian ditanggung oleh desain: konfirmasi lewat pesan respons, dan masukkan korespondensi permintaan-respons ke dalam protokol.

7. Ringkasan

  • Named pipe adalah kandidat pertama IPC di mesin yang sama. Alasannya: sama mudahnya seperti I/O berkas, plus terintegrasi dengan model keamanan Windows berupa ACL dan impersonation.
  • Pilihan mode: “mode pesan jika permintaan dan respons; mode byte jika sudah ada framing sendiri”. Bahkan dalam mode pesan, penanganan pembacaan terpecah (ERROR_MORE_DATA) tetap diperlukan.
  • Beberapa klien: beberapa instance + overlapped, atau async/await di .NET. Untuk yang baru, tipe asinkron .NET lebih lugas.
  • Pada pipe yang menjadi batas hak, pakai sebagai satu set: tolak jarak jauh, ACL eksplisit, FIRST_PIPE_INSTANCE (hanya yang pertama), dan minimalkan tingkat impersonation di sisi klien.
  • Untuk ImpersonateNamedPipeClient, memeriksa nilai kembalian dan RevertToSelf adalah nyawa.
  • Rajut “keseharian komunikasi” — urutan startup, putus koneksi, batas atas pesan, konfirmasi respons — ke dalam desain protokol.

Named pipe adalah API lama, tetapi untuk keperluan “membuat proses saling berbicara di mesin yang sama sambil menghormati batas akun Windows”, ini masih alat yang paling masuk akal. Titik keputusan desain hampir seluruhnya tercakup dalam lingkup artikel ini. Setelah itu, tuliskan protokol sendiri di selembar kertas sebelum masuk ke implementasi.

Artikel terkait

Area konsultasi terkait

KomuraSoft LLC menangani desain dan implementasi yang melibatkan komunikasi antarproses — pemisahan layanan dan aplikasi UI, pemisahan hak administrator, dan semacamnya — penggantian IPC yang ada (shared memory, soket sendiri, COM, dan lain-lain) dengan named pipe, serta tinjauan keamanan komunikasi pipe pada layanan berhak istimewa. Konsultasi mulai dari diskusi desain protokol pun dipersilakan.

Tautan referensi

  1. Microsoft Learn, Named Pipes. Tentang named pipe sebagai saluran satu arah atau dua arah antara pipe server dan satu atau lebih pipe client; bahwa semua instance berbagi nama yang sama tetapi punya buffer dan handle independen; dan bahwa dapat dipakai dari proses lokal maupun jarak jauh. ↩ ↩2

  2. Microsoft Learn, Impersonating a Named Pipe Client. Tentang impersonation yang memungkinkan thread server beroperasi dalam lingkup hak klien; bahwa tingkat impersonation bawaan adalah SecurityImpersonation; dan bahwa klien dapat mengontrol tingkat impersonation dengan flag SECURITY_SQOS_PRESENT saat CreateFile (SECURITY_IDENTIFICATION hanya mengizinkan identifikasi). ↩ ↩2

  3. Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h). Tentang arah pipe (inbound, outbound, dua arah), tipe byte dan tipe pesan (PIPE_TYPE_BYTE / PIPE_TYPE_MESSAGE) serta mode baca (PIPE_READMODE_MESSAGE), jumlah instance maksimum (PIPE_UNLIMITED_INSTANCES), mode asinkron lewat FILE_FLAG_OVERLAPPED, jaminan instance pertama lewat FILE_FLAG_FIRST_PIPE_INSTANCE, dan timeout bawaan untuk WaitNamedPipe. ↩ ↩2 ↩3 ↩4

  4. Microsoft Learn, Named Pipe Server Using Overlapped I/O. Tentang sampel resmi server satu thread yang memproses koneksi simultan dengan beberapa klien lewat operasi overlapped. Tentang bentuk yang menunggu struktur OVERLAPPED dan event tiap instance dengan WaitForMultipleObjects lalu memajukan mesin keadaan instance yang selesai, serta konfirmasi penyelesaian I/O tertunda dengan GetOverlappedResult. ↩ ↩2

  5. Microsoft Learn, CreateNamedPipeW function (namedpipeapi.h). Tentang dua mode klien jarak jauh: PIPE_ACCEPT_REMOTE_CLIENTS (terima koneksi jarak jauh dan periksa terhadap security descriptor) dan PIPE_REJECT_REMOTE_CLIENTS (tolak otomatis koneksi klien jarak jauh). ↩ ↩2

  6. Microsoft Learn, ImpersonateNamedPipeClient function (namedpipeapi.h). Tentang thread sisi server yang mulai impersonation dalam konteks keamanan klien dari pesan terakhir yang dibaca dari pipe; tentang kembali dengan RevertToSelf setelah selesai; dan bahwa jika pemrosesan dilanjutkan saat impersonation gagal, eksekusi berjalan dalam konteks (berhak istimewa) proses server sendiri, sehingga nilai kembalian harus selalu diperiksa dan saat gagal permintaan klien tidak boleh dijalankan. ↩ ↩2 ↩3

  7. Microsoft Learn, Named Pipe Client. Tentang klien yang membuka pipe dengan CreateFile; bahwa jika semua instance terpakai hasilnya ERROR_PIPE_BUSY lalu menunggu yang kosong dengan WaitNamedPipe; dan bahwa handle yang dibuka secara bawaan byte-read, blocking, dan non-overlapped, serta dapat diubah ke mode baca pesan dengan SetNamedPipeHandleState. ↩ ↩2

  8. Microsoft Learn, Named Pipe Operations. Tentang operasi overlapped lewat ReadFileEx / WriteFileEx, pembacaan tanpa mengambil lewat PeekNamedPipe, TransactNamedPipe yang mengirim permintaan dan menerima respons dalam satu panggilan pada pipe dua arah tipe pesan, dan bahwa pembacaan yang memblokir sebelum klien start dapat menimbulkan balapan. ↩ ↩2

  9. Microsoft Learn, How to: Use Named Pipes for Network Interprocess Communication (.NET). Tentang koneksi serta baca/tulis dengan NamedPipeServerStream / NamedPipeClientStream, transfer satuan pesan lewat PipeTransmissionMode.Message, dan penanganan beberapa klien dengan metode asinkron. ↩ ↩2

  10. Microsoft Learn, PipeOptions Enum (System.IO.Pipes). Tentang mengaktifkan I/O asinkron dengan Asynchronous, dan bahwa CurrentUserOnly dapat mengizinkan koneksi hanya dengan proses pengguna yang sama (dan tingkat elevasi yang sama). ↩

  11. Microsoft Learn, Named Pipe Security and Access Rights. Tentang komposisi hak akses named pipe; bahwa GENERIC_WRITE mencakup FILE_CREATE_PIPE_INSTANCE, sehingga memberi generic write kepada klien juga mengizinkan pembuatan instance server; dan bahwa baca serta tulis data hendaknya diberikan sebagai hak akses terpisah. ↩

Artikel terbaru dengan tag yang sama untuk mendalami topik-topik terdekat.

Halaman-halaman ini menempatkan topik dalam konteks layanan dan keputusan yang lebih luas.

Artikel ini berkaitan langsung dengan layanan berikut.

Pertanyaan yang sering diajukan

Pertanyaan yang sering muncul dalam konsultasi tentang topik artikel ini.

Bagaimana memilah pemakaian named pipe dan TCP (soket localhost)?
Untuk komunikasi antarproses di mesin yang sama, named pipe adalah kandidat pertama. Alasannya ada pada model keamanan. Di tingkat OS, pipe dapat mengontrol siapa yang boleh terhubung lewat Windows security descriptor (ACL). Di sisi server, ImpersonateNamedPipeClient memungkinkan memeriksa dan meminjam akun Windows pihak yang terhubung. Kontrasnya, port TCP localhost dapat dihubungi siapa saja, sehingga identitas rekan harus dipastikan dengan autentikasi sendiri. Di sisi lain, pendekatan berbasis TCP lebih menguntungkan jika komunikasi jarak jauh kemungkinan besar akan menyusul, jika juga perlu berbicara dengan proses di OS lain, atau jika ingin memakai aset protokol yang sudah ada seperti gRPC. Pertimbangan ini juga dijabarkan di artikel tabel keputusan komunikasi antarproses.
Mode byte atau mode pesan, mana yang sebaiknya dipakai?
Jika ingin memperlakukan satu penulisan sebagai satu satuan makna, mode pesan (PIPE_TYPE_MESSAGE+PIPE_READMODE_MESSAGE) lebih nyaman. Sisi penerima dapat membaca dalam satuan yang ditulis pengirim, sehingga batas pesan tidak perlu dikelola sendiri. Mode byte adalah aliran byte tanpa potongan seperti TCP, dan framing (misalnya prefix panjang) harus dirancang sendiri. Jika yang dialirkan sudah protokol yang punya framing (misalnya format serialisasi berpanjang), mode byte tidak bermasalah. Perhatian: bahkan dalam mode pesan, jika buffer terima lebih kecil dari pesan, terjadi pembacaan terpecah (ERROR_MORE_DATA), jadi penanganan itu tetap diperlukan. Mode baca juga pengaturan per handle; yang ditetapkan CreateNamedPipe hanya sisi server. Sisi klien harus menentukan PIPE_READMODE_MESSAGE dengan SetNamedPipeHandleState setelah CreateFile. Di .NET, server menentukan PipeTransmissionMode.Message, dan klien mengatur NamedPipeClientStream.ReadMode ke Message setelah terhubung.
Bagaimana membuat server yang melayani beberapa klien sekaligus?
Named pipe dapat membuat beberapa instance dengan nama yang sama, dan satu instance menangani satu klien. Ada dua bentuk. Yang pertama adalah tipe sinkron: satu thread per klien. Implementasinya lugas, tetapi mengonsumsi thread sebanyak jumlah klien. Yang kedua memakai I/O asinkron dengan FILE_FLAG_OVERLAPPED, lalu sejumlah kecil thread menangani ConnectNamedPipe, ReadFile, dan WriteFile untuk semua instance. Sampel resmi Microsoft juga menunjukkan implementasi yang memproses beberapa instance di satu thread. Di .NET, WaitForConnectionAsync pada NamedPipeServerStream plus async/await membuat tipe asinkron bisa ditulis hampir sama lugasnya dengan tipe sinkron. Untuk implementasi baru, kecuali ada alasan khusus, tipe asinkron .NET yang disarankan.
Apa minimum yang harus dilakukan untuk keamanan named pipe?
Ada empat poin. Pertama, jika koneksi jarak jauh tidak diperlukan, tentukan PIPE_REJECT_REMOTE_CLIENTS agar koneksi lewat jaringan ditolak secara eksplisit. Kedua, tetapkan ACL yang sesuai lewat SECURITY_ATTRIBUTES, dan persempit pengguna serta grup yang boleh terhubung (ACL bawaan terlalu longgar untuk sebagian penggunaan). Ketiga, tentukan FILE_FLAG_FIRST_PIPE_INSTANCE saat membuat instance pertama, agar pembajakan nama — pipe bernama sama dibuat lebih dulu — dapat dideteksi (jangan pasang flag ini pada instance kedua dan seterusnya). Keempat, klien yang hanya ingin diidentifikasi server harus menentukan SECURITY_SQOS_PRESENT|SECURITY_IDENTIFICATION pada CreateFile, agar server palsu tidak meminjam (meng-impersonate) haknya. Pada konfigurasi broker di mana server melakukan akses sungguhan dengan hak klien, impersonation perlu diizinkan, jadi pembatasan ini dipakai atau tidak tergantung apakah desainnya memang tidak membiarkan server meminjam hak.
Apa yang perlu diwaspadai saat memakai ImpersonateNamedPipeClient?
Yang paling penting adalah memeriksa nilai kembalian. Jika pemrosesan dilanjutkan padahal impersonation gagal, operasi berikutnya berjalan dengan hak proses server sendiri (sering kali tinggi), dan operasi yang seharusnya tidak diizinkan bagi klien ikut lolos. Dokumentasi resmi juga menyatakan secara eksplisit bahwa saat gagal, permintaan klien tidak boleh dijalankan. Impersonation juga berlangsung dalam konteks pesan terakhir yang dibaca dari pipe, jadi harus dipanggil setelah membaca sesuatu, dan setelah pekerjaan selesai harus kembali ke konteks semula dengan RevertToSelf. Mekanisme seputar impersonation (token, tingkat impersonation, SeImpersonatePrivilege) dijelaskan secara rinci di artikel tentang token impersonation.

Profil penulis

Halaman perkenalan penulis artikel.

Go Komura

Direktur KomuraSoft LLC

Berspesialisasi dalam pengembangan perangkat lunak Windows, konsultasi teknis, dan investigasi bug, terutama pada proyek dengan sistem yang sudah ada dan bug yang sulit direproduksi.

Kembali ke blog