Do not call `chown` to config files

This commit fixes a recently discovered issue on Kubernetes #4496
It make necessary to avoid calling `chown` to config files during the
bootstrap of the containers.
This commit is contained in:
Tan Jiang 2018-04-08 23:43:45 +08:00
parent 4da4dd6694
commit 1fc4142e1a
15 changed files with 56 additions and 43 deletions

View File

@ -22,7 +22,7 @@
"realm": "$token_endpoint/service/token",
"service": "harbor-notary",
"issuer": "harbor-token-issuer",
"rootcertbundle": "/config/root.crt"
"rootcertbundle": "/etc/notary/root.crt"
}
}
}

View File

@ -41,7 +41,7 @@ services:
depends_on:
- postgres
volumes:
- ./common/config/clair:/config:z
- ./common/config/clair/config.yaml:/etc/clair/config.yaml:z
logging:
driver: "syslog"
options:

View File

@ -15,7 +15,7 @@ services:
- notary-sig
- harbor-notary
volumes:
- ./common/config/notary:/config:z
- ./common/config/notary:/etc/notary:z
depends_on:
- notary-db
- notary-signer
@ -34,7 +34,7 @@ services:
aliases:
- notarysigner
volumes:
- ./common/config/notary:/config:z
- ./common/config/notary:/etc/notary:z
env_file:
- ./common/config/notary/signer_env
depends_on:

View File

@ -1,5 +1,4 @@
#!/bin/bash
set -e
chown -R 10000:10000 /config
sudo -E -H -u \#10000 sh -c "/dumb-init -- /clair2.0.1/clair -config /config/config.yaml"
sudo -E -H -u \#10000 sh -c "/dumb-init -- /clair2.0.1/clair -config /etc/clair/config.yaml"
set +e

View File

@ -1,13 +1,4 @@
#!/bin/sh
if [ -d /etc/jobservice/ ]; then
chown -R 10000:10000 /etc/jobservice/
fi
if [ -d /var/log/jobs ]; then
chown -R 10000:10000 /var/log/jobs/
fi
if [ -d /var/log/jobs/scan_job ]; then
chmod +x /var/log/jobs/scan_job
fi
sudo -E -u \#10000 "/harbor/harbor_jobservice" "-c" "/etc/jobservice/config.yml"

View File

@ -1,3 +1,2 @@
#!/bin/sh
chown 10000:10000 -R /config
sudo -E -u \#10000 sh -c "/usr/bin/env /migrations/migrate.sh && /bin/notary-server -config=/config/server-config.json -logf=logfmt"
sudo -E -u \#10000 sh -c "/usr/bin/env /migrations/migrate.sh && /bin/notary-server -config=/etc/notary/server-config.json -logf=logfmt"

View File

@ -1,3 +1,2 @@
#!/bin/sh
chown 10000:10000 -R /config
sudo -E -u \#10000 sh -c "/usr/bin/env && /migrations/migrate.sh && /bin/notary-signer -config=/config/signer-config.json -logf=logfmt"
sudo -E -u \#10000 sh -c "/usr/bin/env && /migrations/migrate.sh && /bin/notary-signer -config=/etc/notary/signer-config.json -logf=logfmt"

View File

@ -2,12 +2,12 @@
set -e
if [ -d /etc/registry ]; then
chown 10000:10000 -R /etc/registry
fi
# The directory /var/lib/registry is within the container, and used to store image in CI testing.
# So for now we need to chown to it to avoid failure in CI.
if [ -d /var/lib/registry ]; then
chown 10000:10000 -R /var/lib/registry
fi
if [ -d /storage ]; then
if ! stat -c '%u:%g' /storage | grep -q '10000:10000' ; then
# 10000 is the id of harbor user/group.

View File

@ -1,6 +1,3 @@
#!/bin/sh
if [ -d /etc/ui/ ]; then
chown -R 10000:10000 /etc/ui/
fi
sudo -E -u \#10000 "/harbor/harbor_ui"

View File

