1
0
Fork 0

Merge pull request #1422 from rqlite/cli-mtls

Add mTLS support to rqlite CLI
master
Philip O'Toole 10 months ago committed by GitHub
commit 60faad15e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,6 +15,7 @@ When officially released 8.0 will support (mostly) seamless upgrades from the 7.
- [PR #1362](https://github.com/rqlite/rqlite/pull/1362): Enable SQLite [FTS5](https://www.sqlite.org/fts5.html). Fixes [issue #1361](https://github.com/rqlite/rqlite/issues/1361)
- [PR #1405](https://github.com/rqlite/rqlite/pull/1405): Support a configurable HTTP connection timeout in the rqlite CLI. Thanks @jtarchie
- [PR #1418](https://github.com/rqlite/rqlite/pull/1418): Add basic CORS support. Fixes [issue #687](https://github.com/rqlite/rqlite/issues/687). Thanks @kkoreilly
- [PR #1422](https://github.com/rqlite/rqlite/pull/1422): Add mTLS support to rqlite CLI. Fixes [issue #1421](https://github.com/rqlite/rqlite/issues/1421)
### Implementation changes and bug fixes
- [PR #1368](https://github.com/rqlite/rqlite/pull/1374): Switch to always-on expvar and pprof.

@ -3,12 +3,10 @@ package main
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
@ -22,6 +20,7 @@ import (
"github.com/rqlite/rqlite/cmd"
"github.com/rqlite/rqlite/cmd/rqlite/history"
httpcl "github.com/rqlite/rqlite/cmd/rqlite/http"
"github.com/rqlite/rqlite/rtls"
)
const maxRedirect = 21
@ -42,6 +41,8 @@ type argT struct {
Prefix string `cli:"P,prefix" usage:"rqlited HTTP URL prefix" dft:"/"`
Insecure bool `cli:"i,insecure" usage:"do not verify rqlited HTTPS certificate" dft:"false"`
CACert string `cli:"c,ca-cert" usage:"path to trusted X.509 root CA certificate"`
ClientCert string `cli:"d,client-cert" usage:"path to client X.509 certificate for mTLS"`
ClientKey string `cli:"k,client-key" usage:"path to client X.509 key for mTLS"`
Credentials string `cli:"u,user" usage:"set basic auth credentials in form username:password"`
Version bool `cli:"v,version" usage:"display CLI version"`
HTTPTimeout clix.Duration `cli:"t,http-timeout" usage:"set timeout on HTTP requests" dft:"30s"`
@ -365,7 +366,7 @@ func getNodes(client *http.Client, argv *argT) (Nodes, error) {
return nil, err
}
response, err := ioutil.ReadAll(resp.Body)
response, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
@ -380,25 +381,15 @@ func getNodes(client *http.Client, argv *argT) (Nodes, error) {
}
func getHTTPClient(argv *argT) (*http.Client, error) {
var rootCAs *x509.CertPool
if argv.CACert != "" {
pemCerts, err := ioutil.ReadFile(argv.CACert)
if err != nil {
return nil, err
}
rootCAs = x509.NewCertPool()
ok := rootCAs.AppendCertsFromPEM(pemCerts)
if !ok {
return nil, fmt.Errorf("failed to parse root CA certificate(s)")
}
tlsConfig, err := rtls.CreateClientConfig(argv.ClientCert, argv.ClientKey, argv.CACert, argv.Insecure)
if err != nil {
return nil, err
}
tlsConfig.NextProtos = nil // CLI refuses to connect otherwise.
client := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: argv.Insecure, RootCAs: rootCAs},
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
},
Timeout: argv.HTTPTimeout.Duration,
@ -446,24 +437,13 @@ func getVersionWithClient(client *http.Client, argv *argT) (string, error) {
func sendRequest(ctx *cli.Context, makeNewRequest func(string) (*http.Request, error), urlStr string, argv *argT) (*[]byte, error) {
url := urlStr
var rootCAs *x509.CertPool
if argv.CACert != "" {
pemCerts, err := ioutil.ReadFile(argv.CACert)
if err != nil {
return nil, err
}
rootCAs = x509.NewCertPool()
ok := rootCAs.AppendCertsFromPEM(pemCerts)
if !ok {
return nil, fmt.Errorf("failed to parse root CA certificate(s)")
}
tlsConfig, err := rtls.CreateClientConfig(argv.ClientCert, argv.ClientKey, argv.CACert, argv.Insecure)
if err != nil {
return nil, err
}
tlsConfig.NextProtos = nil // CLI refuses to connect otherwise.
client := http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: argv.Insecure, RootCAs: rootCAs},
TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment,
}}
@ -491,7 +471,7 @@ func sendRequest(ctx *cli.Context, makeNewRequest func(string) (*http.Request, e
if err != nil {
return nil, err
}
response, err := ioutil.ReadAll(resp.Body)
response, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
@ -577,7 +557,7 @@ func cliJSON(ctx *cli.Context, cmd, line, url string, argv *argT) error {
return fmt.Errorf("unauthorized")
}
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
@ -634,7 +614,7 @@ func urlsToWriter(client *http.Client, urls []string, w io.Writer, argv *argT) e
return nil
}
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

@ -389,7 +389,7 @@ func (s *Service) Start() error {
if s.ClientVerify {
b.WriteString(", mutual TLS enabled")
} else {
b.WriteString(", mutual disabled")
b.WriteString(", mutual TLS disabled")
}
// print the message
s.logger.Println(b.String())

Loading…
Cancel
Save