resolver: support self signed certificates

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
v0.7
Tonis Tiigi 2020-03-09 09:00:04 -07:00
parent 430c5256d5
commit 56f76a5621
6 changed files with 151 additions and 55 deletions

31
cmd/buildkitd/config.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"io"
"os"
"github.com/BurntSushi/toml"
"github.com/moby/buildkit/cmd/buildkitd/config"
"github.com/pkg/errors"
)
func Load(r io.Reader) (config.Config, *toml.MetaData, error) {
var c config.Config
md, err := toml.DecodeReader(r, &c)
if err != nil {
return c, nil, errors.Wrap(err, "failed to parse config")
}
return c, &md, nil
}
func LoadFile(fp string) (config.Config, *toml.MetaData, error) {
f, err := os.Open(fp)
if err != nil {
if os.IsNotExist(err) {
return config.Config{}, nil, nil
}
return config.Config{}, nil, errors.Wrapf(err, "failed to load config from %s", fp)
}
defer f.Close()
return Load(f)
}

View File

@ -1,13 +1,5 @@
package config
import (
"io"
"os"
"github.com/BurntSushi/toml"
"github.com/pkg/errors"
)
// Config provides containerd configuration data for the server
type Config struct {
Debug bool `toml:"debug"`
@ -42,9 +34,17 @@ type GRPCConfig struct {
}
type RegistryConfig struct {
Mirrors []string `toml:"mirrors"`
PlainHTTP *bool `toml:"http"`
Insecure *bool `toml:"insecure"`
Mirrors []string `toml:"mirrors"`
PlainHTTP *bool `toml:"http"`
Insecure *bool `toml:"insecure"`
RootCAs []string `toml:"ca"`
KeyPairs []TLSKeyPair `toml:"keypair"`
TLSConfigDir []string `toml:"tlsconfigdir"`
}
type TLSKeyPair struct {
Key string `toml:"key"`
Certificate string `toml:"cert"`
}
type TLSConfig struct {
@ -103,24 +103,3 @@ type DNSConfig struct {
Options []string `toml:"options"`
SearchDomains []string `toml:"searchDomains"`
}
func Load(r io.Reader) (Config, *toml.MetaData, error) {
var c Config
md, err := toml.DecodeReader(r, &c)
if err != nil {
return c, nil, errors.Wrap(err, "failed to parse config")
}
return c, &md, nil
}
func LoadFile(fp string) (Config, *toml.MetaData, error) {
f, err := os.Open(fp)
if err != nil {
if os.IsNotExist(err) {
return Config{}, nil, nil
}
return Config{}, nil, errors.Wrapf(err, "failed to load config from %s", fp)
}
defer f.Close()
return Load(f)
}

View File

@ -1,4 +1,4 @@
package config
package main
import (
"bytes"
@ -51,6 +51,12 @@ keepDuration=7200
[registry."docker.io"]
mirrors=["hub.docker.io"]
http=true
insecure=true
ca=["myca.pem"]
tlsconfigdir=["/etc/buildkitd/myregistry"]
[[registry."docker.io".keypair]]
key="key.pem"
cert="cert.pem"
[dns]
nameservers=["1.1.1.1","8.8.8.8"]
@ -102,7 +108,12 @@ searchDomains=["example.com"]
require.Equal(t, 0, len(cfg.Workers.Containerd.GCPolicy[1].Filters))
require.Equal(t, *cfg.Registries["docker.io"].PlainHTTP, true)
require.Equal(t, *cfg.Registries["docker.io"].Insecure, true)
require.Equal(t, cfg.Registries["docker.io"].Mirrors[0], "hub.docker.io")
require.Equal(t, cfg.Registries["docker.io"].RootCAs, []string{"myca.pem"})
require.Equal(t, cfg.Registries["docker.io"].TLSConfigDir, []string{"/etc/buildkitd/myregistry"})
require.Equal(t, cfg.Registries["docker.io"].KeyPairs[0].Key, "key.pem")
require.Equal(t, cfg.Registries["docker.io"].KeyPairs[0].Certificate, "cert.pem")
require.NotNil(t, cfg.DNS)
require.Equal(t, cfg.DNS.Nameservers, []string{"1.1.1.1", "8.8.8.8"})

View File

@ -182,7 +182,7 @@ func main() {
ctx, cancel := context.WithCancel(appcontext.Context())
defer cancel()
cfg, md, err := config.LoadFile(c.GlobalString("config"))
cfg, md, err := LoadFile(c.GlobalString("config"))
if err != nil {
return err
}
@ -337,7 +337,7 @@ func defaultConfigPath() string {
}
func defaultConf() (config.Config, *toml.MetaData, error) {
cfg, md, err := config.LoadFile(defaultConfigPath())
cfg, md, err := LoadFile(defaultConfigPath())
if err != nil {
if _, ok := errors.Cause(err).(*os.PathError); !ok {
return config.Config{}, nil, err
@ -621,15 +621,7 @@ func newController(c *cli.Context, cfg *config.Config) (*control.Controller, err
}
func resolverFunc(cfg *config.Config) docker.RegistryHosts {
m := map[string]resolver.RegistryConf{}
for k, v := range cfg.Registries {
m[k] = resolver.RegistryConf{
Mirrors: v.Mirrors,
PlainHTTP: v.PlainHTTP,
Insecure: v.Insecure,
}
}
return resolver.NewRegistryConfig(m)
return resolver.NewRegistryConfig(cfg.Registries)
}
func newWorkerController(c *cli.Context, wiOpt workerInitializerOpt) (*worker.Controller, error) {

View File

@ -83,4 +83,9 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
[registry."docker.io"]
mirrors = ["hub.docker.io"]
http = true
insecure = true
ca=["/etc/config/myca.pem"]
[[registry."docker.io".keypair]]
key="/etc/config/key.pem"
cert="/etc/config/cert.pem"
```

View File

@ -3,37 +3,109 @@ package resolver
import (
"context"
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
"github.com/moby/buildkit/cmd/buildkitd/config"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/auth"
"github.com/moby/buildkit/util/tracing"
"github.com/pkg/errors"
)
type RegistryConf struct {
Mirrors []string
PlainHTTP *bool
Insecure *bool
}
func fillInsecureOpts(host string, c config.RegistryConfig, h *docker.RegistryHost) error {
tc, err := loadTLSConfig(c)
if err != nil {
return err
}
func fillInsecureOpts(host string, c RegistryConf, h *docker.RegistryHost) {
if c.PlainHTTP != nil && *c.PlainHTTP {
h.Scheme = "http"
} else if c.Insecure != nil && *c.Insecure {
h.Client = &http.Client{
Transport: tracing.NewTransport(&http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}),
if tc == nil {
tc = &tls.Config{}
}
tc.InsecureSkipVerify = true
} else if c.PlainHTTP == nil {
if ok, _ := docker.MatchLocalhost(host); ok {
h.Scheme = "http"
}
}
if tc != nil && h.Scheme != "http" {
h.Client = &http.Client{
Transport: tracing.NewTransport(&http.Transport{TLSClientConfig: tc}),
}
}
return nil
}
func NewRegistryConfig(m map[string]RegistryConf) docker.RegistryHosts {
func loadTLSConfig(c config.RegistryConfig) (*tls.Config, error) {
for _, d := range c.TLSConfigDir {
fs, err := ioutil.ReadDir(d)
if err != nil && !os.IsNotExist(err) && !os.IsPermission(err) {
return nil, errors.WithStack(err)
}
for _, f := range fs {
if strings.HasSuffix(f.Name(), ".crt") {
c.RootCAs = append(c.RootCAs, filepath.Join(d, f.Name()))
}
if strings.HasSuffix(f.Name(), ".cert") {
c.KeyPairs = append(c.KeyPairs, config.TLSKeyPair{
Certificate: filepath.Join(d, f.Name()),
Key: filepath.Join(d, strings.TrimSuffix(f.Name(), ".cert")+".key"),
})
}
}
}
var tc *tls.Config
if len(c.RootCAs) > 0 {
tc = &tls.Config{}
systemPool, err := x509.SystemCertPool()
if err != nil {
if runtime.GOOS == "windows" {
systemPool = x509.NewCertPool()
} else {
return nil, errors.Wrapf(err, "unable to get system cert pool")
}
}
tc.RootCAs = systemPool
}
for _, p := range c.RootCAs {
dt, err := ioutil.ReadFile(p)
if err != nil {
return nil, errors.Wrapf(err, "failed to read %s", p)
}
tc.RootCAs.AppendCertsFromPEM(dt)
}
for _, kp := range c.KeyPairs {
cert, err := tls.LoadX509KeyPair(kp.Certificate, kp.Key)
if err != nil {
return nil, errors.Wrapf(err, "failed to load keypair for %s", kp.Certificate)
}
if tc == nil {
tc = &tls.Config{}
}
tc.Certificates = append(tc.Certificates, cert)
}
return tc, nil
}
func NewRegistryConfig(m map[string]config.RegistryConfig) docker.RegistryHosts {
return docker.Registries(
func(host string) ([]docker.RegistryHost, error) {
c, ok := m[host]
@ -51,7 +123,10 @@ func NewRegistryConfig(m map[string]RegistryConf) docker.RegistryHosts {
Path: "/v2",
Capabilities: docker.HostCapabilityPull | docker.HostCapabilityResolve,
}
fillInsecureOpts(mirror, m[mirror], &h)
if err := fillInsecureOpts(mirror, m[mirror], &h); err != nil {
return nil, err
}
out = append(out, h)
}
@ -67,7 +142,10 @@ func NewRegistryConfig(m map[string]RegistryConf) docker.RegistryHosts {
Path: "/v2",
Capabilities: docker.HostCapabilityPush | docker.HostCapabilityPull | docker.HostCapabilityResolve,
}
fillInsecureOpts(host, c, &h)
if err := fillInsecureOpts(host, c, &h); err != nil {
return nil, err
}
out = append(out, h)
return out, nil