resolver: support self signed certificates
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>v0.7
parent
430c5256d5
commit
56f76a5621
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"})
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue