*: support insecure registries
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
8441dca284
commit
8b53fabcbd
6 changed files with 129 additions and 38 deletions
|
@ -95,6 +95,10 @@ pause_command = "{{ .PauseCommand }}"
|
|||
# unspecified so that the default system-wide policy will be used.
|
||||
signature_policy = "{{ .SignaturePolicyPath }}"
|
||||
|
||||
# insecure_registries is used to skip TLS verification when pulling images.
|
||||
insecure_registries = [
|
||||
{{ range $opt := .InsecureRegistries }}{{ printf "\t%q,\n" $opt }}{{ end }}]
|
||||
|
||||
# The "crio.network" table contains settings pertaining to the
|
||||
# management of CNI plugins.
|
||||
[crio.network]
|
||||
|
|
|
@ -62,6 +62,9 @@ func mergeConfig(config *server.Config, ctx *cli.Context) error {
|
|||
if ctx.GlobalIsSet("storage-opt") {
|
||||
config.StorageOptions = ctx.GlobalStringSlice("storage-opt")
|
||||
}
|
||||
if ctx.GlobalIsSet("insecure-registry") {
|
||||
config.InsecureRegistries = ctx.GlobalStringSlice("insecure-registries")
|
||||
}
|
||||
if ctx.GlobalIsSet("default-transport") {
|
||||
config.DefaultTransport = ctx.GlobalString("default-transport")
|
||||
}
|
||||
|
@ -180,6 +183,10 @@ func main() {
|
|||
Name: "storage-opt",
|
||||
Usage: "storage driver option",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "insecure-registry",
|
||||
Usage: "whether to disable TLS verification for the given registry",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "default-transport",
|
||||
Usage: "default transport",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/containers/image/copy"
|
||||
"github.com/containers/image/docker/reference"
|
||||
"github.com/containers/image/image"
|
||||
|
@ -19,9 +21,16 @@ type ImageResult struct {
|
|||
Size *uint64
|
||||
}
|
||||
|
||||
type indexInfo struct {
|
||||
name string
|
||||
secure bool
|
||||
}
|
||||
|
||||
type imageService struct {
|
||||
store storage.Store
|
||||
defaultTransport string
|
||||
store storage.Store
|
||||
defaultTransport string
|
||||
insecureRegistryCIDRs []*net.IPNet
|
||||
indexConfigs map[string]*indexInfo
|
||||
}
|
||||
|
||||
// ImageServer wraps up various CRI-related activities into a reusable
|
||||
|
@ -40,7 +49,7 @@ type ImageServer interface {
|
|||
// when it's asked to pull an image.
|
||||
GetStore() storage.Store
|
||||
// CanPull preliminary checks whether we're allowed to pull an image
|
||||
CanPull(imageName string, sourceCtx *types.SystemContext) (bool, error)
|
||||
CanPull(imageName string, options *copy.Options) (bool, error)
|
||||
}
|
||||
|
||||
func (svc *imageService) ListImages(filter string) ([]ImageResult, error) {
|
||||
|
@ -119,22 +128,12 @@ func imageSize(img types.Image) *uint64 {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (svc *imageService) CanPull(imageName string, sourceCtx *types.SystemContext) (bool, error) {
|
||||
if imageName == "" {
|
||||
return false, storage.ErrNotAnImage
|
||||
}
|
||||
srcRef, err := alltransports.ParseImageName(imageName)
|
||||
func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) {
|
||||
srcRef, err := svc.prepareImage(imageName, options)
|
||||
if err != nil {
|
||||
if svc.defaultTransport == "" {
|
||||
return false, err
|
||||
}
|
||||
srcRef2, err2 := alltransports.ParseImageName(svc.defaultTransport + imageName)
|
||||
if err2 != nil {
|
||||
return false, err
|
||||
}
|
||||
srcRef = srcRef2
|
||||
return false, err
|
||||
}
|
||||
rawSource, err := srcRef.NewImageSource(sourceCtx, nil)
|
||||
rawSource, err := srcRef.NewImageSource(options.SourceCtx, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -148,21 +147,13 @@ func (svc *imageService) CanPull(imageName string, sourceCtx *types.SystemContex
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
policy, err := signature.DefaultPolicy(systemContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policyContext, err := signature.NewPolicyContext(policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// prepareImage creates an image reference from an image string and set options
|
||||
// for the source context
|
||||
func (svc *imageService) prepareImage(imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
if imageName == "" {
|
||||
return nil, storage.ErrNotAnImage
|
||||
}
|
||||
if options == nil {
|
||||
options = ©.Options{}
|
||||
}
|
||||
|
||||
srcRef, err := alltransports.ParseImageName(imageName)
|
||||
if err != nil {
|
||||
if svc.defaultTransport == "" {
|
||||
|
@ -174,6 +165,36 @@ func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName
|
|||
}
|
||||
srcRef = srcRef2
|
||||
}
|
||||
|
||||
if options.SourceCtx == nil {
|
||||
options.SourceCtx = &types.SystemContext{}
|
||||
}
|
||||
|
||||
hostname := reference.Domain(srcRef.DockerReference())
|
||||
if secure := svc.isSecureIndex(hostname); !secure {
|
||||
options.SourceCtx.DockerInsecureSkipTLSVerify = !secure
|
||||
}
|
||||
return srcRef, nil
|
||||
}
|
||||
|
||||
func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) {
|
||||
policy, err := signature.DefaultPolicy(systemContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policyContext, err := signature.NewPolicyContext(policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if options == nil {
|
||||
options = ©.Options{}
|
||||
}
|
||||
|
||||
srcRef, err := svc.prepareImage(imageName, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dest := imageName
|
||||
if srcRef.DockerReference() != nil {
|
||||
dest = srcRef.DockerReference().Name()
|
||||
|
@ -215,11 +236,47 @@ func (svc *imageService) GetStore() storage.Store {
|
|||
return svc.store
|
||||
}
|
||||
|
||||
func (svc *imageService) isSecureIndex(indexName string) bool {
|
||||
if index, ok := svc.indexConfigs[indexName]; ok {
|
||||
return index.secure
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(indexName)
|
||||
if err != nil {
|
||||
// assume indexName is of the form `host` without the port and go on.
|
||||
host = indexName
|
||||
}
|
||||
|
||||
addrs, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
addrs = []net.IP{ip}
|
||||
}
|
||||
|
||||
// if ip == nil, then `host` is neither an IP nor it could be looked up,
|
||||
// either because the index is unreachable, or because the index is behind an HTTP proxy.
|
||||
// So, len(addrs) == 0 and we're not aborting.
|
||||
}
|
||||
|
||||
// Try CIDR notation only if addrs has any elements, i.e. if `host`'s IP could be determined.
|
||||
for _, addr := range addrs {
|
||||
for _, ipnet := range svc.insecureRegistryCIDRs {
|
||||
// check if the addr falls in the subnet
|
||||
if (*net.IPNet)(ipnet).Contains(addr) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GetImageService returns an ImageServer that uses the passed-in store, and
|
||||
// which will prepend the passed-in defaultTransport value to an image name if
|
||||
// a name that's passed to its PullImage() method can't be resolved to an image
|
||||
// in the store and can't be resolved to a source on its own.
|
||||
func GetImageService(store storage.Store, defaultTransport string) (ImageServer, error) {
|
||||
func GetImageService(store storage.Store, defaultTransport string, insecureRegistries []string) (ImageServer, error) {
|
||||
if store == nil {
|
||||
var err error
|
||||
store, err = storage.GetStore(storage.DefaultStoreOptions)
|
||||
|
@ -227,8 +284,30 @@ func GetImageService(store storage.Store, defaultTransport string) (ImageServer,
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
return &imageService{
|
||||
store: store,
|
||||
defaultTransport: defaultTransport,
|
||||
}, nil
|
||||
|
||||
is := &imageService{
|
||||
store: store,
|
||||
defaultTransport: defaultTransport,
|
||||
indexConfigs: make(map[string]*indexInfo, 0),
|
||||
insecureRegistryCIDRs: make([]*net.IPNet, 0),
|
||||
}
|
||||
|
||||
insecureRegistries = append(insecureRegistries, "127.0.0.0/8")
|
||||
// Split --insecure-registry into CIDR and registry-specific settings.
|
||||
for _, r := range insecureRegistries {
|
||||
// Check if CIDR was passed to --insecure-registry
|
||||
_, ipnet, err := net.ParseCIDR(r)
|
||||
if err == nil {
|
||||
// Valid CIDR.
|
||||
is.insecureRegistryCIDRs = append(is.insecureRegistryCIDRs, ipnet)
|
||||
} else {
|
||||
// Assume `host:port` if not CIDR.
|
||||
is.indexConfigs[r] = &indexInfo{
|
||||
name: r,
|
||||
secure: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return is, nil
|
||||
}
|
||||
|
|
|
@ -117,6 +117,9 @@ type ImageConfig struct {
|
|||
// that this be left unspecified so that the default system-wide policy
|
||||
// will be used.
|
||||
SignaturePolicyPath string `toml:"signature_policy"`
|
||||
// InsecureRegistries is a list of registries that must be contacted w/o
|
||||
// TLS verification.
|
||||
InsecureRegistries []string `toml:"insecure_registries"`
|
||||
}
|
||||
|
||||
// NetworkConfig represents the "crio.network" TOML config table
|
||||
|
|
|
@ -38,8 +38,6 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
|
|||
}
|
||||
}
|
||||
options := ©.Options{
|
||||
// TODO: we need a way to specify insecure registries like docker
|
||||
//DockerInsecureSkipTLSVerify: true,
|
||||
SourceCtx: &types.SystemContext{},
|
||||
}
|
||||
// a not empty username should be sufficient to decide whether to send auth
|
||||
|
@ -53,7 +51,7 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
|
|||
}
|
||||
}
|
||||
|
||||
canPull, err := s.storageImageServer.CanPull(image, options.SourceCtx)
|
||||
canPull, err := s.storageImageServer.CanPull(image, options)
|
||||
if err != nil && !canPull {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -545,7 +545,7 @@ func New(config *Config) (*Server, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
imageService, err := storage.GetImageService(store, config.DefaultTransport)
|
||||
imageService, err := storage.GetImageService(store, config.DefaultTransport, config.InsecureRegistries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue