Merge pull request #46 from pterodactyl/feature/docker-repo-auth

Add Docker registry authentication
This commit is contained in:
Dane Everitt 2020-07-31 20:27:35 -07:00 committed by GitHub
commit cecc72110c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 3 deletions

View File

@ -1,5 +1,12 @@
package config package config
import (
"encoding/base64"
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
)
type dockerNetworkInterfaces struct { type dockerNetworkInterfaces struct {
V4 struct { V4 struct {
Subnet string `default:"172.18.0.0/16"` Subnet string `default:"172.18.0.0/16"`
@ -53,4 +60,28 @@ type DockerConfiguration struct {
// Defines the location of the timezone file on the host system that should // Defines the location of the timezone file on the host system that should
// be mounted into the created containers so that they all use the same time. // be mounted into the created containers so that they all use the same time.
TimezonePath string `default:"/etc/timezone" json:"timezone_path" yaml:"timezone_path"` TimezonePath string `default:"/etc/timezone" json:"timezone_path" yaml:"timezone_path"`
// Registries .
Registries map[string]RegistryConfiguration `json:"registries" yaml:"registries"`
}
// RegistryConfiguration .
type RegistryConfiguration struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
}
// Base64 .
func (c RegistryConfiguration) Base64() (string, error) {
authConfig := types.AuthConfig{
Username: c.Username,
Password: c.Password,
}
b, err := json.Marshal(authConfig)
if err != nil {
return "", errors.WithStack(err)
}
return base64.URLEncoding.EncodeToString(b), nil
} }

View File

@ -654,7 +654,33 @@ func (d *DockerEnvironment) ensureImageExists() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15) ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15)
defer cancel() defer cancel()
out, err := d.Client.ImagePull(ctx, d.Image(), types.ImagePullOptions{All: false}) image := d.Image()
// Get a registry auth configuration from the config.
var registryAuth *config.RegistryConfiguration
for registry, c := range config.Get().Docker.Registries {
if !strings.HasPrefix(image, registry) {
continue
}
log.WithField("registry", registry).Debug("using authentication for repository")
registryAuth = &c
break
}
// Get the ImagePullOptions.
imagePullOptions := types.ImagePullOptions{All: false}
if registryAuth != nil {
b64, err := registryAuth.Base64()
if err != nil {
log.WithError(err).Error("failed to get registry auth credentials")
}
// b64 is a string so if there is an error it will just be empty, not nil.
imagePullOptions.RegistryAuth = b64
}
out, err := d.Client.ImagePull(ctx, image, imagePullOptions)
if err != nil { if err != nil {
images, ierr := d.Client.ImageList(ctx, types.ImageListOptions{}) images, ierr := d.Client.ImageList(ctx, types.ImageListOptions{})
if ierr != nil { if ierr != nil {

View File

@ -114,10 +114,10 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
} }
// Generate a path to the file by cleaning it up and appending the root server path to it. This // Generate a path to the file by cleaning it up and appending the root server path to it. This
// DOES NOT gaurantee that the file resolves within the server data directory. You'll want to use // DOES NOT guarantee that the file resolves within the server data directory. You'll want to use
// the fs.unsafeIsInDataDirectory(p) function to confirm. // the fs.unsafeIsInDataDirectory(p) function to confirm.
func (fs *Filesystem) unsafeFilePath(p string) string { func (fs *Filesystem) unsafeFilePath(p string) string {
// Calling filpath.Clean on the joined directory will resolve it to the absolute path, // Calling filepath.Clean on the joined directory will resolve it to the absolute path,
// removing any ../ type of resolution arguments, and leaving us with a direct path link. // removing any ../ type of resolution arguments, and leaving us with a direct path link.
// //
// This will also trim the existing root path off the beginning of the path passed to // This will also trim the existing root path off the beginning of the path passed to