From 402a482bc6fbd40ab33eb2f06829a09d875ea48b Mon Sep 17 00:00:00 2001 From: Tan Jiang Date: Thu, 23 Mar 2017 21:00:53 +0800 Subject: [PATCH 1/2] generate cert for notary signer in prepare --- .../{root-ca.crt => notary-signer-ca.crt} | 0 .../templates/notary/server-config.json | 2 +- make/docker-compose.notary.yml | 2 + make/prepare | 68 ++++++++++++------- 4 files changed, 47 insertions(+), 25 deletions(-) rename make/common/templates/notary/{root-ca.crt => notary-signer-ca.crt} (100%) diff --git a/make/common/templates/notary/root-ca.crt b/make/common/templates/notary/notary-signer-ca.crt similarity index 100% rename from make/common/templates/notary/root-ca.crt rename to make/common/templates/notary/notary-signer-ca.crt diff --git a/make/common/templates/notary/server-config.json b/make/common/templates/notary/server-config.json index 8e6af5d22..dc8ffba31 100644 --- a/make/common/templates/notary/server-config.json +++ b/make/common/templates/notary/server-config.json @@ -6,7 +6,7 @@ "type": "remote", "hostname": "notarysigner", "port": "7899", - "tls_ca_file": "./root-ca.crt", + "tls_ca_file": "./notary-signer-ca.crt", "key_algorithm": "ecdsa" }, "logging": { diff --git a/make/docker-compose.notary.yml b/make/docker-compose.notary.yml index 0b6340366..102bf3641 100644 --- a/make/docker-compose.notary.yml +++ b/make/docker-compose.notary.yml @@ -60,6 +60,8 @@ services: - TERM=dumb - MYSQL_ALLOW_EMPTY_PASSWORD="true" command: mysqld --innodb_file_per_table + depends_on: + - log logging: driver: "syslog" options: diff --git a/make/prepare b/make/prepare index 2d0ddc67a..878242da3 100755 --- a/make/prepare +++ b/make/prepare @@ -262,29 +262,33 @@ FNULL = open(os.devnull, 'w') from functools import wraps def stat_decorator(func): @wraps(func) - def check_wrapper(*args, **kwargs): - stat = func(*args, **kwargs) - message = "Generated configuration file: %s" % kwargs['path'] \ - if stat == 0 else "Fail to generate %s" % kwargs['path'] + def check_wrapper(*args, **kw): + stat = func(*args, **kw) + message = "Generated certificate, key file: %s, cert file: %s" % (kw['key_path'], kw['cert_path']) \ + if stat == 0 else "Fail to generate key file: %s, cert file: %s" % (kw['key_path'], kw['cert_path']) print(message) if stat != 0: sys.exit(1) return check_wrapper @stat_decorator -def check_private_key_stat(*args, **kwargs): - return subprocess.call(["openssl", "genrsa", "-out", kwargs['path'], "4096"],\ - stdout=FNULL, stderr=subprocess.STDOUT) +def create_root_cert(subj, key_path="./k.key", cert_path="./cert.crt"): + rc = subprocess.call(["openssl", "genrsa", "-out", key_path, "4096"]) + if rc != 0: + return rc + return subprocess.call(["openssl", "req", "-new", "-x509", "-key", key_path,\ + "-out", cert_path, "-days", "3650", "-subj", subj]) @stat_decorator -def check_certificate_stat(*args, **kwargs): - dirty_subj = "/C={0}/ST={1}/L={2}/O={3}/OU={4}/CN={5}/emailAddress={6}"\ - .format(crt_country, crt_state, crt_location, crt_organization,\ - crt_organizationalunit, crt_commonname, crt_email) - subj = validate_crt_subj(dirty_subj) - return subprocess.call(["openssl", "req", "-new", "-x509", "-key",\ - private_key_pem, "-out", root_crt, "-days", "3650", "-subj", subj], \ - stdout=FNULL, stderr=subprocess.STDOUT) +def create_cert(subj, ca_key, ca_cert, key_path="./k.key", cert_path="./cert.crt"): + cert_dir = os.path.dirname(cert_path) + csr_path = os.path.join(cert_dir, "tmp.csr") + rc = subprocess.call(["openssl", "req", "-newkey", "rsa:4096", "-nodes","-sha256","-keyout", key_path,\ + "-out", csr_path, "-subj", subj]) + if rc != 0: + return rc + return subprocess.call(["openssl", "x509", "-req", "-days", "3650", "-in", csr_path, "-CA", \ + ca_cert, "-CAkey", ca_key, "-CAcreateserial", "-out", cert_path]) def openssl_is_installed(stat): if stat == 0: @@ -296,15 +300,14 @@ def openssl_is_installed(stat): if customize_crt == 'on': shell_stat = subprocess.check_call(["which", "openssl"], stdout=FNULL, stderr=subprocess.STDOUT) if openssl_is_installed(shell_stat): + empty_subj = "/C=/ST=/L=/O=/CN=/" private_key_pem = os.path.join(config_dir, "ui", "private_key.pem") root_crt = os.path.join(config_dir, "registry", "root.crt") - - check_private_key_stat(path=private_key_pem) - check_certificate_stat(path=root_crt) + create_root_cert(empty_subj, key_path=private_key_pem, cert_path=root_crt) else: - print("Generated configuration file: %s" % ui_config_dir + "private_key.pem") + 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")) - print("Generated configuration file: %s" % registry_config_dir + "root.crt") + print("Copied configuration file: %s" % registry_config_dir + "root.crt") shutil.copyfile(os.path.join(templates_dir, "registry", "root.crt"), os.path.join(registry_config_dir, "root.crt")) FNULL.close() @@ -316,10 +319,27 @@ if args.notary_mode: shutil.rmtree(os.path.join(notary_config_dir, "mysql-initdb.d")) shutil.copytree(os.path.join(notary_temp_dir, "mysql-initdb.d"), os.path.join(notary_config_dir, "mysql-initdb.d")) #TODO:generate certs? - print("Copying certs for notary signer") - shutil.copy2(os.path.join(notary_temp_dir, "notary-signer.crt"), notary_config_dir) - shutil.copy2(os.path.join(notary_temp_dir, "notary-signer.key"), notary_config_dir) - shutil.copy2(os.path.join(notary_temp_dir, "root-ca.crt"), notary_config_dir) + if customize_crt == 'on': + temp_cert_dir = os.path.join(base_dir, "cert_tmp") + if not os.path.exists(temp_cert_dir): + os.makedirs(temp_cert_dir) + ca_subj = "/C=US/ST=California/L=Palo Alto/O=Vmware/CN=Self Signed CA/" + cert_subj = "/C=US/ST=California/L=Palo Alto/O=Vmware/CN=notarysigner/" + signer_ca_cert = os.path.join(temp_cert_dir, "notary-signer-ca.crt") + signer_ca_key = os.path.join(temp_cert_dir, "notary-signer-ca.key") + signer_cert_path = os.path.join(temp_cert_dir, "notary-signer.crt") + signer_key_path = os.path.join(temp_cert_dir, "notary-signer.key") + 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") + shutil.copy2(signer_cert_path, notary_config_dir) + shutil.copy2(signer_key_path, notary_config_dir) + shutil.copy2(signer_ca_cert, notary_config_dir) + else: + print("Copying certs for notary signer") + shutil.copy2(os.path.join(notary_temp_dir, "notary-signer.crt"), notary_config_dir) + 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) print("Copying notary signer configuration file") From 90bc280ea10f4da57a45ebc0a1eede3fc17b4e66 Mon Sep 17 00:00:00 2001 From: Tan Jiang Date: Fri, 24 Mar 2017 13:16:48 +0800 Subject: [PATCH 2/2] add a 4443 ssl server to nginx config --- docs/use_notary.md | 5 ++- make/common/templates/nginx/nginx.https.conf | 5 ++- .../templates/nginx/notary.location.conf | 12 ------- .../common/templates/nginx/notary.server.conf | 33 +++++++++++++++++++ make/prepare | 2 +- tests/notarytest.sh | 4 +-- 6 files changed, 40 insertions(+), 21 deletions(-) delete mode 100644 make/common/templates/nginx/notary.location.conf create mode 100644 make/common/templates/nginx/notary.server.conf diff --git a/docs/use_notary.md b/docs/use_notary.md index 08d2dfbb0..bd47a0b34 100644 --- a/docs/use_notary.md +++ b/docs/use_notary.md @@ -10,14 +10,13 @@ It can be done via setting envrironment variables: ``` export DOCKER_CONTENT_TRUST=1 -export DOCKER_CONTENT_TRUST_SERVER=https://192.168.0.5/notary +export DOCKER_CONTENT_TRUST_SERVER=https://192.168.0.5:4443/ ``` ### Set alias for notary (optional) Because by default the local directory for storing meta files for notary client is different from docker client. If you want to use notary client to manipulate the keys/meta files generated by Docker Content Trust, please set the alias to reduce the effort: ``` -alias notary="notary -s https//192.168.0.5 -d ~/.docker/trust --tlscacert / -etc/docker/certs.d/192.168.0.5/ca.crt" +alias notary="notary -s https//192.168.0.5:4443 -d ~/.docker/trust --tlscacert /etc/docker/certs.d/192.168.0.5/ca.crt" ``` diff --git a/make/common/templates/nginx/nginx.https.conf b/make/common/templates/nginx/nginx.https.conf index 46cbc0e07..141961ecf 100644 --- a/make/common/templates/nginx/nginx.https.conf +++ b/make/common/templates/nginx/nginx.https.conf @@ -20,7 +20,8 @@ http { upstream ui { server ui:80; } - + + include /etc/nginx/conf.d/*.server.conf; server { listen 443 ssl; @@ -42,8 +43,6 @@ http { # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; - include /etc/nginx/conf.d/*.location.conf; - location / { proxy_pass http://ui/; proxy_set_header Host $$http_host; diff --git a/make/common/templates/nginx/notary.location.conf b/make/common/templates/nginx/notary.location.conf deleted file mode 100644 index cf280befa..000000000 --- a/make/common/templates/nginx/notary.location.conf +++ /dev/null @@ -1,12 +0,0 @@ -location /notary/v2/ { - proxy_pass http://notary-server/v2/; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. - proxy_set_header X-Forwarded-Proto $scheme; - - proxy_buffering off; - proxy_request_buffering off; -} diff --git a/make/common/templates/nginx/notary.server.conf b/make/common/templates/nginx/notary.server.conf new file mode 100644 index 000000000..413461bd4 --- /dev/null +++ b/make/common/templates/nginx/notary.server.conf @@ -0,0 +1,33 @@ + server { + listen 4443 ssl; + + # ssl + ssl_certificate /etc/nginx/cert/server.crt; + ssl_certificate_key /etc/nginx/cert/server.key; + + # recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html + ssl_protocols tlsv1.1 tlsv1.2; + ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:ssl:10m; + + # disable any limits to avoid http 413 for large image uploads + client_max_body_size 0; + + # required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486) + chunked_transfer_encoding on; + + location /v2/ { + proxy_pass http://notary-server/v2/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_buffering off; + proxy_request_buffering off; + } + } + diff --git a/make/prepare b/make/prepare index 878242da3..df52b6662 100755 --- a/make/prepare +++ b/make/prepare @@ -350,7 +350,7 @@ if args.notary_mode: print("Copying nginx configuration file for notary") shutil.copy2(os.path.join(templates_dir, "nginx", "notary.upstream.conf"), nginx_conf_d) - shutil.copy2(os.path.join(templates_dir, "nginx", "notary.location.conf"), nginx_conf_d) + shutil.copy2(os.path.join(templates_dir, "nginx", "notary.server.conf"), nginx_conf_d) default_alias = ''.join(random.choice(string.ascii_letters) for i in range(8)) render(os.path.join(notary_temp_dir, "signer_env"), os.path.join(notary_config_dir, "signer_env"), alias = default_alias) diff --git a/tests/notarytest.sh b/tests/notarytest.sh index 1f48f4449..4cdd515cb 100755 --- a/tests/notarytest.sh +++ b/tests/notarytest.sh @@ -4,7 +4,7 @@ set -e TIMEOUT=10 while [ $TIMEOUT -gt 0 ]; do - STATUS=$(curl -s -o /dev/null -w '%{http_code}' https://127.0.0.1/notary/v2/ -kv) + STATUS=$(curl -s -o /dev/null -w '%{http_code}' https://127.0.0.1:4443/v2/ -kv) if [ $STATUS -eq 401 ]; then echo "Notary is running success." break @@ -16,4 +16,4 @@ done if [ $TIMEOUT -eq 0 ]; then echo "Notary is running fail." exit 1 -fi \ No newline at end of file +fi