Skip to content
Snippets Groups Projects
Commit 4e5b0ec5 authored by Kamil Trzcinski's avatar Kamil Trzcinski
Browse files

Automatically load TLS certificates stored in /etc/gitlab-runner/certs/<host-name>.crt

- Allow to provide custom tls_ca_file during registration or in config.toml file
- Allow to set tls_skip_verify which will disable certificate verification
parent ad3b86c4
No related branches found
No related tags found
No related merge requests found
...@@ -2,9 +2,19 @@ package commands ...@@ -2,9 +2,19 @@ package commands
import ( import (
"gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common"
"gitlab.com/gitlab-org/gitlab-ci-multi-runner/network"
"os" "os"
"path/filepath"
) )
func getDefaultConfigFile() string {
return filepath.Join(getDefaultConfigDirectory(), "config.toml")
}
func getDefaultCertificateDirectory() string {
return filepath.Join(getDefaultConfigDirectory(), "certs")
}
type configOptions struct { type configOptions struct {
config *common.Config config *common.Config
...@@ -44,4 +54,6 @@ func init() { ...@@ -44,4 +54,6 @@ func init() {
if configFile == "" { if configFile == "" {
os.Setenv("CONFIG_FILE", getDefaultConfigFile()) os.Setenv("CONFIG_FILE", getDefaultConfigFile())
} }
network.CertificateDirectory = getDefaultCertificateDirectory()
} }
...@@ -8,13 +8,13 @@ import ( ...@@ -8,13 +8,13 @@ import (
"path/filepath" "path/filepath"
) )
func getDefaultConfigFile() string { func getDefaultConfigDirectory() string {
if os.Getuid() == 0 { if os.Getuid() == 0 {
return "/etc/gitlab-runner/config.toml" return "/etc/gitlab-runner"
} else if homeDir := helpers.GetHomeDir(); homeDir != "" { } else if homeDir := helpers.GetHomeDir(); homeDir != "" {
return filepath.Join(homeDir, ".gitlab-runner", "config.toml") return filepath.Join(homeDir, ".gitlab-runner")
} else if currentDir := helpers.GetCurrentWorkingDirectory(); currentDir != "" { } else if currentDir := helpers.GetCurrentWorkingDirectory(); currentDir != "" {
return filepath.Join(currentDir, "config.toml") return currentDir
} else { } else {
panic("Cannot get default config file location") panic("Cannot get default config file location")
} }
......
package commands package commands
func getDefaultConfigFile() string { import (
return "config.toml" "gitlab.com/gitlab-org/gitlab-ci-multi-runner/helpers"
)
func getDefaultConfigDirectory() string {
if currentDir := helpers.GetCurrentWorkingDirectory(); currentDir != "" {
return currentDir
} else {
panic("Cannot get default config file location")
}
} }
...@@ -39,8 +39,10 @@ type ParallelsConfig struct { ...@@ -39,8 +39,10 @@ type ParallelsConfig struct {
} }
type RunnerCredentials struct { type RunnerCredentials struct {
URL string `toml:"url" json:"url" short:"u" long:"url" env:"CI_SERVER_URL" required:"true" description:"Runner URL"` URL string `toml:"url" json:"url" short:"u" long:"url" env:"CI_SERVER_URL" required:"true" description:"Runner URL"`
Token string `toml:"token" json:"token" short:"t" long:"token" env:"CI_SERVER_TOKEN" required:"true" description:"Runner token"` Token string `toml:"token" json:"token" short:"t" long:"token" env:"CI_SERVER_TOKEN" required:"true" description:"Runner token"`
TLSSkipVerify bool `toml:"tls-skip-verify" json:"tls-skip-verify" long:"tls-skip-verify" env:"CI_SERVER_TLS_SKIP_VERIFY" description:"Whether to verify the TLS certificate when using HTTPS (INSECURE)"`
TLSCAFile string `toml:"tls-ca-file" json:"tls-ca-file" long:"tls-ca-file" env:"CI_SERVER_TLS_CA_FILE" description:"File containing the certificates to verify the peer when using HTTPS"`
} }
type RunnerConfig struct { type RunnerConfig struct {
......
...@@ -3,12 +3,17 @@ package network ...@@ -3,12 +3,17 @@ package network
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"crypto/x509"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/Sirupsen/logrus"
"gitlab.com/gitlab-org/gitlab-ci-multi-runner/common" "gitlab.com/gitlab-org/gitlab-ci-multi-runner/common"
"io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"os"
"path/filepath"
"strings" "strings"
"time" "time"
) )
...@@ -16,11 +21,17 @@ import ( ...@@ -16,11 +21,17 @@ import (
type client struct { type client struct {
http.Client http.Client
url *url.URL url *url.URL
caFile string
skipVerify bool skipVerify bool
updateTime time.Time updateTime time.Time
} }
func (n *client) ensureTlsConfig() { func (n *client) ensureTlsConfig() {
// certificate got modified
if stat, err := os.Stat(n.caFile); err == nil && n.updateTime.Before(stat.ModTime()) {
n.Transport = nil
}
// create or update transport // create or update transport
if n.Transport == nil { if n.Transport == nil {
n.updateTime = time.Now() n.updateTime = time.Now()
...@@ -35,6 +46,25 @@ func (n *client) createTransport() { ...@@ -35,6 +46,25 @@ func (n *client) createTransport() {
InsecureSkipVerify: n.skipVerify, InsecureSkipVerify: n.skipVerify,
} }
// load TLS certificate
if file := n.caFile; file != "" {
logrus.Debugln("Trying to load", file, "...")
data, err := ioutil.ReadFile(file)
if err == nil {
pool := x509.NewCertPool()
if pool.AppendCertsFromPEM(data) {
tlsConfig.RootCAs = pool
} else {
logrus.Errorln("Failed to parse PEM in", n.caFile)
}
} else {
if !os.IsNotExist(err) {
logrus.Errorln("Failed to load", n.caFile, err)
}
}
}
// create transport // create transport
n.Transport = &http.Transport{ n.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
...@@ -107,7 +137,14 @@ func newClient(config common.RunnerCredentials) (c *client, err error) { ...@@ -107,7 +137,14 @@ func newClient(config common.RunnerCredentials) (c *client, err error) {
} }
c = &client{ c = &client{
url: url, url: url,
skipVerify: config.TLSSkipVerify,
caFile: config.TLSCAFile,
}
if CertificateDirectory != "" && c.caFile == "" {
hostAndPort := strings.Split(url.Host, ":")
c.caFile = filepath.Join(CertificateDirectory, hostAndPort[0]+".crt")
} }
return return
......
package network
var CertificateDirectory string
...@@ -16,13 +16,14 @@ func (n *GitLabClient) getClient(runner RunnerCredentials) (c *client, err error ...@@ -16,13 +16,14 @@ func (n *GitLabClient) getClient(runner RunnerCredentials) (c *client, err error
if n.clients == nil { if n.clients == nil {
n.clients = make(map[string]*client) n.clients = make(map[string]*client)
} }
c = n.clients[runner.URL] key := fmt.Sprintf("%s_%d_%s", runner.URL, runner.TLSSkipVerify, runner.TLSCAFile)
c = n.clients[key]
if c == nil { if c == nil {
c, err = newClient(runner) c, err = newClient(runner)
if err != nil { if err != nil {
return return
} }
n.clients[runner.URL] = c n.clients[key] = c
} }
return return
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment