196 lines
6.0 KiB
Plaintext
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`
|
|
|
|
|=== |