Komunikasi antarproses dengan gRPC
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Proses yang berjalan pada komputer yang sama dapat dirancang untuk berkomunikasi satu sama lain. Sistem operasi menyediakan teknologi untuk memungkinkan komunikasi antarproses (IPC) yang cepat dan efisien. Contoh populer teknologi IPC adalah soket domain Unix dan pipa Bernama.
.NET menyediakan dukungan untuk komunikasi antarproses menggunakan gRPC.
Dukungan bawaan untuk Pipa bernama di ASP.NET Core memerlukan .NET 8 atau yang lebih baru.
Memulai
Panggilan IPC dikirim dari klien ke server. Untuk berkomunikasi antara aplikasi di komputer dengan gRPC, setidaknya satu aplikasi harus menghosting server gRPC ASP.NET Core.
Server gRPC ASP.NET Core biasanya dibuat dari templat gRPC. File proyek yang dibuat oleh templat menggunakan Microsoft.NET.SDK.Web
sebagai SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
Nilai Microsoft.NET.SDK.Web
SDK secara otomatis menambahkan referensi ke kerangka kerja ASP.NET Core. Referensi memungkinkan aplikasi untuk menggunakan jenis ASP.NET Core yang diperlukan untuk menghosting server.
Anda juga dapat menambahkan server ke proyek non-ASP.NET Core yang ada, seperti Windows Services, aplikasi WPF, atau aplikasi WinForms. Lihat Host gRPC di proyek non-ASP.NET Core untuk informasi selengkapnya.
Transportasi komunikasi antar proses (IPC)
Panggilan gRPC antara klien dan server pada komputer yang berbeda biasanya dikirim melalui soket TCP. TCP adalah pilihan yang baik untuk berkomunikasi melalui jaringan atau Internet. Namun, transportasi IPC menawarkan keuntungan saat berkomunikasi antara proses pada komputer yang sama:
- Lebih sedikit overhead dan kecepatan transfer yang lebih cepat.
- Integrasi dengan fitur keamanan OS.
- Tidak menggunakan port TCP, yang merupakan sumber daya terbatas.
.NET mendukung beberapa transportasi IPC:
- Soket domain Unix (UDS) adalah teknologi IPC yang didukung secara luas. UDS adalah pilihan terbaik untuk membangun aplikasi lintas platform, dan dapat digunakan di Linux, macOS, dan Windows 10/Windows Server 2019 atau yang lebih baru.
- Pipa bernama didukung oleh semua versi Windows. Pipa bernama terintegrasi dengan baik dengan keamanan Windows, yang dapat mengontrol akses klien ke pipa.
- Transportasi IPC tambahan dengan menerapkan IConnectionListenerFactory dan mendaftarkan implementasi di startup aplikasi.
Bergantung pada OS, aplikasi lintas platform dapat memilih transportasi IPC yang berbeda. Aplikasi dapat memeriksa OS saat startup dan memilih transportasi yang diinginkan untuk platform tersebut:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
if (OperatingSystem.IsWindows())
{
serverOptions.ListenNamedPipe("MyPipeName");
}
else
{
var socketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
serverOptions.ListenUnixSocket(socketPath);
}
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
Pertimbangan keamanan
Aplikasi IPC mengirim dan menerima panggilan RPC. Komunikasi eksternal adalah vektor serangan potensial untuk aplikasi IPC dan harus diamankan dengan benar.
Mengamankan aplikasi server IPC terhadap penelepon tak terduga
Aplikasi server IPC menghosting layanan RPC untuk dihubungi aplikasi lain. Penelepon masuk harus diautentikasi untuk mencegah klien yang tidak tepercaya melakukan panggilan RPC ke server.
Keamanan transportasi adalah salah satu opsi untuk mengamankan server. Transportasi IPC, seperti soket domain Unix dan pipa bernama, mendukung pembatasan akses berdasarkan izin sistem operasi:
- Pipa bernama mendukung pengamanan pipa dengan model kontrol akses Windows. Hak akses dapat dikonfigurasi di .NET saat server dimulai menggunakan PipeSecurity kelas .
- Soket domain Unix mendukung pengamanan soket dengan izin file.
Opsi lain untuk mengamankan server IPC adalah menggunakan autentikasi dan otorisasi yang disertakan dalam ASP.NET Core. Misalnya, server dapat dikonfigurasi untuk memerlukan autentikasi sertifikat. Panggilan RPC yang dilakukan oleh aplikasi klien tanpa sertifikat yang diperlukan gagal dengan respons yang tidak sah.
Memvalidasi server di aplikasi klien IPC
Penting bagi aplikasi klien untuk memvalidasi identity server yang dipanggilnya. Validasi diperlukan untuk melindungi dari aktor jahat agar tidak menghentikan server tepercaya, menjalankannya sendiri, dan menerima data masuk dari klien.
Pipa bernama menyediakan dukungan untuk mendapatkan akun tempat server berjalan. Klien dapat memvalidasi server diluncurkan oleh akun yang diharapkan:
internal static bool CheckPipeConnectionOwnership(
NamedPipeClientStream pipeStream, SecurityIdentifier expectedOwner)
{
var remotePipeSecurity = pipeStream.GetAccessControl();
var remoteOwner = remotePipeSecurity.GetOwner(typeof(SecurityIdentifier));
return expectedOwner.Equals(remoteOwner);
}
Opsi lain untuk memvalidasi server adalah mengamankan titik akhirnya dengan HTTPS di dalam ASP.NET Core. Klien dapat mengonfigurasi SocketsHttpHandler
untuk memvalidasi server menggunakan sertifikat yang diharapkan saat koneksi dibuat.
var socketsHttpHandler = new SocketsHttpHandler()
{
SslOptions = new SslOptions()
{
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
if (sslPolicyErrors != SslPolicyErrors.None)
{
return false;
}
// Validate server cert thumbprint matches the expected thumbprint.
}
}
};
Melindungi dari eskalasi hak istimewa pipa bernama
Pipa bernama mendukung fitur yang disebut peniruan identitas. Dengan menggunakan peniruan identitas, server pipa bernama dapat menjalankan kode dengan hak istimewa pengguna klien. Ini adalah fitur yang kuat tetapi dapat memungkinkan server dengan hak istimewa rendah untuk meniru pemanggil hak istimewa tinggi dan kemudian menjalankan kode berbahaya.
Klien dapat melindungi dari serangan ini dengan tidak mengizinkan peniruan saat menyambungkan ke server. Kecuali diperlukan oleh server, TokenImpersonationLevel nilai None
atau Anonymous
harus digunakan saat membuat koneksi klien:
using var pipeClient = new NamedPipeClientStream(
serverName: ".", pipeName: "testpipe", PipeDirection.In, PipeOptions.None, TokenImpersonationLevel.None);
await pipeClient.ConnectAsync();
TokenImpersonationLevel.None
adalah nilai default dalam NamedPipeClientStream
konstruktor yang tidak memiliki impersonationLevel
parameter.
Mengonfigurasi klien dan server
Klien dan server harus dikonfigurasi untuk menggunakan transportasi komunikasi antar-proses (IPC). Untuk informasi selengkapnya tentang mengonfigurasi Kestrel dan SocketsHttpHandler menggunakan IPC:
- Komunikasi antarproses dengan soket domain gRPC dan Unix
- Komunikasi antarproses dengan pipa gRPC dan Named
Catatan
Dukungan bawaan untuk Pipa bernama di ASP.NET Core memerlukan .NET 8 atau yang lebih baru.
Proses yang berjalan pada komputer yang sama dapat dirancang untuk berkomunikasi satu sama lain. Sistem operasi menyediakan teknologi untuk memungkinkan komunikasi antarproses (IPC) yang cepat dan efisien. Contoh populer teknologi IPC adalah soket domain Unix dan pipa Bernama.
.NET menyediakan dukungan untuk komunikasi antarproses menggunakan gRPC.
Catatan
Dukungan bawaan untuk Pipa bernama di ASP.NET Core memerlukan .NET 8 atau yang lebih baru.
Untuk informasi selengkapnya, lihat versi .NET 8 atau yang lebih baru dari topik ini
Memulai
Panggilan gRPC dikirim dari klien ke server. Untuk berkomunikasi antara aplikasi di komputer dengan gRPC, setidaknya satu aplikasi harus menghosting server gRPC ASP.NET Core.
ASP.NET Core dan gRPC dapat dihosting Microsoft.AspNetCore.App
di aplikasi apa pun menggunakan .NET Core 3.1 atau yang lebih baru dengan menambahkan kerangka kerja ke proyek.
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
File proyek sebelumnya:
- Menambahkan referensi kerangka kerja ke
Microsoft.AspNetCore.App
. Referensi kerangka kerja memungkinkan aplikasi non-ASP.NET Core, seperti Windows Services, aplikasi WPF, atau aplikasi WinForms untuk menggunakan ASP.NET Core dan menghosting server ASP.NET Core. - Menambahkan referensi paket NuGet ke
Grpc.AspNetCore
. .proto
Menambahkan file.
Mengonfigurasi soket domain Unix
Panggilan gRPC antara klien dan server pada komputer yang berbeda biasanya dikirim melalui soket TCP. TCP dirancang untuk berkomunikasi di seluruh jaringan. Soket domain Unix (UDS) adalah teknologi IPC yang didukung secara luas yang lebih efisien daripada TCP ketika klien dan server berada di komputer yang sama. .NET menyediakan dukungan bawaan untuk UDS di aplikasi klien dan server.
Persyaratan:
- .NET 5 atau yang lebih baru
- Linux, macOS, atau Windows 10/Windows Server 2019 atau yang lebih baru
Konfigurasi server
Soket domain Unix (UDS) didukung oleh Kestrel, yang dikonfigurasi dalam Program.cs
:
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(options =>
{
if (File.Exists(SocketPath))
{
File.Delete(SocketPath);
}
options.ListenUnixSocket(SocketPath, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});
Contoh sebelumnya:
- KestrelMengonfigurasi titik akhir di
ConfigureKestrel
. - ListenUnixSocket Panggilan untuk mendengarkan UDS dengan jalur yang ditentukan.
- Membuat titik akhir UDS yang tidak dikonfigurasi untuk menggunakan HTTPS. Untuk informasi tentang mengaktifkan HTTPS, lihat Kestrel Konfigurasi titik akhir HTTPS.
Konfigurasi klien
GrpcChannel
mendukung melakukan panggilan gRPC melalui transportasi kustom. Saat saluran dibuat, saluran dapat dikonfigurasi dengan SocketsHttpHandler
yang memiliki kustom ConnectCallback
. Panggilan balik memungkinkan klien untuk membuat koneksi melalui transportasi kustom dan kemudian mengirim permintaan HTTP melalui transportasi tersebut.
Contoh pabrik koneksi soket domain Unix:
public class UnixDomainSocketConnectionFactory
{
private readonly EndPoint _endPoint;
public UnixDomainSocketConnectionFactory(EndPoint endPoint)
{
_endPoint = endPoint;
}
public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
try
{
await socket.ConnectAsync(_endPoint, cancellationToken).ConfigureAwait(false);
return new NetworkStream(socket, true);
}
catch
{
socket.Dispose();
throw;
}
}
}
Menggunakan pabrik koneksi kustom untuk membuat saluran:
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
public static GrpcChannel CreateChannel()
{
var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
var connectionFactory = new UnixDomainSocketConnectionFactory(udsEndPoint);
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectCallback = connectionFactory.ConnectAsync
};
return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
}
Saluran yang dibuat menggunakan kode sebelumnya mengirim panggilan gRPC melalui soket domain Unix. Dukungan untuk teknologi IPC lainnya dapat diimplementasikan menggunakan ekstensibilitas di Kestrel dan SocketsHttpHandler
.
ASP.NET Core