@ -19,6 +19,9 @@ if sys.version_info[:3][0] == 3:
import configparser as ConfigParser
import io as StringIO
DATA_VOL = "/data"
JOB_LOG_DIR = os.path.join(DATA_VOL, "job_logs")
def validate(conf, args):
if args.ha_mode:
db_host = rcp.get("configuration", "db_host")
@ -68,6 +71,12 @@ def validate(conf, args):
if project_creation != "everyone" and project_creation != "adminonly":
raise Exception("Error invalid value for project_creation_restriction: %s" % project_creation)
#To meet security requirement
#By default it will change file mode to 0600, and make the owner of the file to 10000:10000
def mark_file(path, mode=0o600, uid=10000, gid=10000):
os.chmod(path, mode)
os.chown(path, uid, gid)
def prepare_ha(conf, args):
#files under ha folder will have high prority
protocol = rcp.get("configuration", "ui_url_protocol")
@ -88,7 +97,7 @@ def prepare_ha(conf, args):
if os.path.isfile(cert_path):
shutil.copy2(cert_path, shared_cert_path)
#check if ca exsit
cert_ca_path = "/data/ca_download/ca.crt"
cert_ca_path = os.path.join(DATA_VOL, 'ca_download', 'ca.crt')
shared_ca_path = os.path.join(base_dir, "ha", os.path.basename(cert_ca_path))
if os.path.isfile(shared_ca_path):
shutil.copy2(shared_ca_path, cert_ca_path)
@ -138,16 +147,16 @@ def _get_secret(folder, filename, length=16):
print("loaded secret from file: %s" % key_file)
return key
if not os.path.isdir(folder):
os.makedirs(folder, mode=0o600)
os.makedirs(folder)
key = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(length))
with open(key_file, 'w') as f:
f.write(key)
print("Generated and saved secret to file: %s" % key_file)
os.chmod(key_file, 0o600)
mark_file(key_file)
return key
def prep_conf_dir(root, name):
absolute_path = os.path.join(root, name)
def prep_conf_dir(root, *name):
absolute_path = os.path.join(root, *name)
if not os.path.exists(absolute_path):
os.makedirs(absolute_path)
return absolute_path
@ -173,6 +182,10 @@ def delfile(src):
itemsrc=os.path.join(src,item)
delfile(itemsrc)
if not os.path.exists(JOB_LOG_DIR):
os.makedirs(JOB_LOG_DIR)
mark_file(JOB_LOG_DIR, mode=0o755)
parser = argparse.ArgumentParser()
parser.add_argument('--conf', dest='cfgfile', default=base_dir+'/harbor.cfg',type=str,help="the path of Harbor configuration file")
parser.add_argument('--with-notary', dest='notary_mode', default=False, action='store_true', help="the Harbor instance is to be deployed with notary")
@ -431,7 +444,7 @@ shutil.copyfile(os.path.join(templates_dir, "ui", "app.conf"), ui_conf)
if auth_mode == "uaa_auth":
if os.path.isfile(uaa_ca_cert):
if not os.path.isdir(ui_cert_dir):
os.makedirs(ui_cert_dir, mode=0o600)
os.makedirs(ui_cert_dir)
ui_uaa_ca = os.path.join(ui_cert_dir, "uaa_ca.pem")
print("Copying UAA CA cert to %s" % ui_uaa_ca)
shutil.copyfile(uaa_ca_cert, ui_uaa_ca)
@ -491,8 +504,8 @@ if customize_crt == 'on' and openssl_installed():
private_key_pem = os.path.join(config_dir, "ui", "private_key.pem")
root_crt = os.path.join(config_dir, "registry", "root.crt")
create_root_cert(empty_subj, key_path=private_key_pem, cert_path=root_crt)
os.chmod(private_key_pem, 0o600)
os.chmod(root_crt, 0o600)
mark_file(private_key_pem)
mark_file(root_crt)
else:
print("Copied configuration file: %s" % ui_config_dir + "private_key.pem")
shutil.copyfile(os.path.join(templates_dir, "ui", "private_key.pem"), os.path.join(ui_config_dir, "private_key.pem"))
@ -520,9 +533,6 @@ if args.notary_mode:
create_root_cert(ca_subj, key_path=signer_ca_key, cert_path=signer_ca_cert)
create_cert(cert_subj, signer_ca_key, signer_ca_cert, key_path=signer_key_path, cert_path=signer_cert_path)
print("Copying certs for notary signer")
os.chmod(signer_cert_path, 0o600)
os.chmod(signer_key_path, 0o600)
os.chmod(signer_ca_cert, 0o600)
shutil.copy2(signer_cert_path, notary_config_dir)
shutil.copy2(signer_key_path, notary_config_dir)
shutil.copy2(signer_ca_cert, notary_config_dir)
@ -538,6 +548,10 @@ if args.notary_mode:
shutil.copy2(os.path.join(notary_temp_dir, "notary-signer.key"), notary_config_dir)
shutil.copy2(os.path.join(notary_temp_dir, "notary-signer-ca.crt"), notary_config_dir)
shutil.copy2(os.path.join(registry_config_dir, "root.crt"), notary_config_dir)
mark_file(os.path.join(notary_config_dir, "notary-signer.crt"))
mark_file(os.path.join(notary_config_dir, "notary-signer.key"))
mark_file(os.path.join(notary_config_dir, "notary-signer-ca.crt"))
mark_file(os.path.join(notary_config_dir, "root.crt"))
print("Copying notary signer configuration file")
shutil.copy2(os.path.join(notary_temp_dir, "signer-config.json"), notary_config_dir)
render(os.path.join(notary_temp_dir, "server-config.json"),

View File

@ -36,7 +36,7 @@ import (
)
var (
notaryCachePath = "/etc/ui/notary-cache"
notaryCachePath = "/tmp/notary-cache"
trustPin trustpinning.TrustPinConfig
mockRetriever notary.PassRetriever
)

View File

@ -38,8 +38,9 @@ import (
)
const (
defaultKeyPath string = "/etc/ui/key"
defaultTokenFilePath string = "/etc/ui/token/tokens.properties"
defaultKeyPath = "/etc/ui/key"
defaultTokenFilePath = "/etc/ui/token/tokens.properties"
defaultRegistryTokenPrivateKeyPath = "/etc/ui/private_key.pem"
)
var (
@ -56,7 +57,7 @@ var (
AdmiralClient *http.Client
// TokenReader is used in integration mode to read token
TokenReader admiral.TokenReader
// defined as a var for testing.
defaultCACertPath = "/etc/ui/ca/ca.crt"
)
@ -189,6 +190,15 @@ func AuthMode() (string, error) {
return cfg[common.AUTHMode].(string), nil
}
// TokenPrivateKeyPath returns the path to the key for signing token for registry
func TokenPrivateKeyPath() string {
path := os.Getenv("TOKEN_PRIVATE_KEY_PATH")
if len(path) == 0 {
path = defaultRegistryTokenPrivateKeyPath
}
return path
}
// LDAPConf returns the setting of ldap server
func LDAPConf() (*models.LdapConf, error) {
cfg, err := mg.Get()

View File

@ -185,6 +185,10 @@ func TestConfig(t *testing.T) {
t.Errorf("unexpected scan all policy %v", s)
}
if tokenKeyPath := TokenPrivateKeyPath(); tokenKeyPath != "/etc/ui/private_key.pem" {
t.Errorf("Unexpected token private key path: %s, expected: %s", tokenKeyPath, "/etc/ui/private_key.pem")
}
us, err := UAASettings()
if err != nil {
t.Fatalf("failed to get UAA setting, error: %v", err)

View File

@ -39,7 +39,7 @@ const (
var privateKey string
func init() {
privateKey = "/etc/ui/private_key.pem"
privateKey = config.TokenPrivateKeyPath()
}
// GetResourceActions ...

View File

@ -3,10 +3,10 @@ set -e
cp tests/docker-compose.test.yml make/.
mkdir -p /etc/ui
cp make/common/config/ui/private_key.pem /etc/ui/.
cp make/common/config/ui/private_key.pem /etc/ui/
mkdir src/ui/conf
cp make/common/config/ui/app.conf src/ui/conf/.
cp make/common/config/ui/app.conf src/ui/conf/
IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'`
echo "server ip is "$IP
sed -i -r "s/MYSQL_HOST=mysql/MYSQL_HOST=$IP/" make/common/config/adminserver/env