mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-02-02 10:35:08 -05:00
AB#2306 Public image sharing in Google (#358)
* document how to publicly share images in gcloud * Write disclamer in debugd * Add disclamer about debug images to contributing file * Print debug banner on startup Signed-off-by: Fabian Kammel <fk@edgeless.systems>
This commit is contained in:
parent
abb4fb4f0f
commit
170a8bf5e0
@ -23,7 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Kubernetes operator for Constellation nodes with ability to update node images.
|
- Kubernetes operator for Constellation nodes with ability to update node images.
|
||||||
- cilium strict pod2pod encryption.
|
- CoreOS images are publicly available for GCP.
|
||||||
|
- Cilium strict pod2pod encryption.
|
||||||
- Add a configurable list of enforced measurements to the config. If an expected measurement can not be verified during attestation, but it is not in the list of enforced measurements, only a warning is logged.
|
- Add a configurable list of enforced measurements to the config. If an expected measurement can not be verified during attestation, but it is not in the list of enforced measurements, only a warning is logged.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -10,6 +10,14 @@ ctest
|
|||||||
|
|
||||||
[Run CI e2e tests](/.github/docs/README.md)
|
[Run CI e2e tests](/.github/docs/README.md)
|
||||||
|
|
||||||
|
### Debug Images
|
||||||
|
|
||||||
|
> :warning: These images are not safe to use in production environments. :warning:
|
||||||
|
|
||||||
|
As described in [debugd](/debugd/README.md), it is possible to use a CoreOS image targeted at dev environments. This image allows to upload any [bootstrapper](/bootstrapper/README.md) using [cdbg](/debugd/cdbg).
|
||||||
|
|
||||||
|
To enable the upload, an additional **unsecured** port (4000) is opened which accepts any binary to be run on target machine. **Make sure that this machine is not exposed to the internet.**
|
||||||
|
|
||||||
## Linting
|
## Linting
|
||||||
|
|
||||||
This projects uses [golangci-lint](https://golangci-lint.run/) for linting.
|
This projects uses [golangci-lint](https://golangci-lint.run/) for linting.
|
||||||
|
@ -50,6 +50,10 @@ func configFetchMeasurements(cmd *cobra.Command, fileHandler file.Handler, clien
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.IsImageDebug() {
|
||||||
|
cmd.Println("Configured image does not look like a released production image. Double check image before deploying to production.")
|
||||||
|
}
|
||||||
|
|
||||||
if err := flags.updateURLs(conf); err != nil {
|
if err := flags.updateURLs(conf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,10 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
|||||||
return fmt.Errorf("reading and validating config: %w", err)
|
return fmt.Errorf("reading and validating config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.IsImageDebug() {
|
||||||
|
cmd.Println("Configured image does not look like a released production image. Double check image before deploying to production.")
|
||||||
|
}
|
||||||
|
|
||||||
if !flags.yes {
|
if !flags.yes {
|
||||||
// Ask user to confirm action.
|
// Ask user to confirm action.
|
||||||
cmd.Printf("The following Constellation cluster will be created:\n")
|
cmd.Printf("The following Constellation cluster will be created:\n")
|
||||||
|
@ -66,8 +66,8 @@ func deploy(cmd *cobra.Command, fileHandler file.Handler, constellationConfig *c
|
|||||||
debugConfig.ConstellationDebugConfig.BootstrapperPath = overrideBootstrapperPath
|
debugConfig.ConstellationDebugConfig.BootstrapperPath = overrideBootstrapperPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if !state.ImageNameContainsDebug(constellationConfig) {
|
if !constellationConfig.IsImageDebug() {
|
||||||
log.Println("WARN: constellation image does not contain 'debug', are you using a debug image?")
|
log.Println("WARN: constellation image does not look like a debug image. Are you using a debug image?")
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideIPs, err := cmd.Flags().GetStringSlice("ips")
|
overrideIPs, err := cmd.Flags().GetStringSlice("ips")
|
||||||
|
@ -2,7 +2,6 @@ package state
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
|
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
|
||||||
"github.com/edgelesssys/constellation/internal/config"
|
"github.com/edgelesssys/constellation/internal/config"
|
||||||
@ -77,15 +76,3 @@ func getQEMUInstances(stat state.ConstellationState, _ *config.Config) (controlP
|
|||||||
workers = cloudtypes.ScalingGroup{Instances: stat.QEMUWorkers}
|
workers = cloudtypes.ScalingGroup{Instances: stat.QEMUWorkers}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageNameContainsDebug check wether the image name in config contains "debug".
|
|
||||||
func ImageNameContainsDebug(config *config.Config) bool {
|
|
||||||
switch {
|
|
||||||
case config.Provider.GCP != nil:
|
|
||||||
return strings.Contains(config.Provider.GCP.Image, "debug")
|
|
||||||
case config.Provider.Azure != nil:
|
|
||||||
return strings.Contains(config.Provider.Azure.Image, "debug")
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@ -20,6 +21,13 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const debugBanner = `
|
||||||
|
**************************************
|
||||||
|
THIS A CONSTELLATION DEBUG IMAGE.
|
||||||
|
DO NOT USE IN PRODUCTION.
|
||||||
|
**************************************
|
||||||
|
`
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
verbosity := flag.Int("v", 0, logger.CmdLineVerbosityDescription)
|
verbosity := flag.Int("v", 0, logger.CmdLineVerbosityDescription)
|
||||||
@ -62,6 +70,8 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeDebugBanner(log)
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go sched.Start(ctx, wg)
|
go sched.Start(ctx, wg)
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
@ -69,3 +79,15 @@ func main() {
|
|||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeDebugBanner(log *logger.Logger) {
|
||||||
|
tty, err := os.OpenFile("/dev/ttyS0", os.O_WRONLY, os.ModeAppend)
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("Unable to open /dev/ttyS0 for printing banner: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer tty.Close()
|
||||||
|
if _, err := fmt.Fprint(tty, debugBanner); err != nil {
|
||||||
|
log.Infof("Unable to print to /dev/ttyS0: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -122,6 +122,10 @@ upload-gcp: $(GCP_IMAGE_PATH)
|
|||||||
--guest-os-features=GVNIC,SEV_CAPABLE,VIRTIO_SCSI_MULTIQUEUE,UEFI_COMPATIBLE \
|
--guest-os-features=GVNIC,SEV_CAPABLE,VIRTIO_SCSI_MULTIQUEUE,UEFI_COMPATIBLE \
|
||||||
--labels=bootstrapper-sha1=$$(shasum $(BOOTSTRAPPER_OVERRIDE_PATH) | cut -d " " -f 1),bootstrapper-sha512=$$(sha512sum $(BOOTSTRAPPER_OVERRIDE_PATH) | cut -d " " -f 1 | cut -c-63) \
|
--labels=bootstrapper-sha1=$$(shasum $(BOOTSTRAPPER_OVERRIDE_PATH) | cut -d " " -f 1),bootstrapper-sha512=$$(sha512sum $(BOOTSTRAPPER_OVERRIDE_PATH) | cut -d " " -f 1 | cut -c-63) \
|
||||||
--project $(GCP_PROJECT)
|
--project $(GCP_PROJECT)
|
||||||
|
gcloud compute images add-iam-policy-binding $(GCP_IMAGE_NAME) \
|
||||||
|
--project $(GCP_PROJECT) \
|
||||||
|
--member='allAuthenticatedUsers' \
|
||||||
|
--role='roles/compute.imageUser'
|
||||||
gsutil rm gs://$(GCP_BUCKET)/$(GCP_IMAGE_FILENAME)
|
gsutil rm gs://$(GCP_BUCKET)/$(GCP_IMAGE_FILENAME)
|
||||||
|
|
||||||
image-azure: $(AZURE_IMAGE_PATH)
|
image-azure: $(AZURE_IMAGE_PATH)
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
@ -346,6 +347,22 @@ func (c *Config) RemoveProviderExcept(provider cloudprovider.Provider) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsImageDebug checks whether image name looks like a release image, if not it is
|
||||||
|
// probably a debug image. In the end we do not if bootstrapper or debugd
|
||||||
|
// was put inside an image just by looking at its name.
|
||||||
|
func (c *Config) IsImageDebug() bool {
|
||||||
|
switch {
|
||||||
|
case c.Provider.GCP != nil:
|
||||||
|
gcpRegex := regexp.MustCompile(`^projects\/constellation-images\/global\/images\/constellation-v[\d]+-[\d]+-[\d]+$`)
|
||||||
|
return !gcpRegex.MatchString(c.Provider.GCP.Image)
|
||||||
|
case c.Provider.Azure != nil:
|
||||||
|
azureRegex := regexp.MustCompile(`^\/subscriptions\/0d202bbb-4fa7-4af8-8125-58c269a05435\/resourceGroups\/constellation-images\/providers\/Microsoft.Compute\/galleries\/Constellation\/images\/constellation\/versions\/[\d]+.[\d]+.[\d]+$`)
|
||||||
|
return !azureRegex.MatchString(c.Provider.Azure.Image)
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FromFile returns config file with `name` read from `fileHandler` by parsing
|
// FromFile returns config file with `name` read from `fileHandler` by parsing
|
||||||
// it as YAML.
|
// it as YAML.
|
||||||
func FromFile(fileHandler file.Handler, name string) (*Config, error) {
|
func FromFile(fileHandler file.Handler, name string) (*Config, error) {
|
||||||
|
@ -321,3 +321,58 @@ func TestConfig_UpdateMeasurements(t *testing.T) {
|
|||||||
assert.Equal(newMeasurements, conf.Provider.QEMU.Measurements)
|
assert.Equal(newMeasurements, conf.Provider.QEMU.Measurements)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_IsImageDebug(t *testing.T) {
|
||||||
|
testCases := map[string]struct {
|
||||||
|
conf *Config
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
"gcp release": {
|
||||||
|
conf: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.RemoveProviderExcept(cloudprovider.GCP)
|
||||||
|
conf.Provider.GCP.Image = "projects/constellation-images/global/images/constellation-v1-3-0"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
"gcp debug": {
|
||||||
|
conf: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.RemoveProviderExcept(cloudprovider.GCP)
|
||||||
|
conf.Provider.GCP.Image = "projects/constellation-images/global/images/constellation-20220812102023"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
"azure release": {
|
||||||
|
conf: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.RemoveProviderExcept(cloudprovider.Azure)
|
||||||
|
conf.Provider.Azure.Image = "/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation/images/constellation/versions/2022.0805.151600"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
"azure debug": {
|
||||||
|
conf: func() *Config {
|
||||||
|
conf := Default()
|
||||||
|
conf.RemoveProviderExcept(cloudprovider.Azure)
|
||||||
|
conf.Provider.Azure.Image = "/subscriptions/0d202bbb-4fa7-4af8-8125-58c269a05435/resourceGroups/constellation-images/providers/Microsoft.Compute/galleries/Constellation_Debug/images/v1.4.0/versions/2022.0805.151600"
|
||||||
|
return conf
|
||||||
|
}(),
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
"empty config": {
|
||||||
|
conf: &Config{},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range testCases {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
assert.Equal(tc.want, tc.conf.IsImageDebug())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user