diff --git a/make/photon/portal/Dockerfile b/make/photon/portal/Dockerfile index c65746652..571586983 100644 --- a/make/photon/portal/Dockerfile +++ b/make/photon/portal/Dockerfile @@ -37,14 +37,11 @@ COPY --from=nodeportal /build_dir/swagger2.json /usr/share/nginx/html COPY --from=nodeportal /build_dir/swagger3.json /usr/share/nginx/html COPY --from=nodeportal /build_dir/LICENSE /usr/share/nginx/html -COPY make/photon/portal/nginx.conf /etc/nginx/nginx.conf - -EXPOSE 8080 VOLUME /var/cache/nginx /var/log/nginx /run STOPSIGNAL SIGQUIT -HEALTHCHECK CMD curl --fail -s http://127.0.0.1:8080 || exit 1 +HEALTHCHECK CMD curl --fail -s http://127.0.0.1:8080 || curl --fail -s http://127.0.0.1:8443 || exit 1 USER nginx CMD ["nginx", "-g", "daemon off;"] diff --git a/make/photon/prepare/commands/prepare.py b/make/photon/prepare/commands/prepare.py index dae5dcc14..10b112d51 100644 --- a/make/photon/prepare/commands/prepare.py +++ b/make/photon/prepare/commands/prepare.py @@ -23,6 +23,7 @@ from utils.nginx import prepare_nginx, nginx_confd_dir from utils.redis import prepare_redis from utils.internal_tls import prepare_tls from utils.trivy_adapter import prepare_trivy_adapter +from utils.portal import prepare_portal from g import (config_dir, input_config_path, private_key_pem_path, root_crt_path, secret_key_dir, old_private_key_pem_path, old_crt_path) @@ -43,6 +44,7 @@ def prepare(conf, with_notary, with_clair, with_trivy, with_chartmuseum): logging.error(e) sys.exit(-1) + prepare_portal(config_dict) prepare_log_configs(config_dict) prepare_nginx(config_dict) prepare_core(config_dict, with_notary=with_notary, with_clair=with_clair, with_trivy=with_trivy, with_chartmuseum=with_chartmuseum) diff --git a/make/photon/prepare/g.py b/make/photon/prepare/g.py index 0448beac1..3ae9ca6b4 100644 --- a/make/photon/prepare/g.py +++ b/make/photon/prepare/g.py @@ -12,7 +12,7 @@ REDIS_UID = 999 REDIS_GID = 999 ## Global variable -templates_dir = "/usr/src/app/templates" +templates_dir = Path("/usr/src/app/templates") host_root_dir = Path('/hostfs') diff --git a/make/photon/prepare/models.py b/make/photon/prepare/models.py index 0caf4c38c..c0317ac12 100644 --- a/make/photon/prepare/models.py +++ b/make/photon/prepare/models.py @@ -15,7 +15,8 @@ class InternalTLS: 'core.crt', 'core.key', 'job_service.crt', 'job_service.key', 'registryctl.crt', 'registryctl.key', - 'registry.crt', 'registry.key' + 'registry.crt', 'registry.key', + 'portal.crt', 'portal.key' } clair_certs_filename = { diff --git a/make/photon/prepare/scripts/gencert.sh b/make/photon/prepare/scripts/gencert.sh index a7366ec67..a4a24c338 100755 --- a/make/photon/prepare/scripts/gencert.sh +++ b/make/photon/prepare/scripts/gencert.sh @@ -30,6 +30,14 @@ openssl req -new -newkey rsa:4096 -nodes -sha256 \ # Sign proxy openssl x509 -req -days $DAYS -sha256 -in proxy.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out proxy.crt +# generate portal key and csr +openssl req -new -newkey rsa:4096 -nodes -sha256 \ + -keyout portal.key \ + -out portal.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=portal" + +# Sign portal +openssl x509 -req -days $DAYS -sha256 -in portal.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out portal.crt # generate core key and csr openssl req -new \ diff --git a/make/photon/prepare/templates/core/env.jinja b/make/photon/prepare/templates/core/env.jinja index d4acab9c4..1657ea7db 100644 --- a/make/photon/prepare/templates/core/env.jinja +++ b/make/photon/prepare/templates/core/env.jinja @@ -17,6 +17,7 @@ POSTGRESQL_SSLMODE={{harbor_db_sslmode}} POSTGRESQL_MAX_IDLE_CONNS={{harbor_db_max_idle_conns}} POSTGRESQL_MAX_OPEN_CONNS={{harbor_db_max_open_conns}} REGISTRY_URL={{registry_url}} +PORTAL_URL={{portal_url}} TOKEN_SERVICE_URL={{token_service_url}} HARBOR_ADMIN_PASSWORD={{harbor_admin_password}} MAX_JOB_WORKERS={{max_job_workers}} diff --git a/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja b/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja index efe687bd5..bc0f1586f 100644 --- a/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja +++ b/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja @@ -234,6 +234,18 @@ services: - SETGID - SETUID - NET_BIND_SERVICE + volumes: + - type: bind + source: ./common/config/portal/nginx.conf + target: /etc/nginx/nginx.conf +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.portal_crt_path}} + target: /etc/harbor/tls/portal.crt + - type: bind + source: {{internal_tls.portal_key_path}} + target: /etc/harbor/tls/portal.key +{% endif %} networks: - harbor dns_search: . diff --git a/make/photon/prepare/templates/nginx/nginx.http.conf.jinja b/make/photon/prepare/templates/nginx/nginx.http.conf.jinja index c6d2df6c1..724a6241e 100644 --- a/make/photon/prepare/templates/nginx/nginx.http.conf.jinja +++ b/make/photon/prepare/templates/nginx/nginx.http.conf.jinja @@ -19,11 +19,19 @@ http { proxy_http_version 1.1; upstream core { +{% if internal_tls.enabled %} + server core:8443; +{% else %} server core:8080; +{% endif %} } upstream portal { +{% if internal_tls.enabled %} + server portal:8443; +{% else %} server portal:8080; +{% endif %} } log_format timed_combined '$remote_addr - ' @@ -47,7 +55,18 @@ http { include /etc/nginx/conf.d/harbor.http.*.conf; location / { +{% if internal_tls.enabled %} + proxy_pass https://portal/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://portal/; +{% endif %} proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -60,7 +79,18 @@ http { } location /c/ { +{% if internal_tls.enabled %} + proxy_pass https://core/c/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://core/c/; +{% endif %} proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -73,7 +103,18 @@ http { } location /api/ { +{% if internal_tls.enabled %} + proxy_pass https://core/api/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://core/api/; +{% endif %} proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -86,7 +127,18 @@ http { } location /chartrepo/ { +{% if internal_tls.enabled %} + proxy_pass https://core/chartrepo/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://core/chartrepo/; +{% endif %} proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -103,7 +155,18 @@ http { } location /v2/ { +{% if internal_tls.enabled %} + proxy_pass https://core/v2/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://core/v2/; +{% endif %} 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; @@ -118,7 +181,18 @@ http { } location /service/ { +{% if internal_tls.enabled %} + proxy_pass https://core/service/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://core/service/; +{% endif %} proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/make/photon/prepare/templates/nginx/nginx.https.conf.jinja b/make/photon/prepare/templates/nginx/nginx.https.conf.jinja index c7e2e4c42..02b780dbe 100644 --- a/make/photon/prepare/templates/nginx/nginx.https.conf.jinja +++ b/make/photon/prepare/templates/nginx/nginx.https.conf.jinja @@ -28,9 +28,13 @@ http { } upstream portal { +{% if internal_tls.enabled %} + server portal:8443; +{% else %} server portal:8080; +{% endif %} } - + log_format timed_combined '$remote_addr - ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' @@ -69,7 +73,18 @@ http { include /etc/nginx/conf.d/harbor.https.*.conf; location / { +{% if internal_tls.enabled %} + proxy_pass https://portal/; + + proxy_ssl_certificate /etc/harbor/tls/proxy.crt; + proxy_ssl_certificate_key /etc/harbor/tls/proxy.key; + proxy_ssl_trusted_certificate /harbor_cust_cert/harbor_internal_ca.crt; + proxy_ssl_verify_depth 2; + proxy_ssl_verify on; + proxy_ssl_session_reuse on; +{% else %} proxy_pass http://portal/; +{% endif %} 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; diff --git a/make/photon/portal/nginx.conf b/make/photon/prepare/templates/portal/nginx.conf.jinja similarity index 65% rename from make/photon/portal/nginx.conf rename to make/photon/prepare/templates/portal/nginx.conf.jinja index 475fa6e6d..d028b1a06 100644 --- a/make/photon/portal/nginx.conf +++ b/make/photon/prepare/templates/portal/nginx.conf.jinja @@ -15,7 +15,20 @@ http { scgi_temp_path /tmp/scgi_temp; server { +{% if internal_tls.enabled %} + listen 8443 ssl; + # SSL + ssl_certificate /etc/harbor/tls/portal.crt; + ssl_certificate_key /etc/harbor/tls/portal.key; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols 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; +{% else %} listen 8080; +{% endif %} server_name localhost; root /usr/share/nginx/html; diff --git a/make/photon/prepare/utils/configs.py b/make/photon/prepare/utils/configs.py index 0084ee468..871793e1d 100644 --- a/make/photon/prepare/utils/configs.py +++ b/make/photon/prepare/utils/configs.py @@ -95,6 +95,7 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit configs = yaml.load(f) config_dict = { + 'portal_url': 'http://portal:8080', 'registry_url': 'http://registry:5000', 'registry_controller_url': 'http://registryctl:8080', 'core_url': 'http://core:8080', @@ -346,6 +347,7 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit config_dict['internal_tls'] = InternalTLS() if config_dict['internal_tls'].enabled: + config_dict['portal_url'] = 'https://portal:8443' config_dict['registry_url'] = 'https://registry:5443' config_dict['registry_controller_url'] = 'https://registryctl:8443' config_dict['core_url'] = 'https://core:8443' diff --git a/make/photon/prepare/utils/portal.py b/make/photon/prepare/utils/portal.py new file mode 100644 index 000000000..a2524827b --- /dev/null +++ b/make/photon/prepare/utils/portal.py @@ -0,0 +1,18 @@ +from g import config_dir, DEFAULT_GID, DEFAULT_UID, templates_dir +from utils.misc import prepare_dir +from utils.jinja import render_jinja + +portal_config_dir = config_dir.joinpath("portal") +portal_conf_template_path = templates_dir.joinpath("portal", "nginx.conf.jinja") +portal_conf = config_dir.joinpath("portal", "nginx.conf") + +def prepare_portal(config_dict): + prepare_dir(portal_config_dir, uid=DEFAULT_UID, gid=DEFAULT_GID) + + # Render Jobservice config + render_jinja( + str(portal_conf_template_path), + portal_conf, + internal_tls=config_dict['internal_tls'], + uid=DEFAULT_UID, + gid=DEFAULT_GID)