Skip to content

Commit

Permalink
c8d/resolver: Fallback to http for insecure registries
Browse files Browse the repository at this point in the history
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
  • Loading branch information
vvoland authored and rumpl committed Jan 11, 2023
1 parent c83fce8 commit 9032e67
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 24 deletions.
57 changes: 41 additions & 16 deletions daemon/containerd/resolver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package containerd

import (
"net/http"
"strings"

"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
registrytypes "github.com/docker/docker/api/types/registry"
Expand All @@ -9,35 +12,40 @@ import (
)

func (i *ImageService) newResolverFromAuthConfig(authConfig *registrytypes.AuthConfig) (remotes.Resolver, docker.StatusTracker) {
tracker := docker.NewInMemoryTracker()
hostsFn := i.registryHosts.RegistryHosts()
hosts := hostsAuthorizerWrapper(hostsFn, authConfig)

tracker := docker.NewInMemoryTracker()
hosts := hostsWrapper(hostsFn, authConfig, i.registryService)

return docker.NewResolver(docker.ResolverOptions{
Hosts: hosts,
Tracker: tracker,
}), tracker
}

func hostsAuthorizerWrapper(hostsFn docker.RegistryHosts, authConfig *registrytypes.AuthConfig) docker.RegistryHosts {
return docker.RegistryHosts(func(n string) ([]docker.RegistryHost, error) {
func hostsWrapper(hostsFn docker.RegistryHosts, authConfig *registrytypes.AuthConfig, regService registry.Service) docker.RegistryHosts {
return func(n string) ([]docker.RegistryHost, error) {
hosts, err := hostsFn(n)
if err == nil {
for idx, host := range hosts {
if host.Authorizer == nil {
var opts []docker.AuthorizerOpt
if authConfig != nil {
opts = append(opts, authorizationCredsFromAuthConfig(*authConfig))
}
host.Authorizer = docker.NewDockerAuthorizer(opts...)
hosts[idx] = host
if err != nil {
return nil, err
}

for i := range hosts {
if hosts[i].Authorizer == nil {
var opts []docker.AuthorizerOpt
if authConfig != nil {
opts = append(opts, authorizationCredsFromAuthConfig(*authConfig))
}
hosts[i].Authorizer = docker.NewDockerAuthorizer(opts...)

isInsecure := regService.IsInsecureRegistry(hosts[i].Host)
if hosts[i].Client.Transport != nil && isInsecure {
hosts[i].Client.Transport = httpFallback{super: hosts[i].Client.Transport}
}
}
}

return hosts, err
})
return hosts, nil
}
}

func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docker.AuthorizerOpt {
Expand All @@ -57,3 +65,20 @@ func authorizationCredsFromAuthConfig(authConfig registrytypes.AuthConfig) docke
return authConfig.Username, authConfig.Password, nil
})
}

type httpFallback struct {
super http.RoundTripper
}

func (f httpFallback) RoundTrip(r *http.Request) (*http.Response, error) {
resp, err := f.super.RoundTrip(r)
if err != nil {
if strings.Contains(err.Error(), "http: server gave HTTP response to HTTPS client") {
plain := r.Clone(r.Context())
plain.URL.Scheme = "http"
return http.DefaultTransport.RoundTrip(plain)
}
}

return resp, err
}
17 changes: 10 additions & 7 deletions daemon/containerd/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,29 @@ import (
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
)

// ImageService implements daemon.ImageService
type ImageService struct {
client *containerd.Client
snapshotter string
registryHosts RegistryHostsProvider
client *containerd.Client
snapshotter string
registryHosts RegistryHostsProvider
registryService registry.Service
}

type RegistryHostsProvider interface {
RegistryHosts() docker.RegistryHosts
}

// NewService creates a new ImageService.
func NewService(c *containerd.Client, snapshotter string, hostsProvider RegistryHostsProvider) *ImageService {
func NewService(c *containerd.Client, snapshotter string, hostsProvider RegistryHostsProvider, registry registry.Service) *ImageService {
return &ImageService{
client: c,
snapshotter: snapshotter,
registryHosts: hostsProvider,
client: c,
snapshotter: snapshotter,
registryHosts: hostsProvider,
registryService: registry,
}
}

Expand Down
10 changes: 9 additions & 1 deletion daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"path"
"path/filepath"
"runtime"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -177,6 +178,13 @@ func (daemon *Daemon) RegistryHosts() docker.RegistryHosts {

for _, v := range daemon.configStore.InsecureRegistries {
u, err := url.Parse(v)
if err != nil && !strings.HasPrefix(v, "http://") && !strings.HasPrefix(v, "https://") {
originalErr := err
u, err = url.Parse("http://" + v)
if err != nil {
err = originalErr
}
}
c := resolverconfig.RegistryConfig{}
if err == nil {
v = u.Host
Expand Down Expand Up @@ -994,7 +1002,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
if err := configureKernelSecuritySupport(config, driverName); err != nil {
return nil, err
}
d.imageService = ctrd.NewService(d.containerdCli, driverName, d)
d.imageService = ctrd.NewService(d.containerdCli, driverName, d, d.registryService)
} else {
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{
Root: config.Root,
Expand Down
7 changes: 7 additions & 0 deletions registry/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Service interface {
LoadAllowNondistributableArtifacts([]string) error
LoadMirrors([]string) error
LoadInsecureRegistries([]string) error
IsInsecureRegistry(string) bool
}

// defaultService is a registry service. It tracks configuration data such as a list
Expand Down Expand Up @@ -232,3 +233,9 @@ func (s *defaultService) LookupPushEndpoints(hostname string) (endpoints []APIEn
}
return endpoints, err
}

// IsInsecureRegistry returns true if the registry at given host is configured as
// insecure registry.
func (s *defaultService) IsInsecureRegistry(host string) bool {
return !s.config.isSecureIndex(host)
}

0 comments on commit 9032e67

Please sign in to comment.