TLS and go client


(vladimir) #1

I have some problem with TLS. Maybe I’m somewhere wrong.
For TLS I use this steps:

openssl genrsa -out dgraph-private.key -aes256
openssl req -x509 -new -extensions v3_ca -key dgraph-private.key -days 36500 -out dgraph-CA-cert.crt
openssl req -new -nodes -newkey rsa:2048 -keyout server1.key -out server1.csr
openssl x509 -CA dgraph-CA-cert.crt -CAkey dgraph-private.key -CAcreateserial -req -days 36500 -in server1.csr -out server1.crt
cat server1.key server1.crt > server1.pem    //Maybe not needed

Then I start zero and server
dgraph zero --my=localhost:5080 -w zeroCluster --bindall &

dgraph server --my=localhost:7080 --lru_mb=1024 --zero=localhost:5080 -o 0 -p server0/p -w server0/w --bindall --tls_on --tls_ca_certs dgraph-CA-cert.crt --tls_cert server1.crt --tls_cert_key server1.key --tls_cert_key_passphrase somePass–tls_use_system_ca &

In my golang app I use:

package main

import (
	"google.golang.org/grpc"
	"log"
	"context"
	"github.com/dgraph-io/dgo/protos/api"
	"github.com/dgraph-io/dgo"
	"fmt"
	"flag"
	"google.golang.org/grpc/credentials"
	"github.com/dgraph-io/dgraph/x"
)

var (
	// TLS configuration
	tlsEnabled       = flag.Bool("tls.on", true, "Use TLS connections.")
	tlsInsecure      = flag.Bool("tls.insecure", false, "Skip certificate validation (insecure)")
	tlsServerName    = flag.String("tls.server_name", "", "Server name.")
	tlsCert          = flag.String("tls.cert", "server1.crt", "Certificate file path.")
	tlsKey           = flag.String("tls.cert_key", "server1.key", "Certificate key file path.")
	tlsKeyPass       = flag.String("tls.cert_key_passphrase", "somePass", "Certificate key passphrase.")
	tlsRootCACerts   = flag.String("tls.ca_certs", "dgraph-CA-cert.crt", "CA Certs file path.")
	tlsSystemCACerts = flag.Bool("tls.use_system_ca", false, "Include System CA into CA Certs.")
	tlsMinVersion    = flag.String("tls.min_version", "TLS11", "TLS min version.")
	tlsMaxVersion = flag.String("tls.max_version", "TLS12", "TLS max version.")
)

func setupConnection(host string) (*grpc.ClientConn, error) {
	if !*tlsEnabled {
		return grpc.Dial(host, grpc.WithInsecure())
	}

	tlsCfg, _, err := x.GenerateTLSConfig(x.TLSHelperConfig{
		ConfigType:           x.TLSClientConfig,
		Insecure:             *tlsInsecure,
		ServerName:           *tlsServerName,
		Cert:                 *tlsCert,
		Key:                  *tlsKey,
		KeyPassphrase:        *tlsKeyPass,
		RootCACerts:          *tlsRootCACerts,
		UseSystemRootCACerts: *tlsSystemCACerts,
		MinVersion:           *tlsMinVersion,
		MaxVersion:           *tlsMaxVersion,
	})
	if err != nil {
		return nil, err
	}

	return grpc.Dial(host, grpc.WithTransportCredentials(credentials.NewTLS(tlsCfg)))
}

func main() {
	conn, err := setupConnection("37.0.0.164:9080")
	//conn, err := grpc.Dial("37.0.0.164:9080", grpc.WithInsecure())
	if err != nil {
		log.Fatal("While trying to dial gRPC")
	}
	defer conn.Close()

	dc := api.NewDgraphClient(conn)
	dg := dgo.NewDgraphClient(dc)

	ctx := context.Background()


	q := `
		schema{}
`

	resp, err := dg.NewTxn().Query(ctx, q)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Response: %s\n", resp.Json)

}

Can you explain and give examples for these parameters:
tlsServerName = flag.String(“tls.server_name”, “”, “Server name.”)
tlsSystemCACerts = flag.Bool(“tls.use_system_ca”, false, “Include System CA into CA Certs.”)

What’s my mistake?


(vladimir) #2

