Skip to content

Commit

Permalink
Support of SSL protocol
Browse files Browse the repository at this point in the history
The patch adds support for using SSL to encrypt the client-server
communications [1]. It uses a wrapper around the OpenSSL library for
full compatibility with Tarantool Enterprise (GOST cryptographic
algorithms [2] are not supported by Golang's crypto/tls). The feature
can be disabled using a build tag [3] 'go_tarantool_ssl_disable'.

1. https://www.tarantool.io/en/enterprise_doc/security/#enterprise-iproto-encryption
2. https://github.com/gost-engine/engine
3. https://pkg.go.dev/go/build#hdr-Build_Constraints

Closes #155
  • Loading branch information
oleg-jukovec committed Jun 2, 2022
1 parent 0322d14 commit 851079c
Show file tree
Hide file tree
Showing 19 changed files with 950 additions and 11 deletions.
64 changes: 60 additions & 4 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_dispatch:

jobs:
linux:
run-tests-ce:
# We want to run on external PRs, but not on our own internal
# PRs as they'll be run by the push to the branch.
#
Expand All @@ -26,9 +26,6 @@ jobs:
- '2.9'
- '2.x-latest'
coveralls: [false]
include:
- tarantool: '2.x-latest'
coveralls: true

steps:
- name: Clone the connector
Expand Down Expand Up @@ -66,3 +63,62 @@ jobs:
- name: Check workability of benchmark tests
run: make bench-deps bench DURATION=1x COUNT=1

run-tests-ee:
if: github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository

runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
sdk-version:
- '1.10.11-0-gf0b0e7ecf-r470'
- '2.8.3-21-g7d35cd2be-r470'
coveralls: [false]
ssl: [false]
include:
- sdk-version: '2.10.0-1-gfa775b383-r486-linux-x86_64'
coveralls: true
ssl: true

steps:
- name: Clone the connector
uses: actions/checkout@v2

- name: Setup Tarantool ${{ matrix.sdk-version }}
run: |
ARCHIVE_NAME=tarantool-enterprise-bundle-${{ matrix.sdk-version }}.tar.gz
curl -O -L https://${{ secrets.SDK_DOWNLOAD_TOKEN }}@download.tarantool.io/enterprise/${ARCHIVE_NAME}
tar -xzf ${ARCHIVE_NAME}
rm -f ${ARCHIVE_NAME}
- name: Setup golang for the connector and tests
uses: actions/setup-go@v2
with:
go-version: 1.13

- name: Install test dependencies
run: |
source tarantool-enterprise/env.sh
make deps
- name: Run tests
run: |
source tarantool-enterprise/env.sh
make test
env:
TEST_TNT_SSL: ${{matrix.ssl}}

- name: Run tests, collect code coverage data and send to Coveralls
if: ${{ matrix.coveralls }}
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEST_TNT_SSL: ${{matrix.ssl}}
run: |
source tarantool-enterprise/env.sh
make coveralls
- name: Check workability of benchmark tests
run: make bench-deps bench DURATION=1x COUNT=1
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.

### Added

- SSL support (#155)

### Changed

### Fixed
Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ make test
The tests set up all required `tarantool` processes before run and clean up
afterwards.

If you have Tarantool Enterprise Edition 2.10 or newer, you can run additional
SSL tests. To do this, you need to set an environment variable 'TEST_TNT_SSL':

```bash
TEST_TNT_SSL=true make test
```

If you want to run the tests for a specific package:
```bash
make test-<SUBDIR>
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ golangci-lint:
test:
go test ./... -v -p 1

.PHONY: testdata
testdata:
(cd ./testdata; ./generate.sh)

.PHONY: test-connection-pool
test-connection-pool:
@echo "Running tests in connection_pool package"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ faster than other packages according to public benchmarks.
## Table of contents

* [Installation](#installation)
* [Build tags](#build-tags)
* [Documentation](#documentation)
* [API reference](#api-reference)
* [Walking\-through example](#walking-through-example)
Expand Down Expand Up @@ -51,6 +52,13 @@ This should put the source and binary files in subdirectories of
`github.com/tarantool/go-tarantool` to the `import {...}` section at the start
of any Go program.

### Build tags

To disable SSL support and linking with OpenSSL, you can use the tag:
```
go_tarantool_ssl_disable
```

## Documentation

Read the [Tarantool documentation][tarantool-doc-data-model-url]
Expand Down
49 changes: 44 additions & 5 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ const (
connClosed = 2
)

const (
connTransportNone = ""
connTransportSsl = "ssl"
)

type ConnEventKind int
type ConnLogKind int

Expand Down Expand Up @@ -207,6 +212,32 @@ type Opts struct {
Handle interface{}
// Logger is user specified logger used for error messages.
Logger Logger
// Transport is the connection type, by default the connection is unencrypted.
Transport string
// SslOpts is used only if the Transport == 'ssl' is set.
Ssl SslOpts
}

// SslOpts is a way to configure ssl transport.
type SslOpts struct {
// KeyFile is a path to a private SSL key file.
KeyFile string
// CertFile is a path to an SSL sertificate file.
CertFile string
// CaFile is a path to a trusted certificate authorities (CA) file.
CaFile string
// Ciphers is a colon-separated (:) list of SSL cipher suites the connection
// can use.
//
// We don't provide a list of supported ciphers. This is what OpenSSL
// does. The only limitation is usage of TLSv1.2 (because other protocol
// versions don't seem to support the GOST cipher). To add additional
// ciphers (GOST cipher), you must configure OpenSSL.
//
// See also
//
// * https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
Ciphers string
}

// Connect creates and configures a new Connection.
Expand Down Expand Up @@ -358,8 +389,10 @@ func (conn *Connection) Handle() interface{} {
func (conn *Connection) dial() (err error) {
var connection net.Conn
network := "tcp"
opts := conn.opts
address := conn.addr
timeout := conn.opts.Reconnect / 2
timeout := opts.Reconnect / 2
transport := opts.Transport
if timeout == 0 {
timeout = 500 * time.Millisecond
} else if timeout > 5*time.Second {
Expand All @@ -383,11 +416,17 @@ func (conn *Connection) dial() (err error) {
} else if addrLen >= 4 && address[0:4] == "tcp:" {
address = address[4:]
}
connection, err = net.DialTimeout(network, address, timeout)
if transport == connTransportNone {
connection, err = net.DialTimeout(network, address, timeout)
} else if transport == connTransportSsl {
connection, err = sslDialTimeout(network, address, timeout, opts.Ssl)
} else {
err = errors.New("An unsupported transport type: " + transport)
}
if err != nil {
return
}
dc := &DeadlineIO{to: conn.opts.Timeout, c: connection}
dc := &DeadlineIO{to: opts.Timeout, c: connection}
r := bufio.NewReaderSize(dc, 128*1024)
w := bufio.NewWriterSize(dc, 128*1024)
greeting := make([]byte, 128)
Expand All @@ -400,8 +439,8 @@ func (conn *Connection) dial() (err error) {
conn.Greeting.auth = bytes.NewBuffer(greeting[64:108]).String()

// Auth
if conn.opts.User != "" {
scr, err := scramble(conn.Greeting.auth, conn.opts.Pass)
if opts.User != "" {
scr, err := scramble(conn.Greeting.auth, opts.Pass)
if err != nil {
err = errors.New("auth: scrambling failure " + err.Error())
connection.Close()
Expand Down
20 changes: 19 additions & 1 deletion example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,29 @@ type Tuple struct {
func example_connect() *tarantool.Connection {
conn, err := tarantool.Connect(server, opts)
if err != nil {
panic("Connection is not established")
panic("Connection is not established: " + err.Error())
}
return conn
}

// Example demonstrates how to use SSL transport.
func ExampleSslOpts() {
var opts = tarantool.Opts{
User: "test",
Pass: "test",
Transport: "ssl",
Ssl: tarantool.SslOpts{
KeyFile: "testdata/localhost.key",
CertFile: "testdata/localhost.crt",
CaFile: "testdata/ca.crt",
},
}
_, err := tarantool.Connect("127.0.0.1:3013", opts)
if err != nil {
panic("Connection is not established: " + err.Error())
}
}

func ExampleConnection_Select() {
conn := example_connect()
defer conn.Close()
Expand Down
14 changes: 14 additions & 0 deletions export_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package tarantool

import (
"net"
"time"
)

func (schema *Schema) ResolveSpaceIndex(s interface{}, i interface{}) (spaceNo, indexNo uint32, err error) {
return schema.resolveSpaceIndex(s, i)
}

func SslDialTimeout(network, address string, timeout time.Duration,
opts SslOpts) (connection net.Conn, err error) {
return sslDialTimeout(network, address, timeout, opts)
}

func SslCreateContext(opts SslOpts) (ctx interface{}, err error) {
return sslCreateContext(opts)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/google/uuid v1.3.0
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/stretchr/testify v1.7.1 // indirect
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/vmihailenco/msgpack.v2 v2.9.2
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,25 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87 h1:JGzuBxNBq5saVtPUcuu5Y4+kbJON6H02//OT+RNqGts=
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87/go.mod h1:M7H4xYSbzqpW/ZRBMyH0eyqQBsnhAMfsYk5mv0yid7A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
Loading

0 comments on commit 851079c

Please sign in to comment.