From 8f0587275f164fc08483de113c346e8eafb2823e Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:22:53 +0800 Subject: [PATCH 01/18] =?UTF-8?q?perf:=20=E7=A7=BB=E9=99=A4=E5=8F=B3?= =?UTF-8?q?=E4=BE=A7=E6=A0=8F=E7=9A=84=E6=8C=89=E9=92=AE=EF=BC=8C=E9=80=9A?= =?UTF-8?q?=E8=BF=87=20luna=20=E6=8E=A7=E5=88=B6=20(#1281)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 移除右侧栏的按钮,通过 luna 控制 * perf: 优化代码 --------- Co-authored-by: Eric --- ui/src/components/RightPanel.vue | 8 ++++---- ui/src/components/Terminal.vue | 3 +++ ui/src/views/Connection.vue | 6 +++++- ui/src/views/ShareTerminal.vue | 11 ++++++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ui/src/components/RightPanel.vue b/ui/src/components/RightPanel.vue index 8568b5d8..1f3056d0 100644 --- a/ui/src/components/RightPanel.vue +++ b/ui/src/components/RightPanel.vue @@ -6,9 +6,6 @@ >
-
- -
@@ -45,7 +42,7 @@ export default { } }, mounted() { - this.init() + // this.init() this.insertToBody() }, beforeDestroy() { @@ -107,6 +104,9 @@ export default { const element = this.$refs.container const body = document.querySelector('body') body.insertBefore(element, body.firstChild) + }, + toggle() { + this.show = !this.show } } } diff --git a/ui/src/components/Terminal.vue b/ui/src/components/Terminal.vue index 2730ddfd..e20baec9 100644 --- a/ui/src/components/Terminal.vue +++ b/ui/src/components/Terminal.vue @@ -185,6 +185,9 @@ export default { this.term.focus() } break + case 'OPEN': + this.$emit("event", "open", this.terminalId) + break } console.log('KoKo got post message: ', msg) }, diff --git a/ui/src/views/Connection.vue b/ui/src/views/Connection.vue index 48816a4f..36392f24 100644 --- a/ui/src/views/Connection.vue +++ b/ui/src/views/Connection.vue @@ -8,7 +8,7 @@ v-on:event="onEvent" v-on:ws-data="onWsData"> - + @@ -386,6 +386,10 @@ export default { }) this.$log.debug("reconnect: ", data); break + case 'open': + this.$log.debug("open: ", data); + this.$refs.panel.toggle() + break } }, getMinuteLabel(item) { diff --git a/ui/src/views/ShareTerminal.vue b/ui/src/views/ShareTerminal.vue index 098dcd60..02b60389 100644 --- a/ui/src/views/ShareTerminal.vue +++ b/ui/src/views/ShareTerminal.vue @@ -3,10 +3,11 @@ - + @@ -197,6 +198,14 @@ export default { this.themeBackground = themeColors.background; } this.$log.debug(val); + }, + onEvent(event, data) { + switch (event) { + case 'open': + this.$log.debug("open: ", data); + this.$refs.panel.toggle() + break + } } }, From 6cb290c6e068f1e556bf1dc17d25f0d27f4d6a0b Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 19 Jan 2024 17:57:01 +0800 Subject: [PATCH 02/18] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20mysql=20?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E8=BE=93=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/srvconn/conn_mysql.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/srvconn/conn_mysql.go b/pkg/srvconn/conn_mysql.go index 184a3056..2ce500a6 100644 --- a/pkg/srvconn/conn_mysql.go +++ b/pkg/srvconn/conn_mysql.go @@ -215,6 +215,12 @@ func (opt *sqlOption) Envs() []string { } envs := make([]string, 0, 6) + // 设置下系统环境的语言, 中文输入问题 + envLang := os.Getenv("LANG") + if envLang == "" { + envLang = "zh_CN.UTF-8" + } + envs = append(envs, fmt.Sprintf("LANG=%s", envLang)) envs = append(envs, fmt.Sprintf("USERNAME=%s", opt.Username)) envs = append(envs, fmt.Sprintf("HOSTNAME=%s", opt.Host)) envs = append(envs, fmt.Sprintf("PORT=%d", opt.Port)) From aeea73d59f07b084156efdbc3c47b586c996a5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Wed, 3 Jan 2024 16:28:08 +0800 Subject: [PATCH 03/18] =?UTF-8?q?perf:=20=E6=8B=86=E5=88=86=E5=BC=80?= =?UTF-8?q?=E6=BA=90=E5=92=8C=E4=BC=81=E4=B8=9A=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/jms-build-test.yml | 2 +- Dockerfile => Dockerfile-ce | 77 +++++++++++++--------------- Dockerfile-ee | 36 +++++++++++++ 3 files changed, 73 insertions(+), 42 deletions(-) rename Dockerfile => Dockerfile-ce (64%) create mode 100644 Dockerfile-ee diff --git a/.github/workflows/jms-build-test.yml b/.github/workflows/jms-build-test.yml index 33268215..75354532 100644 --- a/.github/workflows/jms-build-test.yml +++ b/.github/workflows/jms-build-test.yml @@ -23,7 +23,7 @@ jobs: build-args: | GOPROXY=direct APT_MIRROR=http://deb.debian.org - file: Dockerfile + file: Dockerfile-ce cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile-ce similarity index 64% rename from Dockerfile rename to Dockerfile-ce index 1c494599..0cada1a3 100644 --- a/Dockerfile +++ b/Dockerfile-ce @@ -10,45 +10,35 @@ RUN set -ex \ && yarn config set registry ${NPM_REGISTRY} WORKDIR /opt/koko/ui -ADD ui/package.json ui/yarn.lock . -RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko \ +ADD ui/package.json ui/yarn.lock ./ +RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko-yarn \ yarn install ADD ui . -RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko \ +RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko-yarn \ yarn build FROM golang:1.21-bullseye as stage-build -LABEL stage=stage-build ARG TARGETARCH WORKDIR /opt/koko -ARG HELM_VERSION=v3.12.2 -ARG DOWNLOAD_URL=https://download.jumpserver.org - -RUN set -ex \ - && echo "no" | dpkg-reconfigure dash +ARG HELM_VERSION=v3.13.3 +ARG KUBECTL_VERSION=v1.29.0 RUN set -ex \ && mkdir -p /opt/koko/bin \ - && wget ${DOWNLOAD_URL}/public/kubectl-linux-${TARGETARCH}.tar.gz -O kubectl.tar.gz \ - && tar -xf kubectl.tar.gz -C /opt/koko/bin/ \ + && wget -q -O kubectl.tar.gz https://dl.k8s.io/${KUBECTL_VERSION}/kubernetes-client-linux-${TARGETARCH}.tar.gz \ + && tar -xf kubectl.tar.gz --strip-components=3 -C /opt/koko/bin/ kubernetes/client/bin/kubectl \ && mv /opt/koko/bin/kubectl /opt/koko/bin/rawkubectl \ - && wget -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ + && wget -q -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ && tar -xf helm.tar.gz --strip-components=1 -C /opt/koko/bin/ linux-${TARGETARCH}/helm \ && mv /opt/koko/bin/helm /opt/koko/bin/rawhelm \ - && \ - if [ "${TARGETARCH}" == "amd64" ] || [ "${TARGETARCH}" == "arm64" ]; then \ - wget ${DOWNLOAD_URL}/files/clickhouse/22.20.2.11/clickhouse-client-linux-${TARGETARCH}.tar.gz; \ - tar -xf clickhouse-client-linux-${TARGETARCH}.tar.gz -C /opt/koko/bin/; \ - fi \ - && wget ${DOWNLOAD_URL}/public/kubectl_aliases.tar.gz -O kubectl_aliases.tar.gz \ - && tar -xf kubectl_aliases.tar.gz \ + && wget -q https://github.com/ahmetb/kubectl-aliases/raw/master/.kubectl_aliases \ && chmod +x /opt/koko/bin/* \ && chown root:root /opt/koko/bin/* \ && rm -f *.tar.gz -ADD go.mod go.sum . +ADD go.mod go.sum ./ ARG GOPROXY=https://goproxy.io ENV CGO_ENABLED=0 @@ -106,8 +96,8 @@ ARG DEPENDENCIES=" \ xz-utils" ARG APT_MIRROR=http://mirrors.ustc.edu.cn - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko \ +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko-apt \ + --mount=type=cache,target=/var/lib/apt,sharing=locked,id=koko-apt \ sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ && rm -f /etc/apt/apt.conf.d/docker-clean \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ @@ -116,33 +106,38 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko \ && echo "no" | dpkg-reconfigure dash \ && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \ && sed -i "s@# export @export @g" ~/.bashrc \ - && sed -i "s@# alias @alias @g" ~/.bashrc \ - && rm -rf /var/lib/apt/lists/* + && sed -i "s@# alias @alias @g" ~/.bashrc -ARG MONGOSH_VERSION=1.10.3 +ARG MONGOSH_VERSION=2.1.1 RUN set -ex \ && \ case "${TARGETARCH}" in \ - amd64) \ - wget https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-x64.tgz \ - && tar -xf mongosh-${MONGOSH_VERSION}-linux-x64.tgz \ - && chown root:root mongosh-${MONGOSH_VERSION}-linux-x64/bin/* \ - && mv mongosh-${MONGOSH_VERSION}-linux-x64/bin/mongosh /usr/local/bin/ \ - && mv mongosh-${MONGOSH_VERSION}-linux-x64/bin/mongosh_crypt_v1.so /usr/local/lib/ \ - && rm -rf mongosh-${MONGOSH_VERSION}-linux-x64* \ + 'amd64') \ + ARCH=x64; \ ;; \ - arm64) \ - wget https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}.tgz \ - && tar -xf mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}.tgz \ - && chown root:root mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/* \ - && mv mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/mongosh /usr/local/bin/ \ - && mv mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/mongosh_crypt_v1.so /usr/local/lib/ \ - && rm -rf mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}* \ + 'arm64') \ + ARCH=arm64; \ + ;; \ + 's390x') \ + ARCH=s390x; \ + ;; \ + 'ppc64le') \ + ARCH=ppc64le; \ ;; \ *) \ - echo "Unsupported architecture: ${TARGETARCH}" \ + echo "Unsupported architecture: ${TARGETARCH}"; \ ;; \ - esac + esac \ + && \ + if [ -n "${ARCH}" ]; then \ + wget -q https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-${ARCH}.tgz \ + && tar -xf mongosh-${MONGOSH_VERSION}-linux-${ARCH}.tgz \ + && chown root:root mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/* \ + && mv mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/mongosh /usr/local/bin/ \ + && mv mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/mongosh_crypt_v1.so /usr/local/lib/ \ + && rm -rf mongosh-${MONGOSH_VERSION}-linux-${ARCH}* \ + ; \ + fi COPY --from=redis /usr/local/bin/redis-cli /usr/local/bin/redis-cli diff --git a/Dockerfile-ee b/Dockerfile-ee new file mode 100644 index 00000000..9f349da9 --- /dev/null +++ b/Dockerfile-ee @@ -0,0 +1,36 @@ +ARG VERSION +FROM debian:bullseye-slim as clickhouse +ARG TARGETARCH + +ARG DEPENDENCIES=" \ + ca-certificates \ + curl" + +ARG APT_MIRROR=http://mirrors.ustc.edu.cn +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko-apt \ + --mount=type=cache,target=/var/lib/apt,sharing=locked,id=koko-apt \ + sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ + && rm -f /etc/apt/apt.conf.d/docker-clean \ + && apt-get update \ + && apt-get install -y --no-install-recommends ${DEPENDENCIES} \ + && LATEST_VERSION=$(curl -s https://packages.clickhouse.com/tgz/stable/ | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort -V -r | head -n 1) \ + && PKG="clickhouse-common-static" \ + && \ + case "${TARGETARCH}" in \ + amd64|arm64) \ + mkdir -p /opt/clickhouse; \ + curl -fO "https://packages.clickhouse.com/tgz/stable/$PKG-$LATEST_VERSION-${TARGETARCH}.tgz"; \ + tar -xf "$PKG-$LATEST_VERSION-${TARGETARCH}.tgz" -C /opt/clickhouse --strip-components=1; \ + rm -f "$PKG-$LATEST_VERSION-${TARGETARCH}.tgz"; \ + ;; \ + *) \ + mkdir -p /opt/clickhouse/usr/bin; \ + echo > /opt/clickhouse/usr/bin/clickhouse; \ + ;; \ + esac \ + && chown -R root:root /opt/clickhouse + +FROM registry.fit2cloud.com/jumpserver/koko-ce:${VERSION} + +COPY --from=clickhouse /opt/clickhouse/usr/bin/clickhouse /usr/local/bin/clickhouse-client + From 3c25a57bbc6da40050aa1cc9330c6d298a8ddf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Fri, 19 Jan 2024 19:36:55 +0800 Subject: [PATCH 04/18] build(deps): bump github.com/kubernetes/kubectl from v1.29.0 to v1.29.1 --- Dockerfile-ce | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile-ce b/Dockerfile-ce index 0cada1a3..e855e8be 100644 --- a/Dockerfile-ce +++ b/Dockerfile-ce @@ -24,11 +24,11 @@ ARG TARGETARCH WORKDIR /opt/koko ARG HELM_VERSION=v3.13.3 -ARG KUBECTL_VERSION=v1.29.0 +ARG KUBECTL_VERSION=v1.29.1 RUN set -ex \ && mkdir -p /opt/koko/bin \ - && wget -q -O kubectl.tar.gz https://dl.k8s.io/${KUBECTL_VERSION}/kubernetes-client-linux-${TARGETARCH}.tar.gz \ - && tar -xf kubectl.tar.gz --strip-components=3 -C /opt/koko/bin/ kubernetes/client/bin/kubectl \ + && wget -q -O kubectl.tar.gz https://github.com/jumpserver-dev/kubectl/releases/download/${KUBECTL_VERSION}/kubectl-${KUBECTL_VERSION}-linux-${TARGETARCH}.tar.gz \ + && tar -xf kubectl.tar.gz --strip-components=1 -C /opt/koko/bin/ \ && mv /opt/koko/bin/kubectl /opt/koko/bin/rawkubectl \ && wget -q -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ && tar -xf helm.tar.gz --strip-components=1 -C /opt/koko/bin/ linux-${TARGETARCH}/helm \ From 43fed763d9d0cfa6402d449bd2f925ac87f66967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Fri, 19 Jan 2024 20:15:32 +0800 Subject: [PATCH 05/18] Revert "Merge pull request #1287 from jumpserver/pr@dev@perf_kubectl_version" This reverts commit 0a52644712c776e49757aea93b9cc3e89c442374, reversing changes made to aeea73d59f07b084156efdbc3c47b586c996a5c7. --- Dockerfile-ce | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile-ce b/Dockerfile-ce index e855e8be..0cada1a3 100644 --- a/Dockerfile-ce +++ b/Dockerfile-ce @@ -24,11 +24,11 @@ ARG TARGETARCH WORKDIR /opt/koko ARG HELM_VERSION=v3.13.3 -ARG KUBECTL_VERSION=v1.29.1 +ARG KUBECTL_VERSION=v1.29.0 RUN set -ex \ && mkdir -p /opt/koko/bin \ - && wget -q -O kubectl.tar.gz https://github.com/jumpserver-dev/kubectl/releases/download/${KUBECTL_VERSION}/kubectl-${KUBECTL_VERSION}-linux-${TARGETARCH}.tar.gz \ - && tar -xf kubectl.tar.gz --strip-components=1 -C /opt/koko/bin/ \ + && wget -q -O kubectl.tar.gz https://dl.k8s.io/${KUBECTL_VERSION}/kubernetes-client-linux-${TARGETARCH}.tar.gz \ + && tar -xf kubectl.tar.gz --strip-components=3 -C /opt/koko/bin/ kubernetes/client/bin/kubectl \ && mv /opt/koko/bin/kubectl /opt/koko/bin/rawkubectl \ && wget -q -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ && tar -xf helm.tar.gz --strip-components=1 -C /opt/koko/bin/ linux-${TARGETARCH}/helm \ From 49df0676ed92c1b9ac92ae187ce0e0f1a9169023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=B9=BF?= Date: Mon, 22 Jan 2024 14:58:46 +0800 Subject: [PATCH 06/18] =?UTF-8?q?Revert=20"perf:=20=E6=8B=86=E5=88=86?= =?UTF-8?q?=E5=BC=80=E6=BA=90=E5=92=8C=E4=BC=81=E4=B8=9A=E9=95=9C=E5=83=8F?= =?UTF-8?q?"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/jms-build-test.yml | 2 +- Dockerfile-ce => Dockerfile | 77 +++++++++++++++------------- Dockerfile-ee | 36 ------------- 3 files changed, 42 insertions(+), 73 deletions(-) rename Dockerfile-ce => Dockerfile (64%) delete mode 100644 Dockerfile-ee diff --git a/.github/workflows/jms-build-test.yml b/.github/workflows/jms-build-test.yml index 75354532..33268215 100644 --- a/.github/workflows/jms-build-test.yml +++ b/.github/workflows/jms-build-test.yml @@ -23,7 +23,7 @@ jobs: build-args: | GOPROXY=direct APT_MIRROR=http://deb.debian.org - file: Dockerfile-ce + file: Dockerfile cache-from: type=gha cache-to: type=gha,mode=max diff --git a/Dockerfile-ce b/Dockerfile similarity index 64% rename from Dockerfile-ce rename to Dockerfile index 0cada1a3..1c494599 100644 --- a/Dockerfile-ce +++ b/Dockerfile @@ -10,35 +10,45 @@ RUN set -ex \ && yarn config set registry ${NPM_REGISTRY} WORKDIR /opt/koko/ui -ADD ui/package.json ui/yarn.lock ./ -RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko-yarn \ +ADD ui/package.json ui/yarn.lock . +RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko \ yarn install ADD ui . -RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko-yarn \ +RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=koko \ yarn build FROM golang:1.21-bullseye as stage-build +LABEL stage=stage-build ARG TARGETARCH WORKDIR /opt/koko +ARG HELM_VERSION=v3.12.2 +ARG DOWNLOAD_URL=https://download.jumpserver.org + +RUN set -ex \ + && echo "no" | dpkg-reconfigure dash -ARG HELM_VERSION=v3.13.3 -ARG KUBECTL_VERSION=v1.29.0 RUN set -ex \ && mkdir -p /opt/koko/bin \ - && wget -q -O kubectl.tar.gz https://dl.k8s.io/${KUBECTL_VERSION}/kubernetes-client-linux-${TARGETARCH}.tar.gz \ - && tar -xf kubectl.tar.gz --strip-components=3 -C /opt/koko/bin/ kubernetes/client/bin/kubectl \ + && wget ${DOWNLOAD_URL}/public/kubectl-linux-${TARGETARCH}.tar.gz -O kubectl.tar.gz \ + && tar -xf kubectl.tar.gz -C /opt/koko/bin/ \ && mv /opt/koko/bin/kubectl /opt/koko/bin/rawkubectl \ - && wget -q -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ + && wget -O helm.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ && tar -xf helm.tar.gz --strip-components=1 -C /opt/koko/bin/ linux-${TARGETARCH}/helm \ && mv /opt/koko/bin/helm /opt/koko/bin/rawhelm \ - && wget -q https://github.com/ahmetb/kubectl-aliases/raw/master/.kubectl_aliases \ + && \ + if [ "${TARGETARCH}" == "amd64" ] || [ "${TARGETARCH}" == "arm64" ]; then \ + wget ${DOWNLOAD_URL}/files/clickhouse/22.20.2.11/clickhouse-client-linux-${TARGETARCH}.tar.gz; \ + tar -xf clickhouse-client-linux-${TARGETARCH}.tar.gz -C /opt/koko/bin/; \ + fi \ + && wget ${DOWNLOAD_URL}/public/kubectl_aliases.tar.gz -O kubectl_aliases.tar.gz \ + && tar -xf kubectl_aliases.tar.gz \ && chmod +x /opt/koko/bin/* \ && chown root:root /opt/koko/bin/* \ && rm -f *.tar.gz -ADD go.mod go.sum ./ +ADD go.mod go.sum . ARG GOPROXY=https://goproxy.io ENV CGO_ENABLED=0 @@ -96,8 +106,8 @@ ARG DEPENDENCIES=" \ xz-utils" ARG APT_MIRROR=http://mirrors.ustc.edu.cn -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko-apt \ - --mount=type=cache,target=/var/lib/apt,sharing=locked,id=koko-apt \ + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko \ sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ && rm -f /etc/apt/apt.conf.d/docker-clean \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ @@ -106,38 +116,33 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko-apt \ && echo "no" | dpkg-reconfigure dash \ && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \ && sed -i "s@# export @export @g" ~/.bashrc \ - && sed -i "s@# alias @alias @g" ~/.bashrc + && sed -i "s@# alias @alias @g" ~/.bashrc \ + && rm -rf /var/lib/apt/lists/* -ARG MONGOSH_VERSION=2.1.1 +ARG MONGOSH_VERSION=1.10.3 RUN set -ex \ && \ case "${TARGETARCH}" in \ - 'amd64') \ - ARCH=x64; \ + amd64) \ + wget https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-x64.tgz \ + && tar -xf mongosh-${MONGOSH_VERSION}-linux-x64.tgz \ + && chown root:root mongosh-${MONGOSH_VERSION}-linux-x64/bin/* \ + && mv mongosh-${MONGOSH_VERSION}-linux-x64/bin/mongosh /usr/local/bin/ \ + && mv mongosh-${MONGOSH_VERSION}-linux-x64/bin/mongosh_crypt_v1.so /usr/local/lib/ \ + && rm -rf mongosh-${MONGOSH_VERSION}-linux-x64* \ ;; \ - 'arm64') \ - ARCH=arm64; \ - ;; \ - 's390x') \ - ARCH=s390x; \ - ;; \ - 'ppc64le') \ - ARCH=ppc64le; \ + arm64) \ + wget https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}.tgz \ + && tar -xf mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}.tgz \ + && chown root:root mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/* \ + && mv mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/mongosh /usr/local/bin/ \ + && mv mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}/bin/mongosh_crypt_v1.so /usr/local/lib/ \ + && rm -rf mongosh-${MONGOSH_VERSION}-linux-${TARGETARCH}* \ ;; \ *) \ - echo "Unsupported architecture: ${TARGETARCH}"; \ + echo "Unsupported architecture: ${TARGETARCH}" \ ;; \ - esac \ - && \ - if [ -n "${ARCH}" ]; then \ - wget -q https://downloads.mongodb.com/compass/mongosh-${MONGOSH_VERSION}-linux-${ARCH}.tgz \ - && tar -xf mongosh-${MONGOSH_VERSION}-linux-${ARCH}.tgz \ - && chown root:root mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/* \ - && mv mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/mongosh /usr/local/bin/ \ - && mv mongosh-${MONGOSH_VERSION}-linux-${ARCH}/bin/mongosh_crypt_v1.so /usr/local/lib/ \ - && rm -rf mongosh-${MONGOSH_VERSION}-linux-${ARCH}* \ - ; \ - fi + esac COPY --from=redis /usr/local/bin/redis-cli /usr/local/bin/redis-cli diff --git a/Dockerfile-ee b/Dockerfile-ee deleted file mode 100644 index 9f349da9..00000000 --- a/Dockerfile-ee +++ /dev/null @@ -1,36 +0,0 @@ -ARG VERSION -FROM debian:bullseye-slim as clickhouse -ARG TARGETARCH - -ARG DEPENDENCIES=" \ - ca-certificates \ - curl" - -ARG APT_MIRROR=http://mirrors.ustc.edu.cn -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=koko-apt \ - --mount=type=cache,target=/var/lib/apt,sharing=locked,id=koko-apt \ - sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ - && rm -f /etc/apt/apt.conf.d/docker-clean \ - && apt-get update \ - && apt-get install -y --no-install-recommends ${DEPENDENCIES} \ - && LATEST_VERSION=$(curl -s https://packages.clickhouse.com/tgz/stable/ | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort -V -r | head -n 1) \ - && PKG="clickhouse-common-static" \ - && \ - case "${TARGETARCH}" in \ - amd64|arm64) \ - mkdir -p /opt/clickhouse; \ - curl -fO "https://packages.clickhouse.com/tgz/stable/$PKG-$LATEST_VERSION-${TARGETARCH}.tgz"; \ - tar -xf "$PKG-$LATEST_VERSION-${TARGETARCH}.tgz" -C /opt/clickhouse --strip-components=1; \ - rm -f "$PKG-$LATEST_VERSION-${TARGETARCH}.tgz"; \ - ;; \ - *) \ - mkdir -p /opt/clickhouse/usr/bin; \ - echo > /opt/clickhouse/usr/bin/clickhouse; \ - ;; \ - esac \ - && chown -R root:root /opt/clickhouse - -FROM registry.fit2cloud.com/jumpserver/koko-ce:${VERSION} - -COPY --from=clickhouse /opt/clickhouse/usr/bin/clickhouse /usr/local/bin/clickhouse-client - From 9d1b94ea284fce156e4172d2d8248c5565154240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Mon, 22 Jan 2024 19:49:27 +0800 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20mips64le=20?= =?UTF-8?q?=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index f2fec5a3..b71af095 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ all: koko-ui $(call make_artifact_full,darwin,arm64) $(call make_artifact_full,linux,amd64) $(call make_artifact_full,linux,arm64) + $(call make_artifact_full,linux,mips64le) $(call make_artifact_full,linux,ppc64le) $(call make_artifact_full,linux,s390x) $(call make_artifact_full,linux,riscv64) @@ -83,6 +84,9 @@ linux-arm64: koko-ui linux-loong64: koko-ui $(call make_artifact_full,linux,loong64) +linux-mips64le: koko-ui + $(call make_artifact_full,linux,mips64le) + linux-ppc64le: koko-ui $(call make_artifact_full,linux,ppc64le) From 6682a857cabe3fe9a2081d02bf158aed10b9e9e0 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 25 Jan 2024 17:41:29 +0800 Subject: [PATCH 08/18] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20clickhouse?= =?UTF-8?q?=20=E6=A0=A1=E9=AA=8C=E5=AF=86=E7=A0=81=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/srvconn/conn_clickhouse.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/srvconn/conn_clickhouse.go b/pkg/srvconn/conn_clickhouse.go index b5987bf8..ee0df55f 100644 --- a/pkg/srvconn/conn_clickhouse.go +++ b/pkg/srvconn/conn_clickhouse.go @@ -2,6 +2,7 @@ package srvconn import ( "fmt" + "net/url" "os" "strconv" @@ -106,8 +107,8 @@ func (opt *sqlOption) ClickHouseDataSourceName() string { opt.Host, opt.Port, opt.DBName, - opt.Username, - opt.Password, + url.QueryEscape(opt.Username), + url.QueryEscape(opt.Password), ) } From 194e605de04674de5205222a897d6d80c3fcc46a Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Fri, 2 Feb 2024 15:05:01 +0800 Subject: [PATCH 09/18] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7session=20=E4=BC=9A=E8=AF=9D=E8=BF=87=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/components/Terminal.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ui/src/components/Terminal.vue b/ui/src/components/Terminal.vue index e20baec9..00ad5550 100644 --- a/ui/src/components/Terminal.vue +++ b/ui/src/components/Terminal.vue @@ -43,6 +43,7 @@ const AsciiDel = 127 const AsciiBackspace = 8 const AsciiCtrlC = 3 const AsciiCtrlZ = 26 +const AsciiEnter = 13 export default { name: "Terminal", @@ -261,6 +262,12 @@ export default { this.lastSendTime = new Date(); this.$log.debug("term on data event") data = this.preprocessInput(data) + + if (data.charCodeAt(0) === AsciiEnter) { + this.sendEventToLuna('RENEWAL', '') + this.$log.debug("Enter enabled") + } + this.ws.send(this.message(this.terminalId, 'TERMINAL_DATA', data)); }); From 26ee1256b2c5b73377d8b391cddf25ce7a7d8cc2 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 25 Jan 2024 17:38:40 +0800 Subject: [PATCH 10/18] =?UTF-8?q?perf:=20scp=20=E5=91=BD=E4=BB=A4=E6=8B=A6?= =?UTF-8?q?=E6=88=AA=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/handler/server_ssh.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/handler/server_ssh.go b/pkg/handler/server_ssh.go index 866b29f3..52fbad02 100644 --- a/pkg/handler/server_ssh.go +++ b/pkg/handler/server_ssh.go @@ -321,10 +321,21 @@ func (s *Server) proxyTokenInfo(sess ssh.Session, tokeInfo *model.ConnectToken) } } +func IsScpCommand(rawStr string) bool { + rawCommands := strings.Split(rawStr, ";") + for _, cmd := range rawCommands { + cmd = strings.TrimSpace(cmd) + if strings.HasPrefix(cmd, "scp") { + return true + } + } + return false +} + func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClient, tokeInfo *model.ConnectToken) { rawStr := sess.RawCommand() - if strings.HasPrefix(rawStr, "scp") && !config.GetConf().EnableVscodeSupport { + if IsScpCommand(rawStr) && !config.GetConf().EnableVscodeSupport { logger.Errorf("Not support scp command: %s", rawStr) utils.IgnoreErrWriteString(sess, "Not support scp command") return From 20fe65b357278c31467b66a8e79f304454cd11eb Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Sun, 4 Feb 2024 11:11:37 +0800 Subject: [PATCH 11/18] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20=E9=94=AE?= =?UTF-8?q?=E7=9B=98=E4=BA=8B=E4=BB=B6=E7=BB=AD=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/components/Terminal.vue | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ui/src/components/Terminal.vue b/ui/src/components/Terminal.vue index 00ad5550..13838187 100644 --- a/ui/src/components/Terminal.vue +++ b/ui/src/components/Terminal.vue @@ -43,7 +43,6 @@ const AsciiDel = 127 const AsciiBackspace = 8 const AsciiCtrlC = 3 const AsciiCtrlZ = 26 -const AsciiEnter = 13 export default { name: "Terminal", @@ -263,11 +262,7 @@ export default { this.$log.debug("term on data event") data = this.preprocessInput(data) - if (data.charCodeAt(0) === AsciiEnter) { - this.sendEventToLuna('RENEWAL', '') - this.$log.debug("Enter enabled") - } - + this.sendEventToLuna('KEYBOARDEVENT', '') this.ws.send(this.message(this.terminalId, 'TERMINAL_DATA', data)); }); From 37f4996639074cc8226afea6a8f940fb9a5f2b33 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 4 Feb 2024 14:02:47 +0800 Subject: [PATCH 12/18] =?UTF-8?q?perf:=20=E9=87=8D=E7=BD=AE=E7=94=A8?= =?UTF-8?q?=E6=88=B7=20ssh=20=E8=AE=A4=E8=AF=81=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/auth/ssh.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/pkg/auth/ssh.go b/pkg/auth/ssh.go index be31acee..210551cd 100644 --- a/pkg/auth/ssh.go +++ b/pkg/auth/ssh.go @@ -18,6 +18,10 @@ type SSHAuthFunc func(ctx ssh.Context, password, publicKey string) (res ssh.Auth func SSHPasswordAndPublicKeyAuth(jmsService *service.JMService) SSHAuthFunc { return func(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) { + if password == "" && publicKey == "" { + logger.Errorf("SSH conn[%s] no password and publickey", ctx.SessionID()) + return ssh.AuthFailed + } remoteAddr, _, _ := net.SplitHostPort(ctx.RemoteAddr().String()) username := ctx.User() if req, ok := parseDirectLoginReq(jmsService, ctx); ok { @@ -35,25 +39,22 @@ func SSHPasswordAndPublicKeyAuth(jmsService *service.JMService) SSHAuthFunc { if password != "" { authMethod = "password" } - userAuthClient, ok := ctx.Value(ContextKeyClient).(*UserAuthClient) - if !ok { - newClient := jmsService.CloneClient() - var accessKey model.AccessKey - conf := config.GetConf() - _ = accessKey.LoadFromFile(conf.AccessKeyFilePath) - userClient := service.NewUserClient( - service.UserClientUsername(username), - service.UserClientRemoteAddr(remoteAddr), - service.UserClientLoginType("T"), - service.UserClientHttpClient(&newClient), - service.UserClientSvcSignKey(accessKey), - ) - userAuthClient = &UserAuthClient{ - UserClient: userClient, - authOptions: make(map[string]authOptions), - } - ctx.SetValue(ContextKeyClient, userAuthClient) + newClient := jmsService.CloneClient() + var accessKey model.AccessKey + conf := config.GetConf() + _ = accessKey.LoadFromFile(conf.AccessKeyFilePath) + userClient := service.NewUserClient( + service.UserClientUsername(username), + service.UserClientRemoteAddr(remoteAddr), + service.UserClientLoginType("T"), + service.UserClientHttpClient(&newClient), + service.UserClientSvcSignKey(accessKey), + ) + userAuthClient := &UserAuthClient{ + UserClient: userClient, + authOptions: make(map[string]authOptions), } + ctx.SetValue(ContextKeyClient, userAuthClient) userAuthClient.SetOption(service.UserClientPassword(password), service.UserClientPublicKey(publicKey)) logger.Infof("SSH conn[%s] authenticating user %s %s", ctx.SessionID(), username, authMethod) From 940e6a36881a087ab820474e2abd9b94f0fb9199 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:32:25 +0800 Subject: [PATCH 13/18] =?UTF-8?q?perf:=20=E8=AE=B0=E5=BD=95=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F=E6=97=A5=E5=BF=97?= =?UTF-8?q?=20(#1297)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 记录会话生命周期日志 * perf: 增加录像存储为 null 记录 * perf: 增加会话生命周期记录 * perf: 记录 sftp 和 ssh 命令会话连接记录 --------- Co-authored-by: Eric --- pkg/handler/server_ssh.go | 18 +++++++++- pkg/httpd/tty.go | 6 ++++ pkg/httpd/userwebsocket.go | 7 ++++ pkg/jms-sdk-go/model/session.go | 38 ++++++++++++++++++++ pkg/jms-sdk-go/service/jms_session_record.go | 24 +++++++++++++ pkg/jms-sdk-go/service/url.go | 2 ++ pkg/koko/task.go | 19 +++++++--- pkg/proxy/recorder.go | 12 +++++++ pkg/proxy/server.go | 9 +++++ pkg/proxy/switch.go | 15 ++++++++ pkg/srvconn/sftp_asset.go | 18 ++++++++-- 11 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 pkg/jms-sdk-go/service/jms_session_record.go diff --git a/pkg/handler/server_ssh.go b/pkg/handler/server_ssh.go index 52fbad02..ca90f9f5 100644 --- a/pkg/handler/server_ssh.go +++ b/pkg/handler/server_ssh.go @@ -332,6 +332,13 @@ func IsScpCommand(rawStr string) bool { return false } +func (s *Server) recordSessionLifecycle(sid string, event model.LifecycleEvent, reason string) { + logObj := model.SessionLifecycleLog{Reason: reason} + if err2 := s.jmsService.RecordSessionLifecycleLog(sid, event, logObj); err2 != nil { + logger.Errorf("Record session %s lifecycle %s failed: %s", sid, event, err2) + } +} + func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClient, tokeInfo *model.ConnectToken) { rawStr := sess.RawCommand() @@ -371,6 +378,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien } ctx, cancel := context.WithCancel(sess.Context()) defer cancel() + traceSession := session.NewSession(&respSession, func(task *model.TerminalTask) error { switch task.Name { case model.TaskKillSession: @@ -393,6 +401,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien logger.Errorf("Get SSH session failed: %s", err) return } + s.recordSessionLifecycle(respSession.ID, model.AssetConnectSuccess, "") defer goSess.Close() defer sshClient.ReleaseSession(goSess) go func() { @@ -455,6 +464,8 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien logger.Errorf("User %s Run command %s failed: %s", tokeInfo.User.String(), rawStr, err) } + reason := string(model.ReasonErrConnectDisconnect) + s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason) } func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient *srvconn.SSHClient, @@ -490,7 +501,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient logger.Errorf("Get SSH session failed: %s", err) return err } - + s.recordSessionLifecycle(respSession.ID, model.AssetConnectSuccess, "") defer goSess.Close() defer sshClient.ReleaseSession(goSess) stdOut, err := goSess.StdoutPipe() @@ -506,6 +517,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient err = goSess.Shell() if err != nil { logger.Errorf("Get SSH session shell failed: %s", err) + s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, err.Error()) return err } logger.Infof("User %s start vscode request to %s", vsReq.user, sshClient) @@ -525,11 +537,15 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient case <-ctx.Done(): logger.Infof("SSH conn[%s] User %s end vscode request %s as session done", vsReq.reqId, vsReq.user, sshClient) + reason := string(model.ReasonErrConnectDisconnect) + s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason) return nil case now := <-ticker.C: if vsReq.expireInfo.IsExpired(now) { logger.Infof("SSH conn[%s] User %s end vscode request %s as permission has expired", vsReq.reqId, vsReq.user, sshClient) + reason := string(model.ReasonErrPermissionExpired) + s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason) return nil } logger.Debugf("SSH conn[%s] user %s vscode request still alive", vsReq.reqId, vsReq.user) diff --git a/pkg/httpd/tty.go b/pkg/httpd/tty.go index 7b9ff088..c0ba06e4 100644 --- a/pkg/httpd/tty.go +++ b/pkg/httpd/tty.go @@ -433,6 +433,8 @@ func (h *tty) JoinRoom(c *Client, roomID string) { Body: nil, Meta: meta, }) + logObj := model.SessionLifecycleLog{User: h.ws.user.String()} + h.ws.RecordLifecycleLog(roomID, model.UserJoinSession, logObj) for { buf := make([]byte, 1024) nr, err := c.Read(buf) @@ -451,6 +453,7 @@ func (h *tty) JoinRoom(c *Client, roomID string) { Body: nil, Meta: meta, }) + h.ws.RecordLifecycleLog(roomID, model.UserLeaveSession, logObj) logger.Infof("Conn[%s] user read end", c.ID()) if err := h.ws.apiClient.FinishShareRoom(h.shareInfo.Record.ID); err != nil { logger.Infof("Conn[%s] finish share room err: %s", c.ID(), err) @@ -463,6 +466,8 @@ func (h *tty) Monitor(c *Client, roomID string) { conn := exchange.WrapperUserCon(c) room.Subscribe(conn) defer room.UnSubscribe(conn) + logObj := model.SessionLifecycleLog{User: h.ws.user.String()} + h.ws.RecordLifecycleLog(roomID, model.AdminJoinMonitor, logObj) for { buf := make([]byte, 1024) _, err := c.Read(buf) @@ -473,5 +478,6 @@ func (h *tty) Monitor(c *Client, roomID string) { logger.Debugf("Conn[%s] user monitor", c.ID()) } logger.Infof("Conn[%s] user read end", c.ID()) + h.ws.RecordLifecycleLog(roomID, model.AdminExitMonitor, logObj) } } diff --git a/pkg/httpd/userwebsocket.go b/pkg/httpd/userwebsocket.go index 4c30a29e..d6c2d7d6 100644 --- a/pkg/httpd/userwebsocket.go +++ b/pkg/httpd/userwebsocket.go @@ -241,3 +241,10 @@ var ( ErrDisableShare = errors.New("disable share") ErrPermissionDenied = errors.New("permission denied") ) + +func (userCon *UserWebsocket) RecordLifecycleLog(sid string, event model.LifecycleEvent, + logObj model.SessionLifecycleLog) { + if err := userCon.apiClient.RecordSessionLifecycleLog(sid, event, logObj); err != nil { + logger.Errorf("Record session lifecycle log err: %s", err) + } +} diff --git a/pkg/jms-sdk-go/model/session.go b/pkg/jms-sdk-go/model/session.go index 5d3763b9..e56b7e82 100644 --- a/pkg/jms-sdk-go/model/session.go +++ b/pkg/jms-sdk-go/model/session.go @@ -100,3 +100,41 @@ const ( SessionReplayErrUploadFailed ReplayError = "replay_upload_failed" SessionReplayErrUnsupported ReplayError = "replay_unsupported" ) + +type LifecycleEvent string + +const ( + AssetConnectSuccess LifecycleEvent = "asset_connect_success" + AssetConnectFinished LifecycleEvent = "asset_connect_finished" + CreateShareLink LifecycleEvent = "create_share_link" + UserJoinSession LifecycleEvent = "user_join_session" + UserLeaveSession LifecycleEvent = "user_leave_session" + AdminJoinMonitor LifecycleEvent = "admin_join_monitor" + AdminExitMonitor LifecycleEvent = "admin_exit_monitor" + ReplayConvertStart LifecycleEvent = "replay_convert_start" + ReplayConvertSuccess LifecycleEvent = "replay_convert_success" + ReplayConvertFailure LifecycleEvent = "replay_convert_failure" + ReplayUploadStart LifecycleEvent = "replay_upload_start" + ReplayUploadSuccess LifecycleEvent = "replay_upload_success" + ReplayUploadFailure LifecycleEvent = "replay_upload_failure" +) + +type SessionLifecycleLog struct { + Reason string `json:"reason"` + User string `json:"user"` +} + +var EmptyLifecycleLog = SessionLifecycleLog{} + +type SessionLifecycleReasonErr string + +const ( + ReasonErrConnectFailed SessionLifecycleReasonErr = "connect_failed" + ReasonErrConnectDisconnect SessionLifecycleReasonErr = "connect_disconnect" + ReasonErrUserClose SessionLifecycleReasonErr = "user_close" + ReasonErrIdleDisconnect SessionLifecycleReasonErr = "idle_disconnect" + ReasonErrAdminTerminate SessionLifecycleReasonErr = "admin_terminate" + ReasonErrMaxSessionTimeout SessionLifecycleReasonErr = "max_session_timeout" + ReasonErrPermissionExpired SessionLifecycleReasonErr = "permission_expired" + ReasonErrNullStorage SessionLifecycleReasonErr = "null_storage" +) diff --git a/pkg/jms-sdk-go/service/jms_session_record.go b/pkg/jms-sdk-go/service/jms_session_record.go new file mode 100644 index 00000000..ac877402 --- /dev/null +++ b/pkg/jms-sdk-go/service/jms_session_record.go @@ -0,0 +1,24 @@ +package service + +import ( + "fmt" + + "github.com/jumpserver/koko/pkg/jms-sdk-go/model" +) + +func (s *JMService) RecordSessionLifecycleLog(sid string, event model.LifecycleEvent, logObj model.SessionLifecycleLog) (err error) { + data := map[string]interface{}{ + "event": event, + } + if logObj.Reason != "" { + data["reason"] = logObj.Reason + } + if logObj.User != "" { + data["user"] = logObj.User + } + + reqURL := fmt.Sprintf(SessionLifecycleLogURL, sid) + var resp map[string]interface{} + _, err = s.authClient.Post(reqURL, data, &resp) + return +} diff --git a/pkg/jms-sdk-go/service/url.go b/pkg/jms-sdk-go/service/url.go index 5feb6255..acbb69d2 100644 --- a/pkg/jms-sdk-go/service/url.go +++ b/pkg/jms-sdk-go/service/url.go @@ -27,6 +27,8 @@ const ( FTPLogListURL = "/api/v1/audits/ftp-logs/" // 上传 ftp日志 FTPLogUpdateURL = "/api/v1/audits/ftp-logs/%s/" FTPLogFileURL = "/api/v1/audits/ftp-logs/%s/upload/" + + SessionLifecycleLogURL = "/api/v1/terminal/sessions/%s/lifecycle_log/" ) // 授权相关API diff --git a/pkg/koko/task.go b/pkg/koko/task.go index dd21178d..428a0fb6 100644 --- a/pkg/koko/task.go +++ b/pkg/koko/task.go @@ -43,6 +43,13 @@ func uploadRemainReplay(jmsService *service.JMService) { return nil }) + recordLifecycleLog := func(id string, event model.LifecycleEvent, reason string) { + logObj := model.SessionLifecycleLog{Reason: reason} + if err1 := jmsService.RecordSessionLifecycleLog(id, event, logObj); err1 != nil { + logger.Errorf("Update session %s activity log failed: %s", id, err1) + } + } + for absPath, remainReplay := range allRemainFiles { absGzPath := absPath if !remainReplay.IsGzip { @@ -64,18 +71,22 @@ func uploadRemainReplay(jmsService *service.JMService) { } _ = os.Remove(absPath) } - Target, _ := filepath.Rel(replayDir, absGzPath) + target, _ := filepath.Rel(replayDir, absGzPath) + + recordLifecycleLog(remainReplay.Id, model.ReplayUploadStart, "") logger.Infof("Upload replay file: %s, type: %s", absGzPath, replayStorage.TypeName()) - if err2 := replayStorage.Upload(absGzPath, Target); err2 != nil { + if err2 := replayStorage.Upload(absGzPath, target); err2 != nil { logger.Errorf("Upload remain replay file %s failed: %s", absGzPath, err2) reason := model.SessionReplayErrUploadFailed if err3 := jmsService.SessionReplayFailed(remainReplay.Id, reason); err3 != nil { logger.Errorf("Update session %s status %s failed: %s", remainReplay.Id, reason, err3) } + recordLifecycleLog(remainReplay.Id, model.ReplayUploadFailure, err2.Error()) continue } - if err := jmsService.FinishReply(remainReplay.Id); err != nil { - logger.Errorf("Notify session %s upload failed: %s", remainReplay.Id, err) + recordLifecycleLog(remainReplay.Id, model.ReplayUploadSuccess, "") + if err1 := jmsService.FinishReply(remainReplay.Id); err1 != nil { + logger.Errorf("Notify session %s upload failed: %s", remainReplay.Id, err1) continue } _ = os.Remove(absGzPath) diff --git a/pkg/proxy/recorder.go b/pkg/proxy/recorder.go index 31e18700..09b3fc88 100644 --- a/pkg/proxy/recorder.go +++ b/pkg/proxy/recorder.go @@ -201,6 +201,7 @@ func (r *ReplyRecorder) Record(p []byte) { func (r *ReplyRecorder) End() { if r.isNullStorage() { + r.recordLifecycleLog(model.ReplayUploadFailure, string(model.ReasonErrNullStorage)) return } _ = r.file.Close() @@ -230,8 +231,10 @@ func (r *ReplyRecorder) uploadReplay() { func (r *ReplyRecorder) UploadGzipFile(maxRetry int) { if r.isNullStorage() { _ = os.Remove(r.absGzipFilePath) + r.recordLifecycleLog(model.ReplayUploadFailure, string(model.ReasonErrNullStorage)) return } + r.recordLifecycleLog(model.ReplayUploadStart, "") for i := 0; i <= maxRetry; i++ { logger.Infof("Upload replay file: %s, type: %s", r.absGzipFilePath, r.storage.TypeName()) err := r.storage.Upload(r.absGzipFilePath, r.Target) @@ -240,8 +243,10 @@ func (r *ReplyRecorder) UploadGzipFile(maxRetry int) { if err = r.jmsService.FinishReply(r.SessionID); err != nil { logger.Errorf("Session[%s] finish replay err: %s", r.SessionID, err) } + r.recordLifecycleLog(model.ReplayUploadSuccess, "") break } + r.recordLifecycleLog(model.ReplayUploadFailure, err.Error()) logger.Errorf("Upload replay file err: %s", err) // 如果还是失败,上传 server 再传一次 if i == maxRetry { @@ -260,6 +265,13 @@ func (r *ReplyRecorder) UploadGzipFile(maxRetry int) { } } +func (r *ReplyRecorder) recordLifecycleLog(event model.LifecycleEvent, reason string) { + eventLog := model.SessionLifecycleLog{Reason: reason} + if err := r.jmsService.RecordSessionLifecycleLog(r.SessionID, event, eventLog); err != nil { + logger.Errorf("Update session %s activity log %s failed: %s", r.SessionID, event, err) + } +} + type ReplyInfo struct { Width int Height int diff --git a/pkg/proxy/server.go b/pkg/proxy/server.go index dc012acf..72d2ec8c 100644 --- a/pkg/proxy/server.go +++ b/pkg/proxy/server.go @@ -1074,9 +1074,18 @@ func (s *Server) Proxy() { if err2 := s.ConnectedFailedCallback(err); err2 != nil { logger.Errorf("Conn[%s] update session err: %s", s.UserConn.ID(), err2) } + errLog := model.SessionLifecycleLog{Reason: err.Error()} + if err1 := s.jmsService.RecordSessionLifecycleLog(s.sessionInfo.ID, model.AssetConnectFinished, + errLog); err1 != nil { + logger.Errorf("Conn[%s] record session activity log err: %s", s.UserConn.ID(), err1) + } return } defer srvCon.Close() + if err1 := s.jmsService.RecordSessionLifecycleLog(s.sessionInfo.ID, model.AssetConnectSuccess, + model.EmptyLifecycleLog); err1 != nil { + logger.Errorf("Conn[%s] record session activity log err: %s", s.UserConn.ID(), err1) + } logger.Infof("Conn[%s] create session %s success", s.UserConn.ID(), s.ID) if err2 := s.ConnectedSuccessCallback(); err2 != nil { diff --git a/pkg/proxy/switch.go b/pkg/proxy/switch.go index f7e6eaaf..350cdc50 100644 --- a/pkg/proxy/switch.go +++ b/pkg/proxy/switch.go @@ -292,6 +292,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo msg = utils.WrapperWarn(msg) replayRecorder.Record([]byte(msg)) room.Broadcast(&exchange.RoomMessage{Event: exchange.DataEvent, Body: []byte("\n\r" + msg)}) + s.recordSessionFinished(model.ReasonErrMaxSessionTimeout) return } @@ -302,6 +303,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo msg = utils.WrapperWarn(msg) replayRecorder.Record([]byte(msg)) room.Broadcast(&exchange.RoomMessage{Event: exchange.DataEvent, Body: []byte("\n\r" + msg)}) + s.recordSessionFinished(model.ReasonErrIdleDisconnect) return } if s.p.CheckPermissionExpired(now) { @@ -310,6 +312,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo msg = utils.WrapperWarn(msg) replayRecorder.Record([]byte(msg)) room.Broadcast(&exchange.RoomMessage{Event: exchange.DataEvent, Body: []byte("\n\r" + msg)}) + s.recordSessionFinished(model.ReasonErrPermissionExpired) return } continue @@ -321,6 +324,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo replayRecorder.Record([]byte(msg)) logger.Infof("Session[%s]: %s", s.ID, msg) room.Broadcast(&exchange.RoomMessage{Event: exchange.DataEvent, Body: []byte("\n\r" + msg)}) + s.recordSessionFinished(model.ReasonErrAdminTerminate) return // 监控窗口大小变化 case win, ok := <-winCh: @@ -339,6 +343,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo // 经过parse处理的server数据,发给user case p, ok := <-srvOutChan: if !ok { + s.recordSessionFinished(model.ReasonErrConnectDisconnect) return } if parser.NeedRecord() { @@ -352,6 +357,7 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo // 经过parse处理的user数据,发给server case p, ok := <-userOutChan: if !ok { + s.recordSessionFinished(model.ReasonErrUserClose) return } if _, err1 := srvConn.Write(p); err1 != nil { @@ -367,9 +373,11 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo continue case <-userConn.Context().Done(): logger.Infof("Session[%s]: user conn context done", s.ID) + s.recordSessionFinished(model.ReasonErrUserClose) return nil case <-exitSignal: logger.Debugf("Session[%s] end by exit signal", s.ID) + s.recordSessionFinished(model.ReasonErrConnectDisconnect) return case notifyMsg := <-s.notifyMsgChan: logger.Infof("Session[%s] notify event: %s", s.ID, notifyMsg.Event) @@ -379,3 +387,10 @@ func (s *SwitchSession) Bridge(userConn UserConnection, srvConn srvconn.ServerCo lastActiveTime = time.Now() } } + +func (s *SwitchSession) recordSessionFinished(reason model.SessionLifecycleReasonErr) { + logObj := model.SessionLifecycleLog{Reason: string(reason)} + if err := s.p.jmsService.RecordSessionLifecycleLog(s.ID, model.AssetConnectFinished, logObj); err != nil { + logger.Errorf("Session[%s] record session asset_connect_finished failed: %s", s.ID, err) + } +} diff --git a/pkg/srvconn/sftp_asset.go b/pkg/srvconn/sftp_asset.go index fff2a7d3..bc97a005 100644 --- a/pkg/srvconn/sftp_asset.go +++ b/pkg/srvconn/sftp_asset.go @@ -535,6 +535,7 @@ func (ad *AssetDir) GetSFTPAndRealPath(su *model.PermAccount, path string) (conn traceSession := session.NewSession(&respSession, terminalFunc) session.AddSession(traceSession) ad.sftpTraceSessions[su.String()] = traceSession + ad.recordSessionLifecycle(traceSession.ID, model.AssetConnectSuccess, "") } if conn.rootDirPath == "" { platform := conn.token.Platform @@ -581,7 +582,7 @@ func (ad *AssetDir) GetSftpClient(su *model.PermAccount) (conn *SftpConn, err er if err != nil { return nil, fmt.Errorf("get connect token account err: %s", err2) } - return ad.getNewSftpConn(&connectToken) + return ad.getNewSftpConn(&connectToken, su) } func (ad *AssetDir) createConnectToken(su *model.PermAccount) (model.ConnectToken, error) { @@ -609,7 +610,8 @@ func (ad *AssetDir) createConnectToken(su *model.PermAccount) (model.ConnectToke return ad.jmsService.GetConnectTokenInfo(tokenInfo.ID) } -func (ad *AssetDir) getNewSftpConn(connectToken *model.ConnectToken) (conn *SftpConn, err error) { +func (ad *AssetDir) getNewSftpConn(connectToken *model.ConnectToken, + su *model.PermAccount) (conn *SftpConn, err error) { if ad.detailAsset == nil { return nil, errNoSelectAsset } @@ -680,6 +682,11 @@ func (ad *AssetDir) getNewSftpConn(connectToken *model.ConnectToken) (conn *Sftp sshClient.ReleaseSession(sess) _ = sshClient.Close() logger.Infof("User %s SSH client(%s) for SFTP release", user.String(), sshClient) + if sftpSession, ok := ad.sftpTraceSessions[su.String()]; ok { + sid := sftpSession.ID + reason := string(model.ReasonErrConnectDisconnect) + ad.recordSessionLifecycle(sid, model.AssetConnectFinished, reason) + } }() homeDirPath, err := sftpClient.Getwd() if err != nil { @@ -741,6 +748,13 @@ func (ad *AssetDir) CreateFTPLog(su *model.PermAccount, operate, filename string return &data } +func (ad *AssetDir) recordSessionLifecycle(sid string, event model.LifecycleEvent, reason string) { + logObj := model.SessionLifecycleLog{Reason: reason} + if err := ad.jmsService.RecordSessionLifecycleLog(sid, event, logObj); err != nil { + logger.Errorf("Update session %s lifecycle %s failed: %s", sid, event, err) + } +} + func IsExistPath(client *sftp.Client, path string) bool { _, err := client.Stat(path) return err == nil From 722650c571df8ed3296a5752aa646d4edc398f5d Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 9 Feb 2024 12:02:31 +0800 Subject: [PATCH 14/18] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 12 ++++++------ go.sum | 27 ++++++++++++++------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index a6ef023e..63a9f768 100644 --- a/go.mod +++ b/go.mod @@ -33,9 +33,9 @@ require ( github.com/spf13/viper v1.12.0 github.com/xlab/treeprint v1.1.0 go.mongodb.org/mongo-driver v1.8.3 - golang.org/x/crypto v0.14.0 - golang.org/x/term v0.13.0 - golang.org/x/text v0.13.0 + golang.org/x/crypto v0.19.0 + golang.org/x/term v0.17.0 + golang.org/x/text v0.14.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 k8s.io/api v0.23.1 k8s.io/apimachinery v0.23.1 @@ -106,7 +106,7 @@ require ( golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect google.golang.org/appengine v1.6.7 // indirect @@ -125,6 +125,6 @@ require ( ) replace ( - github.com/gliderlabs/ssh => github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a - golang.org/x/crypto => github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68 + github.com/gliderlabs/ssh => github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae + golang.org/x/crypto => github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463 ) diff --git a/go.sum b/go.sum index 585365b7..6204a0db 100644 --- a/go.sum +++ b/go.sum @@ -59,14 +59,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= -github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68 h1:bkeuW/ujHp3Rr1K3Ah4/Onw9Ero9uMKX0rPxbzV5mvw= -github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= github.com/LeeEirc/elfinder v0.0.14 h1:6ObxwIoC5zmrnKArUU5Mz++/T3lzgl1Ja0pS1Smd3j4= github.com/LeeEirc/elfinder v0.0.14/go.mod h1:d1bMAAydkZSBxSN/EuQjBg6B0xcPP3boHuYEpzEHYTs= github.com/LeeEirc/httpsig v1.2.1 h1:GGmCc2Bug3KeCchlZHwrfyjyAnw+JlzMjKDobPypirs= github.com/LeeEirc/httpsig v1.2.1/go.mod h1:aoLZLXCSNDgkzsH2sGLWn3hlVbF+Voe8fCArxLt9nWA= -github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a h1:/EdJeCK6cTaKNgftQLP9uyBL4Q86MFawU0WsK22yn2A= -github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a/go.mod h1:O9BMs9PYwCJbftRP9O2Ig5Wd3hbLSpzhvP0bqU9EONg= github.com/LeeEirc/tclientlib v0.0.3-0.20230803101925-fb52a90cb08d h1:4qUSGc/34IALiDs2kBrjbCKfx7zvAt16K+gTRzNN8Fo= github.com/LeeEirc/tclientlib v0.0.3-0.20230803101925-fb52a90cb08d/go.mod h1:TF2v0XZYyRcZfx4NmA/EEFRkdKZLsQd8YnlhGKl1KUA= github.com/LeeEirc/terminalparser v0.0.0-20220328021224-de16b7643ea4 h1:Gk7m4Nu2jqVqJAJqNlTYqkiq96WkANAtB4fVi+t7Xv8= @@ -279,6 +275,10 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463 h1:ZQTX/4gO/G8SFtzn9K8M2mac83TSIyEHX9/2bnBKf1Y= +github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae h1:zND4fMpJoOf90TILA9CY9KTub+YLK+pdiG6LM/+9UBo= +github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae/go.mod h1:KdoSNwfOgcFXlcr2OQ34eeKfIl7K8l6cAQ6twkYaLcU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= @@ -522,7 +522,7 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -612,16 +612,17 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -633,9 +634,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 26563ceb176c676a2c2935a577a98b5a0a5de337 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 21 Feb 2024 13:47:19 +0800 Subject: [PATCH 15/18] =?UTF-8?q?perf:=20=E5=AE=8C=E5=96=84=E7=BD=91?= =?UTF-8?q?=E5=85=B3=E8=BF=9E=E6=8E=A5=20aws=20redis=20=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/srvconn/conn_redis.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/srvconn/conn_redis.go b/pkg/srvconn/conn_redis.go index 3bd37c3f..227cdb6d 100644 --- a/pkg/srvconn/conn_redis.go +++ b/pkg/srvconn/conn_redis.go @@ -154,6 +154,10 @@ func checkRedisAccount(args *sqlOption) error { if args.UseSSL { tlsConfig := tls.Config{} + // 连接使用的是内部地址或者localhost时,跳过证书验证 + if args.Host == "127.0.0.1" || args.Host == "localhost" { + tlsConfig.InsecureSkipVerify = true + } if args.CaCert != "" { rootCAs := x509.NewCertPool() rootCAs.AppendCertsFromPEM([]byte(args.CaCert)) From 914e22c46fbd671c6988aa702f8a55e773887cf2 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 26 Feb 2024 13:31:18 +0800 Subject: [PATCH 16/18] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=BB=88?= =?UTF-8?q?=E7=AB=AF=E8=BF=9E=E6=8E=A5=E8=B5=84=E4=BA=A7=E9=80=80=E5=87=BA?= =?UTF-8?q?=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/handler/select_handler.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/handler/select_handler.go b/pkg/handler/select_handler.go index 861e6fe4..08652fe4 100644 --- a/pkg/handler/select_handler.go +++ b/pkg/handler/select_handler.go @@ -5,7 +5,6 @@ import ( "sort" "strconv" "strings" - "time" "github.com/jumpserver/koko/pkg/i18n" "github.com/jumpserver/koko/pkg/jms-sdk-go/model" @@ -218,8 +217,6 @@ func (u *UserSelectHandler) DisplayCurrentResult() { func (u *UserSelectHandler) Proxy(target model.PermAsset) { u.proxyAsset(target) - time.Sleep(time.Second * 2) - u.DisplayCurrentResult() } func (u *UserSelectHandler) Retrieve(pageSize, offset int, searches ...string) []model.PermAsset { From 613ca76f089fcec78aacd0ed2d877072d3572f83 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 27 Feb 2024 18:00:56 +0800 Subject: [PATCH 17/18] =?UTF-8?q?perf:=20=E8=B0=83=E6=95=B4=20API=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/httpd/webserver.go | 2 +- pkg/jms-sdk-go/model/setting.go | 34 ++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pkg/httpd/webserver.go b/pkg/httpd/webserver.go index bbce9e2d..944f4387 100644 --- a/pkg/httpd/webserver.go +++ b/pkg/httpd/webserver.go @@ -196,7 +196,7 @@ func (s *Server) GenerateViewMeta(targetId string) (meta ViewPageMata) { if err != nil { logger.Errorf("Get core api public setting err: %s", err) } - meta.IconURL = setting.LogoURLS.Favicon + meta.IconURL = setting.Interface.Favicon return } diff --git a/pkg/jms-sdk-go/model/setting.go b/pkg/jms-sdk-go/model/setting.go index 4faaabdb..3e2fbdb1 100644 --- a/pkg/jms-sdk-go/model/setting.go +++ b/pkg/jms-sdk-go/model/setting.go @@ -1,13 +1,13 @@ package model type PublicSetting struct { - LoginTitle string `json:"LOGIN_TITLE"` - LogoURLS struct { - LogOut string `json:"logo_logout"` - Index string `json:"logo_index"` - Image string `json:"login_image"` - Favicon string `json:"favicon"` - } `json:"LOGO_URLS"` + Interface struct { + LoginTitle string `json:"login_title"` + LogOut string `json:"logo_logout"` + Index string `json:"logo_index"` + Image string `json:"login_image"` + Favicon string `json:"favicon"` + } `json:"INTERFACE"` EnableWatermark bool `json:"SECURITY_WATERMARK_ENABLED"` EnableSessionShare bool `json:"SECURITY_SESSION_SHARE"` EnableAnnouncement bool `json:"ANNOUNCEMENT_ENABLED"` @@ -32,13 +32,6 @@ type PublicSetting struct { "SECURITY_PASSWORD_EXPIRATION_TIME": 10000, "SECURITY_LUNA_REMEMBER_AUTH": true, "XPACK_LICENSE_IS_VALID": true, - "LOGIN_TITLE": "欢迎使用JumpServer开源堡垒机", - "LOGO_URLS": { - "logo_logout": "/static/img/logo.png", - "logo_index": "/static/img/logo_text.png", - "login_image": "/static/img/login_image.jpg", - "favicon": "/static/img/facio.ico" - }, "TICKETS_ENABLED": true, "PASSWORD_RULE": { "SECURITY_PASSWORD_MIN_LENGTH": 6, @@ -53,6 +46,17 @@ type PublicSetting struct { "AUTH_FEISHU": true, "SECURITY_WATERMARK_ENABLED": true, "SECURITY_SESSION_SHARE": true, - "XRDP_ENABLED": true + "XRDP_ENABLED": true, + INTERFACE: { + logo_logout: "/static/img/logo.png", + logo_index: "/static/img/logo_text_white.png", + login_image: "/static/img/login_image.png", + favicon: "/static/img/facio.ico", + login_title: "JumpServer 开源堡垒机", + theme: "classic_green", + theme_info: { }, + beian_link: "", + beian_text: "" + } } */ From 515a6b0c7b34099da545401f9f50813a1f70a101 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 28 Feb 2024 10:59:14 +0800 Subject: [PATCH 18/18] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/handler/server_ssh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/handler/server_ssh.go b/pkg/handler/server_ssh.go index ca90f9f5..5d0c64cd 100644 --- a/pkg/handler/server_ssh.go +++ b/pkg/handler/server_ssh.go @@ -391,7 +391,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien defer func() { if err2 := s.jmsService.SessionFinished(respSession.ID, modelCommon.NewNowUTCTime()); err2 != nil { - logger.Errorf("Create tunnel session err: %s", err) + logger.Errorf("Create tunnel session err: %s", err2) } session.RemoveSession(traceSession) }() @@ -491,7 +491,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient session.AddSession(traceSession) defer func() { if err2 := s.jmsService.SessionFinished(respSession.ID, modelCommon.NewNowUTCTime()); err2 != nil { - logger.Errorf("Create tunnel session err: %s", err) + logger.Errorf("Create tunnel session err: %s", err2) } session.RemoveSession(traceSession) }()