TLS step by step.
It’s working for me. Commands is bold.

  • Generate CA key & certificate

openssl genrsa -out MyRootCA.key 2048

Out: MyRootCA.key

openssl req -x509 -new -nodes -key MyRootCA.key -sha256 -days 1024 -out MyRootCA.pem

Country Name (2 letter code) [AU]: RU
State or Province Name (full name) [Some-State]: MoscowRegion
Locality Name (eg, city) []: Moscow
Organization Name (eg, company) [Internet Widgits Pty Ltd]: SomeSystems
Organizational Unit Name (eg, section) []: Statistics
Common Name (e.g. server FQDN or YOUR name) []: CaServer
Email Address []: my@protonmail.com

Out: MyRootCA.pem
  • Generate server key & certificate signing request

openssl genrsa -out MyServer.key 2048

Out: MyServer.key

openssl req -new -key MyServer.key -out MyServer.csr

Country Name (2 letter code) [AU]: RU
State or Province Name (full name) [Some-State]: MoscowRegion
Locality Name (eg, city) []: Moscow
Organization Name (eg, company) [Internet Widgits Pty Ltd]: SomeSystems
Organizational Unit Name (eg, section) []: Statistics
Common Name (e.g. server FQDN or YOUR name) []: CaServer
Email Address []: my@protonmail.com

A challenge password []:YasFkqvWsHEPHimW
An optional company name []:

Out: MyServer.csr
  • Generate server certificate based on our own CA certificate

openssl x509 -req -in MyServer.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAcreateserial -out MyServer.pem -days 1024 -sha256

Out: MyServer.pem
  • Generate client key & certificate signing request

openssl genrsa -out MyClient.key 2048

Out: MyClient.key

openssl req -new -key MyClient.key -out MyClient.csr

Country Name (2 letter code) [AU]: RU
State or Province Name (full name) [Some-State]: MoscowRegion
Locality Name (eg, city) []: Moscow
Organization Name (eg, company) [Internet Widgits Pty Ltd]: SomeSystems
Organizational Unit Name (eg, section) []: StatisticsClient
Common Name (e.g. server FQDN or YOUR name) []: rsroot
Email Address []: my@protonmail.com

A challenge password []:Y1kHbLGkdwsu2py8M
An optional company name []:

Out: MyClient.csr
  • Generate client certificate based on our own CA certificate

openssl x509 -req -in MyClient.csr -CA MyRootCA.pem -CAkey MyRootCA.key -CAcreateserial -out MyClient.pem -days 1024 -sha256

Out: MyClient.pem

You can put files thru scp per host:
scp -P 22 MyRootCA.pem MyServer.key MyServer.pem user@77.77.77.235:~/

1 zero and server on host 2gb RAM:

dgraph zero --my=77.77.77.235:5080 -w zeroCluster --bindall | tee -a Zero_Cluster_output.txt &

dgraph server --my=77.77.77.235:7080 --lru_mb=1024 --zero=localhost:5080 -o 0 -p server0/p -w server0/w --tls_on --tls_ca_certs MyRootCA.pem --tls_cert MyServer.pem --tls_cert_key MyServer.key --tls_client_auth=REQUIREANDVERIFY | tee -a dgraph_server_output.txt &

3 zero, 3 replicas, 3 hosts.
Attention:
You can input your IP in zero and server.
You must start all 3 dgraph zero, and after 3 dgraph servers.

Zero

  1. ssh -p 22 user1@77.77.77.235
    dgraph zero --my=77.77.77.235:5080 --replicas 3 -w zeroCluster --idx=1 --bindall | tee -a Zero_Cluster_output.txt &

  2. ssh -p 22 user2@77.77.77.47
    dgraph zero --my=77.77.77.47:5081 --replicas 3 -w zeroCluster1 -o 1 --idx=2 --bindall --peer=77.77.77.235:5080 | tee -a Zero_Cluster_output.txt &

  3. ssh -p 22 user3@77.77.77.177
    dgraph zero --my=77.77.77.177:5082 --replicas 3 -w zeroCluster2 -o 2 --bindall --idx=3 --peer=77.77.77.235:5080 | tee -a Zero_Cluster_output.txt &

