composer: More configuration of how composer is served

Allows you to disable tls
This commit is contained in:
sanne 2021-09-30 15:17:40 +02:00 committed by Sanne Raymaekers
parent fed4b97e4e
commit 1e724be8e9
6 changed files with 105 additions and 64 deletions

View file

@ -104,10 +104,20 @@ func (c *Composer) InitWeldr(repoPaths []string, weldrListener net.Listener,
return nil
}
func (c *Composer) InitAPI(cert, key string, enableJWT bool, l net.Listener) error {
func (c *Composer) InitAPI(cert, key string, enableTLS bool, enableMTLS bool, enableJWT bool, l net.Listener) error {
c.api = cloudapi.NewServer(c.workers, c.rpm, c.distros)
c.koji = kojiapi.NewServer(c.logger, c.workers, c.rpm, c.distros)
if !enableTLS {
c.apiListener = l
return nil
}
// If both are off or both are on, error out
if enableJWT == enableMTLS {
return fmt.Errorf("API: Either mTLS or JWT authentication must be enabled")
}
clientAuth := tls.RequireAndVerifyClientCert
if enableJWT {
// jwt enabled => tls listener without client auth
@ -133,7 +143,17 @@ func (c *Composer) InitLocalWorker(l net.Listener) {
c.localWorkerListener = l
}
func (c *Composer) InitRemoteWorkers(cert, key string, enableJWT bool, l net.Listener) error {
func (c *Composer) InitRemoteWorkers(cert, key string, enableTLS bool, enableMTLS bool, enableJWT bool, l net.Listener) error {
if !enableTLS {
c.workerListener = l
return nil
}
// If both are off or both are on, error out
if enableJWT == enableMTLS {
return fmt.Errorf("Remote worker API: Either mTLS or JWT authentication must be enabled")
}
clientAuth := tls.RequireAndVerifyClientCert
if enableJWT {
// jwt enabled => tls listener without client auth
@ -227,11 +247,11 @@ func (c *Composer) Start() error {
handler := http.Handler(mux)
var err error
if c.config.ComposerAPI.EnableJWT {
if c.config.Koji.EnableJWT {
handler, err = auth.BuildJWTAuthHandler(
c.config.ComposerAPI.JWTKeysURL,
c.config.ComposerAPI.JWTKeysCA,
c.config.ComposerAPI.JWTACLFile,
c.config.Koji.JWTKeysURL,
c.config.Koji.JWTKeysCA,
c.config.Koji.JWTACLFile,
[]string{
"/metrics/?$",
}, mux)

View file

@ -10,32 +10,38 @@ import (
)
type ComposerConfigFile struct {
Koji struct {
AllowedDomains []string `toml:"allowed_domains"`
CA string `toml:"ca"`
} `toml:"koji"`
Worker struct {
AllowedDomains []string `toml:"allowed_domains"`
CA string `toml:"ca"`
PGHost string `toml:"pg_host" env:"PGHOST"`
PGPort string `toml:"pg_port" env:"PGPORT"`
PGDatabase string `toml:"pg_database" env:"PGDATABASE"`
PGUser string `toml:"pg_user" env:"PGUSER"`
PGPassword string `toml:"pg_password" env:"PGPASSWORD"`
PGSSLMode string `toml:"pg_ssl_mode" env:"PGSSLMODE"`
EnableJWT bool `toml:"enable_jwt"`
JWTKeysURL string `toml:"jwt_keys_url"`
JWTKeysCA string `toml:"jwt_ca_file"`
JWTACLFile string `toml:"jwt_acl_file"`
} `toml:"worker"`
ComposerAPI struct {
EnableJWT bool `toml:"enable_jwt"`
JWTKeysURL string `toml:"jwt_keys_url"`
JWTKeysCA string `toml:"jwt_ca_file"`
JWTACLFile string `toml:"jwt_acl_file"`
} `toml:"composer_api"`
WeldrAPI WeldrAPIConfig `toml:"weldr_api"`
logLevel string `toml:"log_level"`
Koji KojiAPIConfig `toml:"koji"`
Worker WorkerAPIConfig `toml:"worker"`
WeldrAPI WeldrAPIConfig `toml:"weldr_api"`
LogLevel string `toml:"log_level"`
}
type KojiAPIConfig struct {
AllowedDomains []string `toml:"allowed_domains"`
CA string `toml:"ca"`
EnableTLS bool `toml:"enable_tls"`
EnableMTLS bool `toml:"enable_mtls"`
EnableJWT bool `toml:"enable_jwt"`
JWTKeysURL string `toml:"jwt_keys_url"`
JWTKeysCA string `toml:"jwt_ca_file"`
JWTACLFile string `toml:"jwt_acl_file"`
}
type WorkerAPIConfig struct {
AllowedDomains []string `toml:"allowed_domains"`
CA string `toml:"ca"`
PGHost string `toml:"pg_host" env:"PGHOST"`
PGPort string `toml:"pg_port" env:"PGPORT"`
PGDatabase string `toml:"pg_database" env:"PGDATABASE"`
PGUser string `toml:"pg_user" env:"PGUSER"`
PGPassword string `toml:"pg_password" env:"PGPASSWORD"`
PGSSLMode string `toml:"pg_ssl_mode" env:"PGSSLMODE"`
EnableTLS bool `toml:"enable_tls"`
EnableMTLS bool `toml:"enable_mtls"`
EnableJWT bool `toml:"enable_jwt"`
JWTKeysURL string `toml:"jwt_keys_url"`
JWTKeysCA string `toml:"jwt_ca_file"`
JWTACLFile string `toml:"jwt_acl_file"`
}
type WeldrAPIConfig struct {
@ -65,6 +71,16 @@ func (c *ComposerConfigFile) weldrDistrosImageTypeDenyList() map[string][]string
// - 'ec2' and 'ec2-ha' image types on 'rhel-85' are not exposed via Weldr API
func GetDefaultConfig() *ComposerConfigFile {
return &ComposerConfigFile{
Koji: KojiAPIConfig{
EnableTLS: true,
EnableMTLS: true,
EnableJWT: false,
},
Worker: WorkerAPIConfig{
EnableTLS: true,
EnableMTLS: true,
EnableJWT: false,
},
WeldrAPI: WeldrAPIConfig{
map[string]WeldrDistroConfig{
"rhel-*": {

View file

@ -23,13 +23,24 @@ func TestNonExisting(t *testing.T) {
func TestDefaultConfig(t *testing.T) {
defaultConfig := GetDefaultConfig()
require.Empty(t, defaultConfig.Koji)
require.Empty(t, defaultConfig.Worker)
require.False(t, defaultConfig.ComposerAPI.EnableJWT)
require.Equal(t, "", defaultConfig.ComposerAPI.JWTKeysCA)
require.False(t, defaultConfig.Koji.EnableJWT)
require.Equal(t, "", defaultConfig.Koji.JWTKeysCA)
require.False(t, defaultConfig.Worker.EnableJWT)
require.Equal(t, "", defaultConfig.Worker.JWTKeysCA)
require.Equal(t, KojiAPIConfig{
EnableTLS: true,
EnableMTLS: true,
EnableJWT: false,
}, defaultConfig.Koji)
require.Equal(t, WorkerAPIConfig{
EnableTLS: true,
EnableMTLS: true,
EnableJWT: false,
}, defaultConfig.Worker)
expectedWeldrAPIConfig := WeldrAPIConfig{
DistroConfigs: map[string]WeldrDistroConfig{
"rhel-*": {
@ -66,10 +77,10 @@ func TestConfig(t *testing.T) {
require.NotNil(t, config)
require.Equal(t, "composer-db", config.Worker.PGDatabase)
require.True(t, config.ComposerAPI.EnableJWT)
require.Equal(t, "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/certs", config.ComposerAPI.JWTKeysURL)
require.Equal(t, "", config.ComposerAPI.JWTKeysCA)
require.Equal(t, "/var/lib/osbuild-composer/acl", config.ComposerAPI.JWTACLFile)
require.False(t, config.Koji.EnableJWT)
require.Equal(t, "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/certs", config.Koji.JWTKeysURL)
require.Equal(t, "", config.Koji.JWTKeysCA)
require.Equal(t, "/var/lib/osbuild-composer/acl", config.Koji.JWTACLFile)
}
func TestWeldrDistrosImageTypeDenyList(t *testing.T) {

View file

@ -40,7 +40,7 @@ func main() {
}
logrus.SetOutput(os.Stdout)
logLevel, err := logrus.ParseLevel(config.logLevel)
logLevel, err := logrus.ParseLevel(config.LogLevel)
if err == nil {
logrus.SetLevel(logLevel)
@ -98,7 +98,7 @@ func main() {
logrus.Fatal("The osbuild-composer-api.socket unit is misconfigured. It should contain only one socket.")
}
err = composer.InitAPI(ServerCertFile, ServerKeyFile, config.ComposerAPI.EnableJWT, l[0])
err = composer.InitAPI(ServerCertFile, ServerKeyFile, config.Koji.EnableTLS, config.Koji.EnableMTLS, config.Koji.EnableJWT, l[0])
if err != nil {
logrus.Fatalf("Error initializing koji API: %v", err)
}
@ -109,7 +109,7 @@ func main() {
logrus.Fatal("The osbuild-remote-worker.socket unit is misconfigured. It should contain only one socket.")
}
err = composer.InitRemoteWorkers(ServerCertFile, ServerKeyFile, config.Worker.EnableJWT, l[0])
err = composer.InitRemoteWorkers(ServerCertFile, ServerKeyFile, config.Worker.EnableTLS, config.Worker.EnableMTLS, config.Worker.EnableJWT, l[0])
if err != nil {
logrus.Fatalf("Error initializing worker API: %v", err)
}

View file

@ -1,6 +1,9 @@
[koji]
allowed_domains = [ "osbuild.org" ]
ca = "/etc/osbuild-composer/ca-crt.pem"
enable_jwt = false
jwt_keys_url = "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/certs"
jwt_acl_file = "/var/lib/osbuild-composer/acl"
[worker]
allowed_domains = [ "osbuild.org" ]
@ -15,8 +18,3 @@ image_type_denylist = [ "qcow2" ]
# overrides the default rhel-* configuration
[weldr_api.distros."rhel-*"]
[composer_api]
enable_jwt = true
jwt_keys_url = "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/certs"
jwt_acl_file = "/var/lib/osbuild-composer/acl"

View file

@ -1157,26 +1157,24 @@ sudo mv -f /usr/libexec/osbuild-composer/dnf-json.bak /usr/libexec/osbuild-compo
#
cat <<EOF | sudo tee "/etc/osbuild-composer/osbuild-composer.toml"
[koji]
allowed_domains = [ "localhost", "client.osbuild.org" ]
ca = "/etc/osbuild-composer/ca-crt.pem"
enable_tls = false
enable_mtls = false
enable_jwt = true
jwt_keys_url = "https://localhost:8080/certs"
jwt_ca_file = "/etc/osbuild-composer/ca-crt.pem"
jwt_acl_file = ""
[worker]
allowed_domains = [ "localhost", "worker.osbuild.org" ]
ca = "/etc/osbuild-composer/ca-crt.pem"
pg_host = "localhost"
pg_port = "5432"
pg_database = "osbuildcomposer"
pg_user = "postgres"
pg_password = "foobar"
pg_ssl_mode = "disable"
enable_tls = false
enable_mtls = false
enable_jwt = true
jwt_keys_url = "https://localhost:8080/certs"
jwt_ca_file = "/etc/osbuild-composer/ca-crt.pem"
[composer_api]
enable_jwt = true
jwt_keys_url = "https://localhost:8080/certs"
jwt_ca_file = "/etc/osbuild-composer/ca-crt.pem"
jwt_acl_file = ""
EOF
cat <<EOF | sudo tee "/etc/osbuild-worker/token"
@ -1205,21 +1203,19 @@ TOKEN="$(curl localhost:8081/token | jq -r .access_token)"
[ "$(curl \
--silent \
--cacert /etc/osbuild-composer/ca-crt.pem \
--output /dev/null \
--write-out '%{http_code}' \
--header "Authorization: Bearer $TOKEN" \
https://localhost/api/composer/v1/version)" = "200" ]
http://localhost:443/api/composer/v1/version)" = "200" ]
[ "$(curl \
--silent \
--cacert /etc/osbuild-composer/ca-crt.pem \
--output /dev/null \
--write-out '%{http_code}' \
--header "Authorization: Bearer badtoken" \
https://localhost/api/composer/v1/version)" = "401" ]
http://localhost:443/api/composer/v1/version)" = "401" ]
sudo systemctl start osbuild-remote-worker@https:--localhost:8700.service
sudo systemctl is-active --quiet osbuild-remote-worker@https:--localhost:8700.service
sudo systemctl start osbuild-remote-worker@http:--localhost:8700.service
sudo systemctl is-active --quiet osbuild-remote-worker@http:--localhost:8700.service
exit 0