== Authentication and encryption

=== Server authentication

Dshackle server supports both server and client certificate authentication, it's strongly recommended to use TLS to
connect to Dshackle server. More to that, the server uses gRPC which is based on HTTP/2, and most of 3rd party tools and
libraries expect it to be encrypted.

Please note that for most of use cases for Dshackle, which is designed to be an internal load balancer, a self-signed
certificates would be enough. In the example below a https://github.com/square/certstrap[certstrap] tool is used to
generate certificates, but traditional `openssl` tool can be used as well.

==== Setup Server certificate

.Generate a server certificate
[source,bash]
----
SERVER_CA="ca.myhost.dev"
SERVER_IP="127.0.0.1"
ORG="My Company"
ORG_UNIT="Blockchain"

certstrap init --common-name "$SERVER_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA"
certstrap request-cert -ip $SERVER_IP --passphrase ""  -o "$ORG" -ou "$ORG_UNIT Server"
certstrap sign $SERVER_IP --CA $SERVER_CA

openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_IP.key -out out/$SERVER_IP.p8.key -nocrypt
----

.Update dshackle.yaml to have:
[source,yaml]
----
version: v1
port: 9001
tls:
  enabled: true
  server:
    certificate: out/127.0.0.1.crt
    key: out/127.0.0.1.p8.key
----

.Verify that server uses the certificate
[source,bash]
----
openssl s_client -alpn h2 -connect 127.0.0.1:9001 -CAfile out/ca.myhost.dev.crt
----

With the configuration above the server listen using TLS and the server identity can be verified by a client against public
server certificate. Please note that a server certificate doesn't prevent from connection by an unauthorized client, it only
verifies the server and encrypts a connection.

==== Setup Client certificate

To have authentication in both ways you'll need to configure client side certificates as well, at that case the server
will also verify each incoming connection and allow to connect only by a client with a trusted certificate.

.Generate a client certificate
[source,bash]
----
CLIENT_CA="client-ca.myhost.dev"
CLIENT_ID="client_1"
ORG="My Company"
ORG_UNIT="Client"

certstrap init --common-name "$CLIENT_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA"
certstrap request-cert --common-name "$CLIENT_ID" --passphrase ""
certstrap sign "$CLIENT_ID" --CA $CLIENT_CA
----

.Update dshackle.yaml to have:
[source,yaml]
----
version: v1
port: 9001
tls:
  enabled: true
  server:
    certificate: out/127.0.0.1.crt
    key: out/127.0.0.1.p8.key
  client:
    require: true
    ca: out/client-ca.myhost.dev.crt
----

.Verify connection with client certificate
[source,bash]
----
openssl s_client -alpn h2 -connect 127.0.0.1:9001 -CAfile out/ca.myhost.dev.crt -cert out/client_1.crt -key out/client_1.key
----