Replicas:

  1. ssh -p 22 user1@77.77.77.235
    dgraph server --my=77.77.77.235:7080 --lru_mb=1024 --zero=77.77.77.235:5080 -o 0 -p server0/p -w server0/w --tls_on --tls_ca_certs MyRootCA.pem --tls_cert MyServer.pem --tls_cert_key MyServer.key --tls_client_auth=REQUIREANDVERIFY | tee -a dgraph_server_output.txt &

  2. ssh -p 22 user2@77.77.77.47
    dgraph server --my=77.77.77.47:7080 --lru_mb=1024 --zero=77.77.77.47:5081 -o 0 -p server0/p -w server0/w --tls_on --tls_ca_certs MyRootCA.pem --tls_cert MyServer.pem --tls_cert_key MyServer.key --tls_client_auth=REQUIREANDVERIFY | tee -a dgraph_server_output.txt &

  3. ssh -p 22 user3@77.77.77.177
    dgraph server --my=77.77.77.177:7080 --lru_mb=1024 --zero=77.77.77.177:5082 -o 0 -p server0/p -w server0/w --tls_on --tls_ca_certs MyRootCA.pem --tls_cert MyServer.pem --tls_cert_key MyServer.key --tls_client_auth=REQUIREANDVERIFY | tee -a dgraph_server_output.txt &

In golang app:

package main

import (
	"google.golang.org/grpc"
	"log"
	"context"
	"github.com/dgraph-io/dgo/protos/api"
	"github.com/dgraph-io/dgo"
	"fmt"
	"flag"
	"google.golang.org/grpc/credentials"
	"github.com/dgraph-io/dgraph/x"
)

var (
	// TLS configuration
	tlsEnabled       = flag.Bool("tls.on", true, "Use TLS connections.")
	tlsInsecure      = flag.Bool("tls.insecure", false, "Skip certificate validation (insecure)")
	tlsServerName    = flag.String("tls.server_name", "CaServer", "Server name.")
	tlsCert          = flag.String("tls.cert", "MyClient.pem", "Certificate file path.")
	tlsKey           = flag.String("tls.cert_key", "MyClient.key", "Certificate key file path.")
	tlsKeyPass       = flag.String("tls.cert_key_passphrase", "Y1kHbLGkdwsu2py8M", "Certificate key passphrase.")
	tlsRootCACerts   = flag.String("tls.ca_certs", "MyRootCA.pem", "CA Certs file path.")
	tlsSystemCACerts = flag.Bool("tls.use_system_ca", false, "Include System CA into CA Certs.")
	tlsMinVersion    = flag.String("tls.min_version", "TLS11", "TLS min version.")
	tlsMaxVersion = flag.String("tls.max_version", "TLS12", "TLS max version.")
)

func setupConnection(host string) (*grpc.ClientConn, error) {
	if !*tlsEnabled {
		return grpc.Dial(host, grpc.WithInsecure())
	}

	tlsCfg, _, err := x.GenerateTLSConfig(x.TLSHelperConfig{
		ConfigType:           x.TLSClientConfig,
		Insecure:             *tlsInsecure,
		ServerName:           *tlsServerName,
		Cert:                 *tlsCert,
		Key:                  *tlsKey,
		KeyPassphrase:        *tlsKeyPass,
		RootCACerts:          *tlsRootCACerts,
		UseSystemRootCACerts: *tlsSystemCACerts,
		MinVersion:           *tlsMinVersion,
		MaxVersion:           *tlsMaxVersion,
	})
	if err != nil {
		return nil, err
	}

	return grpc.Dial(host, grpc.WithTransportCredentials(credentials.NewTLS(tlsCfg)))
}

func main() {
	conn, err := setupConnection("77.77.77.235:9080") //77.77.77.47:9080 or 77.77.77.177:9080
	
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	dc := api.NewDgraphClient(conn)
	dg := dgo.NewDgraphClient(dc)

	ctx := context.Background()


	q := `
		schema{}
`

	resp, err := dg.NewTxn().Query(ctx, q)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Response: %s\n", resp.Json)

}

(vladimir) #3

The best way to use TLS.
OpenSSL Certificate Authority.
https://jamielinux.com/docs/openssl-certificate-authority/