Files
dshackle/docs/08-authentication.adoc
2023-07-13 14:13:57 +04:00

196 lines
6.0 KiB
Plaintext

== Authentication and encryption
=== Server authentication
Dshackle server supports both server and client certificate authentication, and 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 the traditional `openssl` tool can be used as well.
==== Setup Server certificate
.Generate a Certificate Authority
[source,bash]
----
export SERVER_CA="ca.myhost.dev"
export ORG="My Company"
export ORG_UNIT="Blockchain"
certstrap init --common-name "$SERVER_CA" --passphrase "" -o "$ORG" -ou "$ORG_UNIT CA"
openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$SERVER_CA.key -out out/$SERVER_CA.p8.key -nocrypt
----
.Generate a Server Certificate
----
export SERVER_IP="127.0.0.1"
certstrap request-cert -ip $SERVER_IP --common-name $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
----
You are going to get following files now in `out` directory:
- `ca.myhost.dev.crt` your Certification Authority to sign or verify other certificates
- `ca.myhost.dev.p8.key` is the private key for Certification Authority in PKSC 8 format
- `127.0.0.1.crt` server certificate, 127.0.0.1 is an IP address supposed to be used by that instance, and we use local host for demo purposes.
For production use a real IP must be used.
- `127.0.0.1.p8.key` is private key for certificate in PKCS 8 format, it needed by Dshackle server to use certificate
Copy those files to directory with Dshackle and update configuration.
.Update dshackle.yaml to have:
[source,yaml]
----
version: v1
port: 2449
tls:
enabled: true
server:
certificate: 127.0.0.1.crt
key: 127.0.0.1.p8.key
----
.Verify that server uses the certificate
[source,bash]
----
openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt
----
With the configuration above, the server listens using TLS, and the server identity can be verified by a client against a public
server certificate. Please note that a server certificate doesn't prevent a connection from an unauthorized client; it only
verifies the server and encrypts a connection.
==== Use Client Certificate Authentication
To have authentication in both ways, you'll need to configure client side certificates as well, in that case the server
also verifies each incoming connection and allow to connect only by a client with a trusted certificate.
It's possible to connect a Dshackle server to another one, and to do so you'll probably want to use TLS as well.
.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
openssl pkcs8 -topk8 -inform PEM -outform PEM -in out/$CLIENT_ID.key -out out/$CLIENT_ID.p8.key -nocrypt
----
In addition to files mentioned above you got few new files in `out` directory, including:
- `client-ca.myhost.dev.crt` a certificate to validate connecting clients, all their keys much be signed by that
certificate.Server don't need a private key for that certificate because it's used for verification only.
- `client_1.crt` certificate for a client that will connect to the server
- `client_1.p8.key` private key for that certificate, needed by client
Copy `client-ca.myhost.dev.crt` to directory with first Dshackle server.
.Update server dshackle.yaml to have:
[source,yaml]
----
version: v1
port: 2449
tls:
enabled: true
server:
certificate: 127.0.0.1.crt
key: 127.0.0.1.p8.key
client:
require: true
ca: client-ca.myhost.dev.crt
----
.Verify connection with client certificate
[source,bash]
----
openssl s_client -alpn h2 -connect 127.0.0.1:2449 -CAfile out/ca.myhost.dev.crt -cert out/client_1.crt -key out/client_1.key
----
Now you need to setup connection from another Dshackle server. I.e. the server we configured above is going be an
upstream to another Dshackle server, which we configure below.
Setup another Dshackle server on the same machine:
.Configure dshackle.yaml for second server
[source,yaml]
----
version: v1
port: 3449
tls:
enabled: false
----
At this case we run another server on port 3449 in unsecure mode.But to connect to an upstream is still uses a TLS
certificate as described below
[source,yaml]
----
version: v1
cluster:
upstreams:
- id: ds
chain: auto
provider: dshackle
connection:
grpc:
host: 127.0.0.1
port: 2449
tls:
ca: ca.myhost.dev.crt
certificate: client_1.crt
key: client_1.p8.key
----
Now if you run second server it will connect to first server ("upstream") running on port 2449, will verify upstream with certificate `ca.myhost.dev.crt` and authenticate itself by using pair of `client_1.crt` and `client_1.p8.key`
=== Server TLS configuration
|===
| Name | Example | Description
a| `enabled`
a|
[source,yaml]
----
tls:
enabled: true
----
| Enabled or disable TLS. By default it checks if certificate is set, and then enables it. But if you enable the TLS
but didn't specify the certificate or key, then the DShackle will fails to start with error.
a| `server.certificate`, `server.key`
a|
[source,yaml]
----
tls:
server:
certificate: server.com.crt
key: server.com.p8.key
----
| Path to certificate and certificate private key
a| `client.ca`, `client.cas`, `client.required`
a|
[source,yaml]
----
tls:
client:
cas:
- ca1.crt
- ca2.crt
required: true
----
a| Paths to CA used to authenticate incoming connections, used if `required: true`
|===