New to gRPC and couldn\'t really find any example on how to enable SSL on the server side. I generated a key pair using openssl but it complains that the private key is inv
If usage of Certificate Authority (CA) and Certificate Signing Request (CSR) is too sophisticated for your task, you can use self-signed certificates.
Let say, there is 1 server and 2 (or more) clients.
Execute at client1:
openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client1' # generate client1 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server - if necessary only
scp client.crt server-user@my.server:/path/to/certs/client1.crt # copy public cert client1 to server machine
Execute at client2:
openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client2' # generate client2 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server- if necessary only
scp client.crt server-user@my.server:/path/to/certs/client2.crt # copy public cert client2 to server machine
Execute at server:
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 3650 -subj '/CN=my.server' # generate server cert and key
scp server.crt client1-user@client1-addr:/path/to/certs # copy public cert server to client1 machine
scp server.crt client2-user@client2-addr:/path/to/certs # copy public cert server to client2 machine
cat client1.crt client2.crt > client.crt # combine client certs into the single file
Server code:
var clientCert = File.ReadAllText(Path.Combine(certPath, "client.crt"));
var serverCert = File.ReadAllText(Path.Combine(certPath, "server.crt"));
var serverKey = File.ReadAllText(Path.Combine(certPath, "server.key"));
var keyPair = new KeyCertificatePair(serverCert, serverKey);
var credentials = new SslServerCredentials(new List { keyPair }, clientCert, true);
var server = new Server
{
Services = { MyService.BindService(new MyAdminService()) },
Ports = { new ServerPort("0.0.0.0", 54321, credentials) }
};
Client code:
var serverCert = File.ReadAllText(Path.Combine(_certPath, "server.crt"));
var clientCert = File.ReadAllText(Path.Combine(_certPath, "client.crt"));
var clientKey = File.ReadAllText(Path.Combine(_certPath, "client.key"));
var credentials = new SslCredentials(serverCert, new KeyCertificatePair(clientCert, clientKey));
var channel = new Channel("my.server:54321", credentials);
var client = new MyService.MyServiceClient(channel);
IMPORTANT!
To use TLS certificates, use a domain name when generate server certificate.
Client certificates can use any unique string.
Domain name should contain at least 1 dot (.), e.g. my.server or my.server.customzone
If use top-level domain like my-server, it causes a long waiting to resolve it (for me it always about 76 seconds).
Pros: - no need to generate CSR, pass it to machine with CA, sign it there and copy back to originating machine
Cons: - adding new client requires adding certificate to server