diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7e10ddec6..0401a9004 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -5,7 +5,6 @@ env: POSTGRESQL_USR: postgres POSTGRESQL_PWD: root123 POSTGRESQL_DATABASE: registry - ADMINSERVER_URL: http://127.0.0.1:8888 DOCKER_COMPOSE_VERSION: 1.23.0 HARBOR_ADMIN: admin HARBOR_ADMIN_PASSWD: Harbor12345 diff --git a/Makefile b/Makefile index a0cc5863e..920cfb7cf 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,7 @@ NPM_REGISTRY=https://registry.npmjs.org # enable/disable chart repo supporting CHARTFLAG=false BUILDTARGET=build +GEN_TLS= # version prepare # for docker image tag @@ -349,10 +350,16 @@ compile: check_environment versions_prepare compile_core compile_jobservice comp update_prepare_version: @echo "substitute the prepare version tag in prepare file..." - @$(SEDCMDI) -e 's/goharbor\/prepare:.*[[:space:]]\+/goharbor\/prepare:$(VERSIONTAG) /' $(MAKEPATH)/prepare ; + @$(SEDCMDI) -e 's/goharbor\/prepare:.*[[:space:]]\+/goharbor\/prepare:$(VERSIONTAG) prepare /' $(MAKEPATH)/prepare ; + +gen_tls: + @$(DOCKERCMD) run --rm -v /:/hostfs:z goharbor/prepare:$(VERSIONTAG) gencert -p /etc/harbor/tls/internal prepare: update_prepare_version @echo "preparing..." + @if [ -n "$(GEN_TLS)" ] ; then \ + $(DOCKERCMD) run --rm -v /:/hostfs:z goharbor/prepare:$(VERSIONTAG) gencert -p /etc/harbor/tls/internal; \ + fi @$(MAKEPATH)/$(PREPARECMD) $(PREPARECMD_PARA) build: diff --git a/make/harbor.yml.tmpl b/make/harbor.yml.tmpl index 6f9495f05..203cd7e21 100644 --- a/make/harbor.yml.tmpl +++ b/make/harbor.yml.tmpl @@ -17,6 +17,15 @@ https: certificate: /your/certificate/path private_key: /your/private/key/path +# # Uncomment following will enable tls communication between all harbor components +# internal_tls: +# # set enabled to true means internal tls is enabled +# enabled: true +# # verify_client_cert used to decide whether verify client certificate +# verify_client_cert: false +# # put your cert and key files on dir +# dir: /etc/harbor/tls/internal + # Uncomment external_url if you want to enable external proxy # And when it enabled the hostname will no longer used # external_url: https://reg.mydomain.com:8433 diff --git a/make/photon/clair-adapter/Dockerfile b/make/photon/clair-adapter/Dockerfile index 3d6df4f7d..915303c6c 100644 --- a/make/photon/clair-adapter/Dockerfile +++ b/make/photon/clair-adapter/Dockerfile @@ -1,10 +1,14 @@ ARG harbor_base_image_version FROM goharbor/harbor-clair-adapter-base:${harbor_base_image_version} +COPY ./make/photon/common/install_cert.sh /home/clair-adapter +COPY ./make/photon/clair-adapter/entrypoint.sh /home/clair-adapter COPY ./make/photon/clair-adapter/binary/harbor-scanner-clair /clair-adapter/clair-adapter -RUN chown -R 10000:10000 /clair-adapter \ - && chmod u+x /clair-adapter/clair-adapter +RUN chown -R clair-adapter:clair-adapter /etc/pki/tls/certs \ + && chown -R clair-adapter:clair-adapter /clair-adapter && chmod u+x /clair-adapter/clair-adapter \ + && chown clair-adapter:clair-adapter /home/clair-adapter/entrypoint.sh && chmod u+x /home/clair-adapter/entrypoint.sh \ + && chown clair-adapter:clair-adapter /home/clair-adapter/install_cert.sh && chmod u+x /home/clair-adapter/install_cert.sh EXPOSE 8080 @@ -12,4 +16,4 @@ HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -sS 127.0.0.1:8080 USER clair-adapter -ENTRYPOINT ["/clair-adapter/clair-adapter"] \ No newline at end of file +ENTRYPOINT ["/home/clair-adapter/entrypoint.sh"] \ No newline at end of file diff --git a/make/photon/clair-adapter/entrypoint.sh b/make/photon/clair-adapter/entrypoint.sh new file mode 100644 index 000000000..367e70e20 --- /dev/null +++ b/make/photon/clair-adapter/entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +/home/clair-adapter/install_cert.sh + +/clair-adapter/clair-adapter \ No newline at end of file diff --git a/make/photon/clair/Dockerfile b/make/photon/clair/Dockerfile index 5b7e2183a..e04dcc0b4 100644 --- a/make/photon/clair/Dockerfile +++ b/make/photon/clair/Dockerfile @@ -10,10 +10,10 @@ VOLUME /config EXPOSE 6060 6061 -RUN chown -R clair:clair /etc/pki/tls/certs \ - && chown -R clair:clair /home/clair \ +RUN chown -R clair:clair /etc/pki/tls/certs && chown -R clair:clair /home/clair \ && chmod u+x /home/clair/clair \ && chmod u+x /home/clair/docker-entrypoint.sh \ + && chmod u+x /home/clair/install_cert.sh \ && chmod +x /home/clair/dumb-init HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -sS 127.0.0.1:6061/health || exit 1 diff --git a/make/photon/core/Dockerfile b/make/photon/core/Dockerfile index 6ea45e847..e0e3e96af 100644 --- a/make/photon/core/Dockerfile +++ b/make/photon/core/Dockerfile @@ -2,12 +2,18 @@ ARG harbor_base_image_version FROM goharbor/harbor-core-base:${harbor_base_image_version} HEALTHCHECK CMD curl --fail -s http://127.0.0.1:8080/api/v2.0/ping || exit 1 +COPY ./make/photon/common/install_cert.sh /harbor/ +COPY ./make/photon/core/entrypoint.sh /harbor/ COPY ./make/photon/core/harbor_core /harbor/ COPY ./src/core/views /harbor/views COPY ./make/migrations /harbor/migrations -RUN chmod u+x /harbor/harbor_core +RUN chown -R harbor:harbor /etc/pki/tls/certs \ + && chown harbor:harbor /harbor/entrypoint.sh && chmod u+x /harbor/entrypoint.sh \ + && chown harbor:harbor /harbor/install_cert.sh && chmod u+x /harbor/install_cert.sh \ + && chown harbor:harbor /harbor/harbor_core && chmod u+x /harbor/harbor_core + WORKDIR /harbor/ USER harbor -ENTRYPOINT ["/harbor/harbor_core"] +ENTRYPOINT ["/harbor/entrypoint.sh"] COPY make/photon/prepare/versions /harbor/ diff --git a/make/photon/core/Dockerfile.base b/make/photon/core/Dockerfile.base index db9991d27..865834fad 100644 --- a/make/photon/core/Dockerfile.base +++ b/make/photon/core/Dockerfile.base @@ -2,5 +2,5 @@ FROM photon:2.0 RUN tdnf install sudo tzdata -y >> /dev/null \ && tdnf clean all \ - && groupadd -r -g 10000 harbor && useradd --no-log-init -r -g 10000 -u 10000 harbor \ + && groupadd -r -g 10000 harbor && useradd --no-log-init -r -m -g 10000 -u 10000 harbor \ && mkdir /harbor/ diff --git a/make/photon/core/entrypoint.sh b/make/photon/core/entrypoint.sh new file mode 100644 index 000000000..40aa646a8 --- /dev/null +++ b/make/photon/core/entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +/harbor/install_cert.sh + +/harbor/harbor_core diff --git a/make/photon/jobservice/Dockerfile b/make/photon/jobservice/Dockerfile index eabfdc5ef..1ba469411 100644 --- a/make/photon/jobservice/Dockerfile +++ b/make/photon/jobservice/Dockerfile @@ -1,9 +1,15 @@ ARG harbor_base_image_version FROM goharbor/harbor-jobservice-base:${harbor_base_image_version} +COPY ./make/photon/common/install_cert.sh /harbor/ +COPY ./make/photon/jobservice/entrypoint.sh /harbor/ COPY ./make/photon/jobservice/harbor_jobservice /harbor/ -RUN chmod u+x /harbor/harbor_jobservice + +RUN chown -R harbor:harbor /etc/pki/tls/certs \ + && chown harbor:harbor /harbor/entrypoint.sh && chmod u+x /harbor/entrypoint.sh \ + && chown harbor:harbor /harbor/install_cert.sh && chmod u+x /harbor/install_cert.sh \ + && chown harbor:harbor /harbor/harbor_jobservice && chmod u+x /harbor/harbor_jobservice WORKDIR /harbor/ @@ -13,4 +19,4 @@ VOLUME ["/var/log/jobs/"] HEALTHCHECK CMD curl --fail -s http://127.0.0.1:8080/api/v1/stats || exit 1 -ENTRYPOINT ["/harbor/harbor_jobservice", "-c", "/etc/jobservice/config.yml"] +ENTRYPOINT ["/harbor/entrypoint.sh"] diff --git a/make/photon/jobservice/Dockerfile.base b/make/photon/jobservice/Dockerfile.base index 1ad223d45..5bbd68138 100644 --- a/make/photon/jobservice/Dockerfile.base +++ b/make/photon/jobservice/Dockerfile.base @@ -2,4 +2,4 @@ FROM photon:2.0 RUN tdnf install sudo tzdata -y >> /dev/null \ && tdnf clean all \ - && groupadd -r -g 10000 harbor && useradd --no-log-init -r -g 10000 -u 10000 harbor + && groupadd -r -g 10000 harbor && useradd --no-log-init -r -m -g 10000 -u 10000 harbor diff --git a/make/photon/jobservice/entrypoint.sh b/make/photon/jobservice/entrypoint.sh new file mode 100644 index 000000000..9c442c8c6 --- /dev/null +++ b/make/photon/jobservice/entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +/harbor/install_cert.sh + +/harbor/harbor_jobservice -c /etc/jobservice/config.yml diff --git a/make/photon/prepare/Pipfile b/make/photon/prepare/Pipfile index 91b2d3bc1..fa75eec01 100644 --- a/make/photon/prepare/Pipfile +++ b/make/photon/prepare/Pipfile @@ -12,4 +12,4 @@ click = "*" pylint = "*" [requires] -python_version = "3.6" +python_version = "3.7.5" diff --git a/make/photon/prepare/Pipfile.lock b/make/photon/prepare/Pipfile.lock index 20bc8e549..9c0c553b4 100644 --- a/make/photon/prepare/Pipfile.lock +++ b/make/photon/prepare/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "a3c7e13ece64f4447d0bd3648257ca4117192e5d52ff7cdd4b4c2d3109ae6500" + "sha256": "fc86f400c4b9ebc8d4caf833b1e8d8c8962b7f4920b19632e9e4f4e8738ce7e2" }, "pipfile-spec": 6, "requires": { - "python_version": "3.6" + "python_version": "3.7.5" }, "sources": [ { @@ -26,11 +26,11 @@ }, "jinja2": { "hashes": [ - "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", - "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" ], "index": "pypi", - "version": "==2.10.1" + "version": "==2.10.3" }, "markupsafe": { "hashes": [ @@ -76,51 +76,43 @@ "develop": { "astroid": { "hashes": [ - "sha256:6560e1e1749f68c64a4b5dee4e091fce798d2f0d84ebe638cf0e0585a343acf4", - "sha256:b65db1bbaac9f9f4d190199bb8680af6f6f84fd3769a5ea883df8a91fe68b4c4" + "sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a", + "sha256:840947ebfa8b58f318d42301cf8c0a20fd794a33b61cc4638e28e9e61ba32f42" ], - "version": "==2.2.5" + "version": "==2.3.3" }, "isort": { "hashes": [ - "sha256:01cb7e1ca5e6c5b3f235f0385057f70558b70d2f00320208825fa62887292f43", - "sha256:268067462aed7eb2a1e237fcb287852f22077de3fb07964e87e00f829eea2d1a" + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" ], - "version": "==4.3.17" + "version": "==4.3.21" }, "lazy-object-proxy": { "hashes": [ - "sha256:0ce34342b419bd8f018e6666bfef729aec3edf62345a53b537a4dcc115746a33", - "sha256:1b668120716eb7ee21d8a38815e5eb3bb8211117d9a90b0f8e21722c0758cc39", - "sha256:209615b0fe4624d79e50220ce3310ca1a9445fd8e6d3572a896e7f9146bbf019", - "sha256:27bf62cb2b1a2068d443ff7097ee33393f8483b570b475db8ebf7e1cba64f088", - "sha256:27ea6fd1c02dcc78172a82fc37fcc0992a94e4cecf53cb6d73f11749825bd98b", - "sha256:2c1b21b44ac9beb0fc848d3993924147ba45c4ebc24be19825e57aabbe74a99e", - "sha256:2df72ab12046a3496a92476020a1a0abf78b2a7db9ff4dc2036b8dd980203ae6", - "sha256:320ffd3de9699d3892048baee45ebfbbf9388a7d65d832d7e580243ade426d2b", - "sha256:50e3b9a464d5d08cc5227413db0d1c4707b6172e4d4d915c1c70e4de0bbff1f5", - "sha256:5276db7ff62bb7b52f77f1f51ed58850e315154249aceb42e7f4c611f0f847ff", - "sha256:61a6cf00dcb1a7f0c773ed4acc509cb636af2d6337a08f362413c76b2b47a8dd", - "sha256:6ae6c4cb59f199d8827c5a07546b2ab7e85d262acaccaacd49b62f53f7c456f7", - "sha256:7661d401d60d8bf15bb5da39e4dd72f5d764c5aff5a86ef52a042506e3e970ff", - "sha256:7bd527f36a605c914efca5d3d014170b2cb184723e423d26b1fb2fd9108e264d", - "sha256:7cb54db3535c8686ea12e9535eb087d32421184eacc6939ef15ef50f83a5e7e2", - "sha256:7f3a2d740291f7f2c111d86a1c4851b70fb000a6c8883a59660d95ad57b9df35", - "sha256:81304b7d8e9c824d058087dcb89144842c8e0dea6d281c031f59f0acf66963d4", - "sha256:933947e8b4fbe617a51528b09851685138b49d511af0b6c0da2539115d6d4514", - "sha256:94223d7f060301b3a8c09c9b3bc3294b56b2188e7d8179c762a1cda72c979252", - "sha256:ab3ca49afcb47058393b0122428358d2fbe0408cf99f1b58b295cfeb4ed39109", - "sha256:bd6292f565ca46dee4e737ebcc20742e3b5be2b01556dafe169f6c65d088875f", - "sha256:cb924aa3e4a3fb644d0c463cad5bc2572649a6a3f68a7f8e4fbe44aaa6d77e4c", - "sha256:d0fc7a286feac9077ec52a927fc9fe8fe2fabab95426722be4c953c9a8bede92", - "sha256:ddc34786490a6e4ec0a855d401034cbd1242ef186c20d79d2166d6a4bd449577", - "sha256:e34b155e36fa9da7e1b7c738ed7767fc9491a62ec6af70fe9da4a057759edc2d", - "sha256:e5b9e8f6bda48460b7b143c3821b21b452cb3a835e6bbd5dd33aa0c8d3f5137d", - "sha256:e81ebf6c5ee9684be8f2c87563880f93eedd56dd2b6146d8a725b50b7e5adb0f", - "sha256:eb91be369f945f10d3a49f5f9be8b3d0b93a4c2be8f8a5b83b0571b8123e0a7a", - "sha256:f460d1ceb0e4a5dcb2a652db0904224f367c9b3c1470d5a7683c0480e582468b" + "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", + "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", + "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", + "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", + "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", + "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", + "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", + "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", + "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", + "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", + "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", + "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", + "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", + "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", + "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", + "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", + "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", + "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", + "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", + "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", + "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" ], - "version": "==1.3.1" + "version": "==1.4.3" }, "mccabe": { "hashes": [ @@ -131,50 +123,50 @@ }, "pylint": { "hashes": [ - "sha256:5d77031694a5fb97ea95e828c8d10fc770a1df6eb3906067aaed42201a8a6a09", - "sha256:723e3db49555abaf9bf79dc474c6b9e2935ad82230b10c1138a71ea41ac0fff1" + "sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd", + "sha256:886e6afc935ea2590b462664b161ca9a5e40168ea99e5300935f6591ad467df4" ], "index": "pypi", - "version": "==2.3.1" + "version": "==2.4.4" }, "six": { "hashes": [ - "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", - "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", + "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" ], - "version": "==1.12.0" + "version": "==1.13.0" }, "typed-ast": { "hashes": [ - "sha256:04894d268ba6eab7e093d43107869ad49e7b5ef40d1a94243ea49b352061b200", - "sha256:16616ece19daddc586e499a3d2f560302c11f122b9c692bc216e821ae32aa0d0", - "sha256:252fdae740964b2d3cdfb3f84dcb4d6247a48a6abe2579e8029ab3be3cdc026c", - "sha256:2af80a373af123d0b9f44941a46df67ef0ff7a60f95872412a145f4500a7fc99", - "sha256:2c88d0a913229a06282b285f42a31e063c3bf9071ff65c5ea4c12acb6977c6a7", - "sha256:2ea99c029ebd4b5a308d915cc7fb95b8e1201d60b065450d5d26deb65d3f2bc1", - "sha256:3d2e3ab175fc097d2a51c7a0d3fda442f35ebcc93bb1d7bd9b95ad893e44c04d", - "sha256:4766dd695548a15ee766927bf883fb90c6ac8321be5a60c141f18628fb7f8da8", - "sha256:56b6978798502ef66625a2e0f80cf923da64e328da8bbe16c1ff928c70c873de", - "sha256:5cddb6f8bce14325b2863f9d5ac5c51e07b71b462361fd815d1d7706d3a9d682", - "sha256:644ee788222d81555af543b70a1098f2025db38eaa99226f3a75a6854924d4db", - "sha256:64cf762049fc4775efe6b27161467e76d0ba145862802a65eefc8879086fc6f8", - "sha256:68c362848d9fb71d3c3e5f43c09974a0ae319144634e7a47db62f0f2a54a7fa7", - "sha256:6c1f3c6f6635e611d58e467bf4371883568f0de9ccc4606f17048142dec14a1f", - "sha256:b213d4a02eec4ddf622f4d2fbc539f062af3788d1f332f028a2e19c42da53f15", - "sha256:bb27d4e7805a7de0e35bd0cb1411bc85f807968b2b0539597a49a23b00a622ae", - "sha256:c9d414512eaa417aadae7758bc118868cd2396b0e6138c1dd4fda96679c079d3", - "sha256:f0937165d1e25477b01081c4763d2d9cdc3b18af69cb259dd4f640c9b900fe5e", - "sha256:fb96a6e2c11059ecf84e6741a319f93f683e440e341d4489c9b161eca251cf2a", - "sha256:fc71d2d6ae56a091a8d94f33ec9d0f2001d1cb1db423d8b4355debfe9ce689b7" + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" ], - "markers": "implementation_name == 'cpython'", - "version": "==1.3.4" + "markers": "implementation_name == 'cpython' and python_version < '3.8'", + "version": "==1.4.0" }, "wrapt": { "hashes": [ - "sha256:4aea003270831cceb8a90ff27c4031da6ead7ec1886023b80ce0dfe0adf61533" + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" ], - "version": "==1.11.1" + "version": "==1.11.2" } } } diff --git a/make/photon/prepare/commands/__init__.py b/make/photon/prepare/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/make/photon/prepare/commands/gencerts.py b/make/photon/prepare/commands/gencerts.py new file mode 100644 index 000000000..0d2a58865 --- /dev/null +++ b/make/photon/prepare/commands/gencerts.py @@ -0,0 +1,29 @@ +import os +import sys +import click +import pathlib +from subprocess import check_call, PIPE, STDOUT + +from utils.cert import openssl_installed +from utils.misc import get_realpath + +gen_tls_script = pathlib.Path(__file__).parent.parent.joinpath('scripts/gencert.sh').absolute() + +@click.command() +@click.option('-p', '--path', default='/etc/harbor/tls/internal') +@click.option('-d', '--days', default='365') +def gencert(path, days): + path = get_realpath(path) + click.echo('Check openssl ...') + if not openssl_installed(): + raise(Exception('openssl not installed')) + + click.echo("start generate internal tls certs") + if not os.path.exists(path): + click.echo('path {} not exist, create it...'.format(path)) + os.makedirs(path, exist_ok=True) + + shell_stat = check_call([gen_tls_script, days], stdout=PIPE, stderr=STDOUT, cwd=path) + if shell_stat != 0: + click.echo('Can not generate internal tls certs') + sys.exit(-1) diff --git a/make/photon/prepare/commands/prepare.py b/make/photon/prepare/commands/prepare.py new file mode 100644 index 000000000..00b8c7bdd --- /dev/null +++ b/make/photon/prepare/commands/prepare.py @@ -0,0 +1,78 @@ +# pylint: disable=no-value-for-parameter + +import sys +import logging + +import click + +from utils.misc import delfile +from utils.configs import validate, parse_yaml_config +from utils.cert import prepare_registry_ca, SSL_CERT_KEY_PATH, SSL_CERT_PATH, get_secret_key +from utils.db import prepare_db +from utils.jobservice import prepare_job_service +from utils.registry import prepare_registry +from utils.registry_ctl import prepare_registry_ctl +from utils.core import prepare_core +from utils.notary import prepare_notary +from utils.log import prepare_log_configs +from utils.clair import prepare_clair +from utils.clair_adapter import prepare_clair_adapter +from utils.chart import prepare_chartmuseum +from utils.docker_compose import prepare_docker_compose +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 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) + +@click.command() +@click.option('--conf', default=input_config_path, help="the path of Harbor configuration file") +@click.option('--with-notary', is_flag=True, help="the Harbor instance is to be deployed with notary") +@click.option('--with-clair', is_flag=True, help="the Harbor instance is to be deployed with clair") +@click.option('--with-trivy', is_flag=True, help="the Harbor instance is to be deployed with Trivy") +@click.option('--with-chartmuseum', is_flag=True, help="the Harbor instance is to be deployed with chart repository supporting") +def prepare(conf, with_notary, with_clair, with_trivy, with_chartmuseum): + + delfile(config_dir) + config_dict = parse_yaml_config(conf, with_notary=with_notary, with_clair=with_clair, with_trivy=with_trivy, with_chartmuseum=with_chartmuseum) + try: + validate(config_dict, notary_mode=with_notary) + except Exception as e: + click.echo('Error happened in config validation...') + logging.error(e) + sys.exit(-1) + + 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) + prepare_registry(config_dict) + prepare_registry_ctl(config_dict) + prepare_db(config_dict) + prepare_job_service(config_dict) + prepare_redis(config_dict) + prepare_tls(config_dict) + + get_secret_key(secret_key_dir) + + # If Customized cert enabled + prepare_registry_ca( + private_key_pem_path=private_key_pem_path, + root_crt_path=root_crt_path, + old_private_key_pem_path=old_private_key_pem_path, + old_crt_path=old_crt_path) + + if with_notary: + prepare_notary(config_dict, nginx_confd_dir, SSL_CERT_PATH, SSL_CERT_KEY_PATH) + + if with_clair: + prepare_clair(config_dict) + prepare_clair_adapter(config_dict) + + if with_trivy: + prepare_trivy_adapter(config_dict) + + if with_chartmuseum: + prepare_chartmuseum(config_dict) + + prepare_docker_compose(config_dict, with_clair, with_trivy, with_notary, with_chartmuseum) diff --git a/make/photon/prepare/g.py b/make/photon/prepare/g.py index 769f96a80..c15be4dad 100644 --- a/make/photon/prepare/g.py +++ b/make/photon/prepare/g.py @@ -12,27 +12,33 @@ REDIS_UID = 999 REDIS_GID = 999 ## Global variable -host_root_dir = '/hostfs' +templates_dir = "/usr/src/app/templates" + +host_root_dir = Path('/hostfs') base_dir = '/harbor_make' -templates_dir = "/usr/src/app/templates" -config_dir = '/config' -data_dir = '/data' -secret_dir = '/secret' -secret_key_dir = '/secret/keys' +config_dir = Path('/config') +data_dir = Path('/data') + +secret_dir = data_dir.joinpath('secret') +secret_key_dir = secret_dir.joinpath('keys') +trust_ca_dir = secret_dir.joinpath('keys', 'trust_ca') +internal_tls_dir = secret_dir.joinpath('tls') + +storage_ca_bundle_filename = 'storage_ca_bundle.crt' old_private_key_pem_path = Path('/config/core/private_key.pem') old_crt_path = Path('/config/registry/root.crt') -private_key_pem_path = Path('/secret/core/private_key.pem') -root_crt_path = Path('/secret/registry/root.crt') +private_key_pem_path = secret_dir.joinpath('core', 'private_key.pem') +root_crt_path = secret_dir.joinpath('registry', 'root.crt') config_file_path = '/compose_location/harbor.yml' input_config_path = '/input/harbor.yml' versions_file_path = Path('/usr/src/app/versions') -cert_dir = os.path.join(config_dir, "nginx", "cert") -core_cert_dir = os.path.join(config_dir, "core", "certificates") +cert_dir = config_dir.joinpath("nginx", "cert") +core_cert_dir = config_dir.joinpath("core", "certificates") INTERNAL_NO_PROXY_DN = { '127.0.0.1', diff --git a/make/photon/prepare/main.py b/make/photon/prepare/main.py index 9028a1a13..3003cc8e3 100644 --- a/make/photon/prepare/main.py +++ b/make/photon/prepare/main.py @@ -1,77 +1,13 @@ -# pylint: disable=no-value-for-parameter - -import sys -import logging +from commands.prepare import prepare +from commands.gencerts import gencert import click -from utils.misc import delfile -from utils.configs import validate, parse_yaml_config -from utils.cert import prepare_ca, SSL_CERT_KEY_PATH, SSL_CERT_PATH, get_secret_key -from utils.db import prepare_db -from utils.jobservice import prepare_job_service -from utils.registry import prepare_registry -from utils.registry_ctl import prepare_registry_ctl -from utils.core import prepare_core -from utils.notary import prepare_notary -from utils.log import prepare_log_configs -from utils.clair import prepare_clair -from utils.clair_adapter import prepare_clair_adapter -from utils.trivy_adapter import prepare_trivy_adapter -from utils.chart import prepare_chartmuseum -from utils.docker_compose import prepare_docker_compose -from utils.nginx import prepare_nginx, nginx_confd_dir -from utils.redis import prepare_redis -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) -# Main function -@click.command() -@click.option('--conf', default=input_config_path, help="the path of Harbor configuration file") -@click.option('--with-notary', is_flag=True, help="the Harbor instance is to be deployed with notary") -@click.option('--with-clair', is_flag=True, help="the Harbor instance is to be deployed with clair") -@click.option('--with-trivy', is_flag=True, help="the Harbor instance is to be deployed with Trivy") -@click.option('--with-chartmuseum', is_flag=True, help="the Harbor instance is to be deployed with chart repository supporting") -def main(conf, with_notary, with_clair, with_trivy, with_chartmuseum): +@click.group() +def cli(): + pass - delfile(config_dir) - config_dict = parse_yaml_config(conf, with_notary=with_notary, with_clair=with_clair, with_trivy=with_trivy, with_chartmuseum=with_chartmuseum) - try: - validate(config_dict, notary_mode=with_notary) - except Exception as e: - logging.info('Error happened in config validation...') - logging.error(e) - sys.exit(-1) - - 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) - prepare_registry(config_dict) - prepare_registry_ctl(config_dict) - prepare_db(config_dict) - prepare_job_service(config_dict) - prepare_redis(config_dict) - - get_secret_key(secret_key_dir) - - # If Customized cert enabled - prepare_ca( - private_key_pem_path=private_key_pem_path, - root_crt_path=root_crt_path, - old_private_key_pem_path=old_private_key_pem_path, - old_crt_path=old_crt_path) - if with_notary: - prepare_notary(config_dict, nginx_confd_dir, SSL_CERT_PATH, SSL_CERT_KEY_PATH) - - if with_clair: - prepare_clair(config_dict) - prepare_clair_adapter(config_dict) - - if with_trivy: - prepare_trivy_adapter(config_dict) - - if with_chartmuseum: - prepare_chartmuseum(config_dict) - - prepare_docker_compose(config_dict, with_clair, with_trivy, with_notary, with_chartmuseum) +cli.add_command(prepare) +cli.add_command(gencert) if __name__ == '__main__': - main() + cli() diff --git a/make/photon/prepare/models.py b/make/photon/prepare/models.py new file mode 100644 index 000000000..0caf4c38c --- /dev/null +++ b/make/photon/prepare/models.py @@ -0,0 +1,140 @@ +import os +import logging +from pathlib import Path +from shutil import copytree, rmtree + +from g import internal_tls_dir, DEFAULT_GID, DEFAULT_UID, PG_GID, PG_UID +from utils.misc import check_permission, owner_can_read, get_realpath + + +class InternalTLS: + + harbor_certs_filename = { + 'harbor_internal_ca.crt', + 'proxy.crt', 'proxy.key', + 'core.crt', 'core.key', + 'job_service.crt', 'job_service.key', + 'registryctl.crt', 'registryctl.key', + 'registry.crt', 'registry.key' + } + + clair_certs_filename = { + 'clair_adapter.crt', 'clair_adapter.key', + 'clair.crt', 'clair.key' + } + + trivy_certs_filename = { + 'trivy_adapter.crt', 'trivy_adapter.key', + } + + notary_certs_filename = { + 'notary_signer.crt', 'notary_signer.key', + 'notary_server.crt', 'notary_server.key' + } + + chart_museum_filename = { + 'chartmuseum.crt', + 'chartmuseum.key' + } + + db_certs_filename = { + 'harbor_db.crt', 'harbor_db.key' + } + + def __init__(self, tls_enabled=False, verify_client_cert=False, tls_dir='', data_volume='', **kwargs): + self.data_volume = data_volume + self.verify_client_cert = verify_client_cert + self.enabled = tls_enabled + self.tls_dir = tls_dir + if self.enabled: + self.required_filenames = self.harbor_certs_filename + if kwargs.get('with_clair'): + self.required_filenames.update(self.clair_certs_filename) + if kwargs.get('with_notary'): + self.required_filenames.update(self.notary_certs_filename) + if kwargs.get('with_chartmuseum'): + self.required_filenames.update(self.chart_museum_filename) + if kwargs.get('with_trivy'): + self.required_filenames.update(self.trivy_certs_filename) + if not kwargs.get('external_database'): + self.required_filenames.update(self.db_certs_filename) + + def __getattribute__(self, name: str): + """ + Make the call like 'internal_tls.core_crt_path' possible + """ + # only handle when enabled tls and name ends with 'path' + if name.endswith('_path'): + if not (self.enabled): + return object.__getattribute__(self, name) + + name_parts = name.split('_') + if len(name_parts) < 3: + return object.__getattribute__(self, name) + + filename = '{}.{}'.format('_'.join(name_parts[:-2]), name_parts[-2]) + + if filename in self.required_filenames: + return os.path.join(self.data_volume, 'secret', 'tls', filename) + + return object.__getattribute__(self, name) + + def _check(self, filename: str): + """ + Check the permission of cert and key is correct + """ + + path = Path(os.path.join(internal_tls_dir, filename)) + + if not path.exists: + if filename == 'harbor_internal_ca.crt': + return + raise Exception('File {} not exist'.format(filename)) + + if not path.is_file: + raise Exception('invalid {}'.format(filename)) + + # check key file permission + if filename.endswith('.key') and not check_permission(path, mode=0o600): + raise Exception('key file {} permission is not 600'.format(filename)) + + # check owner can read cert file + if filename.endswith('.crt') and not owner_can_read(path.stat().st_mode): + raise Exception('File {} should readable by owner'.format(filename)) + + def validate(self) -> bool: + if not self.enabled: + return True + + if not internal_tls_dir.exists(): + raise Exception('Internal dir for tls {} not exist'.format(internal_tls_dir)) + + for filename in self.required_filenames: + self._check(filename) + + return True + + def prepare(self): + """ + Prepare moves certs in tls file to data volume with correct permission. + """ + if not self.enabled: + logging.info('internal tls NOT enabled...') + return + original_tls_dir = get_realpath(self.tls_dir) + if internal_tls_dir.exists(): + rmtree(internal_tls_dir) + copytree(original_tls_dir, internal_tls_dir, symlinks=True) + + for file in internal_tls_dir.iterdir(): + if file.name.endswith('.key'): + file.chmod(0o600) + elif file.name.endswith('.crt'): + file.chmod(0o644) + + if file.name in self.db_certs_filename: + os.chown(file, PG_UID, PG_GID) + else: + os.chown(file, DEFAULT_UID, DEFAULT_GID) + + diff --git a/make/photon/prepare/scripts/gencert.sh b/make/photon/prepare/scripts/gencert.sh new file mode 100755 index 000000000..6cf970509 --- /dev/null +++ b/make/photon/prepare/scripts/gencert.sh @@ -0,0 +1,139 @@ +#! /bin/bash +set -e + +if [ -z "$1" ]; then + echo "No argument supplied set days to 365" + DAYS=365 +else + echo "No argument supplied set days to $1" + DAYS=$1 +fi + +CA_KEY="harbor_internal_ca.key" +CA_CRT="harbor_internal_ca.crt" + +# CA key and certificate +if [[ ! -f $CA_KEY && ! -f $CA_CRT ]]; then +openssl req -x509 -nodes -days $DAYS -newkey rsa:4096 \ + -keyout $CA_KEY -out $CA_CRT \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware" +else + echo "$CA_KEY and $CA_CRT exist, use them to generate certs" +fi + +# generate proxy key and csr +openssl req -new -newkey rsa:4096 -nodes -sha256 \ + -keyout proxy.key \ + -out proxy.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=proxy" + +# 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 core key and csr +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout core.key \ + -out core.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=core" + +# Sign core csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in core.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out core.crt + + +# job_service key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout job_service.key \ + -out job_service.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=jobservice" + +# sign job_service csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in job_service.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out job_service.crt + +# generate registry key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout registry.key \ + -out registry.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=registry" + +# sign registry csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in registry.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out registry.crt + +# generate registryctl key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout registryctl.key \ + -out registryctl.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=registryctl" + +# sign registryctl csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in registryctl.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out registryctl.crt + + + +# generate clair_adapter key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout clair_adapter.key \ + -out clair_adapter.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=clair-adapter" + +# sign clair_adapter csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in clair_adapter.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out clair_adapter.crt + + +# generate clair key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout clair.key \ + -out clair.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=clair" + +# sign clair csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in clair.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out clair.crt + + +# generate trivy_adapter key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout trivy_adapter.key \ + -out trivy_adapter.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=trivy-adapter" + +# sign trivy_adapter csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in trivy_adapter.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out trivy_adapter.crt + + +# generate notary_signer key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout notary_signer.key \ + -out notary_signer.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=notary_signer" + +# sign notary_signer csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in notary_signer.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out notary_signer.crt + +# generate notary_server key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout notary_server.key \ + -out notary_server.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=notary_server" + +# sign notary_server csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in notary_server.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out notary_server.crt + + +# generate chartmuseum key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout chartmuseum.key \ + -out chartmuseum.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=chartmuseum" + +# sign chartmuseum csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in chartmuseum.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out chartmuseum.crt + + +# generate harbor_db key +openssl req -new \ + -newkey rsa:4096 -nodes -sha256 -keyout harbor_db.key \ + -out harbor_db.csr \ + -subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=harbor_db" + +# sign harbor_db csr with CA certificate and key +openssl x509 -req -days $DAYS -sha256 -in harbor_db.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -out harbor_db.crt diff --git a/make/photon/prepare/templates/chartserver/env.jinja b/make/photon/prepare/templates/chartserver/env.jinja index e9d7f98b1..214846130 100644 --- a/make/photon/prepare/templates/chartserver/env.jinja +++ b/make/photon/prepare/templates/chartserver/env.jinja @@ -1,5 +1,13 @@ ## Settings should be set +{%if internal_tls.enabled %} +PORT=9443 +TLS_CERT=/etc/harbor/ssl/chartmuseum.crt +TLS_KEY=/etc/harbor/ssl/chartmuseum.key +# Uncomment if need mTLS +# TLS_CA_CERT=/etc/harbor/ssl/harbor_internal_ca.crt +{% else %} PORT=9999 +{% endif %} # Only support redis now. If redis is setup, then enable cache CACHE={{cache_store}} @@ -34,8 +42,6 @@ CHART_URL={{public_url}}/chartrepo CHART_URL= {% endif %} AUTH_ANONYMOUS_GET=false -TLS_CERT= -TLS_KEY= CONTEXT_PATH= INDEX_LIMIT=0 MAX_STORAGE_OBJECTS=0 diff --git a/make/photon/prepare/templates/clair-adapter/env.jinja b/make/photon/prepare/templates/clair-adapter/env.jinja index 906832128..741071668 100644 --- a/make/photon/prepare/templates/clair-adapter/env.jinja +++ b/make/photon/prepare/templates/clair-adapter/env.jinja @@ -1,4 +1,10 @@ SCANNER_LOG_LEVEL={{log_level}} SCANNER_CLAIR_URL={{clair_url}} SCANNER_CLAIR_DATABASE_URL=postgresql://{{clair_db_username}}:{{clair_db_password}}@{{clair_db_host}}:{{clair_db_port}}/{{clair_db_name}}?sslmode={{clair_db_sslmode}} -SCANNER_STORE_REDIS_URL={{redis_url_clair}} \ No newline at end of file +SCANNER_STORE_REDIS_URL={{redis_url_clair}} + +{%if internal_tls.enabled %} +SCANNER_API_SERVER_ADDR=:8443 +SCANNER_API_SERVER_TLS_CERTIFICATE=/etc/harbor/ssl/clair_adapter.crt +SCANNER_API_SERVER_TLS_KEY=/etc/harbor/ssl/clair_adapter.key +{% endif %} diff --git a/make/photon/prepare/templates/core/env.jinja b/make/photon/prepare/templates/core/env.jinja index 597625882..e67207a4e 100644 --- a/make/photon/prepare/templates/core/env.jinja +++ b/make/photon/prepare/templates/core/env.jinja @@ -52,3 +52,10 @@ CSRF_KEY={{csrf_key}} HTTP_PROXY={{core_http_proxy}} HTTPS_PROXY={{core_https_proxy}} NO_PROXY={{core_no_proxy}} + +{%if internal_tls.enabled %} +INTERNAL_TLS_ENABLED=true +INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/core.key +INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/core.crt +INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt +{% endif %} \ No newline at end of file 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 167aa4f6c..397f97a29 100644 --- a/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja +++ b/make/photon/prepare/templates/docker_compose/docker-compose.yml.jinja @@ -41,10 +41,19 @@ services: source: {{gcs_keyfile}} target: /etc/registry/gcs.key {% endif %} -{%if registry_custom_ca_bundle_path %} +{%if internal_tls.enabled %} - type: bind - source: {{registry_custom_ca_bundle_path}} - target: /harbor_cust_cert/custom-ca-bundle.crt + source: {{internal_tls.core_key_path}} + target: /harbor_cust_cert/core.crt + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.registry_crt_path}} + target: /etc/harbor/tls/registry.crt + - type: bind + source: {{internal_tls.registry_key_path}} + target: /etc/harbor/tls/registry.key {% endif %} networks: - harbor @@ -77,10 +86,16 @@ services: - type: bind source: ./common/config/registryctl/config.yml target: /etc/registryctl/config.yml -{%if registry_custom_ca_bundle_path %} +{%if internal_tls.enabled %} - type: bind - source: {{registry_custom_ca_bundle_path}} - target: /harbor_cust_cert/custom-ca-bundle.crt + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.registryctl_crt_path}} + target: /etc/harbor/ssl/registryctl.crt + - type: bind + source: {{internal_tls.registryctl_key_path}} + target: /etc/harbor/ssl/registryctl.key {% endif %} networks: - harbor @@ -157,6 +172,17 @@ services: - type: bind source: {{uaa_ca_file}} target: /etc/core/certificates/uaa_ca.pem +{% endif %} +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.core_crt_path}} + target: /etc/harbor/ssl/core.crt + - type: bind + source: {{internal_tls.core_key_path}} + target: /etc/harbor/ssl/core.key {% endif %} networks: harbor: @@ -227,6 +253,17 @@ services: - type: bind source: ./common/config/jobservice/config.yml target: /etc/jobservice/config.yml +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.job_service_crt_path}} + target: /etc/harbor/ssl/job_service.crt + - type: bind + source: {{internal_tls.job_service_key_path}} + target: /etc/harbor/ssl/job_service.key +{% endif %} networks: - harbor {% if with_clair %} @@ -289,6 +326,17 @@ services: - ./common/config/nginx:/etc/nginx:z {% if protocol == 'https' %} - {{data_volume}}/secret/cert:/etc/cert:z +{% endif %} +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /etc/harbor/tls/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.proxy_crt_path}} + target: /etc/harbor/tls/proxy.crt + - type: bind + source: {{internal_tls.proxy_key_path}} + target: /etc/harbor/tls/proxy.key {% endif %} networks: - harbor @@ -331,6 +379,17 @@ services: - type: bind source: {{data_volume}}/secret/registry/root.crt target: /etc/notary/root.crt +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /etc/harbor/ssl/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.notary_server_crt_path}} + target: /etc/harbor/ssl/notary_server.crt + - type: bind + source: {{internal_tls.notary_server_key_path}} + target: /etc/harbor/ssl/notary_server.key +{% endif %} env_file: - ./common/config/notary/server_env depends_on: @@ -361,6 +420,17 @@ services: - type: bind source: {{data_volume}}/secret/notary/notary-signer.key target: /etc/notary/notary-signer.key +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /etc/harbor/ssl/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.notary_signer_crt_path}} + target: /etc/harbor/ssl/notary_signer.crt + - type: bind + source: {{internal_tls.notary_signer_key_path}} + target: /etc/harbor/ssl/notary_signer.key +{% endif %} env_file: - ./common/config/notary/signer_env depends_on: @@ -398,11 +468,17 @@ services: - type: bind source: ./common/config/clair/config.yaml target: /etc/clair/config.yaml - {%if registry_custom_ca_bundle_path %} +{%if internal_tls.enabled %} - type: bind - source: {{registry_custom_ca_bundle_path}} - target: /harbor_cust_cert/custom-ca-bundle.crt - {% endif %} + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.clair_crt_path}} + target: /etc/harbor/ssl/clair.crt + - type: bind + source: {{internal_tls.clair_key_path}} + target: /etc/harbor/ssl/clair.key +{% endif %} logging: driver: "syslog" options: @@ -428,6 +504,18 @@ services: - clair {% if external_redis == False %} - redis +{% endif %} +{%if internal_tls.enabled %} + volumes: + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.clair_adapter_crt_path}} + target: /etc/harbor/ssl/clair_adapter.crt + - type: bind + source: {{internal_tls.clair_adapter_key_path}} + target: /etc/harbor/ssl/clair_adapter.key {% endif %} logging: driver: "syslog" @@ -458,6 +546,18 @@ services: - type: bind source: {{data_volume}}/trivy-adapter/reports target: /home/scanner/.cache/reports +{%if internal_tls.enabled %} + volumes: + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /harbor_cust_cert/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.trivy_adapter_crt_path}} + target: /etc/harbor/ssl/trivy_adapter.crt + - type: bind + source: {{internal_tls.trivy_adapter_key_path}} + target: /etc/harbor/ssl/trivy_adapter.key +{% endif %} logging: driver: "syslog" options: @@ -486,15 +586,21 @@ services: volumes: - {{data_volume}}/chart_storage:/chart_storage:z - ./common/config/chartserver:/etc/chartserver:z +{%if internal_tls.enabled %} + - type: bind + source: {{internal_tls.harbor_internal_ca_crt_path}} + target: /etc/harbor/ssl/harbor_internal_ca.crt + - type: bind + source: {{internal_tls.chartmuseum_crt_path}} + target: /etc/harbor/ssl/chartmuseum.crt + - type: bind + source: {{internal_tls.chartmuseum_key_path}} + target: /etc/harbor/ssl/chartmuseum.key +{% endif %} {% if gcs_keyfile %} - type: bind source: {{gcs_keyfile}} target: /etc/chartserver/gcs.key -{% endif %} -{%if registry_custom_ca_bundle_path %} - - type: bind - source: {{registry_custom_ca_bundle_path}} - target: /harbor_cust_cert/custom-ca-bundle.crt {% endif %} logging: driver: "syslog" diff --git a/make/photon/prepare/templates/jobservice/config.yml.jinja b/make/photon/prepare/templates/jobservice/config.yml.jinja index 0348a8cdf..f7675130e 100644 --- a/make/photon/prepare/templates/jobservice/config.yml.jinja +++ b/make/photon/prepare/templates/jobservice/config.yml.jinja @@ -1,14 +1,20 @@ --- #Protocol used to serve -protocol: "http" +{% if internal_tls.enabled %} +protocol: "https" -#Config certification if use 'https' protocol -#https_config: -# cert: "server.crt" -# key: "server.key" +https_config: + cert: "/etc/harbor/ssl/job_service.crt" + key: "/etc/harbor/ssl/job_service.key" + +#Server listening port +port: 8443 +{% else %} +protocol: "http" #Server listening port port: 8080 +{% endif %} #Worker pool worker_pool: diff --git a/make/photon/prepare/templates/jobservice/env.jinja b/make/photon/prepare/templates/jobservice/env.jinja index 95e1cf260..7fcbb47ff 100644 --- a/make/photon/prepare/templates/jobservice/env.jinja +++ b/make/photon/prepare/templates/jobservice/env.jinja @@ -1,10 +1,22 @@ CORE_SECRET={{core_secret}} +REGISTRY_URL={{registry_url}} JOBSERVICE_SECRET={{jobservice_secret}} CORE_URL={{core_url}} +REGISTRY_CONTROLLER_URL={{registry_controller_url}} JOBSERVICE_WEBHOOK_JOB_MAX_RETRY={{notification_webhook_job_max_retry}} +{%if internal_tls.enabled %} +INTERNAL_TLS_ENABLED=true +INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt +INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/job_service.key +INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/job_service.crt +{% endif %} +{% if internal_tls.verify_client_cert %} +INTERNAL_VERIFY_CLIENT_CERT=true +{% endif %} + HTTP_PROXY={{jobservice_http_proxy}} HTTPS_PROXY={{jobservice_https_proxy}} NO_PROXY={{jobservice_no_proxy}} REGISTRY_CREDENTIAL_USERNAME={{registry_username}} -REGISTRY_CREDENTIAL_PASSWORD={{registry_password}} \ No newline at end of file +REGISTRY_CREDENTIAL_PASSWORD={{registry_password}} diff --git a/make/photon/prepare/templates/nginx/nginx.https.conf.jinja b/make/photon/prepare/templates/nginx/nginx.https.conf.jinja index a1d3fa320..650994b30 100644 --- a/make/photon/prepare/templates/nginx/nginx.https.conf.jinja +++ b/make/photon/prepare/templates/nginx/nginx.https.conf.jinja @@ -20,7 +20,11 @@ http { proxy_http_version 1.1; upstream core { +{% if internal_tls.enabled %} + server core:8443; +{% else %} server core:8080; +{% endif %} } upstream portal { @@ -80,7 +84,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 /etc/harbor/tls/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; @@ -95,7 +110,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 /etc/harbor/tls/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; @@ -110,7 +136,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 /etc/harbor/tls/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; @@ -129,7 +166,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 /etc/harbor/tls/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; @@ -141,7 +189,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 /etc/harbor/tls/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 $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/prepare/templates/registry/config.yml.jinja b/make/photon/prepare/templates/registry/config.yml.jinja index d566da0b4..89d2fac2f 100644 --- a/make/photon/prepare/templates/registry/config.yml.jinja +++ b/make/photon/prepare/templates/registry/config.yml.jinja @@ -21,10 +21,20 @@ redis: password: {{redis_password}} db: {{redis_db_index_reg}} http: +{% if internal_tls.enabled %} + addr: :5443 +{% else %} addr: :5000 +{% endif %} secret: placeholder debug: addr: localhost:5001 +{% if internal_tls.enabled %} + tls: + certificate: /etc/harbor/tls/registry.crt + key: /etc/harbor/tls/registry.key +{% endif %} + auth: htpasswd: realm: harbor-registry-basic-realm diff --git a/make/photon/prepare/templates/registryctl/config.yml.jinja b/make/photon/prepare/templates/registryctl/config.yml.jinja index 7b2a1d910..84e4093aa 100644 --- a/make/photon/prepare/templates/registryctl/config.yml.jinja +++ b/make/photon/prepare/templates/registryctl/config.yml.jinja @@ -1,8 +1,14 @@ --- +{% if internal_tls.enabled %} +protocol: "https" +port: 8443 + +https_config: + cert: "/etc/harbor/ssl/registryctl.crt" + key: "/etc/harbor/ssl/registryctl.key" + +{% else %} protocol: "http" port: 8080 +{% endif %} log_level: "INFO" - -#https_config: -# cert: "server.crt" -# key: "server.key" \ No newline at end of file diff --git a/make/photon/prepare/templates/registryctl/env.jinja b/make/photon/prepare/templates/registryctl/env.jinja index ee1c2d6f7..2bae9a2b1 100644 --- a/make/photon/prepare/templates/registryctl/env.jinja +++ b/make/photon/prepare/templates/registryctl/env.jinja @@ -1,3 +1,11 @@ CORE_SECRET={{core_secret}} JOBSERVICE_SECRET={{jobservice_secret}} - +{%if internal_tls.enabled %} +INTERNAL_TLS_ENABLED=true +INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt +INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/registryctl.key +INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/registryctl.crt +{% endif %} +{% if internal_tls.verify_client_cert %} +INTERNAL_VERIFY_CLIENT_CERT=true +{% endif %} diff --git a/make/photon/prepare/templates/trivy-adapter/env.jinja b/make/photon/prepare/templates/trivy-adapter/env.jinja index b07db6f04..4930d5431 100644 --- a/make/photon/prepare/templates/trivy-adapter/env.jinja +++ b/make/photon/prepare/templates/trivy-adapter/env.jinja @@ -12,3 +12,8 @@ SCANNER_TRIVY_GITHUB_TOKEN={{trivy_github_token}} HTTP_PROXY={{trivy_http_proxy}} HTTPS_PROXY={{trivy_https_proxy}} NO_PROXY={{trivy_no_proxy}} +{%if internal_tls.enabled %} +SCANNER_API_SERVER_ADDR=:8443 +SCANNER_API_SERVER_TLS_KEY=/etc/harbor/ssl/trivy_adapter.key +SCANNER_API_SERVER_TLS_CERTIFICATE=/etc/harbor/ssl/trivy_adapter.crt +{% endif %} diff --git a/make/photon/prepare/utils/cert.py b/make/photon/prepare/utils/cert.py index d7ed07c7c..ee1ef632d 100644 --- a/make/photon/prepare/utils/cert.py +++ b/make/photon/prepare/utils/cert.py @@ -3,18 +3,17 @@ import os, subprocess, shutil from pathlib import Path from subprocess import DEVNULL -from g import DEFAULT_GID, DEFAULT_UID +from g import DEFAULT_GID, DEFAULT_UID, trust_ca_dir, storage_ca_bundle_filename from .misc import ( mark_file, generate_random_string, check_permission, - stat_decorator) + stat_decorator, + get_realpath) SSL_CERT_PATH = os.path.join("/etc/cert", "server.crt") SSL_CERT_KEY_PATH = os.path.join("/etc/cert", "server.key") -secret_keys_dir = '/secret/keys' - def _get_secret(folder, filename, length=16): key_file = os.path.join(folder, filename) if os.path.isfile(key_file): @@ -72,7 +71,7 @@ def openssl_installed(): return True -def prepare_ca( +def prepare_registry_ca( private_key_pem_path: Path, root_crt_path: Path, old_private_key_pem_path: Path, @@ -97,4 +96,36 @@ def prepare_ca( os.chown(root_crt_path, DEFAULT_UID, DEFAULT_GID) if not check_permission(private_key_pem_path, uid=DEFAULT_UID, gid=DEFAULT_GID): - os.chown(private_key_pem_path, DEFAULT_UID, DEFAULT_GID) \ No newline at end of file + os.chown(private_key_pem_path, DEFAULT_UID, DEFAULT_GID) + + +def prepare_trust_ca(**kwargs): + def f(path: str, file_name: str): + + # check if source file valied + src_path = kwargs.get(path) + if not src_path: + return + real_path = get_realpath(src_path) + if not real_path.exists(): + raise Exception('ca file {} is not exist'.format(real_path)) + if not real_path.is_file(): + raise Exception('{} is not file'.format(real_path)) + + dst_path = trust_ca_dir.joinpath(file_name) + # check destination dir exist + if not trust_ca_dir.exists(): + trust_ca_dir.mkdir(parents=True) + else: + os.remove(dst_path) + + # copy src to dst + shutil.copy(src_path, dst_path) + + # change ownership and permission + mark_file(dst_path) + + for p in ( + ('internal_https_ca_path', 'harbor_internal_ca.crt'), + ('registry_custom_ca_bundle_path', storage_ca_bundle_filename)): + f(*p) diff --git a/make/photon/prepare/utils/chart.py b/make/photon/prepare/utils/chart.py index d3f1d1faa..89518e4d6 100644 --- a/make/photon/prepare/utils/chart.py +++ b/make/photon/prepare/utils/chart.py @@ -105,4 +105,5 @@ def prepare_chartmuseum(config_dict): storage_driver=storage_driver, all_storage_driver_configs=all_storage_provider_configs, public_url=config_dict['public_url'], - chart_absolute_url=config_dict['chart_absolute_url']) \ No newline at end of file + chart_absolute_url=config_dict['chart_absolute_url'], + internal_tls=config_dict['internal_tls']) \ No newline at end of file diff --git a/make/photon/prepare/utils/configs.py b/make/photon/prepare/utils/configs.py index 877301446..dbf497ecb 100644 --- a/make/photon/prepare/utils/configs.py +++ b/make/photon/prepare/utils/configs.py @@ -1,6 +1,8 @@ import os import yaml import logging + +from models import InternalTLS from g import versions_file_path, host_root_dir, DEFAULT_UID, INTERNAL_NO_PROXY_DN from utils.misc import generate_random_string, owner_can_read, other_can_read @@ -104,12 +106,11 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit configs = yaml.load(f) config_dict = { - 'adminserver_url': "http://adminserver:8080", - 'registry_url': "http://registry:5000", - 'registry_controller_url': "http://registryctl:8080", - 'core_url': "http://core:8080", - 'core_local_url': "http://127.0.0.1:8080", - 'token_service_url': "http://core:8080/service/token", + 'registry_url': 'http://registry:5000', + 'registry_controller_url': 'http://registryctl:8080', + 'core_url': 'http://core:8080', + 'core_local_url': 'http://127.0.0.1:8080', + 'token_service_url': 'http://core:8080/service/token', 'jobservice_url': 'http://jobservice:8080', 'clair_url': 'http://clair:6060', 'clair_adapter_url': 'http://clair-adapter:8080', @@ -333,6 +334,35 @@ def parse_yaml_config(config_file_path, with_notary, with_clair, with_trivy, wit config_dict['registry_username'] = REGISTRY_USER_NAME config_dict['registry_password'] = generate_random_string(32) + + internal_tls_config = configs['internal_tls'] + # TLS related configs + if internal_tls_config.get('enabled'): + config_dict['internal_tls'] = InternalTLS( + internal_tls_config['enabled'], + internal_tls_config['verify_client_cert'], + internal_tls_config['dir'], + configs['data_volume'], + with_notary=with_notary, + with_clair=with_clair, + with_trivy=with_trivy, + with_chartmuseum=with_chartmuseum, + external_database=config_dict['external_database']) + else: + config_dict['internal_tls'] = InternalTLS() + + if config_dict['internal_tls'].enabled: + config_dict['registry_url'] = 'https://registry:5443' + config_dict['registry_controller_url'] = 'https://registryctl:8443' + config_dict['core_url'] = 'https://core:8443' + config_dict['core_local_url'] = 'https://core:8443' + config_dict['token_service_url'] = 'https://core:8443/service/token' + config_dict['jobservice_url'] = 'https://jobservice:8443' + config_dict['clair_adapter_url'] = 'https://clair-adapter:8443' + config_dict['trivy_adapter_url'] = 'https://trivy-adapter:8443' + # config_dict['notary_url'] = 'http://notary-server:4443' + config_dict['chart_repository_url'] = 'https://chartmuseum:9443' + return config_dict diff --git a/make/photon/prepare/utils/docker_compose.py b/make/photon/prepare/utils/docker_compose.py index 9680179e9..c6c0a8e86 100644 --- a/make/photon/prepare/utils/docker_compose.py +++ b/make/photon/prepare/utils/docker_compose.py @@ -25,7 +25,6 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch 'log_location': configs['log_location'], 'protocol': configs['protocol'], 'http_port': configs['http_port'], - 'registry_custom_ca_bundle_path': configs['registry_custom_ca_bundle_path'], 'external_redis': configs['external_redis'], 'external_database': configs['external_database'], 'with_notary': with_notary, @@ -34,6 +33,10 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch 'with_chartmuseum': with_chartmuseum } + # if configs.get('registry_custom_ca_bundle_path'): + # rendering_variables['registry_custom_ca_bundle_path'] = configs.get('registry_custom_ca_bundle_path') + # rendering_variables['custom_ca_required'] = True + # for gcs storage_config = configs.get('storage_provider_config') or {} if storage_config.get('keyfile') and configs['storage_provider_name'] == 'gcs': @@ -45,6 +48,9 @@ def prepare_docker_compose(configs, with_clair, with_trivy, with_notary, with_ch rendering_variables['cert_path'] = configs['cert_path'] rendering_variables['https_port'] = configs['https_port'] + # internal cert pairs + rendering_variables['internal_tls'] = configs['internal_tls'] + # for uaa uaa_config = configs.get('uaa') or {} if uaa_config.get('ca_file'): diff --git a/make/photon/prepare/utils/internal_tls.py b/make/photon/prepare/utils/internal_tls.py new file mode 100644 index 000000000..1a330e255 --- /dev/null +++ b/make/photon/prepare/utils/internal_tls.py @@ -0,0 +1,4 @@ + +def prepare_tls(config_dict): + config_dict['internal_tls'].prepare() + config_dict['internal_tls'].validate() \ No newline at end of file diff --git a/make/photon/prepare/utils/jobservice.py b/make/photon/prepare/utils/jobservice.py index 1b10900ee..4082af82f 100644 --- a/make/photon/prepare/utils/jobservice.py +++ b/make/photon/prepare/utils/jobservice.py @@ -30,6 +30,7 @@ def prepare_job_service(config_dict): jobservice_conf, uid=DEFAULT_UID, gid=DEFAULT_GID, + internal_tls=config_dict['internal_tls'], max_job_workers=config_dict['max_job_workers'], redis_url=config_dict['redis_url_js'], level=log_level) diff --git a/make/photon/prepare/utils/misc.py b/make/photon/prepare/utils/misc.py index 6280450ee..a405111d0 100644 --- a/make/photon/prepare/utils/misc.py +++ b/make/photon/prepare/utils/misc.py @@ -3,7 +3,7 @@ import secrets from pathlib import Path from functools import wraps -from g import DEFAULT_UID, DEFAULT_GID +from g import DEFAULT_UID, DEFAULT_GID, host_root_dir # To meet security requirement # By default it will change file mode to 0600, and make the owner of the file to 10000:10000 @@ -168,3 +168,12 @@ def stat_decorator(func): return check_wrapper +def get_realpath(path: str) -> Path: + """ + Return the real path in your host if you mounted your host's filesystem to /hostfs, + or return the original path + """ + + if os.path.isdir(host_root_dir): + return os.path.join(host_root_dir, path.lstrip('/')) + return Path(path) diff --git a/make/photon/prepare/utils/nginx.py b/make/photon/prepare/utils/nginx.py index ae1f4003a..f2b96087e 100644 --- a/make/photon/prepare/utils/nginx.py +++ b/make/photon/prepare/utils/nginx.py @@ -61,7 +61,8 @@ def render_nginx_template(config_dict): gid=DEFAULT_GID, https_redirect='$host' + ('https_port' in config_dict and (":" + str(config_dict['https_port'])) or ""), ssl_cert=SSL_CERT_PATH, - ssl_cert_key=SSL_CERT_KEY_PATH) + ssl_cert_key=SSL_CERT_KEY_PATH, + internal_tls=config_dict['internal_tls']) location_file_pattern = CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTPS else: @@ -69,7 +70,8 @@ def render_nginx_template(config_dict): nginx_http_conf_template, nginx_conf, uid=DEFAULT_UID, - gid=DEFAULT_GID) + gid=DEFAULT_GID, + internal_tls=config_dict['internal_tls']) location_file_pattern = CUSTOM_NGINX_LOCATION_FILE_PATTERN_HTTP copy_nginx_location_configs_if_exist(nginx_template_ext_dir, nginx_confd_dir, location_file_pattern) diff --git a/make/photon/prepare/utils/notary.py b/make/photon/prepare/utils/notary.py index 2e571a462..39d8a50e4 100644 --- a/make/photon/prepare/utils/notary.py +++ b/make/photon/prepare/utils/notary.py @@ -1,5 +1,5 @@ import os, shutil, pathlib -from g import templates_dir, config_dir, root_crt_path, secret_key_dir,DEFAULT_UID, DEFAULT_GID +from g import templates_dir, config_dir, root_crt_path, secret_key_dir, secret_dir, DEFAULT_UID, DEFAULT_GID from .cert import openssl_installed, create_cert, create_root_cert, get_alias from .jinja import render_jinja from .misc import mark_file, prepare_dir @@ -25,7 +25,7 @@ def prepare_env_notary(nginx_config_dir): old_signer_key_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer.key')) old_signer_ca_cert_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer-ca.crt')) - notary_secret_dir = prepare_dir('/secret/notary') + notary_secret_dir = prepare_dir(secret_dir ,'notary') signer_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.crt')) signer_key_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.key')) signer_ca_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer-ca.crt')) diff --git a/make/photon/prepare/utils/registry_ctl.py b/make/photon/prepare/utils/registry_ctl.py index 8ffe68104..0541c3804 100644 --- a/make/photon/prepare/utils/registry_ctl.py +++ b/make/photon/prepare/utils/registry_ctl.py @@ -1,6 +1,6 @@ import os, shutil -from g import config_dir, templates_dir +from g import config_dir, templates_dir, DEFAULT_GID, DEFAULT_UID from utils.misc import prepare_dir from utils.jinja import render_jinja @@ -12,19 +12,18 @@ registryctl_conf_env = os.path.join(config_dir, "registryctl", "env") def prepare_registry_ctl(config_dict): # prepare dir - prepare_registry_ctl_config_dir() + prepare_dir(registryctl_config_dir) - # Render Registryctl + # Render Registryctl env render_jinja( registryctl_env_template_path, registryctl_conf_env, **config_dict) - # Copy Registryctl config - copy_registry_ctl_conf(registryctl_config_template_path, registryctl_conf) - -def prepare_registry_ctl_config_dir(): - prepare_dir(registryctl_config_dir) - -def copy_registry_ctl_conf(src, dst): - shutil.copyfile(src, dst) \ No newline at end of file + # Render Registryctl config + render_jinja( + registryctl_config_template_path, + registryctl_conf, + uid=DEFAULT_UID, + gid=DEFAULT_GID, + **config_dict) diff --git a/make/prepare b/make/prepare index 55e83a957..be1c4a0ca 100755 --- a/make/prepare +++ b/make/prepare @@ -55,9 +55,8 @@ docker run --rm -v $input_dir:/input:z \ -v $data_path:/data:z \ -v $harbor_prepare_path:/compose_location:z \ -v $config_dir:/config:z \ - -v $secret_dir:/secret:z \ -v /:/hostfs:z \ - goharbor/prepare:dev $@ + goharbor/prepare:dev prepare $@ echo "Clean up the input dir" # Clean up input dir diff --git a/src/chartserver/client.go b/src/chartserver/client.go index 1ab153570..06558566d 100644 --- a/src/chartserver/client.go +++ b/src/chartserver/client.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "strings" + "sync" "time" commonhttp "github.com/goharbor/harbor/src/common/http" @@ -19,6 +20,11 @@ const ( idleConnectionTimeout = 30 * time.Second ) +var ( + once sync.Once + chartTransport *http.Transport +) + // ChartClient is a http client to get the content from the external http server type ChartClient struct { // HTTP client @@ -31,12 +37,15 @@ type ChartClient struct { // NewChartClient is constructor of ChartClient // credential can be nil func NewChartClient(credential *Credential) *ChartClient { // Create http client with customized timeouts + once.Do(func() { + chartTransport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport).Clone() + chartTransport.MaxIdleConns = maxIdleConnections + chartTransport.IdleConnTimeout = idleConnectionTimeout + }) + client := &http.Client{ - Timeout: clientTimeout, - Transport: &http.Transport{ - MaxIdleConns: maxIdleConnections, - IdleConnTimeout: idleConnectionTimeout, - }, + Timeout: clientTimeout, + Transport: chartTransport, } return &ChartClient{ diff --git a/src/chartserver/reverse_proxy.go b/src/chartserver/reverse_proxy.go index dc42423fb..02b883c8f 100644 --- a/src/chartserver/reverse_proxy.go +++ b/src/chartserver/reverse_proxy.go @@ -17,6 +17,7 @@ import ( "github.com/goharbor/harbor/src/common" "github.com/goharbor/harbor/src/common/api" + commonhttp "github.com/goharbor/harbor/src/common/http" hlog "github.com/goharbor/harbor/src/common/utils/log" n_event "github.com/goharbor/harbor/src/pkg/notifier/event" "github.com/goharbor/harbor/src/replication" @@ -57,6 +58,7 @@ func NewProxyEngine(target *url.URL, cred *Credential, middlewares ...func(http. director(target, cred, req) }, ModifyResponse: modifyResponse, + Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), } if len(middlewares) > 0 { diff --git a/src/common/config/store/driver/rest.go b/src/common/config/store/driver/rest.go index 05902e85d..04a5120e4 100644 --- a/src/common/config/store/driver/rest.go +++ b/src/common/config/store/driver/rest.go @@ -2,7 +2,9 @@ package driver import ( "errors" - "github.com/goharbor/harbor/src/common/http" + "net/http" + + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" "github.com/goharbor/harbor/src/common/utils/log" ) @@ -10,12 +12,17 @@ import ( // RESTDriver - config store driver based on REST API type RESTDriver struct { configRESTURL string - client *http.Client + client *commonhttp.Client } // NewRESTDriver - Create RESTDriver func NewRESTDriver(configRESTURL string, modifiers ...modifier.Modifier) *RESTDriver { - return &RESTDriver{configRESTURL: configRESTURL, client: http.NewClient(nil, modifiers...)} + if commonhttp.InternalTLSEnabled() { + tr := commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + return &RESTDriver{configRESTURL: configRESTURL, client: commonhttp.NewClient(&http.Client{Transport: tr}, modifiers...)} + + } + return &RESTDriver{configRESTURL: configRESTURL, client: commonhttp.NewClient(nil, modifiers...)} } // Load - load config data from REST server diff --git a/src/common/http/client.go b/src/common/http/client.go index e3cc82780..c971e3cd5 100644 --- a/src/common/http/client.go +++ b/src/common/http/client.go @@ -16,18 +16,44 @@ package http import ( "bytes" - "crypto/tls" "encoding/json" "errors" - "github.com/goharbor/harbor/src/common/http/modifier" - "github.com/goharbor/harbor/src/internal" "io" "io/ioutil" "net/http" "net/url" "reflect" + + "github.com/goharbor/harbor/src/common/http/modifier" + "github.com/goharbor/harbor/src/internal" ) +const ( + // InsecureTransport used to get the insecure http Transport + InsecureTransport = iota + // SecureTransport used to get the external secure http Transport + SecureTransport +) + +var ( + secureHTTPTransport *http.Transport + insecureHTTPTransport *http.Transport +) + +func init() { + secureHTTPTransport = http.DefaultTransport.(*http.Transport).Clone() + insecureHTTPTransport = http.DefaultTransport.(*http.Transport).Clone() + insecureHTTPTransport.TLSClientConfig.InsecureSkipVerify = true + + if InternalTLSEnabled() { + tlsConfig, err := GetInternalTLSConfig() + if err != nil { + panic(err) + } + secureHTTPTransport.TLSClientConfig = tlsConfig + } +} + // Client is a util for common HTTP operations, such Get, Head, Post, Put and Delete. // Use Do instead if those methods can not meet your requirement type Client struct { @@ -35,31 +61,22 @@ type Client struct { client *http.Client } -var defaultHTTPTransport, secureHTTPTransport, insecureHTTPTransport *http.Transport - -func init() { - defaultHTTPTransport = &http.Transport{} - - secureHTTPTransport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: false, - }, - } - insecureHTTPTransport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, +// GetHTTPTransport returns HttpTransport based on insecure configuration +func GetHTTPTransport(clientType uint) *http.Transport { + switch clientType { + case SecureTransport: + return secureHTTPTransport + case InsecureTransport: + return insecureHTTPTransport + default: + // default Transport is secure one + return secureHTTPTransport } } -// GetHTTPTransport returns HttpTransport based on insecure configuration -func GetHTTPTransport(insecure ...bool) *http.Transport { - if len(insecure) == 0 { - return defaultHTTPTransport - } - if insecure[0] { +// GetHTTPTransportByInsecure returns a insecure HttpTransport if insecure is true or it returns secure one +func GetHTTPTransportByInsecure(insecure bool) *http.Transport { + if insecure { return insecureHTTPTransport } return secureHTTPTransport @@ -74,9 +91,7 @@ func NewClient(c *http.Client, modifiers ...modifier.Modifier) *Client { } if client.client == nil { client.client = &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - }, + Transport: GetHTTPTransport(SecureTransport), } } if len(modifiers) > 0 { diff --git a/src/common/http/client_test.go b/src/common/http/client_test.go index 09f576c97..176a0d81a 100644 --- a/src/common/http/client_test.go +++ b/src/common/http/client_test.go @@ -7,8 +7,8 @@ import ( ) func TestGetHTTPTransport(t *testing.T) { - transport := GetHTTPTransport(true) + transport := GetHTTPTransport(InsecureTransport) assert.True(t, transport.TLSClientConfig.InsecureSkipVerify) - transport = GetHTTPTransport(false) + transport = GetHTTPTransport(SecureTransport) assert.False(t, transport.TLSClientConfig.InsecureSkipVerify) } diff --git a/src/common/http/tls.go b/src/common/http/tls.go new file mode 100644 index 000000000..be7959ee7 --- /dev/null +++ b/src/common/http/tls.go @@ -0,0 +1,62 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +import ( + "crypto/tls" + "fmt" + "os" + "strings" +) + +const ( + // Internal TLS ENV + internalTLSEnable = "INTERNAL_TLS_ENABLED" + internalVerifyClientCert = "INTERNAL_VERIFY_CLIENT_CERT" + internalTLSKeyPath = "INTERNAL_TLS_KEY_PATH" + internalTLSCertPath = "INTERNAL_TLS_CERT_PATH" + internalTrustCAPath = "INTERNAL_TLS_TRUST_CA_PATH" +) + +// InternalTLSEnabled returns if internal TLS enabled +func InternalTLSEnabled() bool { + return strings.ToLower(os.Getenv(internalTLSEnable)) == "true" +} + +// InternalEnableVerifyClientCert returns if mTLS enabled +func InternalEnableVerifyClientCert() bool { + return strings.ToLower(os.Getenv(internalVerifyClientCert)) == "true" +} + +// GetInternalCertPair used to get internal cert and key pair from environment +func GetInternalCertPair() (tls.Certificate, error) { + crtPath := os.Getenv(internalTLSCertPath) + keyPath := os.Getenv(internalTLSKeyPath) + cert, err := tls.LoadX509KeyPair(crtPath, keyPath) + return cert, err +} + +// GetInternalTLSConfig return a tls.Config for internal https communicate +func GetInternalTLSConfig() (*tls.Config, error) { + // genrate key pair + cert, err := GetInternalCertPair() + if err != nil { + return nil, fmt.Errorf("internal TLS enabled but can't get cert file %w", err) + } + + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + }, nil +} diff --git a/src/common/job/client.go b/src/common/job/client.go index 3c5e060ac..7c22d891a 100644 --- a/src/common/job/client.go +++ b/src/common/job/client.go @@ -62,10 +62,13 @@ func Init() { // NewDefaultClient creates a default client based on endpoint and secret. func NewDefaultClient(endpoint, secret string) *DefaultClient { var c *commonhttp.Client + httpCli := &http.Client{ + Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + } if len(secret) > 0 { - c = commonhttp.NewClient(nil, auth.NewSecretAuthorizer(secret)) + c = commonhttp.NewClient(httpCli, auth.NewSecretAuthorizer(secret)) } else { - c = commonhttp.NewClient(nil) + c = commonhttp.NewClient(httpCli) } e := strings.TrimRight(endpoint, "/") return &DefaultClient{ @@ -74,7 +77,29 @@ func NewDefaultClient(endpoint, secret string) *DefaultClient { } } -// SubmitJob call jobserivce API to submit a job and returns the job's UUID. +// NewReplicationClient used to create a client for replication +func NewReplicationClient(endpoint, secret string) *DefaultClient { + var c *commonhttp.Client + + if len(secret) > 0 { + c = commonhttp.NewClient(&http.Client{ + Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + }, + auth.NewSecretAuthorizer(secret)) + } else { + c = commonhttp.NewClient(&http.Client{ + Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport), + }) + } + + e := strings.TrimRight(endpoint, "/") + return &DefaultClient{ + endpoint: e, + client: c, + } +} + +// SubmitJob call jobservice API to submit a job and returns the job's UUID. func (d *DefaultClient) SubmitJob(jd *models.JobData) (string, error) { url := d.endpoint + "/api/v1/jobs" jq := models.JobRequest{ diff --git a/src/core/api/health.go b/src/core/api/health.go index aa6ba9cc1..6188aa285 100644 --- a/src/core/api/health.go +++ b/src/core/api/health.go @@ -131,7 +131,8 @@ func HTTPStatusCodeHealthChecker(method string, url string, header http.Header, } client := httputil.NewClient(&http.Client{ - Timeout: timeout, + Transport: httputil.GetHTTPTransport(httputil.SecureTransport), + Timeout: timeout, }) resp, err := client.Do(req) if err != nil { diff --git a/src/core/config/config.go b/src/core/config/config.go index 0c18486b0..bd9a6d02f 100755 --- a/src/core/config/config.go +++ b/src/core/config/config.go @@ -229,6 +229,11 @@ func InternalJobServiceURL() string { return strings.TrimSuffix(cfgMgr.Get(common.JobServiceURL).GetString(), "/") } +// GetCoreURL returns the url of core from env +func GetCoreURL() string { + return os.Getenv("CORE_URL") +} + // InternalCoreURL returns the local harbor core url func InternalCoreURL() string { return strings.TrimSuffix(cfgMgr.Get(common.CoreURL).GetString(), "/") @@ -409,7 +414,7 @@ func GetPortalURL() string { // GetRegistryCtlURL returns the URL of registryctl func GetRegistryCtlURL() string { - url := os.Getenv("REGISTRYCTL_URL") + url := os.Getenv("REGISTRY_CONTROLLER_URL") if len(url) == 0 { return common.DefaultRegistryCtlURL } diff --git a/src/core/main.go b/src/core/main.go index e13233266..bee68f79c 100755 --- a/src/core/main.go +++ b/src/core/main.go @@ -26,6 +26,7 @@ import ( _ "github.com/astaxie/beego/session/redis" _ "github.com/goharbor/harbor/src/api/event/handler" "github.com/goharbor/harbor/src/common/dao" + common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/job" "github.com/goharbor/harbor/src/common/models" "github.com/goharbor/harbor/src/common/utils" @@ -161,8 +162,19 @@ func main() { server.RegisterRoutes() - log.Infof("Version: %s, Git commit: %s", version.ReleaseVersion, version.GitCommit) + if common_http.InternalTLSEnabled() { + log.Info("internal TLS enabled, Init TLS ...") + iTLSKeyPath := os.Getenv("INTERNAL_TLS_KEY_PATH") + iTLSCertPath := os.Getenv("INTERNAL_TLS_CERT_PATH") + log.Infof("load client key: %s client cert: %s", iTLSKeyPath, iTLSCertPath) + beego.BConfig.Listen.EnableHTTPS = true + beego.BConfig.Listen.HTTPSPort = 8443 + beego.BConfig.Listen.HTTPSKeyFile = iTLSKeyPath + beego.BConfig.Listen.HTTPSCertFile = iTLSCertPath + } + + log.Infof("Version: %s, Git commit: %s", version.ReleaseVersion, version.GitCommit) beego.RunWithMiddleWares("", middlewares.MiddleWares()...) } diff --git a/src/internal/transport.go b/src/internal/transport.go deleted file mode 100644 index 7a62c9d4e..000000000 --- a/src/internal/transport.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright Project Harbor Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package internal - -import ( - "crypto/tls" - "net/http" -) - -var ( - secureHTTPTransport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: false, - }, - } - insecureHTTPTransport = &http.Transport{ - Proxy: http.ProxyFromEnvironment, - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - } -) - -// GetHTTPTransport returns the HTTP transport based on insecure configuration -func GetHTTPTransport(insecure ...bool) *http.Transport { - if len(insecure) > 0 && insecure[0] { - return insecureHTTPTransport - } - return secureHTTPTransport -} diff --git a/src/jobservice/api/server.go b/src/jobservice/api/server.go index 43ef54cf0..2898b9f9c 100644 --- a/src/jobservice/api/server.go +++ b/src/jobservice/api/server.go @@ -15,12 +15,13 @@ package api import ( + "context" "crypto/tls" "fmt" "net/http" "time" - "context" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/jobservice/config" "github.com/goharbor/harbor/src/jobservice/logger" ) @@ -72,21 +73,11 @@ func NewServer(ctx context.Context, router Router, cfg ServerConfig) *Server { } // Initialize TLS/SSL config if protocol is https - if cfg.Protocol == config.JobServiceProtocolHTTPS { - tlsCfg := &tls.Config{ - MinVersion: tls.VersionTLS12, - CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, - PreferServerCipherSuites: true, - CipherSuites: []uint16{ - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - }, + if cfg.Protocol == config.JobServiceProtocolHTTPS && commonhttp.InternalEnableVerifyClientCert() { + logger.Infof("mTLS enabled ...") + srv.TLSConfig = &tls.Config{ + ClientAuth: tls.RequireAndVerifyClientCert, } - - srv.TLSConfig = tlsCfg - srv.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0) } apiServer.httpServer = srv diff --git a/src/jobservice/hook/hook_client.go b/src/jobservice/hook/hook_client.go index 820880f7b..e7f0a54bf 100644 --- a/src/jobservice/hook/hook_client.go +++ b/src/jobservice/hook/hook_client.go @@ -15,6 +15,7 @@ package hook import ( + "context" "encoding/json" "errors" "fmt" @@ -24,7 +25,8 @@ import ( "strings" "time" - "context" + commonhttp "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/common/utils/log" ) // Client for handling the hook events @@ -54,6 +56,13 @@ func NewClient(ctx context.Context) Client { ExpectContinueTimeout: 1 * time.Second, Proxy: http.ProxyFromEnvironment, } + if commonhttp.InternalEnableVerifyClientCert() { + tlsConfig, err := commonhttp.GetInternalTLSConfig() + if err != nil { + log.Errorf("client load cert file with err: %w", err) + } + transport.TLSClientConfig = tlsConfig + } client := &http.Client{ Timeout: 15 * time.Second, diff --git a/src/jobservice/job/impl/notification/webhook_job.go b/src/jobservice/job/impl/notification/webhook_job.go index b8c56966b..3333b1a57 100644 --- a/src/jobservice/job/impl/notification/webhook_job.go +++ b/src/jobservice/job/impl/notification/webhook_job.go @@ -60,13 +60,17 @@ func (wj *WebhookJob) init(ctx job.Context, params map[string]interface{}) error wj.logger = ctx.GetLogger() wj.ctx = ctx - // default insecureSkipVerify is false - insecureSkipVerify := false + // default use insecure transport + tr := commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) if v, ok := params["skip_cert_verify"]; ok { - insecureSkipVerify = v.(bool) + if insecure, ok := v.(bool); ok { + if insecure { + tr = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + } + } } wj.client = &http.Client{ - Transport: commonhttp.GetHTTPTransport(insecureSkipVerify), + Transport: tr, } return nil diff --git a/src/jobservice/job/impl/replication/scheduler.go b/src/jobservice/job/impl/replication/scheduler.go index a77a019e5..95889bc65 100644 --- a/src/jobservice/job/impl/replication/scheduler.go +++ b/src/jobservice/job/impl/replication/scheduler.go @@ -16,7 +16,6 @@ package replication import ( "fmt" - "github.com/goharbor/harbor/src/internal" "net/http" "os" @@ -61,7 +60,7 @@ func (s *Scheduler) Run(ctx job.Context, params job.Parameters) error { policyID := (int64)(params["policy_id"].(float64)) cred := auth.NewSecretAuthorizer(os.Getenv("JOBSERVICE_SECRET")) client := common_http.NewClient(&http.Client{ - Transport: internal.GetHTTPTransport(true), + Transport: common_http.GetHTTPTransport(common_http.SecureTransport), }, cred) if err := client.Post(url, struct { PolicyID int64 `json:"policy_id"` diff --git a/src/jobservice/runtime/bootstrap.go b/src/jobservice/runtime/bootstrap.go index e70d72e80..0bf0ecd5f 100644 --- a/src/jobservice/runtime/bootstrap.go +++ b/src/jobservice/runtime/bootstrap.go @@ -230,6 +230,7 @@ func (bs *Bootstrap) createAPIServer(ctx context.Context, cfg *config.Configurat Port: cfg.Port, } if cfg.HTTPSConfig != nil { + serverConfig.Protocol = config.JobServiceProtocolHTTPS serverConfig.Cert = cfg.HTTPSConfig.Cert serverConfig.Key = cfg.HTTPSConfig.Key } diff --git a/src/pkg/notification/policy/manager/manager.go b/src/pkg/notification/policy/manager/manager.go index dc41c4ecd..95bcb2114 100755 --- a/src/pkg/notification/policy/manager/manager.go +++ b/src/pkg/notification/policy/manager/manager.go @@ -110,9 +110,8 @@ func (m *DefaultManager) policyHTTPTest(address string, skipCertVerify bool) err } req.Header.Set("Content-Type", "application/json") - client := http.Client{ - Transport: commonhttp.GetHTTPTransport(skipCertVerify), + Transport: commonhttp.GetHTTPTransportByInsecure(skipCertVerify), } resp, err := client.Do(req) diff --git a/src/pkg/registry/auth/authorizer.go b/src/pkg/registry/auth/authorizer.go index 2092e9049..9b5189115 100644 --- a/src/pkg/registry/auth/authorizer.go +++ b/src/pkg/registry/auth/authorizer.go @@ -16,25 +16,27 @@ package auth import ( "fmt" + "net/http" + "net/url" + "strings" + "sync" + "github.com/docker/distribution/registry/client/auth/challenge" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" "github.com/goharbor/harbor/src/internal" "github.com/goharbor/harbor/src/pkg/registry/auth/basic" "github.com/goharbor/harbor/src/pkg/registry/auth/bearer" "github.com/goharbor/harbor/src/pkg/registry/auth/null" - "net/http" - "net/url" - "strings" - "sync" ) // NewAuthorizer creates an authorizer that can handle different auth schemes -func NewAuthorizer(username, password string, insecure bool) internal.Authorizer { +func NewAuthorizer(username, password string, trType uint) internal.Authorizer { return &authorizer{ username: username, password: password, client: &http.Client{ - Transport: internal.GetHTTPTransport(insecure), + Transport: commonhttp.GetHTTPTransport(trType), }, } } diff --git a/src/pkg/registry/client.go b/src/pkg/registry/client.go index df8c7963d..f55d110a1 100644 --- a/src/pkg/registry/client.go +++ b/src/pkg/registry/client.go @@ -27,10 +27,10 @@ import ( "github.com/docker/distribution" "github.com/docker/distribution/manifest/manifestlist" - // register oci manifest unmarshal function - _ "github.com/docker/distribution/manifest/ocischema" + _ "github.com/docker/distribution/manifest/ocischema" // register oci manifest unmarshal function "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/core/config" "github.com/goharbor/harbor/src/internal" ierror "github.com/goharbor/harbor/src/internal/error" @@ -44,7 +44,7 @@ var ( Cli = func() Client { url, _ := config.RegistryURL() username, password := config.RegistryCredential() - return NewClient(url, username, password, true) + return NewClient(url, username, password, false) }() accepts = []string{ @@ -99,22 +99,36 @@ type Client interface { // of the registry automatically and calls the corresponding underlying authorizers(basic/bearer) to // do the auth work. If a customized authorizer is needed, use "NewClientWithAuthorizer" instead func NewClient(url, username, password string, insecure bool) Client { + var transportType uint + if insecure { + transportType = commonhttp.InsecureTransport + } else { + transportType = commonhttp.SecureTransport + } + return &client{ url: url, - authorizer: auth.NewAuthorizer(username, password, insecure), + authorizer: auth.NewAuthorizer(username, password, transportType), client: &http.Client{ - Transport: internal.GetHTTPTransport(insecure), + Transport: commonhttp.GetHTTPTransport(transportType), }, } } // NewClientWithAuthorizer creates a registry client with the provided authorizer func NewClientWithAuthorizer(url string, authorizer internal.Authorizer, insecure bool) Client { + var transportType uint + if insecure { + transportType = commonhttp.InsecureTransport + } else { + transportType = commonhttp.SecureTransport + } + return &client{ url: url, authorizer: authorizer, client: &http.Client{ - Transport: internal.GetHTTPTransport(insecure), + Transport: commonhttp.GetHTTPTransport(transportType), }, } } diff --git a/src/pkg/signature/notary/helper.go b/src/pkg/signature/notary/helper.go index d1514b283..773804e3f 100644 --- a/src/pkg/signature/notary/helper.go +++ b/src/pkg/signature/notary/helper.go @@ -17,17 +17,17 @@ package notary import ( "encoding/hex" "fmt" - "github.com/goharbor/harbor/src/internal" - model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model" "net/http" "os" "path" "strings" "github.com/docker/distribution/registry/auth/token" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/core/config" tokenutil "github.com/goharbor/harbor/src/core/service/token" + model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/trustpinning" @@ -82,7 +82,7 @@ func GetTargets(notaryEndpoint string, username string, fqRepo string) ([]model2 authorizer := ¬aryAuthorizer{ token: t.Token, } - tr := NewTransport(internal.GetHTTPTransport(), authorizer) + tr := NewTransport(commonhttp.GetHTTPTransport(commonhttp.SecureTransport), authorizer) gun := data.GUN(fqRepo) notaryRepo, err := client.NewFileCachedRepository(notaryCachePath, gun, notaryEndpoint, tr, mockRetriever, trustPin) if err != nil { diff --git a/src/registryctl/client/client.go b/src/registryctl/client/client.go index fc6453680..239583110 100644 --- a/src/registryctl/client/client.go +++ b/src/registryctl/client/client.go @@ -57,7 +57,9 @@ func NewClient(baseURL string, cfg *Config) Client { } if cfg != nil { authorizer := auth.NewSecretAuthorizer(cfg.Secret) - client.client = common_http.NewClient(nil, authorizer) + client.client = common_http.NewClient(&http.Client{ + Transport: common_http.GetHTTPTransport(common_http.SecureTransport), + }, authorizer) } return client } diff --git a/src/registryctl/main.go b/src/registryctl/main.go index 835403427..4f6a3709e 100644 --- a/src/registryctl/main.go +++ b/src/registryctl/main.go @@ -19,6 +19,7 @@ import ( "flag" "net/http" + common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/registryctl/config" "github.com/goharbor/harbor/src/registryctl/handlers" @@ -37,25 +38,13 @@ func (s *RegistryCtl) Start() { Handler: s.Handler, } - if s.ServerConf.Protocol == "HTTPS" { - tlsCfg := &tls.Config{ - MinVersion: tls.VersionTLS12, - CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, - PreferServerCipherSuites: true, - CipherSuites: []uint16{ - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - }, - } - - regCtl.TLSConfig = tlsCfg - regCtl.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0) - } - var err error - if s.ServerConf.Protocol == "HTTPS" { + if s.ServerConf.Protocol == "https" { + if common_http.InternalEnableVerifyClientCert() { + regCtl.TLSConfig = &tls.Config{ + ClientAuth: tls.RequireAndVerifyClientCert, + } + } err = regCtl.ListenAndServeTLS(s.ServerConf.HTTPSConfig.Cert, s.ServerConf.HTTPSConfig.Key) } else { err = regCtl.ListenAndServe() diff --git a/src/replication/adapter/aliacr/adapter.go b/src/replication/adapter/aliacr/adapter.go index bfdf0e45b..69d6914a2 100644 --- a/src/replication/adapter/aliacr/adapter.go +++ b/src/replication/adapter/aliacr/adapter.go @@ -4,9 +4,7 @@ import ( "encoding/json" "errors" "fmt" - "github.com/docker/distribution/registry/client/auth/challenge" - "github.com/goharbor/harbor/src/internal" - "github.com/goharbor/harbor/src/pkg/registry/auth/bearer" + "net/http" "path/filepath" "regexp" @@ -14,8 +12,11 @@ import ( "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "github.com/aliyun/alibaba-cloud-sdk-go/services/cr" + "github.com/docker/distribution/registry/client/auth/challenge" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils" "github.com/goharbor/harbor/src/common/utils/log" + "github.com/goharbor/harbor/src/pkg/registry/auth/bearer" adp "github.com/goharbor/harbor/src/replication/adapter" "github.com/goharbor/harbor/src/replication/adapter/native" "github.com/goharbor/harbor/src/replication/model" @@ -69,9 +70,13 @@ func newAdapter(registry *model.Registry) (*adapter, error) { } func ping(registry *model.Registry) (string, string, error) { - client := &http.Client{ - Transport: internal.GetHTTPTransport(registry.Insecure), + client := &http.Client{} + if registry.Insecure { + client.Transport = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) + } else { + client.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) } + resp, err := client.Get(registry.URL + "/v2/") if err != nil { return "", "", err diff --git a/src/replication/adapter/awsecr/adapter.go b/src/replication/adapter/awsecr/adapter.go index d2d0be73f..beb3c21b4 100644 --- a/src/replication/adapter/awsecr/adapter.go +++ b/src/replication/adapter/awsecr/adapter.go @@ -16,7 +16,6 @@ package awsecr import ( "errors" - "github.com/goharbor/harbor/src/internal" "net/http" "regexp" @@ -25,6 +24,7 @@ import ( "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" awsecrapi "github.com/aws/aws-sdk-go/service/ecr" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" adp "github.com/goharbor/harbor/src/replication/adapter" "github.com/goharbor/harbor/src/replication/adapter/native" @@ -245,11 +245,12 @@ func (a *adapter) createRepository(repository string) error { if a.region == "" { return errors.New("no region parsed") } + config := &aws.Config{ Credentials: cred, Region: &a.region, HTTPClient: &http.Client{ - Transport: internal.GetHTTPTransport(a.registry.Insecure), + Transport: commonhttp.GetHTTPTransportByInsecure(a.registry.Insecure), }, } if a.forceEndpoint != nil { @@ -287,11 +288,18 @@ func (a *adapter) DeleteManifest(repository, reference string) error { if a.region == "" { return errors.New("no region parsed") } + + var tr *http.Transport + if a.registry.Insecure { + tr = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) + } else { + tr = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + } config := &aws.Config{ Credentials: cred, Region: &a.region, HTTPClient: &http.Client{ - Transport: internal.GetHTTPTransport(a.registry.Insecure), + Transport: tr, }, } if a.forceEndpoint != nil { diff --git a/src/replication/adapter/awsecr/auth.go b/src/replication/adapter/awsecr/auth.go index 10c781815..c81e6f722 100644 --- a/src/replication/adapter/awsecr/auth.go +++ b/src/replication/adapter/awsecr/auth.go @@ -18,18 +18,19 @@ import ( "encoding/base64" "errors" "fmt" + "net/http" + "net/url" + "strings" + "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" awsecrapi "github.com/aws/aws-sdk-go/service/ecr" + commonhttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" "github.com/goharbor/harbor/src/common/utils/log" - "github.com/goharbor/harbor/src/internal" - "net/http" - "net/url" - "strings" - "time" ) // Credential ... @@ -96,11 +97,18 @@ func (a *awsAuthCredential) getAuthorization() (string, string, string, *time.Ti a.accessKey, a.accessSecret, "") + + var tr *http.Transport + if a.insecure { + tr = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) + } else { + tr = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + } config := &aws.Config{ Credentials: cred, Region: &a.region, HTTPClient: &http.Client{ - Transport: internal.GetHTTPTransport(a.insecure), + Transport: tr, }, } if a.forceEndpoint != nil { diff --git a/src/replication/adapter/harbor/adapter.go b/src/replication/adapter/harbor/adapter.go index 94b938668..157c7df63 100644 --- a/src/replication/adapter/harbor/adapter.go +++ b/src/replication/adapter/harbor/adapter.go @@ -26,7 +26,9 @@ import ( "github.com/goharbor/harbor/src/common/http/modifier" common_http_auth "github.com/goharbor/harbor/src/common/http/modifier/auth" "github.com/goharbor/harbor/src/common/utils/log" + "github.com/goharbor/harbor/src/jobservice/config" "github.com/goharbor/harbor/src/pkg/registry/auth/basic" + adp "github.com/goharbor/harbor/src/replication/adapter" "github.com/goharbor/harbor/src/replication/adapter/native" "github.com/goharbor/harbor/src/replication/model" @@ -68,7 +70,12 @@ type adapter struct { } func newAdapter(registry *model.Registry) (*adapter, error) { - transport := util.GetHTTPTransport(registry.Insecure) + var transport *http.Transport + if registry.URL == config.GetCoreURL() { + transport = common_http.GetHTTPTransport(common_http.SecureTransport) + } else { + transport = util.GetHTTPTransport(registry.Insecure) + } // local Harbor instance if registry.Credential != nil && registry.Credential.Type == model.CredentialTypeSecret { authorizer := common_http_auth.NewSecretAuthorizer(registry.Credential.AccessSecret) @@ -296,6 +303,9 @@ func (a *adapter) getProject(name string) (*project, error) { // when harbor is deployed on Kubernetes func (a *adapter) getURL() string { if a.registry.Type == model.RegistryTypeHarbor && a.registry.Name == "Local" { + if common_http.InternalTLSEnabled() { + return "https://core:8443" + } return "http://127.0.0.1:8080" } return a.url diff --git a/src/replication/adapter/native/adapter.go b/src/replication/adapter/native/adapter.go index 0537e713b..e8dce8e3b 100644 --- a/src/replication/adapter/native/adapter.go +++ b/src/replication/adapter/native/adapter.go @@ -17,6 +17,7 @@ package native import ( "errors" "fmt" + "github.com/goharbor/harbor/src/common/utils" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/internal" diff --git a/src/replication/event/handler.go b/src/replication/event/handler.go index ecda54d7a..de1ec50e7 100644 --- a/src/replication/event/handler.go +++ b/src/replication/event/handler.go @@ -18,14 +18,14 @@ import ( "errors" "fmt" - "github.com/goharbor/harbor/src/replication/util" - + commonthttp "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/replication/config" "github.com/goharbor/harbor/src/replication/model" "github.com/goharbor/harbor/src/replication/operation" "github.com/goharbor/harbor/src/replication/policy" "github.com/goharbor/harbor/src/replication/registry" + "github.com/goharbor/harbor/src/replication/util" ) // Handler is the handler to handle event @@ -191,6 +191,6 @@ func GetLocalRegistry() *model.Registry { // use secret to do the auth for the local Harbor AccessSecret: config.Config.JobserviceSecret, }, - Insecure: true, + Insecure: !commonthttp.InternalTLSEnabled(), } } diff --git a/src/replication/util/util.go b/src/replication/util/util.go index a06d92adc..acf97ca7f 100644 --- a/src/replication/util/util.go +++ b/src/replication/util/util.go @@ -15,14 +15,18 @@ package util import ( - "github.com/goharbor/harbor/src/internal" "net/http" "strings" + + commonhttp "github.com/goharbor/harbor/src/common/http" ) // GetHTTPTransport can be used to share the common HTTP transport func GetHTTPTransport(insecure bool) *http.Transport { - return internal.GetHTTPTransport(insecure) + if insecure { + return commonhttp.GetHTTPTransport(commonhttp.InsecureTransport) + } + return commonhttp.GetHTTPTransport(commonhttp.SecureTransport) } // ParseRepository parses the "repository" provided into two parts: namespace and the rest diff --git a/src/server/registry/proxy.go b/src/server/registry/proxy.go index d891f8386..5fe9448db 100644 --- a/src/server/registry/proxy.go +++ b/src/server/registry/proxy.go @@ -16,10 +16,12 @@ package registry import ( "fmt" - "github.com/goharbor/harbor/src/core/config" "net/http" "net/http/httputil" "net/url" + + commonhttp "github.com/goharbor/harbor/src/common/http" + "github.com/goharbor/harbor/src/core/config" ) var proxy = newProxy() @@ -31,6 +33,10 @@ func newProxy() http.Handler { panic(fmt.Sprintf("failed to parse the URL of registry: %v", err)) } proxy := httputil.NewSingleHostReverseProxy(url) + if commonhttp.InternalTLSEnabled() { + proxy.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport) + } + proxy.Director = basicAuthDirector(proxy.Director) return proxy } diff --git a/tests/ci/api_common_install.sh b/tests/ci/api_common_install.sh index 42d66f4f9..c4a3b2b04 100755 --- a/tests/ci/api_common_install.sh +++ b/tests/ci/api_common_install.sh @@ -30,5 +30,5 @@ if [ $GITHUB_TOKEN ]; then sed "s/# github_token: xxx/github_token: $GITHUB_TOKEN/" -i make/harbor.yml fi -sudo make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage CLARITYIMAGE=goharbor/harbor-clarity-ui-builder:1.6.0 NOTARYFLAG=true CLAIRFLAG=true TRIVYFLAG=true CHARTFLAG=true +sudo make install GOBUILDIMAGE=golang:1.13.4 COMPILETAG=compile_golangimage CLARITYIMAGE=goharbor/harbor-clarity-ui-builder:1.6.0 NOTARYFLAG=true CLAIRFLAG=true TRIVYFLAG=true CHARTFLAG=true GEN_TLS=true sleep 10 diff --git a/tests/ci/ut_install.sh b/tests/ci/ut_install.sh index 84d5939c2..149536d1e 100755 --- a/tests/ci/ut_install.sh +++ b/tests/ci/ut_install.sh @@ -22,6 +22,7 @@ sudo -E env "PATH=$PATH" make go_check sudo ./tests/hostcfg.sh sudo ./tests/generateCerts.sh sudo make -f make/photon/Makefile _build_db _build_registry _build_prepare -e VERSIONTAG=dev -e REGISTRYVERSION=${REG_VERSION} -e BASEIMAGETAG=dev +docker run --rm -v /:/hostfs:z goharbor/prepare:dev gencert -p /etc/harbor/tls/internal sudo MAKEPATH=$(pwd)/make ./make/prepare sudo mkdir -p "/data/redis" sudo mkdir -p /etc/core/ca/ && sudo mv ./tests/ca.crt /etc/core/ca/ diff --git a/tests/hostcfg.sh b/tests/hostcfg.sh index 235e57a29..6ba8f416e 100755 --- a/tests/hostcfg.sh +++ b/tests/hostcfg.sh @@ -4,6 +4,12 @@ IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'` #echo $IP sudo sed "s/reg.mydomain.com/$IP/" make/harbor.yml.tmpl |sudo tee make/harbor.yml +# enable internal tls +echo "internal_tls:" >> make/harbor.yml +echo " enabled: true" >> make/harbor.yml +echo " verify_client_cert: true" >> make/harbor.yml +echo " dir: /etc/harbor/tls/internal" >> make/harbor.yml + # TODO: remove it when scanner adapter support internal access of harbor echo "storage_service:" >> make/harbor.yml echo " ca_bundle: /data/cert/server.crt" >> make/harbor.yml