From 7a535342533410313e8ad8dad9d4278734af1551 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:41:11 +0000 Subject: [PATCH 01/30] Bump curve25519-dalek from 4.1.2 to 4.1.3 (#43225) Bumps [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/dalek-cryptography/curve25519-dalek/releases) - [Commits](https://github.com/dalek-cryptography/curve25519-dalek/compare/curve25519-4.1.2...curve25519-4.1.3) --- updated-dependencies: - dependency-name: curve25519-dalek dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2eb297222cb5..bb8ecd77144be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -527,16 +527,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1937,12 +1936,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "portpicker" version = "0.1.1" From 184fad7426a9902a803874f5a51acfcea054bf05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Wed, 19 Jun 2024 16:32:40 +0200 Subject: [PATCH 02/30] Add info for devs on how to restart Connect on changes (#43233) --- web/packages/teleterm/README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/web/packages/teleterm/README.md b/web/packages/teleterm/README.md index 0d94ca5d5be51..92a232ce20380 100644 --- a/web/packages/teleterm/README.md +++ b/web/packages/teleterm/README.md @@ -9,9 +9,6 @@ docs](https://goteleport.com/docs/connect-your-client/teleport-connect/). ## Building and packaging -**Note: At the moment, the OSS build of Connect is broken. Please refer to -[#17706](https://github.com/gravitational/teleport/issues/17706) for a temporary workaround.** - Teleport Connect consists of two main components: the `tsh` tool and the Electron app. To get started, first we need to build `tsh`. @@ -48,16 +45,26 @@ To launch `teleterm` in development mode: ```sh cd teleport +# By default, the dev version assumes that the tsh binary is at build/tsh. yarn start-term -# By default, the dev version assumes that the tsh binary is at build/tsh. -# You can provide a different absolute path to a tsh binary though the CONNECT_TSH_BIN_PATH env var. +# You can provide a different absolute path to the tsh binary though the CONNECT_TSH_BIN_PATH env var. CONNECT_TSH_BIN_PATH=$PWD/build/tsh yarn start-term ``` -For a quick restart which restarts the Electron app and the tsh daemon, press `F6` while the -Electron window is open. If you recompiled tsh, this is going to pick up any new changes as well as -any changes introduced to the main process of the Electron app. +To automatically restart the app when tsh gets rebuilt or +[when the main process or preload scripts change](https://electron-vite.org/guide/hot-reloading), +use [watchexec](https://github.com/watchexec/watchexec): + +```sh +watchexec --restart --watch build --filter tsh --no-project-ignore -- yarn start-term -w +``` + +This can be combined with a tool like [gow](https://github.com/mitranim/gow) to automatically rebuild tsh: + +```sh +gow -s -S '✅\n' -g make build/tsh +``` ### Development-only tools From 5f93a093cc79d8829a500a9244c06293d9ef93d4 Mon Sep 17 00:00:00 2001 From: Gus Luxton Date: Wed, 19 Jun 2024 11:37:20 -0300 Subject: [PATCH 03/30] ami: Add install section to teleport-acm unit file (#43213) All other unit files have an `[Install]` section, this one was just omitted by accident. Without an `[Install]` section, it isn't possible to `systemctl enable teleport-acm.service` or similar. --- assets/aws/files/system/teleport-acm.service | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/aws/files/system/teleport-acm.service b/assets/aws/files/system/teleport-acm.service index 6dcab6c09d70b..0d24e9cbe4c30 100644 --- a/assets/aws/files/system/teleport-acm.service +++ b/assets/aws/files/system/teleport-acm.service @@ -15,3 +15,6 @@ ExecStart=/usr/local/bin/teleport start --config=/etc/teleport.yaml --diag-addr= ExecReload=/bin/sh -c "exec pkill -HUP -L -F /run/teleport/teleport.pid" PIDFile=/run/teleport/teleport.pid LimitNOFILE=524288 + +[Install] +WantedBy=multi-user.target From 1883526aca3f79bf512d55f830df49cc6cb41e52 Mon Sep 17 00:00:00 2001 From: Gus Luxton Date: Wed, 19 Jun 2024 11:38:13 -0300 Subject: [PATCH 04/30] event-handler: Fix link to docs in README (#43236) --- examples/chart/event-handler/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/chart/event-handler/README.md b/examples/chart/event-handler/README.md index 8b38b5c5eef2b..b520604cac6e9 100644 --- a/examples/chart/event-handler/README.md +++ b/examples/chart/event-handler/README.md @@ -4,7 +4,7 @@ This chart sets up and configures a Deployment for the Event Handler plugin. ## Installation -See the [Access Requests with Slack guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-slack/). +See the [Export Events with FluentD Guide](https://goteleport.com/docs/management/export-audit-events/fluentd/). ## Settings From f5cdc233ee5da471e127cf8b9c12c2d2109a7c9d Mon Sep 17 00:00:00 2001 From: Marco Dinis Date: Wed, 19 Jun 2024 15:42:11 +0100 Subject: [PATCH 05/30] Use user directory instead of /tmp for downloading teleport (#43029) Some systems have a very restricted size in `/tmp`. When doing some tests, we found out that Amazon Linux 2023 EC2 instance only has 475MB (possibly related to using an instance with 1GB of RAM?), and that's not enough to download and uncompress the tarball. We tried to optimize that and only extract the `teleport/teleport` binary, but there's not enough space for that as well. So, instead, we are now storing the teleport binary in the user's cache dir. Another change is that we also remove the created folder when the script exits. --- lib/web/scripts/oneoff/oneoff.sh | 23 ++++++++++------------- lib/web/scripts/oneoff/oneoff_test.go | 26 ++++++++++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/lib/web/scripts/oneoff/oneoff.sh b/lib/web/scripts/oneoff/oneoff.sh index a95ca0101782f..1b1549a937e7f 100644 --- a/lib/web/scripts/oneoff/oneoff.sh +++ b/lib/web/scripts/oneoff/oneoff.sh @@ -5,14 +5,16 @@ cdnBaseURL='{{.CDNBaseURL}}' teleportVersion='{{.TeleportVersion}}' teleportFlavor='{{.TeleportFlavor}}' # teleport or teleport-ent successMessage='{{.SuccessMessage}}' +teleportArgs='{{.TeleportArgs}}' # shellcheck disable=all -tempDir=$({{.BinMktemp}} -d) +# Use $HOME or / as base dir +tempDir=$({{.BinMktemp}} -d -p ${HOME:-}/) OS=$({{.BinUname}} -s) ARCH=$({{.BinUname}} -m) # shellcheck enable=all -teleportArgs='{{.TeleportArgs}}' +trap 'rm -rf -- "$tempDir"' EXIT teleportTarballName() { if [ ${OS} = "Darwin" ]; then @@ -36,19 +38,14 @@ teleportTarballName() { } main() { - cd $tempDir - tarballName=$(teleportTarballName) - curl --show-error --fail --location --remote-name ${cdnBaseURL}/${tarballName} - echo "Extracting teleport to $tempDir ..." - tar -xzf ${tarballName} - - mkdir -p ./bin - mv ./${teleportFlavor}/teleport ./bin/teleport - echo "> ./bin/teleport ${teleportArgs} $@" - ./bin/teleport ${teleportArgs} $@ && echo $successMessage + echo "Downloading from ${cdnBaseURL}/${tarballName} and extracting teleport to ${tempDir} ..." + curl --show-error --fail --location ${cdnBaseURL}/${tarballName} | tar xzf - -C ${tempDir} ${teleportFlavor}/teleport - cd - + mkdir -p ${tempDir}/bin + mv ${tempDir}/${teleportFlavor}/teleport ${tempDir}/bin/teleport + echo "> ${tempDir}/bin/teleport ${teleportArgs} $@" + ${tempDir}/bin/teleport ${teleportArgs} $@ && echo $successMessage } main $@ diff --git a/lib/web/scripts/oneoff/oneoff_test.go b/lib/web/scripts/oneoff/oneoff_test.go index b4a4c962ceac8..5de287bb92b40 100644 --- a/lib/web/scripts/oneoff/oneoff_test.go +++ b/lib/web/scripts/oneoff/oneoff_test.go @@ -42,6 +42,10 @@ func TestOneOffScript(t *testing.T) { teleportVersionOutput := "Teleport v13.1.0 git:api/v13.1.0-0-gd83ec74 go1.20.4" scriptName := "oneoff.sh" + homeDir, err := os.UserHomeDir() + require.NoError(t, err) + homeDir = homeDir + "/" + unameMock, err := bintest.NewMock("uname") require.NoError(t, err) defer func() { @@ -96,7 +100,7 @@ func TestOneOffScript(t *testing.T) { unameMock.Expect("-s").AndWriteToStdout("Linux") unameMock.Expect("-m").AndWriteToStdout("x86_64") - mktempMock.Expect("-d").AndWriteToStdout(testWorkingDir) + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) teleportMock.Expect("version").AndWriteToStdout(teleportVersionOutput) err = os.WriteFile(scriptLocation, []byte(script), 0700) @@ -112,9 +116,12 @@ func TestOneOffScript(t *testing.T) { require.True(t, mktempMock.Check(t)) require.True(t, teleportMock.Check(t)) - require.Contains(t, string(out), "> ./bin/teleport version") + require.Contains(t, string(out), "teleport version") require.Contains(t, string(out), teleportVersionOutput) require.Contains(t, string(out), "Test was a success.") + + // Script should remove the temporary directory. + require.NoDirExists(t, testWorkingDir) }) t.Run("command can be executed with extra arguments", func(t *testing.T) { @@ -151,7 +158,7 @@ func TestOneOffScript(t *testing.T) { unameMock.Expect("-s").AndWriteToStdout("Linux") unameMock.Expect("-m").AndWriteToStdout("x86_64") - mktempMock.Expect("-d").AndWriteToStdout(testWorkingDir) + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) teleportMock.Expect("help", "start").AndWriteToStdout(teleportHelpStart) err = os.WriteFile(scriptLocation, []byte(script), 0700) @@ -167,9 +174,12 @@ func TestOneOffScript(t *testing.T) { require.True(t, mktempMock.Check(t)) require.True(t, teleportMock.Check(t)) - require.Contains(t, string(out), "> ./bin/teleport help start") + require.Contains(t, string(out), "/bin/teleport help start") require.Contains(t, string(out), teleportHelpStart) require.Contains(t, string(out), "Test was a success.") + + // Script should remove the temporary directory. + require.NoDirExists(t, testWorkingDir) }) t.Run("invalid OS", func(t *testing.T) { @@ -179,7 +189,7 @@ func TestOneOffScript(t *testing.T) { unameMock.Expect("-s").AndWriteToStdout("Windows") unameMock.Expect("-m").AndWriteToStdout("x86_64") - mktempMock.Expect("-d").AndWriteToStdout(testWorkingDir) + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) err = os.WriteFile(scriptLocation, []byte(script), 0700) require.NoError(t, err) @@ -199,7 +209,7 @@ func TestOneOffScript(t *testing.T) { unameMock.Expect("-s").AndWriteToStdout("Linux") unameMock.Expect("-m").AndWriteToStdout("apple-silicon") - mktempMock.Expect("-d").AndWriteToStdout(testWorkingDir) + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) err = os.WriteFile(scriptLocation, []byte(script), 0700) require.NoError(t, err) @@ -261,7 +271,7 @@ func TestOneOffScript(t *testing.T) { unameMock.Expect("-s").AndWriteToStdout("Linux") unameMock.Expect("-m").AndWriteToStdout("x86_64") - mktempMock.Expect("-d").AndWriteToStdout(testWorkingDir) + mktempMock.Expect("-d", "-p", homeDir).AndWriteToStdout(testWorkingDir) teleportMock.Expect("version").AndWriteToStdout(teleportVersionOutput) err = os.WriteFile(scriptLocation, []byte(script), 0700) @@ -277,7 +287,7 @@ func TestOneOffScript(t *testing.T) { require.True(t, mktempMock.Check(t)) require.True(t, teleportMock.Check(t)) - require.Contains(t, string(out), "> ./bin/teleport version") + require.Contains(t, string(out), "/bin/teleport version") require.Contains(t, string(out), teleportVersionOutput) require.Contains(t, string(out), "Test was a success.") }) From c4ae80a159243fa92adbee9297cb572aeef40119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Wed, 19 Jun 2024 18:24:17 +0200 Subject: [PATCH 06/30] Fix updates outside of act in TabHost tests (#43238) --- web/packages/shared/setupTests.tsx | 1 - .../teleterm/src/ui/TabHost/TabHost.test.tsx | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/web/packages/shared/setupTests.tsx b/web/packages/shared/setupTests.tsx index 3f83181203977..8bf61734b1944 100644 --- a/web/packages/shared/setupTests.tsx +++ b/web/packages/shared/setupTests.tsx @@ -55,7 +55,6 @@ const failOnConsoleIgnoreList = new Set([ 'web/packages/shared/components/TextEditor/TextEditor.test.tsx', 'web/packages/teleport/src/components/BannerList/useAlerts.test.tsx', 'web/packages/teleport/src/Navigation/NavigationItem.test.tsx', - 'web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx', // As of the parent commit (708dac8e0d0), the tests below are flakes. // https://github.com/gravitational/teleport/pull/41252#discussion_r1595036569 'web/packages/teleport/src/Console/DocumentNodes/DocumentNodes.story.test.tsx', diff --git a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx index cef81a193fc93..1237024a97dbf 100644 --- a/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx +++ b/web/packages/teleterm/src/ui/TabHost/TabHost.test.tsx @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import 'jest-canvas-mock'; import { createRef } from 'react'; import { fireEvent, render, screen } from 'design/utils/testing'; @@ -44,7 +45,7 @@ function getMockDocuments(): Document[] { const rootClusterUri = '/clusters/test_uri'; -function getTestSetup({ documents }: { documents: Document[] }) { +async function getTestSetup({ documents }: { documents: Document[] }) { const appContext = new MockAppContext(); jest.spyOn(appContext.mainProcessClient, 'openTabContextMenu'); @@ -78,21 +79,24 @@ function getTestSetup({ documents }: { documents: Document[] }) { jest.spyOn(docsService, 'closeToRight'); jest.spyOn(docsService, 'duplicatePtyAndActivate'); - const utils = render( + render( ); + // Mostly a bogus await just so that all useEffects in all of the mounted contexts have time to be + // processed and not throw an error due to a state update outside of `act`. + expect(await screen.findByTitle(/New Tab/)).toBeInTheDocument(); + return { - ...utils, docsService, mainProcessClient: appContext.mainProcessClient, }; } -test('render documents', () => { - const { docsService } = getTestSetup({ +test('render documents', async () => { + const { docsService } = await getTestSetup({ documents: getMockDocuments(), }); const documents = docsService.getDocuments(); @@ -101,21 +105,21 @@ test('render documents', () => { expect(screen.getByTitle(documents[1].title)).toBeInTheDocument(); }); -test('open tab on click', () => { - const { getByTitle, docsService } = getTestSetup({ +test('open tab on click', async () => { + const { docsService } = await getTestSetup({ documents: [getMockDocuments()[0]], }); const documents = docsService.getDocuments(); const { open } = docsService; - const $tabTitle = getByTitle(documents[0].title); + const $tabTitle = screen.getByTitle(documents[0].title); fireEvent.click($tabTitle); expect(open).toHaveBeenCalledWith(documents[0].uri); }); -test('open context menu', () => { - const { getByTitle, docsService, mainProcessClient } = getTestSetup({ +test('open context menu', async () => { + const { docsService, mainProcessClient } = await getTestSetup({ documents: [getMockDocuments()[0]], }); const { openTabContextMenu } = mainProcessClient; @@ -124,7 +128,7 @@ test('open context menu', () => { const documents = docsService.getDocuments(); const document = documents[0]; - const $tabTitle = getByTitle(documents[0].title); + const $tabTitle = screen.getByTitle(documents[0].title); fireEvent.contextMenu($tabTitle); expect(openTabContextMenu).toHaveBeenCalled(); @@ -146,14 +150,14 @@ test('open context menu', () => { expect(duplicatePtyAndActivate).toHaveBeenCalledWith(document.uri); }); -test('open new tab', () => { - const { getByTitle, docsService } = getTestSetup({ +test('open new tab', async () => { + const { docsService } = await getTestSetup({ documents: [getMockDocuments()[0]], }); const { add, open } = docsService; const mockedClusterDocument = makeDocumentCluster(); docsService.createClusterDocument = () => mockedClusterDocument; - const $newTabButton = getByTitle('New Tab', { exact: false }); + const $newTabButton = screen.getByTitle('New Tab', { exact: false }); fireEvent.click($newTabButton); @@ -161,13 +165,13 @@ test('open new tab', () => { expect(open).toHaveBeenCalledWith(mockedClusterDocument.uri); }); -test('swap tabs', () => { - const { getByTitle, docsService } = getTestSetup({ +test('swap tabs', async () => { + const { docsService } = await getTestSetup({ documents: getMockDocuments(), }); const documents = docsService.getDocuments(); - const $firstTab = getByTitle(documents[0].title); - const $secondTab = getByTitle(documents[1].title); + const $firstTab = screen.getByTitle(documents[0].title); + const $secondTab = screen.getByTitle(documents[1].title); fireEvent.dragStart($secondTab); fireEvent.drop($firstTab); From cbe7d9f53c4a3721f2def80b45c1ee0f4b1bc10e Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Wed, 19 Jun 2024 13:29:04 -0300 Subject: [PATCH 07/30] Use libfido2 on builds if present (#43224) * Use libfido2 on builds if present * Use static libfido2 linking on OS compat tests --- .github/workflows/os-compatibility-test.yaml | 2 +- Makefile | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/os-compatibility-test.yaml b/.github/workflows/os-compatibility-test.yaml index 9d2e6e782d8d5..664e8f2545de0 100644 --- a/.github/workflows/os-compatibility-test.yaml +++ b/.github/workflows/os-compatibility-test.yaml @@ -50,7 +50,7 @@ jobs: - name: Run make run: | - make -j"$(nproc)" binaries + make -j"$(nproc)" binaries FIDO2=static - name: Upload binaries uses: actions/upload-artifact@v3 diff --git a/Makefile b/Makefile index 6cc41513caaeb..cc6f129610f5b 100644 --- a/Makefile +++ b/Makefile @@ -148,6 +148,10 @@ export C_ARCH # Eagerly enable if we detect the package, we want to test as much as possible. ifeq ("$(shell pkg-config libfido2 2>/dev/null; echo $$?)", "0") LIBFIDO2_TEST_TAG := libfido2 +ifeq ($(FIDO2),) +$(info libfido2 found, setting FIDO2=dynamic) +FIDO2 ?= dynamic +endif endif # Build tsh against libfido2? @@ -308,6 +312,9 @@ binaries: # until we can use this Makefile for native Windows builds. .PHONY: $(BUILDDIR)/tctl $(BUILDDIR)/tctl: + @if [[ -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \ + echo 'Warning: Building tctl without libfido2. Install libfido2 to have access to MFA.' >&2; \ + fi GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG) go build -tags "$(PAM_TAG) $(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tctl $(BUILDFLAGS) ./tool/tctl .PHONY: $(BUILDDIR)/teleport @@ -326,6 +333,9 @@ $(BUILDDIR)/teleport: ensure-webassets bpf-bytecode rdpclient $(BUILDDIR)/tsh: KUBECTL_VERSION ?= $(shell go run ./build.assets/kubectl-version/main.go) $(BUILDDIR)/tsh: KUBECTL_SETVERSION ?= -X k8s.io/component-base/version.gitVersion=$(KUBECTL_VERSION) $(BUILDDIR)/tsh: + @if [[ -z "$(LIBFIDO2_BUILD_TAG)" ]]; then \ + echo 'Warning: Building tsh without libfido2. Install libfido2 to have access to MFA.' >&2; \ + fi GOOS=$(OS) GOARCH=$(ARCH) $(CGOFLAG_TSH) go build -tags "$(FIPS_TAG) $(LIBFIDO2_BUILD_TAG) $(TOUCHID_TAG) $(PIV_BUILD_TAG) $(KUSTOMIZE_NO_DYNAMIC_PLUGIN)" -o $(BUILDDIR)/tsh $(BUILDFLAGS) ./tool/tsh .PHONY: $(BUILDDIR)/tbot From 651671c877ae90b8df7c46f913c7783165461f58 Mon Sep 17 00:00:00 2001 From: "STeve (Xin) Huang" Date: Wed, 19 Jun 2024 12:58:52 -0400 Subject: [PATCH 08/30] add a trouble shooting for db auto-user provisioning issue for RDS blue/green deployment (#43104) * add a trouble shooting for db auto-user provisioning issue for RDS blue/green deployment * fix link * add example for non-discovery db --- docs/config.json | 2 +- .../auto-user-provisioning.mdx | 8 +++---- .../auto-user-provisioning/aws-redshift.mdx | 6 ++--- .../auto-user-provisioning/mysql.mdx | 2 +- .../auto-user-provisioning/postgres.mdx | 24 ++++++++++++++++++- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/docs/config.json b/docs/config.json index efac5462f6d1c..97a7e871242c9 100644 --- a/docs/config.json +++ b/docs/config.json @@ -1272,7 +1272,7 @@ "slug": "/database-access/auto-user-provisioning/", "entries": [ { - "title": "AWS Redshift", + "title": "Amazon Redshift", "slug": "/database-access/auto-user-provisioning/aws-redshift/" }, { diff --git a/docs/pages/database-access/auto-user-provisioning.mdx b/docs/pages/database-access/auto-user-provisioning.mdx index 400a05ebbe731..e2bfbec09b3f2 100644 --- a/docs/pages/database-access/auto-user-provisioning.mdx +++ b/docs/pages/database-access/auto-user-provisioning.mdx @@ -6,10 +6,10 @@ description: Configure automatic user provisioning for databases. (!docs/pages/includes/database-access/auto-user-provisioning/intro.mdx!) Currently, automatic user provisioning is supported for the following databases: -- [PostgreSQL databases (self-hosted and AWS RDS)](./auto-user-provisioning/postgres.mdx) -- [MySQL databases (self-hosted and AWS RDS)](./auto-user-provisioning/mysql.mdx) -- [MariaDB databases (self-hosted and AWS RDS)](./auto-user-provisioning/mariadb.mdx) -- [AWS Redshift databases](./auto-user-provisioning/aws-redshift.mdx) +- [PostgreSQL databases (self-hosted and Amazon RDS)](./auto-user-provisioning/postgres.mdx) +- [MySQL databases (self-hosted and Amazon RDS)](./auto-user-provisioning/mysql.mdx) +- [MariaDB databases (self-hosted and Amazon RDS)](./auto-user-provisioning/mariadb.mdx) +- [Amazon Redshift databases](./auto-user-provisioning/aws-redshift.mdx) - [MongoDB databases (self-hosted)](./auto-user-provisioning/mongodb.mdx) diff --git a/docs/pages/database-access/auto-user-provisioning/aws-redshift.mdx b/docs/pages/database-access/auto-user-provisioning/aws-redshift.mdx index dc2522ad737e7..940191586b554 100644 --- a/docs/pages/database-access/auto-user-provisioning/aws-redshift.mdx +++ b/docs/pages/database-access/auto-user-provisioning/aws-redshift.mdx @@ -1,13 +1,13 @@ --- -title: AWS Redshift Automatic User Provisioning -description: Configure automatic user provisioning for AWS Redshift. +title: Amazon Redshift Automatic User Provisioning +description: Configure automatic user provisioning for Amazon Redshift. --- (!docs/pages/includes/database-access/auto-user-provisioning/intro.mdx!) ## Prerequisites -- Teleport cluster v14.1.3 or higher with a configured [AWS +- Teleport cluster v14.1.3 or higher with a configured [Amazon Redshift](../enroll-aws-databases/postgres-redshift.mdx) database. - Ability to connect to and create user accounts in the target database. diff --git a/docs/pages/database-access/auto-user-provisioning/mysql.mdx b/docs/pages/database-access/auto-user-provisioning/mysql.mdx index 4bc25df89bdea..dd7cd3062d459 100644 --- a/docs/pages/database-access/auto-user-provisioning/mysql.mdx +++ b/docs/pages/database-access/auto-user-provisioning/mysql.mdx @@ -114,7 +114,7 @@ ERROR 1105 (HY000): ERROR 1044 (42000): Access denied for user ' example diff --git a/docs/pages/database-access/auto-user-provisioning/postgres.mdx b/docs/pages/database-access/auto-user-provisioning/postgres.mdx index c8cb3d0dd1526..1d15847ec83b1 100644 --- a/docs/pages/database-access/auto-user-provisioning/postgres.mdx +++ b/docs/pages/database-access/auto-user-provisioning/postgres.mdx @@ -192,7 +192,7 @@ GRANT CONNECT ON DATABASE to "reader"; ### Cannot execute in a read-only transaction error -You may encounter the following error when connecting to an AWS RDS Aurora +You may encounter the following error when connecting to an Amazon RDS Aurora reader endpoint: ```shell $ tsh db connect --db-name example @@ -247,6 +247,28 @@ GRANT rds_iam TO "teleport-admin" WITH ADMIN OPTION; (!docs/pages/includes/database-access/psql-ssl-syscall-error.mdx!) +### Amazon RDS Blue/Green deployment enters a state of "Replication degraded" + +Amazon RDS Blue/Green deployment may enter a state of "Replication degraded" +when auto-user provisioning is used to connect to the database. + +This occurs due to a [limitation in PostgreSQL logical +replication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-overview.html#blue-green-deployments-limitations-postgres) +for Blue/Green deployments as Data Definition Language (DDL) statements cannot +be replicated. Consequently, Amazon RDS will enter the "Replication degraded" +state when a DDL change is detected. + +It is recommended to disable database auto-user provisioning before starting +the Blue/Green deployment. + +If the database is auto-discovered by Teleport, you can temporarily remove the +`teleport.dev/db-admin` AWS resource tag. For a database registered using +either static config or a dynamic `db` resource, you can temporarily remove the +`admin_user` setting. + +Once auto-user provisioning is disabled, you can still connect as the database +admin user through Teleport. + ## Next steps - Connect using your [GUI database From 356200464c98c33a7e4c94a94238c28714047b8b Mon Sep 17 00:00:00 2001 From: Cam Hutchison Date: Thu, 20 Jun 2024 16:01:34 +1000 Subject: [PATCH 09/30] build: Ensure we target the min version supported on Mac builds (#43231) * build: Ensure we target the min version supported on Mac builds Ensure relevant flags are passed to the Go, rust and C compilers (xcode) when building the Teleport binaries to target the minimum version of macOS we support. Currently that is 10.15 (Catalina) on x86_64 and 11 (Big Sur) on arm64 (the first supported Apple silicon macOS release). Note that we set the minimum to 10.15 in the build, but it will be updated to 11 by the compilers/tools when building for ARM64. Care is taken with rust builds not to set this min os globally as we also use rust to target web assembly in the web UI and the flags are invalid there. Link: https://goteleport.com/docs/installation/#operating-system-support * Update e for macOS minimum OS changes --- Makefile | 25 +++++++++++++++++-------- e | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index cc6f129610f5b..478ba7da67530 100644 --- a/Makefile +++ b/Makefile @@ -279,6 +279,14 @@ CGOFLAG = CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ BUILDFLAGS = $(ADDFLAGS) -ldflags '-w -s $(KUBECTL_SETVERSION)' -trimpath -buildmode=pie endif +ifeq ("$(OS)","darwin") +# Note the minimum version for Apple silicon (ARM64) is 11.0 and will be automatically +# clamped to the value for builds of that architecture +MINIMUM_SUPPORTED_MACOS_VERSION = 10.15 +MACOSX_VERSION_MIN_FLAG = -mmacosx-version-min=$(MINIMUM_SUPPORTED_MACOS_VERSION) +CGOFLAG = CGO_ENABLED=1 CGO_CFLAGS=$(MACOSX_VERSION_MIN_FLAG) CGO_LDFLAGS=$(MACOSX_VERSION_MIN_FLAG) +endif + CGOFLAG_TSH ?= $(CGOFLAG) # Map ARCH into the architecture flag for electron-builder if they @@ -388,17 +396,18 @@ else bpf-bytecode: endif -ifeq ("$(with_rdpclient)", "yes") -.PHONY: rdpclient -rdpclient: -ifneq ("$(FIPS)","") - cargo build -p rdp-client --features=fips --release --locked $(CARGO_TARGET) -else - cargo build -p rdp-client --release --locked $(CARGO_TARGET) +ifeq ("$(OS)-$(with_rdpclient)", "darwin-yes") +# Set the minimum version linker flag for the rust build of rdpclient (and only rdpclient, +# as the flag is invalid for building ironrdp to wasm in the web UI). Also set an env +# var so any C libraries built by this build also target the correct min version. +rdpclient: export RUSTFLAGS = -C link-arg=$(MACOSX_VERSION_MIN_FLAG) +rdpclient: export MACOSX_DEPLOYMENT_TARGET = $(MINIMUM_SUPPORTED_MACOS_VERSION) endif -else + .PHONY: rdpclient rdpclient: +ifeq ("$(with_rdpclient)", "yes") + cargo build -p rdp-client $(if $(FIPS),--features=fips) --release --locked $(CARGO_TARGET) endif # Build libfido2 and dependencies for MacOS. Uses exported C_ARCH variable defined earlier. diff --git a/e b/e index ea43d59e9c20b..7143c5860fd9a 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit ea43d59e9c20b6b8856642165117807e57fccd2f +Subproject commit 7143c5860fd9af88b94d7976330bf8e6b631a737 From 359ad77210060b0e0b1f5fde395582b7d0a502c9 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:02:03 -0400 Subject: [PATCH 10/30] Remove lib/devicetrust from lib/client (#43186) The native device trust libraries included in lib/devicetrust prevent building client tools that don't use device trust from building with cgo disabled. This moves the default device auth ceremony and device enrollment from lib/client into a location specific to tsh since it's the only tool that requires them. Updates https://github.com/gravitational/teleport/issues/43112. --- lib/client/api.go | 26 ++++++++++++-------------- lib/client/export_test.go | 4 ++-- lib/teleterm/clusters/storage.go | 4 ++++ tool/tsh/common/tsh.go | 14 ++++++++++++-- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/lib/client/api.go b/lib/client/api.go index 0b56b612a850b..173654cabb1af 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -77,8 +77,6 @@ import ( "github.com/gravitational/teleport/lib/client/terminal" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/devicetrust" - dtauthn "github.com/gravitational/teleport/lib/devicetrust/authn" - dtenroll "github.com/gravitational/teleport/lib/devicetrust/enroll" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/multiplexer" @@ -461,9 +459,9 @@ type Config struct { // PROXYSigner is used to sign PROXY headers for securely propagating client IP address PROXYSigner multiplexer.PROXYHeaderSigner - // DTAuthnRunCeremony allows tests to override the default device - // authentication function. - // Defaults to "dtauthn.NewCeremony().Run()". + // DTAuthnRunCeremony is the device authentication function to execute + // during device login ceremonies. If not provided and device trust is + // required, then the device login will fail. DTAuthnRunCeremony DTAuthnRunCeremonyFunc // dtAttemptLoginIgnorePing and dtAutoEnrollIgnorePing allow Device Trust @@ -471,10 +469,10 @@ type Config struct { // Useful to force flows that only typically happen on Teleport Enterprise. dtAttemptLoginIgnorePing, dtAutoEnrollIgnorePing bool - // dtAutoEnroll allows tests to override the default device auto-enroll - // function. - // Defaults to [dtenroll.AutoEnroll]. - dtAutoEnroll dtAutoEnrollFunc + // DTAutoEnroll is the device auto-enroll function to execute during + // device enrollment. If not provided and device trust auto-enrollment + // is enabled, then the enrollment process will fail. + DTAutoEnroll DTAutoEnrollFunc // WebauthnLogin allows tests to override the Webauthn Login func. // Defaults to [wancli.Login]. @@ -1099,8 +1097,8 @@ func (c *Config) ResourceFilter(kind string) *proto.ListResourcesRequest { // DTAuthnRunCeremonyFunc matches the signature of [dtauthn.Ceremony.Run]. type DTAuthnRunCeremonyFunc func(context.Context, devicepb.DeviceTrustServiceClient, *devicepb.UserCertificates) (*devicepb.UserCertificates, error) -// dtAutoEnrollFunc matches the signature of [dtenroll.AutoEnroll]. -type dtAutoEnrollFunc func(context.Context, devicepb.DeviceTrustServiceClient) (*devicepb.Device, error) +// DTAutoEnrollFunc matches the signature of [dtenroll.AutoEnroll]. +type DTAutoEnrollFunc func(context.Context, devicepb.DeviceTrustServiceClient) (*devicepb.Device, error) // TeleportClient is a wrapper around SSH client with teleport specific // workflow built in. @@ -3388,7 +3386,7 @@ func (tc *TeleportClient) DeviceLogin(ctx context.Context, rootAuthClient authcl // Allow tests to override the default authn function. runCeremony := tc.DTAuthnRunCeremony if runCeremony == nil { - runCeremony = dtauthn.NewCeremony().Run + return nil, trace.BadParameter("device authentication not enabled") } // Login without a previous auto-enroll attempt. @@ -3409,9 +3407,9 @@ func (tc *TeleportClient) DeviceLogin(ctx context.Context, rootAuthClient authcl return nil, trace.Wrap(loginErr) // err swallowed for loginErr } - autoEnroll := tc.dtAutoEnroll + autoEnroll := tc.DTAutoEnroll if autoEnroll == nil { - autoEnroll = dtenroll.AutoEnroll + return nil, trace.BadParameter("device auto enrollment not enabled") } // Auto-enroll and Login again. diff --git a/lib/client/export_test.go b/lib/client/export_test.go index 6ea8a9015e1e7..cd74528139cc3 100644 --- a/lib/client/export_test.go +++ b/lib/client/export_test.go @@ -32,6 +32,6 @@ func (tc *TeleportClient) SetDTAuthnRunCeremony(fn DTAuthnRunCeremonyFunc) { tc.DTAuthnRunCeremony = fn } -func (tc *TeleportClient) SetDTAutoEnroll(fn dtAutoEnrollFunc) { - tc.dtAutoEnroll = fn +func (tc *TeleportClient) SetDTAutoEnroll(fn DTAutoEnrollFunc) { + tc.DTAutoEnroll = fn } diff --git a/lib/teleterm/clusters/storage.go b/lib/teleterm/clusters/storage.go index 74948e5f4c478..c226c31700b35 100644 --- a/lib/teleterm/clusters/storage.go +++ b/lib/teleterm/clusters/storage.go @@ -27,6 +27,8 @@ import ( "github.com/gravitational/teleport/api/profile" "github.com/gravitational/teleport/lib/client" + dtauthn "github.com/gravitational/teleport/lib/devicetrust/authn" + dtenroll "github.com/gravitational/teleport/lib/devicetrust/enroll" "github.com/gravitational/teleport/lib/teleterm/api/uri" ) @@ -291,6 +293,8 @@ func (s *Storage) makeDefaultClientConfig() *client.Config { // true. cfg.AllowStdinHijack = true + cfg.DTAuthnRunCeremony = dtauthn.NewCeremony().Run + cfg.DTAutoEnroll = dtenroll.AutoEnroll return cfg } diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 99be4a1fddca3..386d158974dfa 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -78,6 +78,8 @@ import ( dbprofile "github.com/gravitational/teleport/lib/client/db" "github.com/gravitational/teleport/lib/client/identityfile" "github.com/gravitational/teleport/lib/defaults" + dtauthn "github.com/gravitational/teleport/lib/devicetrust/authn" + dtenroll "github.com/gravitational/teleport/lib/devicetrust/enroll" "github.com/gravitational/teleport/lib/kube/kubeconfig" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/observability/tracing" @@ -525,6 +527,11 @@ type CLIConf struct { // Defaults to [dtauthn.NewCeremony().Run]. DTAuthnRunCeremony client.DTAuthnRunCeremonyFunc + // DTAutoEnroll allows tests to override the default device + // auto-enroll function. + // Defaults to [dtenroll.AutoEnroll]. + DTAutoEnroll client.DTAutoEnrollFunc + // WebauthnLogin allows tests to override the Webauthn Login func. // Defaults to [wancli.Login]. WebauthnLogin client.WebauthnLoginFunc @@ -683,8 +690,10 @@ func initLogger(cf *CLIConf) { // DO NOT RUN TESTS that call Run() in parallel (unless you taken precautions). func Run(ctx context.Context, args []string, opts ...CliOption) error { cf := CLIConf{ - Context: ctx, - TracingProvider: tracing.NoopProvider(), + Context: ctx, + TracingProvider: tracing.NoopProvider(), + DTAuthnRunCeremony: dtauthn.NewCeremony().Run, + DTAutoEnroll: dtenroll.AutoEnroll, } // run early to enable debug logging if env var is set. @@ -4069,6 +4078,7 @@ func loadClientConfigFromCLIConf(cf *CLIConf, proxy string) (*client.Config, err c.MockSSOLogin = cf.MockSSOLogin c.MockHeadlessLogin = cf.MockHeadlessLogin c.DTAuthnRunCeremony = cf.DTAuthnRunCeremony + c.DTAutoEnroll = cf.DTAutoEnroll c.WebauthnLogin = cf.WebauthnLogin // pass along MySQL/Postgres path overrides (only used in tests). From 26736198a5de12c6ffe3410dae80609648342653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Skrz=C4=99tnicki?= Date: Thu, 20 Jun 2024 15:41:26 +0200 Subject: [PATCH 11/30] Properly coalesce null table list into empty array. (#42961) --- lib/srv/db/postgres/sql/update-permissions.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/srv/db/postgres/sql/update-permissions.sql b/lib/srv/db/postgres/sql/update-permissions.sql index 50a50e32cd62d..16a564146d13d 100644 --- a/lib/srv/db/postgres/sql/update-permissions.sql +++ b/lib/srv/db/postgres/sql/update-permissions.sql @@ -7,8 +7,7 @@ DECLARE diff_count_1 INTEGER; diff_count_2 INTEGER; BEGIN - - grant_data = COALESCE(permissions_->'tables', '[]'::JSONB); + grant_data = COALESCE(NULLIF(permissions_->'tables', 'null'), '[]'::JSONB); -- If the user has active connections to current database, verify that permissions haven't changed. IF EXISTS (SELECT usename FROM pg_stat_activity WHERE usename = username AND datname = current_database()) THEN From 1c252009bd37adad8035f0a473ed6b8cb36ff404 Mon Sep 17 00:00:00 2001 From: Hugo Shaka Date: Thu, 20 Jun 2024 10:17:42 -0400 Subject: [PATCH 12/30] Mark Discovery service healthy on startup (#43278) --- lib/service/discovery.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/service/discovery.go b/lib/service/discovery.go index 99738862b9780..845c9edbc4de2 100644 --- a/lib/service/discovery.go +++ b/lib/service/discovery.go @@ -128,6 +128,11 @@ func (process *TeleportProcess) initDiscoveryService() error { } logger.InfoContext(process.ExitContext(), "Discovery service has successfully started") + // The Discovery service doesn't have heartbeats so we cannot use them to check health. + // For now, we just mark ourselves ready all the time on startup. + // If we don't, a process only running the Discovery service will never report ready. + process.OnHeartbeat(teleport.ComponentDiscovery)(nil) + if err := discoveryService.Wait(); err != nil { return trace.Wrap(err) } From 043b3e92ce42a3615d5a57b1973eac3595024dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Thu, 20 Jun 2024 16:27:56 +0200 Subject: [PATCH 13/30] Disable debug service in agents ran by Connect My Computer (#43267) * Disable debug service in Connect My Computer * Update jest-environment of Node.js tests * Remove modes from mkdir and writeFile --- .../agentCleanupDaemon.test.ts | 3 ++ .../agentDownloader/fileDownloader.test.ts | 2 +- .../mainProcess/createAgentConfigFile.test.ts | 19 ++++++++-- .../src/mainProcess/createAgentConfigFile.ts | 38 ++++++++++++++++++- .../terminateWithTimeout.test.ts | 3 ++ .../grpcCredentials/makeCert/makeCert.test.ts | 3 ++ 6 files changed, 62 insertions(+), 6 deletions(-) diff --git a/web/packages/teleterm/src/agentCleanupDaemon/agentCleanupDaemon.test.ts b/web/packages/teleterm/src/agentCleanupDaemon/agentCleanupDaemon.test.ts index 997abd394c699..4a9d7001a61f1 100644 --- a/web/packages/teleterm/src/agentCleanupDaemon/agentCleanupDaemon.test.ts +++ b/web/packages/teleterm/src/agentCleanupDaemon/agentCleanupDaemon.test.ts @@ -1,3 +1,6 @@ +/** + * @jest-environment node + */ /** * Teleport * Copyright (C) 2023 Gravitational, Inc. diff --git a/web/packages/teleterm/src/mainProcess/agentDownloader/fileDownloader.test.ts b/web/packages/teleterm/src/mainProcess/agentDownloader/fileDownloader.test.ts index e1171c33956d8..7f9af2d97c133 100644 --- a/web/packages/teleterm/src/mainProcess/agentDownloader/fileDownloader.test.ts +++ b/web/packages/teleterm/src/mainProcess/agentDownloader/fileDownloader.test.ts @@ -1,5 +1,5 @@ /** - * @jest-environment jsdom + * @jest-environment node */ /** * Teleport diff --git a/web/packages/teleterm/src/mainProcess/createAgentConfigFile.test.ts b/web/packages/teleterm/src/mainProcess/createAgentConfigFile.test.ts index a11f29d1eec4a..30ecda05521bc 100644 --- a/web/packages/teleterm/src/mainProcess/createAgentConfigFile.test.ts +++ b/web/packages/teleterm/src/mainProcess/createAgentConfigFile.test.ts @@ -1,3 +1,6 @@ +/** + * @jest-environment node + */ /** * Teleport * Copyright (C) 2023 Gravitational, Inc. @@ -24,6 +27,7 @@ import { makeRuntimeSettings } from 'teleterm/mainProcess/fixtures/mocks'; import { createAgentConfigFile, + disableDebugServiceStanza, generateAgentConfigPaths, } from './createAgentConfigFile'; @@ -34,10 +38,12 @@ beforeEach(() => { jest .spyOn(childProcess, 'execFile') .mockImplementation((command, args, options, callback) => { - callback(undefined, '', ''); - return this; + callback(null, '', ''); + return undefined; }); jest.spyOn(fs, 'rm').mockImplementation(() => Promise.resolve()); + jest.spyOn(fs, 'mkdir').mockImplementation(() => Promise.resolve(undefined)); + jest.spyOn(fs, 'writeFile').mockImplementation(() => Promise.resolve()); }); test('teleport configure is called with proper arguments', async () => { @@ -69,7 +75,7 @@ test('teleport configure is called with proper arguments', async () => { [ 'node', 'configure', - `--output=${userDataDir}/agents/cluster.local/config.yaml`, + `--output=stdout`, `--data-dir=${userDataDir}/agents/cluster.local/data`, `--proxy=${proxy}`, `--token=${token}`, @@ -80,6 +86,13 @@ test('teleport configure is called with proper arguments', async () => { }, expect.anything() ); + expect(fs.writeFile).toHaveBeenCalledWith( + `${userDataDir}/agents/cluster.local/config.yaml`, + // It'd be nice to make childProcess.execFile return certain output and then verify that this + // argument includes that output + disableDebugServiceStanza. Alas, the promisified version of + // execFile isn't easily mockable – stdout in tests is just "undefined" for some reason. + expect.stringContaining(disableDebugServiceStanza) + ); }); test('previous config file is removed before calling teleport configure', async () => { diff --git a/web/packages/teleterm/src/mainProcess/createAgentConfigFile.ts b/web/packages/teleterm/src/mainProcess/createAgentConfigFile.ts index f5aaf05a5289b..4345563e3ee7f 100644 --- a/web/packages/teleterm/src/mainProcess/createAgentConfigFile.ts +++ b/web/packages/teleterm/src/mainProcess/createAgentConfigFile.ts @@ -52,12 +52,12 @@ export async function createAgentConfigFile( .map(keyAndValue => keyAndValue.join('=')) .join(','); - await asyncExecFile( + const { stdout } = await asyncExecFile( runtimeSettings.agentBinaryPath, [ 'node', 'configure', - `--output=${configFile}`, + '--output=stdout', `--data-dir=${dataDirectory}`, `--proxy=${args.proxy}`, `--token=${args.token}`, @@ -67,8 +67,42 @@ export async function createAgentConfigFile( timeout: 10_000, // 10 seconds } ); + + try { + await fs.mkdir(path.dirname(configFile), { + // Create the agents dir too if it doesn't already exist. + recursive: true, + }); + } catch (error) { + // Ignore error if directory already exists. + if (error['code'] !== 'EEXIST') { + throw error; + } + } + + await fs.writeFile(configFile, stdout + disableDebugServiceStanza); } +// The debug service is enabled by default. It starts when the teleport agent is launched and it +// creates a debug.sock file in the data directory. Unfortunately, there's a length limit on the +// socket path – 107 characters on Linux and 104 characters on macOS [1]. If exceeded, creating a +// new listener fails with "bind: invalid argument". +// +// The default path for debug.sock for Connect My Computer on macOS is +// /Users//Library/Application Support/Teleport Connect/agents//data/debug.sock +// The constant part is 76 characters which leaves just 28 characters for the hostname and user. +// +// As a workaround, we disable the debug service. This is going to work until someone adds another +// socket which is crucial to run a Teleport agent. +// +// See the GitHub issue for more details: https://github.com/gravitational/teleport/issues/43250 +// +// [1] https://unix.stackexchange.com/questions/367008/why-is-socket-path-length-limited-to-a-hundred-chars +export const disableDebugServiceStanza = ` +debug_service: + enabled: false +`; + export async function removeAgentDirectory( runtimeSettings: RuntimeSettings, rootClusterUri: RootClusterUri diff --git a/web/packages/teleterm/src/mainProcess/terminateWithTimeout/terminateWithTimeout.test.ts b/web/packages/teleterm/src/mainProcess/terminateWithTimeout/terminateWithTimeout.test.ts index 6138dc074d95d..e26a7fd20e5c2 100644 --- a/web/packages/teleterm/src/mainProcess/terminateWithTimeout/terminateWithTimeout.test.ts +++ b/web/packages/teleterm/src/mainProcess/terminateWithTimeout/terminateWithTimeout.test.ts @@ -1,3 +1,6 @@ +/** + * @jest-environment node + */ /** * Teleport * Copyright (C) 2023 Gravitational, Inc. diff --git a/web/packages/teleterm/src/services/grpcCredentials/makeCert/makeCert.test.ts b/web/packages/teleterm/src/services/grpcCredentials/makeCert/makeCert.test.ts index b7aa3e437297f..2a7c6358a4ba5 100644 --- a/web/packages/teleterm/src/services/grpcCredentials/makeCert/makeCert.test.ts +++ b/web/packages/teleterm/src/services/grpcCredentials/makeCert/makeCert.test.ts @@ -1,3 +1,6 @@ +/** + * @jest-environment node + */ /** * (The MIT License) * From 57384e7570a7e348cc3ca5573a001a7613dec99a Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Thu, 20 Jun 2024 15:48:38 +0100 Subject: [PATCH 14/30] Fix gRPC connections being disconnected regardless of DisconnectCertExpiry (#43270) * Fix gRPC connections being disconnected regardless of DisconnectCertExpiry * Remove log lines * Add test * back out the changes that added Authorizer --- lib/auth/transport_credentials.go | 7 +++++-- lib/authz/permissions.go | 7 ++++++- lib/authz/permissions_test.go | 22 +++++++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/auth/transport_credentials.go b/lib/auth/transport_credentials.go index 2da934c4dd172..1e0e87904637e 100644 --- a/lib/auth/transport_credentials.go +++ b/lib/auth/transport_credentials.go @@ -183,8 +183,11 @@ func newTimeoutConn(conn net.Conn, clock clockwork.Clock, expires time.Time) (ne } return &timeoutConn{ - Conn: conn, - timer: clock.AfterFunc(expires.Sub(clock.Now()), func() { conn.Close() }), + Conn: conn, + timer: clock.AfterFunc(expires.Sub(clock.Now()), func() { + log.Debug("Closing gRPC connection due to certificate expiry") + conn.Close() + }), }, nil } diff --git a/lib/authz/permissions.go b/lib/authz/permissions.go index efa3dc36cb3b3..5f72ad9c92815 100644 --- a/lib/authz/permissions.go +++ b/lib/authz/permissions.go @@ -335,7 +335,12 @@ func (c *Context) GetDisconnectCertExpiry(authPref types.AuthPreference) time.Ti // See https://github.com/gravitational/teleport/issues/18544 // If the session doesn't need to be disconnected on cert expiry just return the default value. - if c.Checker != nil && !c.Checker.AdjustDisconnectExpiredCert(authPref.GetDisconnectExpiredCert()) { + disconnectExpiredCert := authPref.GetDisconnectExpiredCert() + if c.Checker != nil { + disconnectExpiredCert = c.Checker.AdjustDisconnectExpiredCert(disconnectExpiredCert) + } + + if !disconnectExpiredCert { return time.Time{} } diff --git a/lib/authz/permissions_test.go b/lib/authz/permissions_test.go index 39a4abc4086f0..25b6c18171584 100644 --- a/lib/authz/permissions_test.go +++ b/lib/authz/permissions_test.go @@ -62,12 +62,14 @@ func TestGetDisconnectExpiredCertFromIdentity(t *testing.T) { name string expires time.Time previousIdentityExpires time.Time + checker services.AccessChecker mfaVerified bool disconnectExpiredCert bool expected time.Time }{ { name: "mfa overrides expires when set", + checker: &fakeCtxChecker{}, expires: now, previousIdentityExpires: inAnHour, mfaVerified: true, @@ -76,6 +78,7 @@ func TestGetDisconnectExpiredCertFromIdentity(t *testing.T) { }, { name: "expires returned when mfa unset", + checker: &fakeCtxChecker{}, expires: now, mfaVerified: false, disconnectExpiredCert: true, @@ -83,11 +86,28 @@ func TestGetDisconnectExpiredCertFromIdentity(t *testing.T) { }, { name: "unset when disconnectExpiredCert is false", + checker: &fakeCtxChecker{}, expires: now, previousIdentityExpires: inAnHour, mfaVerified: true, disconnectExpiredCert: false, }, + { + name: "no expiry returned when checker nil and disconnectExpiredCert false", + checker: nil, + expires: now, + mfaVerified: false, + disconnectExpiredCert: false, + expected: time.Time{}, + }, + { + name: "expiry returned when checker nil and disconnectExpiredCert true", + checker: nil, + expires: now, + mfaVerified: false, + disconnectExpiredCert: true, + expected: now, + }, } { t.Run(test.name, func(t *testing.T) { var mfaVerified string @@ -103,7 +123,7 @@ func TestGetDisconnectExpiredCertFromIdentity(t *testing.T) { authPref := types.DefaultAuthPreference() authPref.SetDisconnectExpiredCert(test.disconnectExpiredCert) - ctx := Context{Checker: &fakeCtxChecker{}, Identity: WrapIdentity(identity)} + ctx := Context{Checker: test.checker, Identity: WrapIdentity(identity)} got := ctx.GetDisconnectCertExpiry(authPref) require.Equal(t, test.expected, got) From 632cf8c205b2abb05627f9755c8f7ad8c467c9c5 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 20 Jun 2024 09:51:49 -0500 Subject: [PATCH 15/30] Add new logos (#43221) --- web/packages/design/src/Image/Image.story.js | 2 +- .../design/src/assets/images/Assets.story.tsx | 4 +- .../src/assets/images/enterprise-dark.svg | 14 +++- .../src/assets/images/enterprise-light.svg | 14 +++- .../src/assets/images/teleport-logo.svg | 38 --------- .../src/assets/images/teleport-medallion.svg | 74 ------------------ web/packages/teleport/index.html | 13 ++- .../teleport/public/app/favicon-dark.png | Bin 0 -> 664 bytes .../teleport/public/app/favicon-light.png | Bin 0 -> 1093 bytes web/packages/teleport/public/app/favicon.ico | Bin 1929 -> 0 bytes .../teleport/src/Navigation/logoDark.svg | 3 - .../teleport/src/Navigation/logoLight.svg | 3 - web/packages/teleport/src/TopBar/logoDark.svg | 3 - .../teleport/src/TopBar/logoLight.svg | 3 - web/packages/teleport/webpack.dev.config.js | 2 +- web/packages/teleport/webpack.prod.config.js | 2 +- 16 files changed, 40 insertions(+), 135 deletions(-) delete mode 100644 web/packages/design/src/assets/images/teleport-logo.svg delete mode 100644 web/packages/design/src/assets/images/teleport-medallion.svg create mode 100644 web/packages/teleport/public/app/favicon-dark.png create mode 100644 web/packages/teleport/public/app/favicon-light.png delete mode 100644 web/packages/teleport/public/app/favicon.ico delete mode 100644 web/packages/teleport/src/Navigation/logoDark.svg delete mode 100644 web/packages/teleport/src/Navigation/logoLight.svg delete mode 100644 web/packages/teleport/src/TopBar/logoDark.svg delete mode 100644 web/packages/teleport/src/TopBar/logoLight.svg diff --git a/web/packages/design/src/Image/Image.story.js b/web/packages/design/src/Image/Image.story.js index 367c69383b522..bd9bd97910e9c 100644 --- a/web/packages/design/src/Image/Image.story.js +++ b/web/packages/design/src/Image/Image.story.js @@ -20,7 +20,7 @@ import React from 'react'; import Image from '../Image'; -import teleportSvg from './../assets/images/teleport-medallion.svg'; +import teleportSvg from './../assets/images/enterprise-dark.svg'; export default { title: 'Design/Image', diff --git a/web/packages/design/src/assets/images/Assets.story.tsx b/web/packages/design/src/assets/images/Assets.story.tsx index f17d0850164fb..3f0122a92f1e4 100644 --- a/web/packages/design/src/assets/images/Assets.story.tsx +++ b/web/packages/design/src/assets/images/Assets.story.tsx @@ -24,8 +24,7 @@ import kubeLogo from "design/assets/images/kube-logo.svg"; import sampleLogoLong from "design/assets/images/sample-logo-long.svg"; import sampleLogoSquire from "design/assets/images/sample-logo-squire.svg"; import secKeyGraphic from "design/assets/images/sec-key-graphic.svg"; -import teleportLogo from "design/assets/images/teleport-logo.svg"; -import teleportMedallion from "design/assets/images/teleport-medallion.svg"; +import teleportLogo from "design/assets/images/enterprise-light.svg"; import {TeleportLogoII} from "design/assets/images/TeleportLogoII"; import cloudCity from "design/assets/images/backgrounds/cloud-city.png" @@ -50,7 +49,6 @@ export const ImageSVG = () => ( - ); diff --git a/web/packages/design/src/assets/images/enterprise-dark.svg b/web/packages/design/src/assets/images/enterprise-dark.svg index 1ed6d944a3875..672f87a7e5f51 100644 --- a/web/packages/design/src/assets/images/enterprise-dark.svg +++ b/web/packages/design/src/assets/images/enterprise-dark.svg @@ -1,3 +1,13 @@ - - + + + + + + + + + + + + diff --git a/web/packages/design/src/assets/images/enterprise-light.svg b/web/packages/design/src/assets/images/enterprise-light.svg index 70dac68db813b..6b2c1b9de133f 100644 --- a/web/packages/design/src/assets/images/enterprise-light.svg +++ b/web/packages/design/src/assets/images/enterprise-light.svg @@ -1,3 +1,13 @@ - - + + + + + + + + + + + + diff --git a/web/packages/design/src/assets/images/teleport-logo.svg b/web/packages/design/src/assets/images/teleport-logo.svg deleted file mode 100644 index c6f480018efee..0000000000000 --- a/web/packages/design/src/assets/images/teleport-logo.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - gravity/logo/teleport - with text - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/web/packages/design/src/assets/images/teleport-medallion.svg b/web/packages/design/src/assets/images/teleport-medallion.svg deleted file mode 100644 index 045f91fb9f9a4..0000000000000 --- a/web/packages/design/src/assets/images/teleport-medallion.svg +++ /dev/null @@ -1,74 +0,0 @@ - - - - teleport medallion - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/web/packages/teleport/index.html b/web/packages/teleport/index.html index 192d614ccc2bb..f6c081bbe15bc 100644 --- a/web/packages/teleport/index.html +++ b/web/packages/teleport/index.html @@ -8,7 +8,18 @@ - + + diff --git a/web/packages/teleport/public/app/favicon-dark.png b/web/packages/teleport/public/app/favicon-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c252b2b9994c9da744b5e6b38ccb55a300bf4f4a GIT binary patch literal 664 zcmV;J0%!e+P)*`QdwfuqWyYnTn{<17P z0F^+*r5~do6P_`JxfR?R-iSpVBitGya)}9U32&goJlYzacTk76fXBdJ5ejUer1;=R^g`UDRGnx$JCX!|s;d9ba%xA*P zo;roW359FSV=ZK?!bc6Qo0(e0iJmEvb@GO%Y)}Tbg0^CEu?#zu4J$aoD|ixg$7r3h z=941J+xLiCxAcSsW3);X11Rvc4dXLx{zG$Kw&Iq(e=GCvpkrU4Ymst*Lp#|P37I2Q z;x3_pr;0~rK*uwCKd|=)#l{(7{Vgv-WG%O_2!E?w(9%VS`ZhF-XDMhyC{CJR3nM*~ zOK-!3ae@_&ZZMCHkg*D%L&_xPTk%RL>@n`}6ybfz=w8OwH-_iPnj8GzVdP{~Ijo@& zn2(&$L*ZIoc#V;xS!AV1&nzRaWOP&ES0}oXQ5Sm=wunZ(;Sj!QTefiBq+Y}P6I@>P zuCHXl30k)S#kC7hJ7tUIuqb*3p0?{YmBB3Vx);Py^?O$PU$8IW*+B&ws05zQdi6l^ yYg?tWHUorI7IsjHd#J}(c=8{S`A6j)D)9r!TXn!nG*0jU0000sXj literal 0 HcmV?d00001 diff --git a/web/packages/teleport/public/app/favicon-light.png b/web/packages/teleport/public/app/favicon-light.png new file mode 100644 index 0000000000000000000000000000000000000000..29f34f2ed1e85c4193d2497273d1d1dcf11fcebc GIT binary patch literal 1093 zcmV-L1iJf)P)!$VXO4&{(^PR1`tHB-%0iqtNK2Q{jPUU4^-~n*h$ud8VJ^-z)r1o> z@74&+nGk0O{_0%sZMOu|UQ>5)BX=1z>n|>LnE4^pTgxV*ec6*wq*sPs18wFT zhsyQe`65Z35TX$j+MG^!-_%&#BZP5s7GYs%HC<=T^*EZb4$hhdQkWrFbWnxSFAK>Q?U&Q_UMnWyJj8-%@V zXt6@Wf)pqZ3X8yonV>4E_}13{@t^$f4(^Ki7@`FGb_s_h!ZBMJB5U=r&qNy9LD?N@cDQtJuDG$bFUTv{FQ@VsswCjIe>}K<@)mZ zTp=z9(4v@@iFDpK!#7KGmMM(X9pIh!m1Q29(r~(nBSII3y=0Zr9*F7_FY!l2w}06Gy?L%{1NW zwkr`1)RYNzdw3+R+wHblGm<`nKLoL7Ha7@8@R5ncSuSWopVm##>s=5*>~|pPK@aq@ zfS_F4?}MGI7tQ~88)CB+u(ADW#8S`w;@L+ia+e<>*+T^ued+xJ7sl);VKP%L00000 LNkvXXu0mjfsBrN_ literal 0 HcmV?d00001 diff --git a/web/packages/teleport/public/app/favicon.ico b/web/packages/teleport/public/app/favicon.ico deleted file mode 100644 index 909c94fcbbe1085ea1cf12e8da50b80af60cad92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1929 zcmV;42X^?0P)Px+LrFwIR7efAS7~fjMHHShbK3_LC?Zg(21`LDvO`cdWerjk0YjTmwz33Blr<0t z!AQgyRDxAhLISibt)w)Nx`6cu7^{*ZOW+R#N-M?`L3V8I>w9;`@65dW(rN;aA5Qb$ zy}fhJ`Of#9Gjr#Wc!ZHPY~Oei{#xUUbR|r>G(wP}TB%K~5@J*7sl4wJ4d*3l=LUL09O{4?32R@h+VaUEq81>ek z3v+I=|NLGh?Wz9mG$cK=y==Su{py^%{5%dkX5^kCIOj4O4o+H^E28gB)U3v{&eBk& z6gt0^N;+IrIrAPn2V>swvNn<1w?Gfe2|60~u_XBld+TE=lpmVsnJ7&CZ>2Gr-1&|zz`+zMUhAPcKP4me zH**=31G!+BWGS?$lb(82X_3+x7AO7-ihx*JR;8G)@Xd?Dge!@tlQilTT<`Kyv&$`z zS5R7wzMdsW2EW zu`!^VwZopz7&8^!#3P6XdJs~SO)wo77&ey zUioV+#ycFp#HcIJVW^0Nn1FLlL6wLk6{cLmoh|BggX= zDH7|z)}R|jizHnZ)zRz#l;wSt!34OG5Gp6sioTTO)(T^6sh+c#3GjS;Oc_}CGnU75 z2T#v!m)*bMM>N!M4q_WfP#GlGEU(b|!tRR;*75E9ZabbwldZM2Lj{$fzR6?$hyX zDkS8lu~eCjWrP@PBc-T?O*_61Ml)c^4dSC~Ff3EJb1*9%Gmm{3JQxZR7zk(W8Jw8{ z)iQSQ{3Lc4c=3Fbfxvg*W3xo3)-vPZu8 zCkq2~b4f!(_%*0Nwq!zYdb@j3Mz4WMZ&G&uT?fH*ss(jB4{r?TC-rXA=kVG4rI?%I z=9m$)<|uRtXReJ3mYT#MB(==eG$u34uB0sAR5dGWUFN>i_!k?9ONf<0LWd~3Pr+Hd zgZuKLiv!>uJQjL7bi|m3lbEx+mtzqyb1mZn;TtO0I$O4MGdWod_I)veH0@yG9lvhB+Ju}M;m^Q7FV zBvrxwZ?J4Y0@VO4R7y_xpgQj*Y(RZ|qbt!+nQ@l<;=!AV)5Ee_wX|v?zq#C)^UTg- z@-Va1^udy8-B90<1=ppp<)hCZpt%{z zjYb0a5kN^+a*|)HzdSvc5#zuM2bH8o@816e@8ILf$=-p_Vu!UQJ$7}(A^u$$<{>~b z62N)PR7uHOt1)Q8bd&&xJsbq3Y=m8br{ww#7jthgzO) P00000NkvXXu0mjfL=TV1 diff --git a/web/packages/teleport/src/Navigation/logoDark.svg b/web/packages/teleport/src/Navigation/logoDark.svg deleted file mode 100644 index 1ed6d944a3875..0000000000000 --- a/web/packages/teleport/src/Navigation/logoDark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/web/packages/teleport/src/Navigation/logoLight.svg b/web/packages/teleport/src/Navigation/logoLight.svg deleted file mode 100644 index 70dac68db813b..0000000000000 --- a/web/packages/teleport/src/Navigation/logoLight.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/web/packages/teleport/src/TopBar/logoDark.svg b/web/packages/teleport/src/TopBar/logoDark.svg deleted file mode 100644 index 1ed6d944a3875..0000000000000 --- a/web/packages/teleport/src/TopBar/logoDark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/web/packages/teleport/src/TopBar/logoLight.svg b/web/packages/teleport/src/TopBar/logoLight.svg deleted file mode 100644 index 70dac68db813b..0000000000000 --- a/web/packages/teleport/src/TopBar/logoLight.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/web/packages/teleport/webpack.dev.config.js b/web/packages/teleport/webpack.dev.config.js index 267709805099a..17b8e43e538d4 100644 --- a/web/packages/teleport/webpack.dev.config.js +++ b/web/packages/teleport/webpack.dev.config.js @@ -11,7 +11,7 @@ module.exports = { plugins: [ ...defaultDevConfig.plugins, configFactory.plugins.indexHtml({ - favicon: path.join(__dirname, '/src/favicon.ico'), + favicon: path.join(__dirname, '/src/favicon-light.png'), }), ], }; diff --git a/web/packages/teleport/webpack.prod.config.js b/web/packages/teleport/webpack.prod.config.js index 46aeb2a7d0afe..346dc67c3df9b 100644 --- a/web/packages/teleport/webpack.prod.config.js +++ b/web/packages/teleport/webpack.prod.config.js @@ -17,7 +17,7 @@ module.exports = { ...defaultProdConfig.plugins, new CleanWebpackPlugin(), configFactory.plugins.indexHtml({ - favicon: path.join(__dirname, '/src/favicon.ico'), + favicon: path.join(__dirname, '/src/favicon-light.png'), }), ], }; From f4ffdb9484582cfe2827e078fffe292d354538b9 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 20 Jun 2024 10:46:13 -0500 Subject: [PATCH 16/30] Update e (#43289) --- e | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e b/e index 7143c5860fd9a..4b953bd193b13 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit 7143c5860fd9af88b94d7976330bf8e6b631a737 +Subproject commit 4b953bd193b13c5b588d1cb4343bdfa10ea41239 From 46e1275df8b2f4852c35c6701e64e4d330fd1789 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:05:21 -0400 Subject: [PATCH 17/30] Move process storage to separate package (#43093) The auth state package contained both process state information and the backing storage used to persist the state. This turns out to be an expensive package for consumers that only care about state and not storage since it brings sqlite into the dependency tree. By splitting storage out to a separate package consumers it makes it possible to build client tools that don't require knowing about process storage to be built without cgo enabled. --- integration/hsm/hsm_test.go | 3 +- integration/instance_test.go | 6 +- lib/auth/init.go | 14 -- lib/auth/state/identity.go | 12 - lib/auth/state/state.go | 173 +------------- lib/auth/storage/storage.go | 215 ++++++++++++++++++ .../state_unix.go => storage/storage_unix.go} | 2 +- .../storage_windows.go} | 2 +- lib/service/service.go | 5 +- tool/tctl/common/admin_action_test.go | 3 +- tool/tctl/common/tctl.go | 3 +- tool/teleport/testenv/test_server.go | 3 +- 12 files changed, 234 insertions(+), 207 deletions(-) create mode 100644 lib/auth/storage/storage.go rename lib/auth/{state/state_unix.go => storage/storage_unix.go} (99%) rename lib/auth/{state/state_windows.go => storage/storage_windows.go} (98%) diff --git a/integration/hsm/hsm_test.go b/integration/hsm/hsm_test.go index 3ce91c7a845b4..f5556ad724595 100644 --- a/integration/hsm/hsm_test.go +++ b/integration/hsm/hsm_test.go @@ -39,6 +39,7 @@ import ( "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/keystore" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/backend/etcdbk" "github.com/gravitational/teleport/lib/backend/lite" @@ -181,7 +182,7 @@ func TestHSMRotation(t *testing.T) { } func getAdminClient(authDataDir string, authAddr string) (*authclient.Client, error) { - identity, err := state.ReadLocalIdentity( + identity, err := storage.ReadLocalIdentity( filepath.Join(authDataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin}) if err != nil { diff --git a/integration/instance_test.go b/integration/instance_test.go index 0c00c6ee4eb4b..baa7f4c79aaa0 100644 --- a/integration/instance_test.go +++ b/integration/instance_test.go @@ -33,7 +33,7 @@ import ( "github.com/gravitational/teleport/api/breaker" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib" - "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/cloud/imds" "github.com/gravitational/teleport/lib/defaults" @@ -141,7 +141,7 @@ func TestInstanceCertReissue(t *testing.T) { authCfg.InstanceMetadataClient = imds.NewDisabledIMDSClient() authRunErrCh := make(chan error, 1) - authIdentitiesCh := make(chan *auth.Identity, 2) + authIdentitiesCh := make(chan *state.Identity, 2) go func() { authRunErrCh <- service.Run(ctx, *authCfg, func(cfg *servicecfg.Config) (service.Process, error) { proc, err := service.NewTeleport(cfg) @@ -198,7 +198,7 @@ func TestInstanceCertReissue(t *testing.T) { agentCfg.InstanceMetadataClient = imds.NewDisabledIMDSClient() agentRunErrCh := make(chan error, 1) - agentIdentitiesCh := make(chan *auth.Identity, 2) + agentIdentitiesCh := make(chan *state.Identity, 2) go func() { agentRunErrCh <- service.Run(ctx, *agentCfg, func(cfg *servicecfg.Config) (service.Process, error) { proc, err := service.NewTeleport(cfg) diff --git a/lib/auth/init.go b/lib/auth/init.go index f11a5384b99f8..779b17bcb08f8 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -1117,20 +1117,6 @@ func checkResourceConsistency(ctx context.Context, keyStore *keystore.Manager, c return nil } -// Identity alias left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -type Identity = state.Identity - -// IdentityID alias left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -type IdentityID = state.IdentityID - -// ReadLocalIdentity left to prevent breaking builds -// TODO(tross): Delete after teleport.e is updated -func ReadLocalIdentity(dataDir string, id state.IdentityID) (*Identity, error) { - return state.ReadLocalIdentity(dataDir, id) -} - // GenerateIdentity generates identity for the auth server func GenerateIdentity(a *Server, id state.IdentityID, additionalPrincipals, dnsNames []string) (*state.Identity, error) { priv, pub, err := native.GenerateKeyPair() diff --git a/lib/auth/state/identity.go b/lib/auth/state/identity.go index 89cf0f84e8afe..e6b5ceb62adb9 100644 --- a/lib/auth/state/identity.go +++ b/lib/auth/state/identity.go @@ -17,7 +17,6 @@ package state import ( - "context" "crypto/tls" "crypto/x509" "fmt" @@ -338,14 +337,3 @@ func ReadSSHIdentityFromKeyPair(keyBytes, certBytes []byte) (*Identity, error) { Cert: cert, }, nil } - -// ReadLocalIdentity reads, parses and returns the given pub/pri key + cert from the -// key storage (dataDir). -func ReadLocalIdentity(dataDir string, id IdentityID) (*Identity, error) { - storage, err := NewProcessStorage(context.TODO(), dataDir) - if err != nil { - return nil, trace.Wrap(err) - } - defer storage.Close() - return storage.ReadIdentity(IdentityCurrent, id.Role) -} diff --git a/lib/auth/state/state.go b/lib/auth/state/state.go index 8a7807e99af71..aa2f7348d0b52 100644 --- a/lib/auth/state/state.go +++ b/lib/auth/state/state.go @@ -19,53 +19,12 @@ package state import ( - "context" - "encoding/json" - "strings" - "github.com/coreos/go-semver/semver" "github.com/gravitational/trace" - "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/lib/backend" - "github.com/gravitational/teleport/lib/utils" ) -// backend implements abstraction over local or remote storage backend methods -// required for Identity/State storage. -// As in backend.Backend, Item keys are assumed to be valid UTF8, which may be enforced by the -// various Backend implementations. -type stateBackend interface { - // Create creates item if it does not exist - Create(ctx context.Context, i backend.Item) (*backend.Lease, error) - // Put puts value into backend (creates if it does not - // exists, updates it otherwise) - Put(ctx context.Context, i backend.Item) (*backend.Lease, error) - // Get returns a single item or not found error - Get(ctx context.Context, key []byte) (*backend.Item, error) -} - -// ProcessStorage is a backend for local process state, -// it helps to manage rotation for certificate authorities -// and keeps local process credentials - x509 and SSH certs and keys. -type ProcessStorage struct { - // BackendStorage is the SQLite backend used for operations unrelated to storing/reading identities and states. - BackendStorage backend.Backend - - // stateStorage is the backend to store agents' identities and states. - // it is not required to close stateBackend storage because it's either the same as BackendStorage or it is Kubernetes - // which does not require any close method - stateStorage stateBackend -} - -// Close closes all resources used by process storage backend. -func (p *ProcessStorage) Close() error { - // we do not need to close stateBackend storage because it's either the same as backend or it's kubernetes - // which does not require any close method - return p.BackendStorage.Close() -} - const ( // IdentityCurrent is a name for the identity credentials that are // currently used by the process. @@ -75,134 +34,8 @@ const ( IdentityReplacement = "replacement" // stateName is an internal resource object name stateName = "state" - // statesPrefix is a key prefix for object states - statesPrefix = "states" - // idsPrefix is a key prefix for identities - idsPrefix = "ids" ) -// GetState reads rotation state from disk. -func (p *ProcessStorage) GetState(ctx context.Context, role types.SystemRole) (*StateV2, error) { - item, err := p.stateStorage.Get(ctx, backend.Key(statesPrefix, strings.ToLower(role.String()), stateName)) - if err != nil { - return nil, trace.Wrap(err) - } - var res StateV2 - if err := utils.FastUnmarshal(item.Value, &res); err != nil { - return nil, trace.BadParameter(err.Error()) - } - - // an empty InitialLocalVersion is treated as an error by CheckAndSetDefaults, but if the field - // is missing in the underlying storage, that indicates the state was written by an older version of - // teleport that didn't record InitialLocalVersion. In that case, we set a sentinel value to indicate - // that the version is unknown rather than being erroneously omitted. - if res.Spec.InitialLocalVersion == "" { - res.Spec.InitialLocalVersion = unknownLocalVersion - } - - if err := res.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - return &res, nil -} - -// CreateState creates process state if it does not exist yet. -func (p *ProcessStorage) CreateState(role types.SystemRole, state StateV2) error { - if err := state.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(state) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), - Value: value, - } - _, err = p.stateStorage.Create(context.TODO(), item) - if err != nil { - return trace.Wrap(err) - } - return nil -} - -// WriteState writes local cluster state to the backend. -func (p *ProcessStorage) WriteState(role types.SystemRole, state StateV2) error { - if err := state.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(state) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), - Value: value, - } - _, err = p.stateStorage.Put(context.TODO(), item) - if err != nil { - return trace.Wrap(err) - } - return nil -} - -// ReadIdentity reads identity using identity name and role. -func (p *ProcessStorage) ReadIdentity(name string, role types.SystemRole) (*Identity, error) { - if name == "" { - return nil, trace.BadParameter("missing parameter name") - } - item, err := p.stateStorage.Get(context.TODO(), backend.Key(idsPrefix, strings.ToLower(role.String()), name)) - if err != nil { - return nil, trace.Wrap(err) - } - var res IdentityV2 - if err := utils.FastUnmarshal(item.Value, &res); err != nil { - return nil, trace.BadParameter(err.Error()) - } - if err := res.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - return ReadIdentityFromKeyPair(res.Spec.Key, &proto.Certs{ - SSH: res.Spec.SSHCert, - TLS: res.Spec.TLSCert, - TLSCACerts: res.Spec.TLSCACerts, - SSHCACerts: res.Spec.SSHCACerts, - }) -} - -// WriteIdentity writes identity to the backend. -func (p *ProcessStorage) WriteIdentity(name string, id Identity) error { - res := IdentityV2{ - ResourceHeader: types.ResourceHeader{ - Kind: types.KindIdentity, - Version: types.V2, - Metadata: types.Metadata{ - Name: name, - }, - }, - Spec: IdentitySpecV2{ - Key: id.KeyBytes, - SSHCert: id.CertBytes, - TLSCert: id.TLSCertBytes, - TLSCACerts: id.TLSCACertsBytes, - SSHCACerts: id.SSHCACertBytes, - }, - } - if err := res.CheckAndSetDefaults(); err != nil { - return trace.Wrap(err) - } - value, err := json.Marshal(res) - if err != nil { - return trace.Wrap(err) - } - item := backend.Item{ - Key: backend.Key(idsPrefix, strings.ToLower(id.ID.Role.String()), name), - Value: value, - } - _, err = p.stateStorage.Put(context.TODO(), item) - return trace.Wrap(err) -} - // StateV2 is a local process state. type StateV2 struct { // ResourceHeader is a common resource header. @@ -214,7 +47,7 @@ type StateV2 struct { // GetInitialLocalVersion gets the initial local version string. If ok is false it indicates that // this state value was written by a teleport agent that was too old to record the initial local version. func (s *StateV2) GetInitialLocalVersion() (v string, ok bool) { - return s.Spec.InitialLocalVersion, s.Spec.InitialLocalVersion != unknownLocalVersion + return s.Spec.InitialLocalVersion, s.Spec.InitialLocalVersion != UnknownLocalVersion } // CheckAndSetDefaults checks and sets defaults values. @@ -242,10 +75,10 @@ func (s *StateV2) CheckAndSetDefaults() error { return nil } -// unknownVersion is a sentinel value used to distinguish between InitialLocalVersion being missing from +// UnknownVersion is a sentinel value used to distinguish between InitialLocalVersion being missing from // state due to malformed input and InitialLocalVersion being missing due to the state having been created before // teleport started recording InitialLocalVersion. -const unknownLocalVersion = "unknown" +const UnknownLocalVersion = "unknown" // StateSpecV2 is a state spec. type StateSpecV2 struct { diff --git a/lib/auth/storage/storage.go b/lib/auth/storage/storage.go new file mode 100644 index 0000000000000..2930760b66b49 --- /dev/null +++ b/lib/auth/storage/storage.go @@ -0,0 +1,215 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package storage provides a mechanism for interacting with +// the persisted state of a Teleport process. +// +// The state is either persisted locally on disk of the Teleport +// process via sqlite, or if running in Kubernetes, to a Kubernetes +// secret. Callers should take care when importing this package as +// it can cause dependency trees to expand rapidly and also requires +// that cgo is enbaled in order to leverage sqlite. +package storage + +import ( + "context" + "encoding/json" + "strings" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/utils" +) + +const ( + // stateName is an internal resource object name + stateName = "state" + // statesPrefix is a key prefix for object states + statesPrefix = "states" + // idsPrefix is a key prefix for identities + idsPrefix = "ids" +) + +// stateBackend implements abstraction over local or remote storage backend methods +// required for Identity/State storage. +// As in backend.Backend, Item keys are assumed to be valid UTF8, which may be enforced by the +// various Backend implementations. +type stateBackend interface { + // Create creates item if it does not exist + Create(ctx context.Context, i backend.Item) (*backend.Lease, error) + // Put puts value into backend (creates if it does not + // exists, updates it otherwise) + Put(ctx context.Context, i backend.Item) (*backend.Lease, error) + // Get returns a single item or not found error + Get(ctx context.Context, key []byte) (*backend.Item, error) +} + +// ProcessStorage is a backend for local process state, +// it helps to manage rotation for certificate authorities +// and keeps local process credentials - x509 and SSH certs and keys. +type ProcessStorage struct { + // BackendStorage is the SQLite backend used for operations unrelated to storing/reading identities and states. + BackendStorage backend.Backend + + // stateStorage is the backend to store agents' identities and states. + // it is not required to close stateBackend storage because it's either the same as BackendStorage or it is Kubernetes + // which does not require any close method + stateStorage stateBackend +} + +// Close closes all resources used by process storage backend. +func (p *ProcessStorage) Close() error { + // we do not need to close stateBackend storage because it's either the same as backend or it's kubernetes + // which does not require any close method + return p.BackendStorage.Close() +} + +// GetState reads rotation state from disk. +func (p *ProcessStorage) GetState(ctx context.Context, role types.SystemRole) (*state.StateV2, error) { + item, err := p.stateStorage.Get(ctx, backend.Key(statesPrefix, strings.ToLower(role.String()), stateName)) + if err != nil { + return nil, trace.Wrap(err) + } + var res state.StateV2 + if err := utils.FastUnmarshal(item.Value, &res); err != nil { + return nil, trace.BadParameter(err.Error()) + } + + // an empty InitialLocalVersion is treated as an error by CheckAndSetDefaults, but if the field + // is missing in the underlying storage, that indicates the state was written by an older version of + // teleport that didn't record InitialLocalVersion. In that case, we set a sentinel value to indicate + // that the version is unknown rather than being erroneously omitted. + if res.Spec.InitialLocalVersion == "" { + res.Spec.InitialLocalVersion = state.UnknownLocalVersion + } + + if err := res.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + return &res, nil +} + +// CreateState creates process state if it does not exist yet. +func (p *ProcessStorage) CreateState(role types.SystemRole, state state.StateV2) error { + if err := state.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(state) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), + Value: value, + } + _, err = p.stateStorage.Create(context.TODO(), item) + if err != nil { + return trace.Wrap(err) + } + return nil +} + +// WriteState writes local cluster state to the backend. +func (p *ProcessStorage) WriteState(role types.SystemRole, state state.StateV2) error { + if err := state.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(state) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(statesPrefix, strings.ToLower(role.String()), stateName), + Value: value, + } + _, err = p.stateStorage.Put(context.TODO(), item) + if err != nil { + return trace.Wrap(err) + } + return nil +} + +// ReadIdentity reads identity using identity name and role. +func (p *ProcessStorage) ReadIdentity(name string, role types.SystemRole) (*state.Identity, error) { + if name == "" { + return nil, trace.BadParameter("missing parameter name") + } + item, err := p.stateStorage.Get(context.TODO(), backend.Key(idsPrefix, strings.ToLower(role.String()), name)) + if err != nil { + return nil, trace.Wrap(err) + } + var res state.IdentityV2 + if err := utils.FastUnmarshal(item.Value, &res); err != nil { + return nil, trace.BadParameter(err.Error()) + } + if err := res.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + return state.ReadIdentityFromKeyPair(res.Spec.Key, &proto.Certs{ + SSH: res.Spec.SSHCert, + TLS: res.Spec.TLSCert, + TLSCACerts: res.Spec.TLSCACerts, + SSHCACerts: res.Spec.SSHCACerts, + }) +} + +// WriteIdentity writes identity to the backend. +func (p *ProcessStorage) WriteIdentity(name string, id state.Identity) error { + res := state.IdentityV2{ + ResourceHeader: types.ResourceHeader{ + Kind: types.KindIdentity, + Version: types.V2, + Metadata: types.Metadata{ + Name: name, + }, + }, + Spec: state.IdentitySpecV2{ + Key: id.KeyBytes, + SSHCert: id.CertBytes, + TLSCert: id.TLSCertBytes, + TLSCACerts: id.TLSCACertsBytes, + SSHCACerts: id.SSHCACertBytes, + }, + } + if err := res.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + value, err := json.Marshal(res) + if err != nil { + return trace.Wrap(err) + } + item := backend.Item{ + Key: backend.Key(idsPrefix, strings.ToLower(id.ID.Role.String()), name), + Value: value, + } + _, err = p.stateStorage.Put(context.TODO(), item) + return trace.Wrap(err) +} + +// ReadLocalIdentity reads, parses and returns the given pub/pri key + cert from the +// key storage (dataDir). +func ReadLocalIdentity(dataDir string, id state.IdentityID) (*state.Identity, error) { + storage, err := NewProcessStorage(context.TODO(), dataDir) + if err != nil { + return nil, trace.Wrap(err) + } + defer storage.Close() + return storage.ReadIdentity(state.IdentityCurrent, id.Role) +} diff --git a/lib/auth/state/state_unix.go b/lib/auth/storage/storage_unix.go similarity index 99% rename from lib/auth/state/state_unix.go rename to lib/auth/storage/storage_unix.go index 9ab1379d5b5ee..7bdc6a227b8c0 100644 --- a/lib/auth/state/state_unix.go +++ b/lib/auth/storage/storage_unix.go @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -package state +package storage import ( "context" diff --git a/lib/auth/state/state_windows.go b/lib/auth/storage/storage_windows.go similarity index 98% rename from lib/auth/state/state_windows.go rename to lib/auth/storage/storage_windows.go index a5246017ed1ee..3c262a2802199 100644 --- a/lib/auth/state/state_windows.go +++ b/lib/auth/storage/storage_windows.go @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -package state +package storage import ( "context" diff --git a/lib/service/service.go b/lib/service/service.go index 3ba187cfdb571..20458cd14770a 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -88,6 +88,7 @@ import ( "github.com/gravitational/teleport/lib/auth/keygen" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/authz" "github.com/gravitational/teleport/lib/automaticupgrades" "github.com/gravitational/teleport/lib/backend" @@ -405,7 +406,7 @@ type TeleportProcess struct { forkedTeleportCount atomic.Int32 // storage is a server local storage - storage *state.ProcessStorage + storage *storage.ProcessStorage // id is a process id - used to identify different processes // during in-process reloads. @@ -917,7 +918,7 @@ func NewTeleport(cfg *servicecfg.Config) (*TeleportProcess, error) { } supervisor := NewSupervisor(processID, cfg.Log) - storage, err := state.NewProcessStorage(supervisor.ExitContext(), filepath.Join(cfg.DataDir, teleport.ComponentProcess)) + storage, err := storage.NewProcessStorage(supervisor.ExitContext(), filepath.Join(cfg.DataDir, teleport.ComponentProcess)) if err != nil { return nil, trace.Wrap(err) } diff --git a/tool/tctl/common/admin_action_test.go b/tool/tctl/common/admin_action_test.go index 52ee2bcc9ad10..48d9bec14bdcc 100644 --- a/tool/tctl/common/admin_action_test.go +++ b/tool/tctl/common/admin_action_test.go @@ -45,6 +45,7 @@ import ( "github.com/gravitational/teleport/lib/auth/mocku2f" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" wancli "github.com/gravitational/teleport/lib/auth/webauthncli" wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" libclient "github.com/gravitational/teleport/lib/client" @@ -1065,7 +1066,7 @@ func newAdminActionTestSuite(t *testing.T) *adminActionTestSuite { hostUUID, err := utils.ReadHostUUID(process.Config.DataDir) require.NoError(t, err) - localAdmin, err := state.ReadLocalIdentity( + localAdmin, err := storage.ReadLocalIdentity( filepath.Join(process.Config.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: hostUUID}, ) diff --git a/tool/tctl/common/tctl.go b/tool/tctl/common/tctl.go index 4a4b502915001..24af9c1da1a24 100644 --- a/tool/tctl/common/tctl.go +++ b/tool/tctl/common/tctl.go @@ -42,6 +42,7 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/client/identityfile" libmfa "github.com/gravitational/teleport/lib/client/mfa" @@ -388,7 +389,7 @@ func ApplyConfig(ccf *GlobalCLIFlags, cfg *servicecfg.Config) (*authclient.Confi } return nil, trace.Wrap(err) } - identity, err := state.ReadLocalIdentity(filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: cfg.HostUUID}) + identity, err := storage.ReadLocalIdentity(filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: cfg.HostUUID}) if err != nil { // The "admin" identity is not present? This means the tctl is running // NOT on the auth server diff --git a/tool/teleport/testenv/test_server.go b/tool/teleport/testenv/test_server.go index 8160937529c15..aa479fa51dd41 100644 --- a/tool/teleport/testenv/test_server.go +++ b/tool/teleport/testenv/test_server.go @@ -49,6 +49,7 @@ import ( "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/native" "github.com/gravitational/teleport/lib/auth/state" + "github.com/gravitational/teleport/lib/auth/storage" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/cloud/imds" "github.com/gravitational/teleport/lib/defaults" @@ -653,7 +654,7 @@ func MakeDefaultAuthClient(t *testing.T, process *service.TeleportProcess) *auth hostUUID, err := utils.ReadHostUUID(process.Config.DataDir) require.NoError(t, err) - identity, err := state.ReadLocalIdentity( + identity, err := storage.ReadLocalIdentity( filepath.Join(cfg.DataDir, teleport.ComponentProcess), state.IdentityID{Role: types.RoleAdmin, HostUUID: hostUUID}, ) From b9bacef8b5e84f1c6cd2965047d1d36c741751c7 Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Thu, 20 Jun 2024 12:38:50 -0400 Subject: [PATCH 18/30] Fix docs markup errors (#43223) Co-authored-by: Alexey Ivanov --- docs/config.json | 17 +- docs/img/IBM/IBM_HA.svg | 213 +++++++++++++++++- .../access-request-plugins/servicenow.mdx | 2 +- .../access-controls/login-rules/guide.mdx | 2 +- docs/pages/access-controls/sso/okta.mdx | 2 +- .../cassandra-self-hosted.mdx | 2 +- .../clickhouse-self-hosted.mdx | 2 +- .../enroll-self-hosted-databases/redis.mdx | 2 +- .../management/admin/trustedclusters.mdx | 2 +- .../management/operations/db-ca-rotation.mdx | 4 +- docs/pages/reference/terraform-provider.mdx | 2 +- 11 files changed, 221 insertions(+), 29 deletions(-) diff --git a/docs/config.json b/docs/config.json index 97a7e871242c9..21e1bf16b3843 100644 --- a/docs/config.json +++ b/docs/config.json @@ -2561,16 +2561,6 @@ "destination": "/access-controls/device-trust/device-management/", "permanent": true }, - { - "source": "/management/guides/teleport-operator/", - "destination": "/management/dynamic-resources/teleport-operator/", - "permanent": true - }, - { - "source": "/management/guides/terraform-provider/", - "destination": "/management/dynamic-resources/terraform-provider/", - "permanent": true - }, { "source": "/get-started/", "destination": "/", @@ -2623,7 +2613,7 @@ }, { "source": "/machine-id/guides/", - "destination": "/machine-id/", + "destination": "/machine-id/introduction/", "permanent": true }, { @@ -2661,11 +2651,6 @@ "destination": "/machine-id/deployment/gitlab/", "permanent": true }, - { - "source": "/machine-id/guides/gitlab/", - "destination": "/machine-id/deployment/github-actions/", - "permanent": true - }, { "source": "/server-access/guides/openssh/", "destination": "/server-access/openssh/", diff --git a/docs/img/IBM/IBM_HA.svg b/docs/img/IBM/IBM_HA.svg index 2dde67c51c185..246d230c0b1d7 100644 --- a/docs/img/IBM/IBM_HA.svg +++ b/docs/img/IBM/IBM_HA.svg @@ -1,3 +1,210 @@ - - -
IBM Cloud
IBM Cloud
Teleport Proxy Autoscale Group
Teleport Proxy Aut...
IBM Cloud Virtual Server
IBM Cloud Virtual...
Teleport Auth
Autoscale Group
Teleport Auth...
IBM Cloud Virtual Server
IBM Cloud Virtual...
VPC
VPC
Instances
Instances
One Teleport cluster can support 10,000 nodes. See Teleport Node setup for more info. 
One Teleport cluster c...
IBM Object Store
IBM Object Store
IBM Database for etcd
IBM Database for etcd
Client
Client
End user using Teleport
Client Tool tsh
End user using T...
SSO Provider
SSO Provider
\ No newline at end of file + + + + + +
+
+
+ IBM Cloud +
+
+
+
+ IBM Cloud +
+ + + + +
+
+
+ + Teleport Proxy Autoscale Group + +
+
+
+
+ Teleport Proxy Aut... +
+ + + + +
+
+
+ IBM Cloud Virtual Server +
+
+
+
+ IBM Cloud Virtual... +
+ + + + + + + +
+
+
+ + Teleport Auth +
+ Autoscale Group +
+
+
+
+
+ Teleport Auth... +
+ + + + +
+
+
+ IBM Cloud Virtual Server +
+
+
+
+ IBM Cloud Virtual... +
+ + + +
+
+
+ VPC +
+
+
+
+ VPC +
+ + + + + +
+
+
+ Instances +
+
+
+
+ Instances +
+ + +
+
+
+ + + One Teleport cluster can support + + + 10,000 nodes. See Teleport Node + + + setup for more info. + + +
+
+
+
+ One Teleport cluster c... +
+ + +
+
+
+ IBM Object Store +
+
+
+
+ IBM Object Store +
+ + + +
+
+
+ IBM Database for etcd +
+
+
+
+ IBM Database for etcd +
+ + + + + + + + + + + + + +
+
+
+ Client +
+
+
+
+ Client +
+ + +
+
+
+ End user using Teleport +
+ Client Tool + + tsh + +
+
+
+
+ End user using T... +
+ + +
+
+
+ SSO Provider +
+
+
+
+ SSO Provider +
+ + +
diff --git a/docs/pages/access-controls/access-request-plugins/servicenow.mdx b/docs/pages/access-controls/access-request-plugins/servicenow.mdx index 69994671274da..af67354e83fe0 100644 --- a/docs/pages/access-controls/access-request-plugins/servicenow.mdx +++ b/docs/pages/access-controls/access-request-plugins/servicenow.mdx @@ -62,7 +62,7 @@ To retrieve the ServiceNow rotation ID, navigate to the group record of the ServiceNow group the rotation belongs to and right click on header, then click 'Select copy sys_id' to copy the ID. -Then using the ServiceNow endpoint '/api/now/on_call_rota/workbench/group/{groupSysId}' +Then using the ServiceNow endpoint `/api/now/on_call_rota/workbench/group/{groupSysId}` retrieve the group's on-call rota information. Select the value of the desired 'rota' from the response. diff --git a/docs/pages/access-controls/login-rules/guide.mdx b/docs/pages/access-controls/login-rules/guide.mdx index 2968d502ebd7b..9fee51b16b766 100644 --- a/docs/pages/access-controls/login-rules/guide.mdx +++ b/docs/pages/access-controls/login-rules/guide.mdx @@ -17,7 +17,7 @@ cluster on version `11.3.1` or greater. Login Rules only operate on SSO logins, so make sure you have configured an OIDC, SAML, or GitHub connector before you begin. -Check the [Single Sign-On](../sso/) docs to learn how to set this up. +Check the [Single Sign-On](../sso.mdx) docs to learn how to set this up. ## Step 1/5. Configure RBAC diff --git a/docs/pages/access-controls/sso/okta.mdx b/docs/pages/access-controls/sso/okta.mdx index dbe91b355f5a7..3840d2488816d 100644 --- a/docs/pages/access-controls/sso/okta.mdx +++ b/docs/pages/access-controls/sso/okta.mdx @@ -18,7 +18,7 @@ Teleport administrators to define policies like: In Teleport Enterprise Cloud and Self-Hosted Teleport Enterprise, Teleport can automatically configure an SSO connector for you when as part of [enrolling the -hosted Okta integration](../../). +hosted Okta integration](../../index.mdx). You can enroll the Okta integration from the Teleport Web UI. diff --git a/docs/pages/database-access/enroll-self-hosted-databases/cassandra-self-hosted.mdx b/docs/pages/database-access/enroll-self-hosted-databases/cassandra-self-hosted.mdx index fafd373c64624..b825c7199ddef 100644 --- a/docs/pages/database-access/enroll-self-hosted-databases/cassandra-self-hosted.mdx +++ b/docs/pages/database-access/enroll-self-hosted-databases/cassandra-self-hosted.mdx @@ -85,7 +85,7 @@ for Cassandra, rather than the Teleport database client CA, discard ### Scylla -(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx dbName="Scylla" format="scylla" !) +(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx dbname="Scylla" format="scylla" !) ## Step 4/5. Configure Cassandra/Scylla diff --git a/docs/pages/database-access/enroll-self-hosted-databases/clickhouse-self-hosted.mdx b/docs/pages/database-access/enroll-self-hosted-databases/clickhouse-self-hosted.mdx index 9c66231dfdbb3..5235289a98c58 100644 --- a/docs/pages/database-access/enroll-self-hosted-databases/clickhouse-self-hosted.mdx +++ b/docs/pages/database-access/enroll-self-hosted-databases/clickhouse-self-hosted.mdx @@ -64,7 +64,7 @@ choose: ## Step 2/5. Create a certificate/key pair -(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx!) +(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx dbname="Clickhouse" !) ## Step 3/5. Configure ClickHouse diff --git a/docs/pages/database-access/enroll-self-hosted-databases/redis.mdx b/docs/pages/database-access/enroll-self-hosted-databases/redis.mdx index 01c966ccb7b66..284daf6768057 100644 --- a/docs/pages/database-access/enroll-self-hosted-databases/redis.mdx +++ b/docs/pages/database-access/enroll-self-hosted-databases/redis.mdx @@ -77,7 +77,7 @@ Install and configure Teleport where you will run the Teleport Database Service: ## Step 4/5. Set up mutual TLS -(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx format="redis" dbName="Redis" !) +(!docs/pages/includes/database-access/tctl-auth-sign-3-files.mdx format="redis" dbname="Redis" !) You will need these files to enable mutual TLS on your Redis server. diff --git a/docs/pages/management/admin/trustedclusters.mdx b/docs/pages/management/admin/trustedclusters.mdx index 192f70069d89f..adcf5ef15f131 100644 --- a/docs/pages/management/admin/trustedclusters.mdx +++ b/docs/pages/management/admin/trustedclusters.mdx @@ -106,7 +106,7 @@ configured with a single sign-on identity provider that authenticates her identi Based on the information from the identity provider, the root cluster assigns Alice the `full-access` role and issues her a certificate. The mapping of single sign-on properties to Teleport roles is configured when you add an authentication connector to the Teleport cluster. To learn more about configuring single sign-on -through an external identity provider, see [Configure Single Sign-on](../../access-controls/sso). +through an external identity provider, see [Configure Single Sign-on](../../access-controls/sso.mdx). Alice receives the certificate that specifies the roles assigned to her in the root cluster. This metadata about her roles is contained in the certificate extensions and is protected by the signature of the root diff --git a/docs/pages/management/operations/db-ca-rotation.mdx b/docs/pages/management/operations/db-ca-rotation.mdx index 4a8f1692fef50..26c48bb514676 100644 --- a/docs/pages/management/operations/db-ca-rotation.mdx +++ b/docs/pages/management/operations/db-ca-rotation.mdx @@ -128,7 +128,7 @@ You do not need to reconfigure databases at this point if you are rotating only the `db` CA, although there is no harm in doing so. Consult the appropriate -[Teleport Database Access Guide](../../database-access/guides) for your +[Teleport Database Access Guide](../../database-access/guides.mdx) for your databases before proceeding to the `update_clients` rotation phase. @@ -172,7 +172,7 @@ lose access** to those databases after transitioning to the `standby` phase in this final step. To avoid down time, consult the appropriate -[Teleport Database Access Guide](../../database-access/guides) and reconfigure +[Teleport Database Access Guide](../../database-access/guides.mdx) and reconfigure your databases before proceeding. Otherwise, access may still be restored by reconfiguring your self-hosted databases after this step. diff --git a/docs/pages/reference/terraform-provider.mdx b/docs/pages/reference/terraform-provider.mdx index 680d34469b66b..351431d627b44 100644 --- a/docs/pages/reference/terraform-provider.mdx +++ b/docs/pages/reference/terraform-provider.mdx @@ -1512,7 +1512,7 @@ Allow is a list of TokenRules, nodes using this token must match one allow rule | ref | string | | Ref allows access to be limited to jobs triggered by a specific git ref. Ensure this is used in combination with ref_type. This field supports simple "glob-style" matching: - Use '*' to match zero or more characters. - Use '?' to match any single character. | | ref_protected | bool | | | | ref_type | string | | RefType allows access to be limited to jobs triggered by a specific git ref type. Example: `branch` or `tag` | -| sub | string | | Sub roughly uniquely identifies the workload. Example: `project_path:mygroup/my-project:ref_type:branch:ref:main` project_path:{group}/{project}:ref_type:{type}:ref:{branch_name} This field supports simple "glob-style" matching: - Use '*' to match zero or more characters. - Use '?' to match any single character. | +| sub | string | | Sub roughly uniquely identifies the workload. Example: `project_path:mygroup/my-project:ref_type:branch:ref:main project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}` This field supports simple "glob-style" matching: - Use '*' to match zero or more characters. - Use '?' to match any single character. | | user_email | string | | UserEmail is the email of the user executing the job | | user_id | string | | UserID is the ID of the user executing the job | | user_login | string | | UserLogin is the username of the user executing the job | From deac28ff9025736d48545b2130471dfb3ff87400 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 20 Jun 2024 14:01:48 -0300 Subject: [PATCH 19/30] Document recent libfido2 Makefile changes (#43296) --- README.md | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 30a3c3d3cf75c..d3f9371139dcf 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,8 @@ Ensure you have installed correct versions of necessary dependencies: `Rust` and `Cargo` versions in [build.assets/Makefile](https://github.com/gravitational/teleport/blob/master/build.assets/Makefile#L21) (search for `RUST_VERSION`) -* For `tsh` version > `10.x` with FIDO support, you will need `libfido` and `openssl 1.1` installed locally +* For `tsh` version > `10.x` with FIDO2 support, you will need `libfido2` and + `pkg-config` installed locally * To build the web UI: * [`yarn`](https://classic.yarnpkg.com/en/docs/install)(< 2.0.0) is required. * If you prefer not to install/use yarn, but have docker available, you can run `make docker-ui` instead. @@ -195,18 +196,26 @@ maintainer, ask the team for access. make build/tsh TOUCHID=yes ``` -To build `tsh` with `libfido`: +`tsh` dynamically links against libfido2 by default, to support development +environments, as long as the library itself can be found: - ```shell - make build/tsh FIDO2=dynamic - ``` +```shell +$ brew install libfido2 pkg-config # Replace with your package manager of choice - * On a Mac, with `libfido` and `openssl 3` installed via `homebrew` +$ make build/tsh +> libfido2 found, setting FIDO2=dynamic +> (...) +``` - ```shell - export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig" - make build/tsh FIDO2=dynamic - ``` +Release binaries are linked statically against libfido2. You may switch the +linking mode using the FIDO2 variable: + +```shell +make build/tsh FIDO2=dynamic # dynamic linking +make build/tsh FIDO2=static # static linking, for an easy setup use `make enter` + # or `build.assets/macos/build-fido2-macos.sh`. +make build/tsh FIDO2=off # doesn't link libfido2 in any way +``` #### Build output and run locally @@ -405,4 +414,4 @@ The remainder of the source code in this repository is available under the from source must comply with the terms of this license. Teleport Community Edition builds distributed on http://goteleport.com/download -are available under a [modified Apache 2.0 license](./LICENSE-community). \ No newline at end of file +are available under a [modified Apache 2.0 license](./LICENSE-community). From 894dcccbb0a2046293de7d85084fc18ea402a940 Mon Sep 17 00:00:00 2001 From: Bartosz Leper Date: Thu, 20 Jun 2024 19:18:32 +0200 Subject: [PATCH 20/30] Add a FieldCheckbox component (#43171) * Add a FieldCheckbox component Also use it wherever applicable * Add licenses --- web/packages/design/src/Checkbox/Checkbox.tsx | 39 ++++---- web/packages/design/src/Checkbox/index.ts | 7 +- web/packages/design/src/theme/typography.js | 20 ++++ .../RequestCheckout/RequestCheckout.tsx | 72 +++++++++----- .../FieldCheckbox/FieldCheckbox.story.tsx | 66 +++++++++++++ .../FieldCheckbox/FieldCheckbox.test.tsx | 74 ++++++++++++++ .../FieldCheckbox/FieldCheckbox.tsx | 97 +++++++++++++++++++ .../shared/components/FieldCheckbox/index.ts | 19 ++++ .../SecurityGroupPicker.tsx | 5 +- .../EditAwsOidcIntegrationDialog.test.tsx | 16 +-- .../EditAwsOidcIntegrationDialog.tsx | 24 ++--- web/packages/teleport/src/Login/Login.tsx | 41 ++++---- 12 files changed, 393 insertions(+), 87 deletions(-) create mode 100644 web/packages/shared/components/FieldCheckbox/FieldCheckbox.story.tsx create mode 100644 web/packages/shared/components/FieldCheckbox/FieldCheckbox.test.tsx create mode 100644 web/packages/shared/components/FieldCheckbox/FieldCheckbox.tsx create mode 100644 web/packages/shared/components/FieldCheckbox/index.ts diff --git a/web/packages/design/src/Checkbox/Checkbox.tsx b/web/packages/design/src/Checkbox/Checkbox.tsx index fb6b5f458a3f7..447fe38911c83 100644 --- a/web/packages/design/src/Checkbox/Checkbox.tsx +++ b/web/packages/design/src/Checkbox/Checkbox.tsx @@ -18,7 +18,7 @@ import styled from 'styled-components'; -import React from 'react'; +import React, { forwardRef } from 'react'; import { Flex } from 'design'; import { space } from 'design/system'; @@ -52,7 +52,7 @@ export const CheckboxInput = styled.input` ${space} `; -type CheckboxSize = 'large' | 'small'; +export type CheckboxSize = 'large' | 'small'; interface StyledCheckboxProps { size?: CheckboxSize; @@ -79,27 +79,28 @@ interface StyledCheckboxProps { onChange?: (e: React.ChangeEvent) => void; } -// TODO (bl-nero): Make this the default checkbox -export function StyledCheckbox(props: StyledCheckboxProps) { - const { style, className, size, ...inputProps } = props; - return ( - // The outer wrapper and inner wrapper are separate to allow using - // positioning CSS attributes on the checkbox while still maintaining its - // internal integrity that requires the internal wrapper to be positioned. - - - {/* The checkbox is rendered as two items placed on top of each other: +export const StyledCheckbox = forwardRef( + (props, ref) => { + const { style, className, size, ...inputProps } = props; + return ( + // The outer wrapper and inner wrapper are separate to allow using + // positioning CSS attributes on the checkbox while still maintaining its + // internal integrity that requires the internal wrapper to be positioned. + + + {/* The checkbox is rendered as two items placed on top of each other: the actual checkbox, which is a native input control, and an SVG checkmark. Note that we avoid the usual "label with content" trick, because we want to be able to use this component both with and without surrounding labels. Instead, we use absolute positioning and an actually rendered input with a custom appearance. */} - - - - - ); -} + + + + + ); + } +); const OuterWrapper = styled.span` line-height: 0; @@ -132,7 +133,7 @@ const Checkmark = styled(Icon.CheckThick)` } `; -export const StyledCheckboxInternal = styled.input.attrs(props => ({ +const CheckboxInternal = styled.input.attrs(props => ({ // TODO(bl-nero): Make radio buttons a separate control. type: props.type || 'checkbox', }))` diff --git a/web/packages/design/src/Checkbox/index.ts b/web/packages/design/src/Checkbox/index.ts index e6b2994f0c59e..cf3e1d5328311 100644 --- a/web/packages/design/src/Checkbox/index.ts +++ b/web/packages/design/src/Checkbox/index.ts @@ -16,4 +16,9 @@ * along with this program. If not, see . */ -export { CheckboxInput, CheckboxWrapper, StyledCheckbox } from './Checkbox'; +export { + CheckboxInput, + CheckboxWrapper, + StyledCheckbox, + type CheckboxSize, +} from './Checkbox'; diff --git a/web/packages/design/src/theme/typography.js b/web/packages/design/src/theme/typography.js index 30b5a3f79946e..138510a1c933f 100644 --- a/web/packages/design/src/theme/typography.js +++ b/web/packages/design/src/theme/typography.js @@ -101,6 +101,26 @@ const typography = { fontSize: '14px', lineHeight: '20px', }, + + // TODO(bl-nero): Migrate everything to the new typography. + newBody1: { + fontSize: '16px', + fontWeight: light, + lineHeight: '24px', + letterSpacing: '0.08px', + }, + newBody2: { + fontSize: '14px', + fontWeight: light, + lineHeight: '20px', + letterSpacing: '0.035px', + }, + newBody3: { + fontSize: '12px', + fontWeight: regular, + lineHeight: '20px', + letterSpacing: '0.015px', + }, }; export default typography; diff --git a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx index 63299daa76617..0d6e576505858 100644 --- a/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx +++ b/web/packages/shared/components/AccessRequests/NewRequest/RequestCheckout/RequestCheckout.tsx @@ -38,7 +38,6 @@ import { Cross, } from 'design/Icon'; import Table, { Cell } from 'design/DataTable'; -import { CheckboxInput, CheckboxWrapper } from 'design/Checkbox'; import { Danger } from 'design/Alert'; import Validation, { useRule, Validator } from 'shared/components/Validation'; @@ -46,6 +45,8 @@ import { Attempt } from 'shared/hooks/useAttemptNext'; import { pluralize } from 'shared/utils/text'; import { Option } from 'shared/components/Select'; +import { FieldCheckbox } from 'shared/components/FieldCheckbox'; + import { CreateRequest } from '../../Shared/types'; import { AssumeStartTime } from '../../AssumeStartTime/AssumeStartTime'; import { AccessDurationRequest } from '../../AccessDuration'; @@ -521,34 +522,20 @@ function ResourceRequestRoles({ {fetchAttempt.status === 'success' && expanded && ( {roles.map((roleName, index) => { - const id = `${roleName}${index}`; + const checked = selectedRoles.includes(roleName); return ( - theme.colors.levels.surface}; - - &:hover { - border-color: ${({ theme }) => - theme.colors.levels.elevated}; - } - `} - as="label" - htmlFor={id} - > - + { onInputChange(roleName, e); }} - checked={selectedRoles.includes(roleName)} + checked={checked} + label={roleName} + size="small" /> - {roleName} - + ); })} {selectedRoles.length < roles.length && ( @@ -577,6 +564,45 @@ function ResourceRequestRoles({ ); } +const RoleRowContainer = styled.div<{ checked?: boolean }>` + transition: all 150ms; + position: relative; + + // TODO(bl-nero): That's the third place where we're copying these + // definitions. We need to make them reusable. + :hover { + background-color: ${props => props.theme.colors.levels.surface}; + + // We use a pseudo element for the shadow with position: absolute in order to prevent + // the shadow from increasing the size of the layout and causing scrollbar flicker. + :after { + box-shadow: ${props => props.theme.boxShadow[3]}; + content: ''; + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + } + } +`; + +const StyledFieldCheckbox = styled(FieldCheckbox)` + margin: 0; + padding: ${p => p.theme.space[2]}px; + background-color: ${props => + props.checked + ? props.theme.colors.interactive.tonal.primary[2] + : 'transparent'}; + border-bottom: ${props => props.theme.borders[2]} + ${props => props.theme.colors.interactive.tonal.neutral[0]}; + + & > label { + display: block; // make it full-width + } +`; + function TextBox({ reason, updateReason, diff --git a/web/packages/shared/components/FieldCheckbox/FieldCheckbox.story.tsx b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.story.tsx new file mode 100644 index 0000000000000..fd646a956a7e2 --- /dev/null +++ b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.story.tsx @@ -0,0 +1,66 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React from 'react'; + +import Box from 'design/Box'; + +import { FieldCheckbox } from '.'; + +export default { + title: 'Shared', +}; + +export const FieldCheckboxStory = () => ( + + + + + + + + + + +); + +FieldCheckboxStory.storyName = 'FieldCheckbox'; diff --git a/web/packages/shared/components/FieldCheckbox/FieldCheckbox.test.tsx b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.test.tsx new file mode 100644 index 0000000000000..603db29bb0961 --- /dev/null +++ b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.test.tsx @@ -0,0 +1,74 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { render, screen, userEvent } from 'design/utils/testing'; +import React, { useRef, useState } from 'react'; + +import { FieldCheckbox } from './FieldCheckbox'; + +test('controlled flow', async () => { + const onChange = jest.fn(); + + function TestField() { + const [checked, setChecked] = useState(false); + function onCbChange(e: React.ChangeEvent) { + const c = e.currentTarget.checked; + setChecked(c); + onChange(c); + } + return ( + + ); + } + + const user = userEvent.setup(); + render(); + + await user.click(screen.getByLabelText('I agree')); + expect(screen.getByLabelText('I agree')).toBeChecked(); + expect(onChange).toHaveBeenLastCalledWith(true); + + await user.click(screen.getByLabelText('I agree')); + expect(screen.getByLabelText('I agree')).not.toBeChecked(); + expect(onChange).toHaveBeenLastCalledWith(false); +}); + +test('uncontrolled flow', async () => { + let checkboxRef; + function TestForm() { + const cbRefInternal = useRef(); + checkboxRef = cbRefInternal; + return ( +
+ + + ); + } + + const user = userEvent.setup(); + render(); + expect(screen.getByTestId('form')).toHaveFormValues({}); + + await user.click(screen.getByLabelText('Make it so')); + expect(screen.getByTestId('form')).toHaveFormValues({ ack: true }); + expect(checkboxRef.current.checked).toBe(true); + + await user.click(screen.getByLabelText('Make it so')); + expect(screen.getByTestId('form')).toHaveFormValues({}); + expect(checkboxRef.current.checked).toBe(false); +}); diff --git a/web/packages/shared/components/FieldCheckbox/FieldCheckbox.tsx b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.tsx new file mode 100644 index 0000000000000..d6f3112f5b321 --- /dev/null +++ b/web/packages/shared/components/FieldCheckbox/FieldCheckbox.tsx @@ -0,0 +1,97 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import Box from 'design/Box'; +import { CheckboxSize, StyledCheckbox } from 'design/Checkbox'; +import Flex from 'design/Flex'; +import LabelInput from 'design/LabelInput'; +import Text from 'design/Text'; +import { SpaceProps } from 'design/system'; +import React, { forwardRef } from 'react'; +import styled from 'styled-components'; + +interface FieldCheckboxProps extends SpaceProps { + name?: string; + label?: React.ReactNode; + helperText?: React.ReactNode; + checked?: boolean; + defaultChecked?: boolean; + disabled?: boolean; + size?: CheckboxSize; + onChange?: (e: React.ChangeEvent) => void; +} + +/** Renders a checkbox with an associated label and an optional helper text. */ +export const FieldCheckbox = forwardRef( + ( + { + name, + label, + helperText, + checked, + defaultChecked, + disabled, + size, + onChange, + ...styles + }, + ref + ) => { + const labelColor = disabled ? 'text.disabled' : 'text.main'; + const helperColor = disabled ? 'text.disabled' : 'text.slightlyMuted'; + const labelTypography = size === 'small' ? 'newBody2' : 'newBody1'; + const helperTypography = size === 'small' ? 'newBody3' : 'newBody2'; + return ( + + + + + + + {label} + + + {helperText} + + + + + + ); + } +); + +const StyledLabel = styled(LabelInput)<{ disabled?: boolean }>` + // Typically, a short label in a wide container means a lot of whitespace that + // acts as a click target for a checkbox. To avoid this, we use inline-flex to + // wrap the label around its content. + display: inline-flex; + width: auto; + gap: ${props => props.theme.space[2]}px; + margin-bottom: 0; + line-height: 0; + cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; +`; diff --git a/web/packages/shared/components/FieldCheckbox/index.ts b/web/packages/shared/components/FieldCheckbox/index.ts new file mode 100644 index 0000000000000..42ddb445487f9 --- /dev/null +++ b/web/packages/shared/components/FieldCheckbox/index.ts @@ -0,0 +1,19 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +export { FieldCheckbox } from './FieldCheckbox'; diff --git a/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx b/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx index 009824e058d12..e02a94a86d5bf 100644 --- a/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx +++ b/web/packages/teleport/src/Discover/Shared/SecurityGroupPicker/SecurityGroupPicker.tsx @@ -21,7 +21,7 @@ import React, { useState } from 'react'; import { Flex, Link } from 'design'; import Table, { Cell } from 'design/DataTable'; import { Danger } from 'design/Alert'; -import { CheckboxInput } from 'design/Checkbox'; +import { StyledCheckbox } from 'design/Checkbox'; import { FetchStatus } from 'design/DataTable/types'; import { Attempt } from 'shared/hooks/useAttemptNext'; @@ -165,8 +165,7 @@ function CheckboxCell({ return ( - { onChange(item, e); diff --git a/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.test.tsx b/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.test.tsx index 7339646b588af..2b4bd61998c36 100644 --- a/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.test.tsx +++ b/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.test.tsx @@ -47,7 +47,7 @@ test('user acknowledging script was ran when s3 bucket fields are edited', async // Initial state. expect(screen.queryByTestId('scriptbox')).not.toBeInTheDocument(); - expect(screen.queryByTestId('checkbox')).not.toBeInTheDocument(); + expect(screen.queryByLabelText(/I ran the command/i)).not.toBeInTheDocument(); expect( screen.queryByRole('button', { name: /generate command/i }) ).not.toBeInTheDocument(); @@ -73,7 +73,7 @@ test('user acknowledging script was ran when s3 bucket fields are edited', async expect( screen.queryByRole('button', { name: /generate command/i }) ).not.toBeInTheDocument(); - expect(screen.getByTestId('checkbox')).toBeInTheDocument(); + expect(screen.getByLabelText(/I ran the command/i)).toBeInTheDocument(); expect(screen.getByTestId('scriptbox')).toBeInTheDocument(); // Click on checkbox should enable save button and disable edit button. @@ -120,7 +120,7 @@ test('render warning on save when leaving s3 fields empty', async () => { // Initial state. expect(screen.queryByTestId('scriptbox')).not.toBeInTheDocument(); - expect(screen.queryByTestId('checkbox')).not.toBeInTheDocument(); + expect(screen.queryByLabelText(/I ran the command/i)).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: /save/i })).toBeDisabled(); expect( screen.queryByRole('button', { name: /generate command/i }) @@ -136,14 +136,14 @@ test('render warning on save when leaving s3 fields empty', async () => { ).toBeEnabled() ); - expect(screen.queryByTestId('checkbox')).not.toBeInTheDocument(); + expect(screen.queryByLabelText(/I ran the command/i)).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: /save/i })).toBeDisabled(); userEvent.click(screen.getByRole('button', { name: /generate command/i })); await screen.findByRole('button', { name: /edit/i }); expect(screen.getByRole('button', { name: /save/i })).toBeDisabled(); - userEvent.click(screen.getByTestId('checkbox')); + userEvent.click(screen.getByLabelText(/I ran the command/i)); await waitFor(() => expect(screen.getByRole('button', { name: /save/i })).toBeEnabled() ); @@ -202,14 +202,14 @@ test('render warning on save when deleting existing s3 fields', async () => { ).toBeEnabled() ); - expect(screen.queryByTestId('checkbox')).not.toBeInTheDocument(); + expect(screen.queryByLabelText(/I ran the command/i)).not.toBeInTheDocument(); expect(screen.getByRole('button', { name: /save/i })).toBeDisabled(); userEvent.click(screen.getByRole('button', { name: /generate command/i })); await screen.findByRole('button', { name: /edit/i }); expect(screen.getByRole('button', { name: /save/i })).toBeDisabled(); - userEvent.click(screen.getByTestId('checkbox')); + userEvent.click(screen.getByLabelText(/I ran the command/i)); await waitFor(() => expect(screen.getByRole('button', { name: /save/i })).toBeEnabled() ); @@ -286,7 +286,7 @@ test('edit submit called with proper fields', async () => { userEvent.click(screen.getByRole('button', { name: /generate command/i })); await screen.findByRole('button', { name: /edit/i }); - userEvent.click(screen.getByTestId('checkbox')); + userEvent.click(screen.getByLabelText(/I ran the command/i)); await waitFor(() => expect(screen.getByRole('button', { name: /save/i })).toBeEnabled() ); diff --git a/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.tsx b/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.tsx index e5b0dd47c0ece..35a3dfd1c0dec 100644 --- a/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.tsx +++ b/web/packages/teleport/src/Integrations/EditAwsOidcIntegrationDialog.tsx @@ -37,9 +37,10 @@ import useAttempt from 'shared/hooks/useAttemptNext'; import FieldInput from 'shared/components/FieldInput'; import Validation, { Validator } from 'shared/components/Validation'; import { requiredRoleArn } from 'shared/components/Validation/rules'; -import { CheckboxInput } from 'design/Checkbox'; import { TextSelectCopyMulti } from 'shared/components/TextSelectCopy'; +import { FieldCheckbox } from 'shared/components/FieldCheckbox'; + import { Integration } from 'teleport/services/integrations'; import cfg from 'teleport/config'; import { splitAwsIamArn } from 'teleport/services/integrations/aws'; @@ -207,19 +208,14 @@ export function EditAwsOidcIntegrationDialog(props: Props) { {showGenerateCommand && scriptUrl && ( - - { - setConfirmed(e.target.checked); - }} - /> - I ran the command - + { + setConfirmed(e.target.checked); + }} + /> )} {requiresS3BucketWarning && showS3BucketWarning ? ( diff --git a/web/packages/teleport/src/Login/Login.tsx b/web/packages/teleport/src/Login/Login.tsx index 5c51d1a1bac1d..555552ce23e11 100644 --- a/web/packages/teleport/src/Login/Login.tsx +++ b/web/packages/teleport/src/Login/Login.tsx @@ -20,7 +20,8 @@ import React, { useState } from 'react'; import styled from 'styled-components'; import { Box, Text, Link, Flex, ButtonPrimary } from 'design'; -import { StyledCheckbox } from 'design/Checkbox'; + +import { FieldCheckbox } from 'shared/components/FieldCheckbox'; import FormLogin from 'teleport/components/FormLogin'; import { LogoHero } from 'teleport/components/LogoHero'; @@ -124,24 +125,26 @@ function LicenseAcknowledgement({ {' '} to evaluate and use Teleport. - - { - setChecked(e.target.checked); - }} - /> - - By clicking continue, you agree to our{' '} - - Terms and Conditions - - . - - + { + setChecked(e.target.checked); + }} + label={ + <> + By clicking continue, you agree to our{' '} + + Terms and Conditions + + . + + } + /> { From f7e61ccff345f51246dede2a4cb03d5725e56f46 Mon Sep 17 00:00:00 2001 From: rosstimothy <39066650+rosstimothy@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:18:46 -0400 Subject: [PATCH 21/30] Update e ref (#43299) --- e | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e b/e index 4b953bd193b13..c5df1808fe98e 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit 4b953bd193b13c5b588d1cb4343bdfa10ea41239 +Subproject commit c5df1808fe98eb5718070e372308d0b3234f70bc From 2690c76160aa973f22a1d803398dca93afbd8a63 Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Thu, 20 Jun 2024 14:44:52 -0400 Subject: [PATCH 22/30] Remove Node mentions from architecture guides (#42566) Closes #13364 Update mentions of Teleport Nodes, which are outdated, to reflect our new terminology. --- docs/pages/architecture/authentication.mdx | 6 +++--- docs/pages/architecture/authorization.mdx | 2 +- docs/pages/architecture/introduction.mdx | 1 - docs/pages/architecture/session-recording.mdx | 7 ++++--- docs/pages/architecture/trustedclusters.mdx | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/pages/architecture/authentication.mdx b/docs/pages/architecture/authentication.mdx index 39e6ab5a3c61b..4fbf3ec086b34 100644 --- a/docs/pages/architecture/authentication.mdx +++ b/docs/pages/architecture/authentication.mdx @@ -141,8 +141,8 @@ services and rotates SSH and X.509 certificates. ### Internal certificates -Teleport internal services - Auth, Proxy and Nodes use certificates to identify themselves -within a cluster. To join proxies and nodes to the cluster and receive certificates, admins should use +Teleport internal services - the Auth Service, Proxy Service, Agents, and Machine ID Bots - use certificates to identify themselves +within a cluster. To join services to the cluster and receive certificates, admins should use [short-lived tokens or cloud identity services](../agents/join-services-to-your-cluster/join-token.mdx). Unlike users and services, internal services receive long-lived certificates. @@ -163,5 +163,5 @@ cluster certificates, use node [session and identity locking](../access-controls - [Architecture Overview](../core-concepts.mdx) - [Authorization](authorization.mdx) -- [Teleport Nodes](agents.mdx) +- [Teleport Agents](agents.mdx) - [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/authorization.mdx b/docs/pages/architecture/authorization.mdx index 25a9e60ef0bf2..927cf9617eeff 100644 --- a/docs/pages/architecture/authorization.mdx +++ b/docs/pages/architecture/authorization.mdx @@ -397,6 +397,6 @@ spec: - [Access Requests Guides](../access-controls/access-requests.mdx) - [Architecture Overview](../core-concepts.mdx) - [Teleport Auth](authentication.mdx) -- [Teleport Nodes](agents.mdx) +- [Teleport Agents](agents.mdx) - [Teleport Proxy](proxy.mdx) diff --git a/docs/pages/architecture/introduction.mdx b/docs/pages/architecture/introduction.mdx index 1cc52567a61ce..2fd903086c97c 100644 --- a/docs/pages/architecture/introduction.mdx +++ b/docs/pages/architecture/introduction.mdx @@ -13,7 +13,6 @@ works. - [Teleport Agents](./agents.mdx) - [The Teleport Proxy Service](./proxy.mdx) - [Trusted Clusters](./trustedclusters.mdx) -- [Teleport Nodes](./agents.mdx) - [Session Recording](./session-recording.mdx) - [TLS Routing](./tls-routing.mdx) - [Proxy Peering](./proxy-peering.mdx) diff --git a/docs/pages/architecture/session-recording.mdx b/docs/pages/architecture/session-recording.mdx index 9535727e72afc..4f03ef4a18a9e 100644 --- a/docs/pages/architecture/session-recording.mdx +++ b/docs/pages/architecture/session-recording.mdx @@ -123,7 +123,7 @@ Auth Service. ### Synchronous recording When synchronous recording is enabled, the Teleport component doing the recording -(which may be the Node or the Proxy Service instance depending on your configuration) +(which may be the Teleport SSH Service or the Proxy Service instance depending on your configuration) submits each recording event to Teleport's Auth Server as it occurs. In this mode, failure to emit a recording event is considered fatal - the session will be terminated if an event cannot be recorded. This makes synchronous recording best suited for highly @@ -135,8 +135,9 @@ or terminated due to temporary connection loss. In synchronous recording modes, the Auth Server receives a stream of recording events and is responsible for assembling them into the final artifact and uploading it to the storage backend. Since data is streamed directly to the Auth Server, -Teleport administrators don't need to be concerned with disk space on their Nodes -and Proxy Service instances, as no recording data is written to those disks. +Teleport administrators don't need to be concerned with disk space on their +Teleport SSH Service and Proxy Service instances, as no recording data is +written to those disks. ### Asynchronous recording diff --git a/docs/pages/architecture/trustedclusters.mdx b/docs/pages/architecture/trustedclusters.mdx index c03194ea0f61a..9ded37553f570 100644 --- a/docs/pages/architecture/trustedclusters.mdx +++ b/docs/pages/architecture/trustedclusters.mdx @@ -10,7 +10,7 @@ is a group of Teleport connected resources. Each cluster manages a set of certificate authorities (CAs) for its users and resources. Trusted Clusters allow the users of one cluster, the **root cluster**, to -seamlessly SSH into the Nodes of another cluster, the **leaf cluster**, while +access resources registered with another cluster, the **leaf cluster**, while remaining authenticated with only a single Auth Service. The leaf cluster can be running behind a firewall without any ingress ports open. From b58d3f93734e3a748f61011e3131bd263a177f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Cie=C5=9Blak?= Date: Thu, 20 Jun 2024 20:45:21 +0200 Subject: [PATCH 23/30] Display full list of DNS zones in VNet panel (#43195) * Remove unused getCluster func from clusterConfigCache * Make ClusterConfigCache public * Improve warning when fetching leaf clusters for DNS setup * Return AlreadyExists from VnetService.Start and handle it on frontend * Implement VnetService.ListDNSZones * Share ClusterConfigCache between lib/vnet and lib/teleterm * Extract blink keyframes * Add processing and warning status to ConnectionStatusIndicator * Speed up slide animation for VNet panel * Display DNS zones in VNet panel * Show processing state on repeated calls only after delay * Pass empty deps array to useEffect * Return Promise from usePromiseRejectedOnUnmount * Add ellipsis to processing state copy * MockedUnaryCall.then: Handle onrejected not being defined I just copied stuff from the linked implementation of then. * Fix mistake in comment for ListDNSZones --- .../lib/teleterm/vnet/v1/vnet_service.pb.go | 184 +++++++++++++--- .../teleterm/vnet/v1/vnet_service_grpc.pb.go | 60 ++++- .../vnet/v1/vnet_service_pb.client.ts | 33 +++ .../vnet/v1/vnet_service_pb.grpc-server.ts | 26 +++ .../lib/teleterm/vnet/v1/vnet_service_pb.ts | 96 +++++++- lib/teleterm/apiserver/apiserver.go | 1 + lib/teleterm/apiserver/config.go | 6 + lib/teleterm/teleterm.go | 5 + lib/teleterm/vnet/service.go | 101 ++++++++- lib/vnet/app_resolver.go | 23 +- lib/vnet/clusterconfigcache.go | 64 +++--- lib/vnet/osconfig.go | 18 +- lib/vnet/setup.go | 26 ++- .../lib/teleterm/vnet/v1/vnet_service.proto | 19 ++ tool/tsh/common/vnet_darwin.go | 2 +- web/packages/design/src/keyframes.ts | 14 ++ web/packages/shared/hooks/useAsync.test.ts | 167 +++++++++++++- web/packages/shared/hooks/useAsync.ts | 39 +++- web/packages/shared/utils/wait.ts | 21 ++ .../src/services/tshd/cloneableClient.ts | 14 +- .../src/services/tshd/fixtures/mocks.ts | 1 + .../ui/ConnectMyComputer/NavigationMenu.tsx | 16 +- .../TopBar/Connections/Connections.story.tsx | 31 --- .../src/ui/TopBar/Connections/Connections.tsx | 1 + .../ConnectionStatusIndicator.story.tsx | 106 +++++++++ .../ConnectionStatusIndicator.tsx | 29 ++- .../src/ui/Vnet/VnetSliderStep.story.tsx | 208 ++++++++++++++++++ .../teleterm/src/ui/Vnet/VnetSliderStep.tsx | 108 ++++++--- .../teleterm/src/ui/Vnet/vnetContext.tsx | 20 +- 29 files changed, 1265 insertions(+), 174 deletions(-) create mode 100644 web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator.story.tsx create mode 100644 web/packages/teleterm/src/ui/Vnet/VnetSliderStep.story.tsx diff --git a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go index 320e4bbbb5e31..acbaae240a487 100644 --- a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service.pb.go @@ -192,6 +192,94 @@ func (*StopResponse) Descriptor() ([]byte, []int) { return file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescGZIP(), []int{3} } +// Request for ListDNSZones. +type ListDNSZonesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListDNSZonesRequest) Reset() { + *x = ListDNSZonesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDNSZonesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDNSZonesRequest) ProtoMessage() {} + +func (x *ListDNSZonesRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDNSZonesRequest.ProtoReflect.Descriptor instead. +func (*ListDNSZonesRequest) Descriptor() ([]byte, []int) { + return file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescGZIP(), []int{4} +} + +// Response for ListDNSZones. +type ListDNSZonesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // dns_zones is a deduplicated list of DNS zones. + DnsZones []string `protobuf:"bytes,1,rep,name=dns_zones,json=dnsZones,proto3" json:"dns_zones,omitempty"` +} + +func (x *ListDNSZonesResponse) Reset() { + *x = ListDNSZonesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDNSZonesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDNSZonesResponse) ProtoMessage() {} + +func (x *ListDNSZonesResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDNSZonesResponse.ProtoReflect.Descriptor instead. +func (*ListDNSZonesResponse) Descriptor() ([]byte, []int) { + return file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescGZIP(), []int{5} +} + +func (x *ListDNSZonesResponse) GetDnsZones() []string { + if x != nil { + return x.DnsZones + } + return nil +} + var File_teleport_lib_teleterm_vnet_v1_vnet_service_proto protoreflect.FileDescriptor var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDesc = []byte{ @@ -204,26 +292,38 @@ var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDesc = []byte{ 0x74, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x32, 0xd2, 0x01, 0x0a, 0x0b, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x62, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, - 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x2a, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, - 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x65, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x33, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x7a, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x32, 0xcb, 0x02, + 0x0a, 0x0b, 0x56, 0x6e, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, + 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, + 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, + 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x5f, 0x0a, 0x04, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x55, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2f, 0x76, - 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6e, 0x65, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, + 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, + 0x65, 0x73, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6c, 0x69, + 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, 0x6e, 0x65, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x2e, 0x76, + 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x4e, 0x53, 0x5a, 0x6f, + 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x55, 0x5a, 0x53, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x72, 0x6d, 0x2f, 0x76, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6e, 0x65, 0x74, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -238,20 +338,24 @@ func file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescGZIP() []byte return file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDescData } -var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_goTypes = []any{ - (*StartRequest)(nil), // 0: teleport.lib.teleterm.vnet.v1.StartRequest - (*StartResponse)(nil), // 1: teleport.lib.teleterm.vnet.v1.StartResponse - (*StopRequest)(nil), // 2: teleport.lib.teleterm.vnet.v1.StopRequest - (*StopResponse)(nil), // 3: teleport.lib.teleterm.vnet.v1.StopResponse + (*StartRequest)(nil), // 0: teleport.lib.teleterm.vnet.v1.StartRequest + (*StartResponse)(nil), // 1: teleport.lib.teleterm.vnet.v1.StartResponse + (*StopRequest)(nil), // 2: teleport.lib.teleterm.vnet.v1.StopRequest + (*StopResponse)(nil), // 3: teleport.lib.teleterm.vnet.v1.StopResponse + (*ListDNSZonesRequest)(nil), // 4: teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest + (*ListDNSZonesResponse)(nil), // 5: teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse } var file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_depIdxs = []int32{ 0, // 0: teleport.lib.teleterm.vnet.v1.VnetService.Start:input_type -> teleport.lib.teleterm.vnet.v1.StartRequest 2, // 1: teleport.lib.teleterm.vnet.v1.VnetService.Stop:input_type -> teleport.lib.teleterm.vnet.v1.StopRequest - 1, // 2: teleport.lib.teleterm.vnet.v1.VnetService.Start:output_type -> teleport.lib.teleterm.vnet.v1.StartResponse - 3, // 3: teleport.lib.teleterm.vnet.v1.VnetService.Stop:output_type -> teleport.lib.teleterm.vnet.v1.StopResponse - 2, // [2:4] is the sub-list for method output_type - 0, // [0:2] is the sub-list for method input_type + 4, // 2: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:input_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest + 1, // 3: teleport.lib.teleterm.vnet.v1.VnetService.Start:output_type -> teleport.lib.teleterm.vnet.v1.StartResponse + 3, // 4: teleport.lib.teleterm.vnet.v1.VnetService.Stop:output_type -> teleport.lib.teleterm.vnet.v1.StopResponse + 5, // 5: teleport.lib.teleterm.vnet.v1.VnetService.ListDNSZones:output_type -> teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -311,6 +415,30 @@ func file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_init() { return nil } } + file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*ListDNSZonesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*ListDNSZonesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -318,7 +446,7 @@ func file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_lib_teleterm_vnet_v1_vnet_service_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service_grpc.pb.go b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service_grpc.pb.go index 8bbf28768a63a..5dbbb2788fe92 100644 --- a/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service_grpc.pb.go +++ b/gen/proto/go/teleport/lib/teleterm/vnet/v1/vnet_service_grpc.pb.go @@ -35,8 +35,9 @@ import ( const _ = grpc.SupportPackageIsVersion8 const ( - VnetService_Start_FullMethodName = "/teleport.lib.teleterm.vnet.v1.VnetService/Start" - VnetService_Stop_FullMethodName = "/teleport.lib.teleterm.vnet.v1.VnetService/Stop" + VnetService_Start_FullMethodName = "/teleport.lib.teleterm.vnet.v1.VnetService/Start" + VnetService_Stop_FullMethodName = "/teleport.lib.teleterm.vnet.v1.VnetService/Stop" + VnetService_ListDNSZones_FullMethodName = "/teleport.lib.teleterm.vnet.v1.VnetService/ListDNSZones" ) // VnetServiceClient is the client API for VnetService service. @@ -49,6 +50,16 @@ type VnetServiceClient interface { Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) // Stop stops VNet. Stop(ctx context.Context, in *StopRequest, opts ...grpc.CallOption) (*StopResponse, error) + // ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + // includes the proxy service hostnames and custom DNS zones configured in vnet_config. + // + // This is fetched independently of what the Electron app thinks the current state of the cluster + // looks like, since the VNet admin process also fetches this data independently of the Electron + // app. + // + // Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + // be fetched (due to e.g., a network error or an expired cert). + ListDNSZones(ctx context.Context, in *ListDNSZonesRequest, opts ...grpc.CallOption) (*ListDNSZonesResponse, error) } type vnetServiceClient struct { @@ -79,6 +90,16 @@ func (c *vnetServiceClient) Stop(ctx context.Context, in *StopRequest, opts ...g return out, nil } +func (c *vnetServiceClient) ListDNSZones(ctx context.Context, in *ListDNSZonesRequest, opts ...grpc.CallOption) (*ListDNSZonesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListDNSZonesResponse) + err := c.cc.Invoke(ctx, VnetService_ListDNSZones_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // VnetServiceServer is the server API for VnetService service. // All implementations must embed UnimplementedVnetServiceServer // for forward compatibility @@ -89,6 +110,16 @@ type VnetServiceServer interface { Start(context.Context, *StartRequest) (*StartResponse, error) // Stop stops VNet. Stop(context.Context, *StopRequest) (*StopResponse, error) + // ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + // includes the proxy service hostnames and custom DNS zones configured in vnet_config. + // + // This is fetched independently of what the Electron app thinks the current state of the cluster + // looks like, since the VNet admin process also fetches this data independently of the Electron + // app. + // + // Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + // be fetched (due to e.g., a network error or an expired cert). + ListDNSZones(context.Context, *ListDNSZonesRequest) (*ListDNSZonesResponse, error) mustEmbedUnimplementedVnetServiceServer() } @@ -102,6 +133,9 @@ func (UnimplementedVnetServiceServer) Start(context.Context, *StartRequest) (*St func (UnimplementedVnetServiceServer) Stop(context.Context, *StopRequest) (*StopResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") } +func (UnimplementedVnetServiceServer) ListDNSZones(context.Context, *ListDNSZonesRequest) (*ListDNSZonesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListDNSZones not implemented") +} func (UnimplementedVnetServiceServer) mustEmbedUnimplementedVnetServiceServer() {} // UnsafeVnetServiceServer may be embedded to opt out of forward compatibility for this service. @@ -151,6 +185,24 @@ func _VnetService_Stop_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _VnetService_ListDNSZones_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListDNSZonesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VnetServiceServer).ListDNSZones(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VnetService_ListDNSZones_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VnetServiceServer).ListDNSZones(ctx, req.(*ListDNSZonesRequest)) + } + return interceptor(ctx, in, info, handler) +} + // VnetService_ServiceDesc is the grpc.ServiceDesc for VnetService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -166,6 +218,10 @@ var VnetService_ServiceDesc = grpc.ServiceDesc{ MethodName: "Stop", Handler: _VnetService_Stop_Handler, }, + { + MethodName: "ListDNSZones", + Handler: _VnetService_ListDNSZones_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "teleport/lib/teleterm/vnet/v1/vnet_service.proto", diff --git a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.client.ts b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.client.ts index 7002e075f65b1..c7e0676724901 100644 --- a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.client.ts +++ b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.client.ts @@ -23,6 +23,8 @@ import type { RpcTransport } from "@protobuf-ts/runtime-rpc"; import type { ServiceInfo } from "@protobuf-ts/runtime-rpc"; import { VnetService } from "./vnet_service_pb"; +import type { ListDNSZonesResponse } from "./vnet_service_pb"; +import type { ListDNSZonesRequest } from "./vnet_service_pb"; import type { StopResponse } from "./vnet_service_pb"; import type { StopRequest } from "./vnet_service_pb"; import { stackIntercept } from "@protobuf-ts/runtime-rpc"; @@ -48,6 +50,20 @@ export interface IVnetServiceClient { * @generated from protobuf rpc: Stop(teleport.lib.teleterm.vnet.v1.StopRequest) returns (teleport.lib.teleterm.vnet.v1.StopResponse); */ stop(input: StopRequest, options?: RpcOptions): UnaryCall; + /** + * ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + * includes the proxy service hostnames and custom DNS zones configured in vnet_config. + * + * This is fetched independently of what the Electron app thinks the current state of the cluster + * looks like, since the VNet admin process also fetches this data independently of the Electron + * app. + * + * Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + * be fetched (due to e.g., a network error or an expired cert). + * + * @generated from protobuf rpc: ListDNSZones(teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest) returns (teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse); + */ + listDNSZones(input: ListDNSZonesRequest, options?: RpcOptions): UnaryCall; } /** * VnetService provides methods to manage a VNet instance. @@ -78,4 +94,21 @@ export class VnetServiceClient implements IVnetServiceClient, ServiceInfo { const method = this.methods[1], opt = this._transport.mergeOptions(options); return stackIntercept("unary", this._transport, method, opt, input); } + /** + * ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + * includes the proxy service hostnames and custom DNS zones configured in vnet_config. + * + * This is fetched independently of what the Electron app thinks the current state of the cluster + * looks like, since the VNet admin process also fetches this data independently of the Electron + * app. + * + * Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + * be fetched (due to e.g., a network error or an expired cert). + * + * @generated from protobuf rpc: ListDNSZones(teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest) returns (teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse); + */ + listDNSZones(input: ListDNSZonesRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[2], opt = this._transport.mergeOptions(options); + return stackIntercept("unary", this._transport, method, opt, input); + } } diff --git a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.grpc-server.ts b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.grpc-server.ts index 80d48a460d628..79e407a8f008f 100644 --- a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.grpc-server.ts +++ b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.grpc-server.ts @@ -20,6 +20,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // +import { ListDNSZonesResponse } from "./vnet_service_pb"; +import { ListDNSZonesRequest } from "./vnet_service_pb"; import { StopResponse } from "./vnet_service_pb"; import { StopRequest } from "./vnet_service_pb"; import { StartResponse } from "./vnet_service_pb"; @@ -43,6 +45,20 @@ export interface IVnetService extends grpc.UntypedServiceImplementation { * @generated from protobuf rpc: Stop(teleport.lib.teleterm.vnet.v1.StopRequest) returns (teleport.lib.teleterm.vnet.v1.StopResponse); */ stop: grpc.handleUnaryCall; + /** + * ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + * includes the proxy service hostnames and custom DNS zones configured in vnet_config. + * + * This is fetched independently of what the Electron app thinks the current state of the cluster + * looks like, since the VNet admin process also fetches this data independently of the Electron + * app. + * + * Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + * be fetched (due to e.g., a network error or an expired cert). + * + * @generated from protobuf rpc: ListDNSZones(teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest) returns (teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse); + */ + listDNSZones: grpc.handleUnaryCall; } /** * @grpc/grpc-js definition for the protobuf service teleport.lib.teleterm.vnet.v1.VnetService. @@ -75,5 +91,15 @@ export const vnetServiceDefinition: grpc.ServiceDefinition = { requestDeserialize: bytes => StopRequest.fromBinary(bytes), responseSerialize: value => Buffer.from(StopResponse.toBinary(value)), requestSerialize: value => Buffer.from(StopRequest.toBinary(value)) + }, + listDNSZones: { + path: "/teleport.lib.teleterm.vnet.v1.VnetService/ListDNSZones", + originalName: "ListDNSZones", + requestStream: false, + responseStream: false, + responseDeserialize: bytes => ListDNSZonesResponse.fromBinary(bytes), + requestDeserialize: bytes => ListDNSZonesRequest.fromBinary(bytes), + responseSerialize: value => Buffer.from(ListDNSZonesResponse.toBinary(value)), + requestSerialize: value => Buffer.from(ListDNSZonesRequest.toBinary(value)) } }; diff --git a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts index fd91639430a9f..b01b23b0f82e9 100644 --- a/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts +++ b/gen/proto/ts/teleport/lib/teleterm/vnet/v1/vnet_service_pb.ts @@ -21,6 +21,7 @@ // along with this program. If not, see . // import { ServiceType } from "@protobuf-ts/runtime-rpc"; +import { WireType } from "@protobuf-ts/runtime"; import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; import type { IBinaryWriter } from "@protobuf-ts/runtime"; import { UnknownFieldHandler } from "@protobuf-ts/runtime"; @@ -57,6 +58,26 @@ export interface StopRequest { */ export interface StopResponse { } +/** + * Request for ListDNSZones. + * + * @generated from protobuf message teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest + */ +export interface ListDNSZonesRequest { +} +/** + * Response for ListDNSZones. + * + * @generated from protobuf message teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse + */ +export interface ListDNSZonesResponse { + /** + * dns_zones is a deduplicated list of DNS zones. + * + * @generated from protobuf field: repeated string dns_zones = 1; + */ + dnsZones: string[]; +} // @generated message type with reflection information, may provide speed optimized methods class StartRequest$Type extends MessageType { constructor() { @@ -157,10 +178,83 @@ class StopResponse$Type extends MessageType { * @generated MessageType for protobuf message teleport.lib.teleterm.vnet.v1.StopResponse */ export const StopResponse = new StopResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ListDNSZonesRequest$Type extends MessageType { + constructor() { + super("teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest", []); + } + create(value?: PartialMessage): ListDNSZonesRequest { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ListDNSZonesRequest): ListDNSZonesRequest { + return target ?? this.create(); + } + internalBinaryWrite(message: ListDNSZonesRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.teleterm.vnet.v1.ListDNSZonesRequest + */ +export const ListDNSZonesRequest = new ListDNSZonesRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ListDNSZonesResponse$Type extends MessageType { + constructor() { + super("teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse", [ + { no: 1, name: "dns_zones", kind: "scalar", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ } + ]); + } + create(value?: PartialMessage): ListDNSZonesResponse { + const message = globalThis.Object.create((this.messagePrototype!)); + message.dnsZones = []; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: ListDNSZonesResponse): ListDNSZonesResponse { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* repeated string dns_zones */ 1: + message.dnsZones.push(reader.string()); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ListDNSZonesResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* repeated string dns_zones = 1; */ + for (let i = 0; i < message.dnsZones.length; i++) + writer.tag(1, WireType.LengthDelimited).string(message.dnsZones[i]); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.lib.teleterm.vnet.v1.ListDNSZonesResponse + */ +export const ListDNSZonesResponse = new ListDNSZonesResponse$Type(); /** * @generated ServiceType for protobuf service teleport.lib.teleterm.vnet.v1.VnetService */ export const VnetService = new ServiceType("teleport.lib.teleterm.vnet.v1.VnetService", [ { name: "Start", options: {}, I: StartRequest, O: StartResponse }, - { name: "Stop", options: {}, I: StopRequest, O: StopResponse } + { name: "Stop", options: {}, I: StopRequest, O: StopResponse }, + { name: "ListDNSZones", options: {}, I: ListDNSZonesRequest, O: ListDNSZonesResponse } ]); diff --git a/lib/teleterm/apiserver/apiserver.go b/lib/teleterm/apiserver/apiserver.go index 40e387638877e..d54531afca218 100644 --- a/lib/teleterm/apiserver/apiserver.go +++ b/lib/teleterm/apiserver/apiserver.go @@ -56,6 +56,7 @@ func New(cfg Config) (*APIServer, error) { InsecureSkipVerify: cfg.InsecureSkipVerify, ClusterIDCache: cfg.ClusterIDCache, InstallationID: cfg.InstallationID, + Clock: cfg.Clock, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/teleterm/apiserver/config.go b/lib/teleterm/apiserver/config.go index 1f296dce88893..76495b8a181b2 100644 --- a/lib/teleterm/apiserver/config.go +++ b/lib/teleterm/apiserver/config.go @@ -20,6 +20,7 @@ package apiserver import ( "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" "github.com/sirupsen/logrus" "google.golang.org/grpc" @@ -41,6 +42,7 @@ type Config struct { // Log is a component logger Log logrus.FieldLogger TshdServerCreds grpc.ServerOption + Clock clockwork.Clock // ListeningC propagates the address on which the gRPC server listens. Mostly useful in tests, as // the Electron app gets the server port from stdout. ListeningC chan<- utils.NetAddr @@ -76,5 +78,9 @@ func (c *Config) CheckAndSetDefaults() error { c.ClusterIDCache = &clusteridcache.Cache{} } + if c.Clock == nil { + c.Clock = clockwork.NewRealClock() + } + return nil } diff --git a/lib/teleterm/teleterm.go b/lib/teleterm/teleterm.go index d2348a7bb93d3..a5a1e35468e43 100644 --- a/lib/teleterm/teleterm.go +++ b/lib/teleterm/teleterm.go @@ -27,6 +27,7 @@ import ( "syscall" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -48,9 +49,12 @@ func Serve(ctx context.Context, cfg Config) error { return trace.Wrap(err) } + clock := clockwork.NewRealClock() + storage, err := clusters.NewStorage(clusters.Config{ Dir: cfg.HomeDir, InsecureSkipVerify: cfg.InsecureSkipVerify, + Clock: clock, }) if err != nil { return trace.Wrap(err) @@ -78,6 +82,7 @@ func Serve(ctx context.Context, cfg Config) error { ListeningC: cfg.ListeningC, ClusterIDCache: clusterIDCache, InstallationID: cfg.InstallationID, + Clock: clock, }) if err != nil { return trace.Wrap(err) diff --git a/lib/teleterm/vnet/service.go b/lib/teleterm/vnet/service.go index 440dee1bf78ce..ed8f99b301855 100644 --- a/lib/teleterm/vnet/service.go +++ b/lib/teleterm/vnet/service.go @@ -25,10 +25,12 @@ import ( "time" "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" "google.golang.org/protobuf/types/known/timestamppb" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils" prehogv1alpha "github.com/gravitational/teleport/gen/proto/go/prehog/v1alpha" apiteleterm "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/v1" api "github.com/gravitational/teleport/gen/proto/go/teleport/lib/teleterm/vnet/v1" @@ -55,11 +57,12 @@ const ( type Service struct { api.UnimplementedVnetServiceServer - cfg Config - mu sync.Mutex - status status - processManager *vnet.ProcessManager - usageReporter usageReporter + cfg Config + mu sync.Mutex + status status + usageReporter usageReporter + processManager *vnet.ProcessManager + clusterConfigCache *vnet.ClusterConfigCache } // New creates an instance of Service. @@ -85,6 +88,7 @@ type Config struct { // InstallationID is a unique ID of this particular Connect installation, used for usage // reporting. InstallationID string + Clock clockwork.Clock } // CheckAndSetDefaults checks and sets the defaults @@ -101,6 +105,10 @@ func (c *Config) CheckAndSetDefaults() error { return trace.BadParameter("missing InstallationID") } + if c.Clock == nil { + c.Clock = clockwork.NewRealClock() + } + return nil } @@ -113,7 +121,7 @@ func (s *Service) Start(ctx context.Context, req *api.StartRequest) (*api.StartR } if s.status == statusRunning { - return &api.StartResponse{}, nil + return nil, trace.AlreadyExists("VNet is already running") } appProvider := &appProvider{ @@ -150,7 +158,11 @@ func (s *Service) Start(ctx context.Context, req *api.StartRequest) (*api.StartR appProvider.usageReporter = usageReporter } - processManager, err := vnet.SetupAndRun(ctx, appProvider) + s.clusterConfigCache = vnet.NewClusterConfigCache(s.cfg.Clock) + processManager, err := vnet.SetupAndRun(ctx, &vnet.SetupAndRunConfig{ + AppProvider: appProvider, + ClusterConfigCache: s.clusterConfigCache, + }) if err != nil { return nil, trace.Wrap(err) } @@ -201,6 +213,81 @@ func (s *Service) Stop(ctx context.Context, req *api.StopRequest) (*api.StopResp return &api.StopResponse{}, nil } +// ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This +// includes the proxy service hostnames and custom DNS zones configured in vnet_config. +// +// This is fetched independently of what the Electron app thinks the current state of the cluster +// looks like, since the VNet admin process also fetches this data independently of the Electron +// app. +// +// Just like the admin process, it skips root and leaf clusters for which DNS couldn't be fetched +// (due to e.g., a network error or an expired cert). +func (s *Service) ListDNSZones(ctx context.Context, req *api.ListDNSZonesRequest) (*api.ListDNSZonesResponse, error) { + // Acquire the lock just to check the status of the service. We don't want the actual process of + // listing DNS zones to block the user from performing other operations. + s.mu.Lock() + + if s.status != statusRunning { + return nil, trace.CompareFailed("VNet is not running") + } + + defer s.mu.Unlock() + + profileNames, err := s.cfg.DaemonService.ListProfileNames() + if err != nil { + return nil, trace.Wrap(err) + } + + dnsZones := []string{} + + for _, profileName := range profileNames { + rootClusterURI := uri.NewClusterURI(profileName) + cLog := log.With("cluster", rootClusterURI) + + rootClient, err := s.cfg.DaemonService.GetCachedClient(ctx, rootClusterURI) + if err != nil { + cLog.WarnContext(ctx, "Failed to create root cluster client, profile may be expired, skipping DNS zones of this cluster", "error", err) + continue + } + clusterConfig, err := s.clusterConfigCache.GetClusterConfig(ctx, rootClient) + if err != nil { + cLog.WarnContext(ctx, "Failed to load VNet configuration, profile may be expired, skipping DNS zones of this cluster", "error", err) + continue + } + + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + + leafClusters, err := s.cfg.DaemonService.ListLeafClusters(ctx, rootClusterURI.String()) + if err != nil { + cLog.WarnContext(ctx, "Failed to list leaf clusters, profile may be expired, skipping DNS zones from leaf clusters of this cluster", "error", err) + continue + } + + for _, leafCluster := range leafClusters { + cLog := log.With("cluster", leafCluster.URI.String()) + + clusterClient, err := s.cfg.DaemonService.GetCachedClient(ctx, leafCluster.URI) + if err != nil { + cLog.WarnContext(ctx, "Failed to create leaf cluster client, skipping DNS zones for this leaf cluster", "error", err) + continue + } + clusterConfig, err := s.clusterConfigCache.GetClusterConfig(ctx, clusterClient) + if err != nil { + cLog.WarnContext(ctx, "Failed to load VNet configuration, skipping DNS zones for this leaf cluster", "error", err) + continue + } + + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + } + } + + dnsZones = utils.Deduplicate(dnsZones) + + return &api.ListDNSZonesResponse{ + DnsZones: dnsZones, + }, nil +} + func (s *Service) stopLocked() error { if s.status == statusClosed { return trace.CompareFailed("VNet service has been closed") diff --git a/lib/vnet/app_resolver.go b/lib/vnet/app_resolver.go index c6ab2befd2e77..4ab308b6e459e 100644 --- a/lib/vnet/app_resolver.go +++ b/lib/vnet/app_resolver.go @@ -93,7 +93,7 @@ type DialOptions struct { // TCPAppResolver implements [TCPHandlerResolver] for Teleport TCP apps. type TCPAppResolver struct { appProvider AppProvider - clusterConfigCache *clusterConfigCache + clusterConfigCache *ClusterConfigCache customDNSZoneChecker *customDNSZoneValidator slog *slog.Logger clock clockwork.Clock @@ -117,7 +117,7 @@ func NewTCPAppResolver(appProvider AppProvider, opts ...tcpAppResolverOption) (* opt(r) } r.clock = cmp.Or(r.clock, clockwork.NewRealClock()) - r.clusterConfigCache = newClusterConfigCache(appProvider.GetCachedClient, r.clock) + r.clusterConfigCache = cmp.Or(r.clusterConfigCache, NewClusterConfigCache(r.clock)) r.customDNSZoneChecker = newCustomDNSZoneValidator(r.lookupTXT) return r, nil } @@ -138,6 +138,13 @@ func withLookupTXTFunc(lookupTXT lookupTXTFunc) tcpAppResolverOption { } } +// WithClusterConfigCache is a functional option to override the cluster config cache. +func WithClusterConfigCache(clusterConfigCache *ClusterConfigCache) tcpAppResolverOption { + return func(r *TCPAppResolver) { + r.clusterConfigCache = clusterConfigCache + } +} + // ResolveTCPHandler resolves a fully-qualified domain name to a [TCPHandlerSpec] for a Teleport TCP app that should // be used to handle all future TCP connections to [fqdn]. // Avoid using [trace.Wrap] on [ErrNoTCPHandler] to prevent collecting a full stack trace on every unhandled @@ -208,12 +215,12 @@ func (r *TCPAppResolver) clusterClientForAppFQDN(ctx context.Context, profileNam continue } - clusterConfig, err := r.clusterConfigCache.getClusterConfig(ctx, clusterClient) + clusterConfig, err := r.clusterConfigCache.GetClusterConfig(ctx, clusterClient) if err != nil { r.slog.ErrorContext(ctx, "Failed to get VnetConfig, apps in the cluster will not be resolved.", "profile", profileName, "leaf_cluster", leafClusterName, "error", err) continue } - for _, zone := range clusterConfig.dnsZones { + for _, zone := range clusterConfig.DNSZones { if !isSubdomain(fqdn, zone) { // The queried app fqdn is not a subdomain of this zone, skip it. continue @@ -221,13 +228,13 @@ func (r *TCPAppResolver) clusterClientForAppFQDN(ctx context.Context, profileNam // Found a matching cluster. - if zone == clusterConfig.proxyPublicAddr { + if zone == clusterConfig.ProxyPublicAddr { // We don't need to validate a custom DNS zone if this is the proxy public address, this is a // normal app public_addr. return clusterClient, nil } // The queried app fqdn is a subdomain of this custom zone. Check if the zone is valid. - if err := r.customDNSZoneChecker.validate(ctx, clusterConfig.clusterName, zone); err != nil { + if err := r.customDNSZoneChecker.validate(ctx, clusterConfig.ClusterName, zone); err != nil { // Return an error here since the FQDN does match this custom zone, but the zone failed to // validate. return nil, trace.Wrap(err, "validating custom DNS zone %q matching queried FQDN %q", zone, fqdn) @@ -289,13 +296,13 @@ func (r *TCPAppResolver) resolveTCPHandlerForCluster( return nil, trace.Wrap(err) } - clusterConfig, err := r.clusterConfigCache.getClusterConfig(ctx, clusterClient) + clusterConfig, err := r.clusterConfigCache.GetClusterConfig(ctx, clusterClient) if err != nil { return nil, trace.Wrap(err) } return &TCPHandlerSpec{ - IPv4CIDRRange: clusterConfig.ipv4CIDRRange, + IPv4CIDRRange: clusterConfig.IPv4CIDRRange, TCPHandler: appHandler, }, nil } diff --git a/lib/vnet/clusterconfigcache.go b/lib/vnet/clusterconfigcache.go index fcba8bd034fc3..7f01f56516b95 100644 --- a/lib/vnet/clusterconfigcache.go +++ b/lib/vnet/clusterconfigcache.go @@ -29,52 +29,48 @@ import ( "golang.org/x/sync/singleflight" ) -type getClusterClientFunc = func(ctx context.Context, profileName, leafClusterName string) (ClusterClient, error) - -type clusterConfig struct { - // clusterName is the name of the cluster as reported by Ping. - clusterName string - // proxyPublicAddr is the public address of the proxy as reported by Ping, with any ports removed, this is - // just the hostname. This is often but not always identical to the clusterName. For root clusters this +type ClusterConfig struct { + // ClusterName is the name of the cluster as reported by Ping. + ClusterName string + // ProxyPublicAddr is the public address of the proxy as reported by Ping, with any ports removed, this is + // just the hostname. This is often but not always identical to the ClusterName. For root clusters this // will be the same as the profile name (the profile is named after the proxy public addr). - proxyPublicAddr string - // dnsZones is the list of DNS zones that are valid for this cluster, this includes proxyPublicAddr *and* + ProxyPublicAddr string + // DNSZones is the list of DNS zones that are valid for this cluster, this includes ProxyPublicAddr *and* // any configured custom DNS zones for the cluster. - dnsZones []string - // ipv4CIDRRange is the CIDR range that IPv4 addresses should be assigned from for apps in this cluster. - ipv4CIDRRange string - // expires is the time at which this information should be considered stale and refetched. Stale data may + DNSZones []string + // IPv4CIDRRange is the CIDR range that IPv4 addresses should be assigned from for apps in this cluster. + IPv4CIDRRange string + // Expires is the time at which this information should be considered stale and refetched. Stale data may // be used if a subsequent fetch fails. - expires time.Time + Expires time.Time } -func (e *clusterConfig) stale(clock clockwork.Clock) bool { - return clock.Now().After(e.expires) +func (e *ClusterConfig) stale(clock clockwork.Clock) bool { + return clock.Now().After(e.Expires) } -// clusterConfigCache is a read-through cache for cluster VnetConfigs. Cached entries go stale after 5 +// ClusterConfigCache is a read-through cache for cluster VnetConfigs. Cached entries go stale after 5 // minutes, after which they will be re-fetched on the next read. // // If a read from the cluster fails but there is a stale cache entry present, this prefers to return the stale // cached entry. This is desirable in cases where the profile for a cluster expires during VNet operation, // it's better to use the stale custom DNS zones than to remove all DNS configuration for that cluster. -type clusterConfigCache struct { +type ClusterConfigCache struct { flightGroup singleflight.Group clock clockwork.Clock - getClient getClusterClientFunc - cache map[string]*clusterConfig + cache map[string]*ClusterConfig mu sync.RWMutex } -func newClusterConfigCache(getClient getClusterClientFunc, clock clockwork.Clock) *clusterConfigCache { - return &clusterConfigCache{ - clock: clock, - getClient: getClient, - cache: make(map[string]*clusterConfig), +func NewClusterConfigCache(clock clockwork.Clock) *ClusterConfigCache { + return &ClusterConfigCache{ + clock: clock, + cache: make(map[string]*ClusterConfig), } } -func (c *clusterConfigCache) getClusterConfig(ctx context.Context, clusterClient ClusterClient) (*clusterConfig, error) { +func (c *ClusterConfigCache) GetClusterConfig(ctx context.Context, clusterClient ClusterClient) (*ClusterConfig, error) { k := clusterClient.ClusterName() // Use a singleflight.Group to avoid concurrent requests for the same cluster VnetConfig. @@ -107,10 +103,10 @@ func (c *clusterConfigCache) getClusterConfig(ctx context.Context, clusterClient if err != nil { return nil, trace.Wrap(err) } - return result.(*clusterConfig), nil + return result.(*ClusterConfig), nil } -func (c *clusterConfigCache) getClusterConfigUncached(ctx context.Context, clusterClient ClusterClient) (*clusterConfig, error) { +func (c *ClusterConfigCache) getClusterConfigUncached(ctx context.Context, clusterClient ClusterClient) (*ClusterConfig, error) { pingResp, err := clusterClient.CurrentCluster().Ping(ctx) if err != nil { return nil, trace.Wrap(err) @@ -140,11 +136,11 @@ func (c *clusterConfigCache) getClusterConfigUncached(ctx context.Context, clust ipv4CIDRRange = cmp.Or(vnetConfig.GetSpec().GetIpv4CidrRange(), defaultIPv4CIDRRange) } - return &clusterConfig{ - clusterName: clusterName, - proxyPublicAddr: proxyPublicAddr, - dnsZones: dnsZones, - ipv4CIDRRange: ipv4CIDRRange, - expires: c.clock.Now().Add(5 * time.Minute), + return &ClusterConfig{ + ClusterName: clusterName, + ProxyPublicAddr: proxyPublicAddr, + DNSZones: dnsZones, + IPv4CIDRRange: ipv4CIDRRange, + Expires: c.clock.Now().Add(5 * time.Minute), }, nil } diff --git a/lib/vnet/osconfig.go b/lib/vnet/osconfig.go index 0d77606f23e29..c080327e17cb9 100644 --- a/lib/vnet/osconfig.go +++ b/lib/vnet/osconfig.go @@ -42,7 +42,7 @@ type osConfig struct { type osConfigurator struct { clientStore *client.Store - clusterConfigCache *clusterConfigCache + clusterConfigCache *ClusterConfigCache tunName string tunIPv6 string dnsAddr string @@ -68,7 +68,7 @@ func newOSConfigurator(tunName, ipv6Prefix, dnsAddr string) (*osConfigurator, er homePath: homePath, clientStore: client.NewFSClientStore(homePath), } - configurator.clusterConfigCache = newClusterConfigCache(configurator.getClusterClient, clockwork.NewRealClock()) + configurator.clusterConfigCache = NewClusterConfigCache(clockwork.NewRealClock()) return configurator, nil } @@ -89,7 +89,7 @@ func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { "profile", profileName, "error", err) continue } - clusterConfig, err := c.clusterConfigCache.getClusterConfig(ctx, rootClient) + clusterConfig, err := c.clusterConfigCache.GetClusterConfig(ctx, rootClient) if err != nil { slog.WarnContext(ctx, "Failed to load VNet configuration, profile may be expired, not configuring VNet for this cluster", @@ -97,13 +97,13 @@ func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { continue } - dnsZones = append(dnsZones, clusterConfig.dnsZones...) - cidrRanges = append(cidrRanges, clusterConfig.ipv4CIDRRange) + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) leafClusters, err := getLeafClusters(ctx, rootClient) if err != nil { slog.WarnContext(ctx, - "Failed to list leaf clusters, profile may be expired, not configuring VNet for this cluster", + "Failed to list leaf clusters, profile may be expired, not configuring VNet for leaf clusters of this cluster", "profile", profileName, "error", err) continue } @@ -116,7 +116,7 @@ func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { continue } - clusterConfig, err := c.clusterConfigCache.getClusterConfig(ctx, clusterClient) + clusterConfig, err := c.clusterConfigCache.GetClusterConfig(ctx, clusterClient) if err != nil { slog.WarnContext(ctx, "Failed to load VNet configuration, not configuring VNet for this cluster", @@ -124,8 +124,8 @@ func (c *osConfigurator) updateOSConfiguration(ctx context.Context) error { continue } - dnsZones = append(dnsZones, clusterConfig.dnsZones...) - cidrRanges = append(cidrRanges, clusterConfig.ipv4CIDRRange) + dnsZones = append(dnsZones, clusterConfig.DNSZones...) + cidrRanges = append(cidrRanges, clusterConfig.IPv4CIDRRange) } } diff --git a/lib/vnet/setup.go b/lib/vnet/setup.go index fe9ee88a78357..64eaca6368498 100644 --- a/lib/vnet/setup.go +++ b/lib/vnet/setup.go @@ -38,7 +38,11 @@ import ( // ctx is used to wait for setup steps that happen before SetupAndRun hands out the control to the // process manager. If ctx gets canceled during SetupAndRun, the process manager gets closed along // with its background tasks. -func SetupAndRun(ctx context.Context, appProvider AppProvider) (*ProcessManager, error) { +func SetupAndRun(ctx context.Context, config *SetupAndRunConfig) (*ProcessManager, error) { + if err := config.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + ipv6Prefix, err := NewIPv6Prefix() if err != nil { return nil, trace.Wrap(err) @@ -100,7 +104,8 @@ func SetupAndRun(ctx context.Context, appProvider AppProvider) (*ProcessManager, } } - appResolver, err := NewTCPAppResolver(appProvider) + appResolver, err := NewTCPAppResolver(config.AppProvider, + WithClusterConfigCache(config.ClusterConfigCache)) if err != nil { return nil, trace.Wrap(err) } @@ -123,6 +128,23 @@ func SetupAndRun(ctx context.Context, appProvider AppProvider) (*ProcessManager, return pm, nil } +// SetupAndRunConfig provides collaborators for the [SetupAndRun] function. +type SetupAndRunConfig struct { + // AppProvider is a required field providing an interface implementation for [AppProvider]. + AppProvider AppProvider + // ClusterConfigCache is an optional field providing [ClusterConfigCache]. If empty, a new cache + // will be created. + ClusterConfigCache *ClusterConfigCache +} + +func (c *SetupAndRunConfig) CheckAndSetDefaults() error { + if c.AppProvider == nil { + return trace.BadParameter("missing AppProvider") + } + + return nil +} + func newProcessManager() (*ProcessManager, context.Context) { ctx, cancel := context.WithCancel(context.Background()) g, ctx := errgroup.WithContext(ctx) diff --git a/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto b/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto index 7b1cd1b6bc386..70c7ec795c505 100644 --- a/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto +++ b/proto/teleport/lib/teleterm/vnet/v1/vnet_service.proto @@ -26,6 +26,16 @@ service VnetService { rpc Start(StartRequest) returns (StartResponse); // Stop stops VNet. rpc Stop(StopRequest) returns (StopResponse); + // ListDNSZones returns DNS zones of all root and leaf clusters with non-expired user certs. This + // includes the proxy service hostnames and custom DNS zones configured in vnet_config. + // + // This is fetched independently of what the Electron app thinks the current state of the cluster + // looks like, since the VNet admin process also fetches this data independently of the Electron + // app. + // + // Just like the admin process, it skips root and leaf clusters for which the vnet_config couldn't + // be fetched (due to e.g., a network error or an expired cert). + rpc ListDNSZones(ListDNSZonesRequest) returns (ListDNSZonesResponse); } // Request for Start. @@ -39,3 +49,12 @@ message StopRequest {} // Response for Stop. message StopResponse {} + +// Request for ListDNSZones. +message ListDNSZonesRequest {} + +// Response for ListDNSZones. +message ListDNSZonesResponse { + // dns_zones is a deduplicated list of DNS zones. + repeated string dns_zones = 1; +} diff --git a/tool/tsh/common/vnet_darwin.go b/tool/tsh/common/vnet_darwin.go index 8a396fabdc585..0bb5592f7147c 100644 --- a/tool/tsh/common/vnet_darwin.go +++ b/tool/tsh/common/vnet_darwin.go @@ -44,7 +44,7 @@ func (c *vnetCommand) run(cf *CLIConf) error { return trace.Wrap(err) } - processManager, err := vnet.SetupAndRun(cf.Context, appProvider) + processManager, err := vnet.SetupAndRun(cf.Context, &vnet.SetupAndRunConfig{AppProvider: appProvider}) if err != nil { return trace.Wrap(err) } diff --git a/web/packages/design/src/keyframes.ts b/web/packages/design/src/keyframes.ts index f89f6511c07ee..c49799db9f67f 100644 --- a/web/packages/design/src/keyframes.ts +++ b/web/packages/design/src/keyframes.ts @@ -32,3 +32,17 @@ export const rotate360 = keyframes` from { transform: rotate(0deg); } to { transform: rotate(360deg); } `; + +// The animation should start from 100% opacity so that a transition from non-blinking state to a +// blinking state isn't abrupt. +export const blink = keyframes` + 0% { + opacity: 100%; + } + 50% { + opacity: 0; + } + 100% { + opacity: 100%; + } + `; diff --git a/web/packages/shared/hooks/useAsync.test.ts b/web/packages/shared/hooks/useAsync.test.ts index c0bee77515a11..881268e302d19 100644 --- a/web/packages/shared/hooks/useAsync.test.ts +++ b/web/packages/shared/hooks/useAsync.test.ts @@ -18,7 +18,14 @@ import { renderHook, act, waitFor } from '@testing-library/react'; -import { useAsync, CanceledError } from './useAsync'; +import { wait } from 'shared/utils/wait'; + +import { + useAsync, + CanceledError, + Attempt, + useDelayedRepeatedAttempt, +} from './useAsync'; test('run returns a promise which resolves with the attempt data', async () => { const returnValue = Symbol(); @@ -212,3 +219,161 @@ test('error and statusText are set when the callback returns a rejected promise' // The promise returned from run always succeeds, but any errors are captured as the second arg. await expect(runPromise).resolves.toEqual([null, expectedError]); }); + +describe('useDelayedRepeatedAttempt', () => { + it('does not update attempt status if it resolves before delay', async () => { + let resolve: (symbol: symbol) => void; + const { result } = renderHook(() => { + const [eagerAttempt, run] = useAsync(() => { + // Resolve to a symbol so that successful attempts are not equal to each other. + return new Promise(res => { + resolve = res; + }); + }); + const delayedAttempt = useDelayedRepeatedAttempt(eagerAttempt, 500); + + return { run, delayedAttempt }; + }); + + await act(async () => { + const promise = result.current.run(); + resolve(Symbol()); + await promise; + }); + + expect(result.current.delayedAttempt.status).toEqual('success'); + const oldDelayedAttempt = result.current.delayedAttempt; + + act(() => { + // Start promise but do not await it, instead wait for attempt updates. This ensures that we + // catch any state updates caused by the promise being resolved. + result.current.run(); + resolve(Symbol()); + }); + + // Wait for delayedAttempt to get updated. + let nextDelayedAttempt: Attempt; + await waitFor( + () => { + // result.current always returns the current result. Capture the attempt that's being + // compared within waitFor so that we can check its status outside of the block and be sure + // that it's the same attempt. + nextDelayedAttempt = result.current.delayedAttempt; + expect(nextDelayedAttempt).not.toBe(oldDelayedAttempt); + }, + { + onTimeout: error => { + error.message = + 'delayedAttempt did not get updated within timeout. ' + + `This might mean that the logic for detecting attempt updates is incorrect.\n${error.message}`; + return error; + }, + } + ); + + // As the promise was resolved before the delay, the attempt status should still be success. + expect(nextDelayedAttempt.status).toEqual('success'); + }); + + it('updates attempt status to processing if it does not resolve before delay', async () => { + let resolve: (symbol: symbol) => void; + const { result } = renderHook(() => { + const [eagerAttempt, run] = useAsync(() => { + // Resolve to a symbol so that successful attempts are not equal to each other. + return new Promise(res => { + resolve = res; + }); + }); + const delayedAttempt = useDelayedRepeatedAttempt(eagerAttempt, 100); + + return { run, delayedAttempt }; + }); + + await act(async () => { + const promise = result.current.run(); + resolve(Symbol()); + await promise; + }); + + expect(result.current.delayedAttempt.status).toEqual('success'); + const oldDelayedAttempt = result.current.delayedAttempt; + + let promise: Promise<[symbol, Error]>; + act(() => { + // Start promise but do not resolve it. + promise = result.current.run(); + }); + + // Wait for delayedAttempt to get updated. + let nextDelayedAttempt: Attempt; + await waitFor(() => { + // result.current always returns the current result. Capture the attempt that's being compared + // within waitFor so that we can check its status outside of the block and be sure that it's + // the same attempt. + nextDelayedAttempt = result.current.delayedAttempt; + expect(nextDelayedAttempt).not.toBe(oldDelayedAttempt); + }); + expect(nextDelayedAttempt.status).toEqual('processing'); + + await act(async () => { + // Resolve the promise after the status was updated to processing. + resolve(Symbol()); + await promise; + }); + expect(result.current.delayedAttempt.status).toEqual('success'); + }); + + it('cancels pending update', async () => { + const delayMs = 100; + let resolve: (symbol: symbol) => void; + const { result } = renderHook(() => { + const [eagerAttempt, run] = useAsync(() => { + // Resolve to a symbol so that successful attempts are not equal to each other. + return new Promise(res => { + resolve = res; + }); + }); + const delayedAttempt = useDelayedRepeatedAttempt(eagerAttempt, delayMs); + + return { run, delayedAttempt, eagerAttempt }; + }); + + await act(async () => { + const promise = result.current.run(); + resolve(Symbol()); + await promise; + }); + + expect(result.current.delayedAttempt.status).toEqual('success'); + + let promise: Promise<[symbol, Error]>; + act(() => { + // Start promise but do not resolve it. + promise = result.current.run(); + }); + + // The _eager_ attempt gets updated to a processing state. + // This means that the hook now enqueued a delayed update of delayedAttempt. + expect(result.current.eagerAttempt.status).toEqual('processing'); + expect(result.current.delayedAttempt.status).toEqual('success'); + + await act(async () => { + // Resolve the promise. This transitions eagerAttempt and delayedAttempt to a success state. + resolve(Symbol()); + await promise; + }); + + expect(result.current.eagerAttempt.status).toEqual('success'); + expect(result.current.delayedAttempt.status).toEqual('success'); + + // Wait until the delay. If the pending update was not properly canceled, this should execute + // it. As such, this will count as a state update outside of `act`, which will surface an error. + // + // In case the update does not get canceled, delayedAttempt will not get updated to pending. + // The pending update will call setCurrentAttempt, which will set currentAttempt to processing. + // The hook will reexecute and the effect will set currentAttempt back to success since + // currentAttempt != attempt. This is all because at the time when the pending update gets + // erroneously executed, eagerAttempt is already successful. + await wait(delayMs); + }); +}); diff --git a/web/packages/shared/hooks/useAsync.ts b/web/packages/shared/hooks/useAsync.ts index f546cff8df2eb..9eeb2dca639e1 100644 --- a/web/packages/shared/hooks/useAsync.ts +++ b/web/packages/shared/hooks/useAsync.ts @@ -47,7 +47,6 @@ import { useCallback, useState, useRef, useEffect } from 'react'; * return { fetchUserProfileAttempt, fetchUserProfile }; * } * - * * @example In the view layer you can use it like this: * function UserProfile(props) { * const { fetchUserProfileAttempt, fetchUserProfile } = useUserProfile(props.id); @@ -274,3 +273,41 @@ export function mapAttempt( data: mapFunction(attempt.data), }; } + +/** + * useDelayedRepeatedAttempt makes it so that on repeated calls to `run`, the attempt changes its + * state to 'processing' only after a delay. This can be used to mask repeated calls and + * optimistically show stale results. + * + * @example + * const [eagerFetchUserProfileAttempt, fetchUserProfile] = useAsync(async () => { + * return await fetch(`/users/${userId}`); + * }) + * const fetchUserProfileAttempt = useDelayedRepeatedAttempt(eagerFetchUserProfileAttempt, 600) + */ +export function useDelayedRepeatedAttempt( + attempt: Attempt, + delayMs = 400 +): Attempt { + const [currentAttempt, setCurrentAttempt] = useState(attempt); + + useEffect(() => { + if ( + currentAttempt.status === 'success' && + attempt.status === 'processing' + ) { + const timeout = setTimeout(() => { + setCurrentAttempt(attempt); + }, delayMs); + return () => { + clearTimeout(timeout); + }; + } + + if (currentAttempt !== attempt) { + setCurrentAttempt(attempt); + } + }, [attempt, currentAttempt, delayMs]); + + return currentAttempt; +} diff --git a/web/packages/shared/utils/wait.ts b/web/packages/shared/utils/wait.ts index 5d4c70bc32f78..3f64695227310 100644 --- a/web/packages/shared/utils/wait.ts +++ b/web/packages/shared/utils/wait.ts @@ -15,6 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { useRef, useEffect } from 'react'; /** Resolves after a given duration. */ export function wait(ms: number, abortSignal?: AbortSignal): Promise { @@ -51,3 +52,23 @@ export function waitForever(abortSignal: AbortSignal): Promise { abortSignal.addEventListener('abort', abort, { once: true }); }); } + +/** + * usePromiseRejectedOnUnmount is useful when writing stories for loading states. + */ +export const usePromiseRejectedOnUnmount = () => { + const abortControllerRef = useRef(new AbortController()); + + useEffect(() => { + return () => { + abortControllerRef.current.abort(); + }; + }, []); + + const promiseRef = useRef>(); + if (!promiseRef.current) { + promiseRef.current = waitForever(abortControllerRef.current.signal); + } + + return promiseRef.current; +}; diff --git a/web/packages/teleterm/src/services/tshd/cloneableClient.ts b/web/packages/teleterm/src/services/tshd/cloneableClient.ts index 725d9a9298bd2..117ad7053e897 100644 --- a/web/packages/teleterm/src/services/tshd/cloneableClient.ts +++ b/web/packages/teleterm/src/services/tshd/cloneableClient.ts @@ -409,9 +409,17 @@ export class MockedUnaryCall onrejected?: (reason: any) => TResult2 | PromiseLike ): Promise { if (this.error) { - // Despite this being an error branch, it needs to use Promise.resolve. Otherwise we'd get - // uncaught errors. See https://www.promisejs.org/implementing/#then - return Promise.resolve(onrejected(this.error)); + if (typeof onrejected === 'function') { + try { + // Despite this being an error branch, it needs to use Promise.resolve. Otherwise we'd get + // uncaught errors. See https://www.promisejs.org/implementing/#then + return Promise.resolve(onrejected(this.error)); + } catch (ex) { + return Promise.reject(ex); + } + } else { + return Promise.reject(this.error); + } } return Promise.resolve( diff --git a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts index 42c0d2f9745ca..5855cc7b19042 100644 --- a/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts +++ b/web/packages/teleterm/src/services/tshd/fixtures/mocks.ts @@ -118,4 +118,5 @@ export class MockTshClient implements TshdClient { export class MockVnetClient implements VnetClient { start = () => new MockedUnaryCall({}); stop = () => new MockedUnaryCall({}); + listDNSZones = () => new MockedUnaryCall({ dnsZones: [] }); } diff --git a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.tsx b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.tsx index 53056328a2a5b..4e70e5b299427 100644 --- a/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.tsx +++ b/web/packages/teleterm/src/ui/ConnectMyComputer/NavigationMenu.tsx @@ -18,7 +18,7 @@ import React, { forwardRef, useRef, useState } from 'react'; import styled, { css } from 'styled-components'; -import { Box, Button, Indicator, Menu, MenuItem } from 'design'; +import { Box, Button, Indicator, Menu, MenuItem, blink } from 'design'; import { Laptop, Warning } from 'design/Icon'; import { Attempt, AttemptStatus } from 'shared/hooks/useAsync'; @@ -214,19 +214,7 @@ const StyledStatus = styled(Box)<{ status: IndicatorStatus }>` border-radius: 50%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - @keyframes blink { - 0% { - opacity: 0; - } - 50% { - opacity: 100%; - } - 100% { - opacity: 0; - } - } - - animation: blink 1.4s ease-in-out; + animation: ${blink} 1.4s ease-in-out; animation-iteration-count: ${props => props.status === 'processing' ? 'infinite' : '0'}; diff --git a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx index 21b2654f8e32f..47fe727ab873f 100644 --- a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.story.tsx @@ -150,37 +150,6 @@ export function VnetError() { ); } -export function VnetUnexpectedShutdown() { - const appContext = new MockAppContext(); - prepareAppContext(appContext); - - appContext.statePersistenceService.putState({ - ...appContext.statePersistenceService.getState(), - vnet: { autoStart: true }, - }); - appContext.workspacesService.setState(draft => { - draft.isInitialized = true; - }); - appContext.vnet.start = () => { - setTimeout(() => { - appContext.unexpectedVnetShutdownListener({ - error: 'lorem ipsum dolor sit amet', - }); - }, 0); - return new MockedUnaryCall({}); - }; - - return ( - - - - - - - - ); -} - export function WithScroll() { const appContext = new MockAppContext(); prepareAppContext(appContext); diff --git a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.tsx b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.tsx index 52422d8e7008e..31384e58f7ecc 100644 --- a/web/packages/teleterm/src/ui/TopBar/Connections/Connections.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Connections/Connections.tsx @@ -75,6 +75,7 @@ export function Connections() { */} . + */ + +import styled from 'styled-components'; +import { Flex, Box, Text } from 'design'; + +import { StaticListItem } from 'teleterm/ui/components/ListItem'; + +import { ConnectionStatusIndicator } from './ConnectionStatusIndicator'; + +export default { + title: 'Teleterm/TopBar/ConnectionStatusIndicator', + decorators: [ + Story => { + return ( + + + + ); + }, + ], +}; + +export const Story = () => ( + + + Block +
    + + {' '} + {text[1]} + + + {' '} + {text[2]} + + + {' '} + {text[0]} + + + {' '} + {text[3]} + + + {' '} + {text[4]} + +
+
+ + + Inline + + + {' '} + {text[1]} + + + {text[2]} + + + {text[0]} + + + {text[3]} + + + {text[4]} + + + +
+); + +const text = [ + 'Lorem ipsum', + 'Et ultrices posuere', + 'Dolor sit amet', + 'Ante ipsum primis', + 'Nec porta augue', +]; + +const ListItem = styled(StaticListItem)` + padding: ${props => props.theme.space[1]}px ${props => props.theme.space[2]}px; +`; diff --git a/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator.tsx b/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator.tsx index 3467a38489b18..d5fd400a1ebdb 100644 --- a/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator.tsx +++ b/web/packages/teleterm/src/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator.tsx @@ -17,9 +17,9 @@ */ import styled, { css } from 'styled-components'; -import { Box } from 'design'; +import { Box, blink } from 'design'; -type Status = 'on' | 'off' | 'error'; +type Status = 'on' | 'off' | 'error' | 'warning' | 'processing'; export const ConnectionStatusIndicator = (props: { status: Status; @@ -37,6 +37,7 @@ const StyledStatus = styled(Box)` width: 8px; height: 8px; border-radius: 50%; + ${(props: { $status: Status; [key: string]: any }) => { const { $status, theme } = props; @@ -44,6 +45,13 @@ const StyledStatus = styled(Box)` case 'on': { return { backgroundColor: theme.colors.success.main }; } + case 'processing': { + return css` + background-color: ${props => props.theme.colors.success.main}; + animation: ${blink} 1.4s ease-in-out; + animation-iteration-count: infinite; + `; + } case 'off': { return { border: `1px solid ${theme.colors.grey[300]}` }; } @@ -72,6 +80,23 @@ const StyledStatus = styled(Box)` } `; } + case 'warning': { + return css` + color: ${theme.colors.warning.main}; + &:after { + content: '⚠'; + font-size: 12px; + + ${!props.$inline && + ` + position: absolute; + top: -1px; + left: -2px; + line-height: 8px; + `} + } + `; + } default: { $status satisfies never; } diff --git a/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.story.tsx b/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.story.tsx new file mode 100644 index 0000000000000..4a9eb7d9ab8aa --- /dev/null +++ b/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.story.tsx @@ -0,0 +1,208 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import { useEffect } from 'react'; +import { Box } from 'design'; + +import { usePromiseRejectedOnUnmount } from 'shared/utils/wait'; + +import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider'; +import { MockAppContext } from 'teleterm/ui/fixtures/mocks'; +import { MockedUnaryCall } from 'teleterm/services/tshd/cloneableClient'; + +import { useVnetContext, VnetContextProvider } from './vnetContext'; +import { VnetSliderStep } from './VnetSliderStep'; + +export default { + title: 'Teleterm/Vnet/VnetSliderStep', + decorators: [ + Story => { + return ( + + + + ); + }, + ], +}; + +const dnsZones = ['teleport.example.com', 'company.test']; + +export function Running() { + const appContext = new MockAppContext(); + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + appContext.vnet.listDNSZones = () => new MockedUnaryCall({ dnsZones }); + + return ( + + + + + + ); +} + +export function UpdatingDnsZones() { + const appContext = new MockAppContext(); + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + const promise = usePromiseRejectedOnUnmount(); + appContext.vnet.listDNSZones = () => promise; + + return ( + + + + + + ); +} + +export function UpdatingDnsZonesWithPreviousResults() { + const appContext = new MockAppContext(); + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + const promise = usePromiseRejectedOnUnmount(); + let firstCall = true; + appContext.vnet.listDNSZones = () => { + if (firstCall) { + firstCall = false; + return new MockedUnaryCall({ dnsZones }); + } + return promise; + }; + + return ( + + + + + + + ); +} + +const RerequestDNSZones = () => { + const { listDNSZones, listDNSZonesAttempt } = useVnetContext(); + + useEffect(() => { + if (listDNSZonesAttempt.status === 'success') { + listDNSZones(); + } + }, [listDNSZonesAttempt, listDNSZones]); + + return null; +}; + +export function DnsZonesError() { + const appContext = new MockAppContext(); + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + appContext.vnet.listDNSZones = () => + new MockedUnaryCall(undefined, new Error('something went wrong')); + + return ( + + + + + + ); +} + +export function StartError() { + const appContext = new MockAppContext(); + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + appContext.vnet.start = () => + new MockedUnaryCall(undefined, new Error('something went wrong')); + + return ( + + + + + + ); +} + +export function UnexpectedShutdown() { + const appContext = new MockAppContext(); + + appContext.statePersistenceService.putState({ + ...appContext.statePersistenceService.getState(), + vnet: { autoStart: true }, + }); + appContext.workspacesService.setState(draft => { + draft.isInitialized = true; + }); + appContext.vnet.start = () => { + setTimeout(() => { + appContext.unexpectedVnetShutdownListener({ + error: 'lorem ipsum dolor sit amet', + }); + }, 0); + return new MockedUnaryCall({}); + }; + + return ( + + + + + + ); +} + +const Component = () => ( + +); + +const noop = () => {}; diff --git a/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.tsx b/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.tsx index 697ad53a42bfa..234fe9c95344c 100644 --- a/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.tsx +++ b/web/packages/teleterm/src/ui/Vnet/VnetSliderStep.tsx @@ -16,14 +16,13 @@ * along with this program. If not, see . */ -import { PropsWithChildren, useCallback } from 'react'; +import { PropsWithChildren, useEffect, useRef } from 'react'; import { StepComponentProps } from 'design/StepSlider'; -import { Box, Flex, Text } from 'design'; +import { Box, ButtonSecondary, Flex, Text } from 'design'; import { mergeRefs } from 'shared/libs/mergeRefs'; import { useRefAutoFocus } from 'shared/hooks'; -import * as whatwg from 'whatwg-url'; +import { useDelayedRepeatedAttempt } from 'shared/hooks/useAsync'; -import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; import { ConnectionStatusIndicator } from 'teleterm/ui/TopBar/Connections/ConnectionsFilterableList/ConnectionStatusIndicator'; import { useVnetContext } from './vnetContext'; @@ -39,16 +38,6 @@ export const VnetSliderStep = (props: StepComponentProps) => { const autoFocusRef = useRefAutoFocus({ shouldFocus: visible, }); - const clusters = useStoreSelector( - 'clustersService', - useCallback(state => state.clusters, []) - ); - const rootClusters = [...clusters.values()].filter( - cluster => !cluster.leaf && cluster.connected - ); - const rootProxyHostnames = rootClusters.map( - cluster => new whatwg.URL(`https://${cluster.proxyHost}`).hostname - ); return ( // Padding needs to align with the padding of the previous slider step. @@ -102,21 +91,7 @@ export const VnetSliderStep = (props: StepComponentProps) => { ))}
- {status.value === 'running' && - (rootClusters.length === 0 ? ( - - No clusters connected yet, VNet is not proxying any connections. - - ) : ( - <> - {/* TODO(ravicious): Add leaf clusters and custom DNS zones when support for them - lands in VNet. */} - - Proxying - TCP connections to {rootProxyHostnames.join(', ')} - - - ))} + {status.value === 'running' && }
); }; @@ -129,3 +104,78 @@ const ErrorText = (props: PropsWithChildren) => ( {props.children} ); + +/** + * DnsZones displays the list of currently proxied DNS zones, as understood by the VNet admin + * process. The list is cached in the context and updated when the VNet panel gets opened. + * + * As for 95% of users the list will never change during the lifespan of VNet, the VNet panel always + * optimistically displays previously fetched results while fetching new list. + */ +const DnsZones = () => { + const { listDNSZones, listDNSZonesAttempt: eagerListDNSZonesAttempt } = + useVnetContext(); + const listDNSZonesAttempt = useDelayedRepeatedAttempt( + eagerListDNSZonesAttempt + ); + const dnsZonesRefreshRequestedRef = useRef(false); + + useEffect(function refreshListOnOpen() { + if (!dnsZonesRefreshRequestedRef.current) { + dnsZonesRefreshRequestedRef.current = true; + listDNSZones(); + } + }, []); + + if (listDNSZonesAttempt.status === 'error') { + return ( + + + VNet is working, but Teleport Connect could not fetch DNS zones:{' '} + {listDNSZonesAttempt.statusText} + + Retry + + + ); + } + + if ( + listDNSZonesAttempt.status === '' || + (listDNSZonesAttempt.status === 'processing' && !listDNSZonesAttempt.data) + ) { + return ( + + + Updating the list of DNS zones… + + ); + } + + const dnsZones = listDNSZonesAttempt.data; + + return ( + + + {dnsZones.length === 0 ? ( + <>No clusters connected yet, VNet is not proxying any connections. + ) : ( + <>Proxying TCP connections to {dnsZones.join(', ')} + )} + + ); +}; diff --git a/web/packages/teleterm/src/ui/Vnet/vnetContext.tsx b/web/packages/teleterm/src/ui/Vnet/vnetContext.tsx index 4db7891fc3310..3b731ab77b2fd 100644 --- a/web/packages/teleterm/src/ui/Vnet/vnetContext.tsx +++ b/web/packages/teleterm/src/ui/Vnet/vnetContext.tsx @@ -31,6 +31,7 @@ import { useAsync, Attempt } from 'shared/hooks/useAsync'; import { useAppContext } from 'teleterm/ui/appContextProvider'; import { usePersistedState } from 'teleterm/ui/hooks/usePersistedState'; import { useStoreSelector } from 'teleterm/ui/hooks/useStoreSelector'; +import { isTshdRpcError } from 'teleterm/services/tshd'; /** * VnetContext manages the VNet instance. @@ -47,6 +48,8 @@ export type VnetContext = { startAttempt: Attempt; stop: () => Promise<[void, Error]>; stopAttempt: Attempt; + listDNSZones: () => Promise<[string[], Error]>; + listDNSZonesAttempt: Attempt; }; export type VnetStatus = @@ -81,7 +84,13 @@ export const VnetContextProvider: FC = props => { const [startAttempt, start] = useAsync( useCallback(async () => { - await vnet.start({}); + try { + await vnet.start({}); + } catch (error) { + if (!isTshdRpcError(error, 'ALREADY_EXISTS')) { + throw error; + } + } setStatus({ value: 'running' }); setAppState({ autoStart: true }); }, [vnet, setAppState]) @@ -98,6 +107,13 @@ export const VnetContextProvider: FC = props => { }, [vnet, setAppState]) ); + const [listDNSZonesAttempt, listDNSZones] = useAsync( + useCallback( + () => vnet.listDNSZones({}).then(({ response }) => response.dnsZones), + [vnet] + ) + ); + useEffect(() => { const handleAutoStart = async () => { if ( @@ -151,6 +167,8 @@ export const VnetContextProvider: FC = props => { startAttempt, stop, stopAttempt, + listDNSZones, + listDNSZonesAttempt, }} > {props.children} From c653a844f19af879aae5323fdbd23e5a295e0e9e Mon Sep 17 00:00:00 2001 From: Forrest <30576607+fspmarshall@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:20:16 -0700 Subject: [PATCH 24/30] add ability to disable unqualified hostname lookups (#42952) --- api/utils/route.go | 10 +++++- api/utils/route_test.go | 63 +++++++++++++++++++++++++++++++++++++ lib/auth/auth_with_roles.go | 13 +++++++- lib/proxy/router.go | 12 ++++--- 4 files changed, 92 insertions(+), 6 deletions(-) diff --git a/api/utils/route.go b/api/utils/route.go index 03df193065978..1ca83926e4ee1 100644 --- a/api/utils/route.go +++ b/api/utils/route.go @@ -19,6 +19,7 @@ import ( "errors" "net" "slices" + "strings" "unicode/utf8" "github.com/google/uuid" @@ -49,6 +50,8 @@ type SSHRouteMatcherConfig struct { Resolver HostResolver // CaseInsensitive enabled case insensitive routing when true. CaseInsensitive bool + // DisableUnqualifiedLookups disables lookups for unqualified hostnames. + DisableUnqualifiedLookups bool } // HostResolver provides an interface matching the net.Resolver.LookupHost method. Typically @@ -88,7 +91,12 @@ func newSSHRouteMatcher(cfg SSHRouteMatcherConfig) SSHRouteMatcher { _, err := uuid.Parse(cfg.Host) dialByID := err == nil || aws.IsEC2NodeID(cfg.Host) - ips, _ := cfg.Resolver.LookupHost(context.Background(), cfg.Host) + var ips []string + if !(cfg.DisableUnqualifiedLookups && !strings.Contains(cfg.Host, ".")) { + // unqualified lookups are still on by default, but future versions of teleport may disable them as they tend + // to be responsible for the majority of all lookups generated by a teleport cluster and are of questionable utility. + ips, _ = cfg.Resolver.LookupHost(context.Background(), cfg.Host) + } return SSHRouteMatcher{ cfg: cfg, diff --git a/api/utils/route_test.go b/api/utils/route_test.go index 5de05efa673d8..ce971e04e6ea3 100644 --- a/api/utils/route_test.go +++ b/api/utils/route_test.go @@ -323,3 +323,66 @@ func TestSSHRouteMatcherScoring(t *testing.T) { }) } } + +type recordingHostResolver struct { + didLookup bool +} + +func (r *recordingHostResolver) LookupHost(ctx context.Context, host string) (addrs []string, err error) { + r.didLookup = true + return nil, nil +} + +// TestDisableUnqualifiedLookups verifies that unqualified lookups being disabled results +// in single-element/tld style hostname targets not being resolved. +func TestDisableUnqualifiedLookups(t *testing.T) { + tts := []struct { + desc string + target string + lookup bool + }{ + { + desc: "qualified hostname", + target: "example.com", + lookup: true, + }, + { + desc: "unqualified hostname", + target: "example", + lookup: false, + }, + { + desc: "localhost", + target: "localhost", + lookup: false, + }, + { + desc: "foo.localhost", + target: "foo.localhost", + lookup: true, + }, + { + desc: "uuid", + target: uuid.NewString(), + lookup: false, + }, + { + desc: "qualified uuid", + target: "foo." + uuid.NewString(), + lookup: true, + }, + } + + for _, tt := range tts { + t.Run(tt.desc, func(t *testing.T) { + resolver := &recordingHostResolver{} + _, err := NewSSHRouteMatcherFromConfig(SSHRouteMatcherConfig{ + Host: tt.target, + Resolver: resolver, + DisableUnqualifiedLookups: true, + }) + require.NoError(t, err) + require.Equal(t, tt.lookup, resolver.didLookup) + }) + } +} diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index 66711ac7a9ee7..e5c7d4ff0428a 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "net/url" + "os" "slices" "strings" "time" @@ -1547,6 +1548,8 @@ func (a *ServerWithRoles) authContextForSearch(ctx context.Context, req *proto.L return extendedContext, nil } +var disableUnqualifiedLookups = os.Getenv("TELEPORT_UNSTABLE_DISABLE_UNQUALIFIED_LOOKUPS") == "yes" + // GetSSHTargets gets all servers that would match an equivalent ssh dial request. Note that this method // returns all resources directly accessible to the user *and* all resources available via 'SearchAsRoles', // which is what we want when handling things like ambiguous host errors and resource-based access requests, @@ -1559,7 +1562,15 @@ func (a *ServerWithRoles) GetSSHTargets(ctx context.Context, req *proto.GetSSHTa caseInsensitiveRouting = cfg.GetCaseInsensitiveRouting() } - matcher := apiutils.NewSSHRouteMatcher(req.Host, req.Port, caseInsensitiveRouting) + matcher, err := apiutils.NewSSHRouteMatcherFromConfig(apiutils.SSHRouteMatcherConfig{ + Host: req.Host, + Port: req.Port, + CaseInsensitive: caseInsensitiveRouting, + DisableUnqualifiedLookups: disableUnqualifiedLookups, + }) + if err != nil { + return nil, trace.Wrap(err) + } lreq := proto.ListResourcesRequest{ ResourceType: types.KindNode, diff --git a/lib/proxy/router.go b/lib/proxy/router.go index ade4b4c0f7a53..4028ab026bd9a 100644 --- a/lib/proxy/router.go +++ b/lib/proxy/router.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "net" + "os" "sync" "github.com/gravitational/trace" @@ -417,6 +418,8 @@ func getServer(ctx context.Context, host, port string, site site) (types.Server, return getServerWithResolver(ctx, host, port, site, nil /* use default resolver */) } +var disableUnqualifiedLookups = os.Getenv("TELEPORT_UNSTABLE_DISABLE_UNQUALIFIED_LOOKUPS") == "yes" + // getServerWithResolver attempts to locate a node matching the provided host and port in // the provided site. The resolver argument is used in certain tests to mock DNS resolution // and can generally be left nil. @@ -433,10 +436,11 @@ func getServerWithResolver(ctx context.Context, host, port string, site site, re } routeMatcher, err := apiutils.NewSSHRouteMatcherFromConfig(apiutils.SSHRouteMatcherConfig{ - Host: host, - Port: port, - CaseInsensitive: caseInsensitiveRouting, - Resolver: resolver, + Host: host, + Port: port, + CaseInsensitive: caseInsensitiveRouting, + Resolver: resolver, + DisableUnqualifiedLookups: disableUnqualifiedLookups, }) if err != nil { return nil, trace.Wrap(err) From 800e8e896d65f126eb320a8a6d92f8441fa67549 Mon Sep 17 00:00:00 2001 From: Brian Joerger Date: Thu, 20 Jun 2024 13:32:55 -0700 Subject: [PATCH 25/30] MFA for App Access - `tsh` for cloud apps (#40985) * Add generic app proxy implementation. * Incorporate forwarding proxy in generic app proxy. * Utilize cert checker middleware for http local proxies. * Use generalized local proxy app for aws. * Use generalized local proxy app for azure. * Use generalized local proxy app for gcp. * Refactor, simplify, and unify app logic logic for app, proxy app, and cloud commands. * * Load existing app certs before reissuing new certs for proxy app commands * Fix the same intended functionality for tsh proxy db * Fix hardware key test for tsh app login. * Remove unused code. * Fix merge conflict. * Address Gavin's comments. * Restore RetryWithRelogin for app commands by making missing profile status a retryable error; cache profile status in appInfo. * Address Tim's comments. * Remove read lock. * Add tests to CertChecker and LocalCertGenerator. * Fix lint. --- integration/proxy/proxy_helpers.go | 7 +- lib/client/api.go | 2 +- lib/client/client_store.go | 22 +- lib/client/local_proxy_middleware.go | 321 ++++++++++++++++-- lib/client/local_proxy_middleware_test.go | 173 ++++++++++ lib/srv/alpnproxy/local_proxy.go | 72 ++-- lib/srv/alpnproxy/local_proxy_config_opt.go | 4 +- lib/srv/alpnproxy/local_proxy_test.go | 2 +- tool/tsh/common/app.go | 358 +++++++++++--------- tool/tsh/common/app_aws.go | 187 ++-------- tool/tsh/common/app_azure.go | 190 +++-------- tool/tsh/common/app_cloud.go | 129 ------- tool/tsh/common/app_cloud_test.go | 95 ------ tool/tsh/common/app_gcp.go | 181 ++-------- tool/tsh/common/app_gcp_test.go | 9 +- tool/tsh/common/app_local_proxy.go | 208 ++++++++++++ tool/tsh/common/app_test.go | 37 +- tool/tsh/common/db.go | 8 +- tool/tsh/common/hardware_key_test.go | 105 +++--- tool/tsh/common/kube_proxy.go | 4 +- tool/tsh/common/proxy.go | 143 ++------ 21 files changed, 1132 insertions(+), 1125 deletions(-) create mode 100644 lib/client/local_proxy_middleware_test.go delete mode 100644 tool/tsh/common/app_cloud.go delete mode 100644 tool/tsh/common/app_cloud_test.go create mode 100644 tool/tsh/common/app_local_proxy.go diff --git a/integration/proxy/proxy_helpers.go b/integration/proxy/proxy_helpers.go index 34fc9c56f0f5f..e766bb9ae4dc8 100644 --- a/integration/proxy/proxy_helpers.go +++ b/integration/proxy/proxy_helpers.go @@ -531,12 +531,7 @@ func mustStartALPNLocalProxyWithConfig(t *testing.T, config alpnproxy.LocalProxy }) go func() { - var err error - if config.HTTPMiddleware == nil { - err = lp.Start(context.Background()) - } else { - err = lp.StartHTTPAccessProxy(context.Background()) - } + err := lp.Start(context.Background()) assert.NoError(t, err) }() return lp diff --git a/lib/client/api.go b/lib/client/api.go index 173654cabb1af..26d8eaff141b7 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -593,7 +593,7 @@ func RetryWithRelogin(ctx context.Context, tc *TeleportClient, fn func() error, case utils.IsPredicateError(fnErr): return trace.Wrap(utils.PredicateError{Err: fnErr}) case tc.NonInteractive: - return trace.Wrap(fnErr) + return trace.Wrap(fnErr, "cannot relogin in non-interactive session") case !IsErrorResolvableWithRelogin(fnErr): return trace.Wrap(fnErr) } diff --git a/lib/client/client_store.go b/lib/client/client_store.go index ab55d629bba54..0b0b4f10b120c 100644 --- a/lib/client/client_store.go +++ b/lib/client/client_store.go @@ -82,14 +82,21 @@ func (s *Store) AddKey(key *Key) error { return nil } -// ErrNoCredentials is returned by the client store when a specific key is not found. -// This error can be used to determine whether a client should retrieve new credentials, -// like how it is used with lib/client.RetryWithRelogin. -var ErrNoCredentials = trace.NotFound("no credentials") +var ( + // ErrNoCredentials is returned by the client store when a specific key is not found. + // This error can be used to determine whether a client should retrieve new credentials, + // like how it is used with lib/client.RetryWithRelogin. + ErrNoCredentials = &trace.NotFoundError{Message: "no credentials"} -// IsNoCredentialsError returns whether the given error is an ErrNoCredentials error. + // ErrNoProfile is returned by the client store when a specific profile is not found. + // This error can be used to determine whether a client should retrieve new credentials, + // like how it is used with lib/client.RetryWithRelogin. + ErrNoProfile = &trace.NotFoundError{Message: "no profile"} +) + +// IsNoCredentialsError returns whether the given error implies that the user should retrieve new credentials. func IsNoCredentialsError(err error) bool { - return errors.Is(err, ErrNoCredentials) + return errors.Is(err, ErrNoCredentials) || errors.Is(err, ErrNoProfile) } // GetKey gets the requested key with trusted the requested certificates. The key's @@ -161,6 +168,9 @@ func (s *Store) ReadProfileStatus(profileName string) (*ProfileStatus, error) { profile, err := s.GetProfile(profileName) if err != nil { + if trace.IsNotFound(err) { + return nil, trace.Wrap(ErrNoProfile, err.Error()) + } return nil, trace.Wrap(err) } idx := KeyIndex{ diff --git a/lib/client/local_proxy_middleware.go b/lib/client/local_proxy_middleware.go index aae23ba25996d..e093cdb6c6060 100644 --- a/lib/client/local_proxy_middleware.go +++ b/lib/client/local_proxy_middleware.go @@ -20,16 +20,26 @@ package client import ( "context" + "crypto" + "crypto/rand" + "crypto/rsa" "crypto/tls" "crypto/x509" + "crypto/x509/pkix" + "net" + "os" + "sync" "time" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/constants" "github.com/gravitational/teleport/api/mfa" + "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/auth/authclient" + "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/srv/alpnproxy" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" @@ -38,26 +48,31 @@ import ( // CertChecker is a local proxy middleware that ensures certs are valid // on start up and on each new connection. type CertChecker struct { - // CertReissuer checks and reissues certs. - CertReissuer CertIssuer + // certIssuer checks and issues certs. + certIssuer CertIssuer // clock specifies the time provider. Will be used to override the time anchor // for TLS certificate verification. Defaults to real clock if unspecified clock clockwork.Clock + + cert tls.Certificate + certMu sync.Mutex } var _ alpnproxy.LocalProxyMiddleware = (*CertChecker)(nil) +// NewCertChecker creates a new CertChecker with the given CertIssuer. func NewCertChecker(certIssuer CertIssuer, clock clockwork.Clock) *CertChecker { if clock == nil { clock = clockwork.NewRealClock() } + return &CertChecker{ - CertReissuer: certIssuer, - clock: clock, + certIssuer: certIssuer, + clock: clock, } } -// Create a new CertChecker for the given database. +// NewDBCertChecker creates a new CertChecker for the given database. func NewDBCertChecker(tc *TeleportClient, dbRoute tlsca.RouteToDatabase, clock clockwork.Clock) *CertChecker { return NewCertChecker(&DBCertIssuer{ Client: tc, @@ -65,7 +80,7 @@ func NewDBCertChecker(tc *TeleportClient, dbRoute tlsca.RouteToDatabase, clock c }, clock) } -// Create a new CertChecker for the given app. +// NewAppCertChecker creates a new CertChecker for the given app. func NewAppCertChecker(tc *TeleportClient, appRoute proto.RouteToApp, clock clockwork.Clock) *CertChecker { return NewCertChecker(&AppCertIssuer{ Client: tc, @@ -76,37 +91,72 @@ func NewAppCertChecker(tc *TeleportClient, appRoute proto.RouteToApp, clock cloc // OnNewConnection is a callback triggered when a new downstream connection is // accepted by the local proxy. func (c *CertChecker) OnNewConnection(ctx context.Context, lp *alpnproxy.LocalProxy) error { - return trace.Wrap(c.ensureValidCerts(ctx, lp)) + cert, err := c.GetOrIssueCert(ctx) + if err != nil { + return trace.Wrap(err) + } + + lp.SetCert(cert) + return nil } // OnStart is a callback triggered when the local proxy starts. func (c *CertChecker) OnStart(ctx context.Context, lp *alpnproxy.LocalProxy) error { - return trace.Wrap(c.ensureValidCerts(ctx, lp)) + cert, err := c.GetOrIssueCert(ctx) + if err != nil { + return trace.Wrap(err) + } + + lp.SetCert(cert) + return nil } -// ensureValidCerts ensures that the local proxy is configured with valid certs. -func (c *CertChecker) ensureValidCerts(ctx context.Context, lp *alpnproxy.LocalProxy) error { - if err := lp.CheckCert(c.CertReissuer.CheckCert); err != nil { - log.WithError(err).Debug("local proxy tunnel certificates need to be reissued") - } else { - return nil +// SetCert sets the CertChecker's certificate. +func (c *CertChecker) SetCert(cert tls.Certificate) { + c.certMu.Lock() + defer c.certMu.Unlock() + c.cert = cert +} + +// GetOrIssueCert gets the CertChecker's certificate, or issues a new +// certificate if the it is invalid (e.g. expired) or missing. +func (c *CertChecker) GetOrIssueCert(ctx context.Context) (tls.Certificate, error) { + c.certMu.Lock() + defer c.certMu.Unlock() + + if err := c.checkCert(); err == nil { + return c.cert, nil } - cert, err := c.CertReissuer.IssueCert(ctx) + cert, err := c.certIssuer.IssueCert(ctx) if err != nil { - return trace.Wrap(err) + return tls.Certificate{}, trace.Wrap(err) } // reduce per-handshake processing by setting the parsed leaf. if err := utils.InitCertLeaf(&cert); err != nil { - return trace.Wrap(err) + return tls.Certificate{}, trace.Wrap(err) } certTTL := cert.Leaf.NotAfter.Sub(c.clock.Now()).Round(time.Minute) log.Debugf("Certificate renewed: valid until %s [valid for %v]", cert.Leaf.NotAfter.Format(time.RFC3339), certTTL) - lp.SetCert(cert) - return nil + c.cert = cert + return c.cert, nil +} + +func (c *CertChecker) checkCert() error { + leaf, err := utils.TLSCertLeaf(c.cert) + if err != nil { + return trace.Wrap(err) + } + + // Check for cert expiration. + if err := utils.VerifyCertificateExpiry(leaf, c.clock); err != nil { + return trace.Wrap(err) + } + + return trace.Wrap(c.certIssuer.CheckCert(leaf)) } // CertIssuer checks and issues certs. @@ -139,7 +189,7 @@ func (c *DBCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) { var key *Key if err := RetryWithRelogin(ctx, c.Client, func() error { - newKey, err := c.Client.IssueUserCertsWithMFA(ctx, ReissueParams{ + dbCertParams := ReissueParams{ RouteToCluster: c.Client.SiteName, RouteToDatabase: proto.RouteToDatabase{ ServiceName: c.RouteToApp.ServiceName, @@ -149,7 +199,26 @@ func (c *DBCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) { }, AccessRequests: accessRequests, RequesterName: proto.UserCertsRequest_TSH_DB_LOCAL_PROXY_TUNNEL, - }, mfa.WithPromptReasonSessionMFA("database", c.RouteToApp.ServiceName)) + } + + clusterClient, err := c.Client.ConnectToCluster(ctx) + if err != nil { + return trace.Wrap(err) + } + + newKey, mfaRequired, err := clusterClient.IssueUserCertsWithMFA(ctx, dbCertParams, c.Client.NewMFAPrompt(mfa.WithPromptReasonSessionMFA("database", c.RouteToApp.ServiceName))) + if err != nil { + return trace.Wrap(err) + } + + // If MFA was not required, we do not require certs be stored solely in memory. + // Save it to disk to avoid additional roundtrips for future requests. + if mfaRequired == proto.MFARequired_MFA_REQUIRED_NO { + if err := c.Client.LocalAgent().AddDatabaseKey(newKey); err != nil { + return trace.Wrap(err) + } + } + key = newKey return trace.Wrap(err) }); err != nil { @@ -193,11 +262,12 @@ func (c *AppCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) RequesterName: proto.UserCertsRequest_TSH_APP_LOCAL_PROXY, } - // TODO (Joerger): DELETE IN v17.0.0 clusterClient, err := c.Client.ConnectToCluster(ctx) if err != nil { return trace.Wrap(err) } + + // TODO (Joerger): DELETE IN v17.0.0 rootClient, err := clusterClient.ConnectToRootCluster(ctx) if err != nil { return trace.Wrap(err) @@ -207,7 +277,19 @@ func (c *AppCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) return trace.Wrap(err) } - newKey, _, err := clusterClient.IssueUserCertsWithMFA(ctx, appCertParams, c.Client.NewMFAPrompt(mfa.WithPromptReasonSessionMFA("application", c.RouteToApp.Name))) + newKey, mfaRequired, err := clusterClient.IssueUserCertsWithMFA(ctx, appCertParams, c.Client.NewMFAPrompt(mfa.WithPromptReasonSessionMFA("application", c.RouteToApp.Name))) + if err != nil { + return trace.Wrap(err) + } + + // If MFA was not required, we do not require certs be stored solely in memory. + // Save it to disk to avoid additional roundtrips for future requests. + if mfaRequired == proto.MFARequired_MFA_REQUIRED_NO { + if err := c.Client.LocalAgent().AddAppKey(newKey); err != nil { + return trace.Wrap(err) + } + } + key = newKey return trace.Wrap(err) }); err != nil { @@ -220,3 +302,196 @@ func (c *AppCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) } return appCert, nil } + +// LocalCertGenerator is a TLS Certificate generator used to inject +// valid TLS certificates based on SNI during local HTTPS handshakes. +type LocalCertGenerator struct { + certChecker *CertChecker + caPath string + + mu sync.Mutex + // ca is the certificate authority for signing certificates. + ca tls.Certificate + // certsByHost is a cache of certs for hosts generated with the local CA. + // The key is the host's servername SNI. + certsByHost map[string]*tls.Certificate +} + +// NewLocalCertGenerator creates a new LocalCertGenerator and listens to the +// configured listen address. +func NewLocalCertGenerator(ctx context.Context, certChecker *CertChecker, caPath string) (*LocalCertGenerator, error) { + r := &LocalCertGenerator{ + certChecker: certChecker, + caPath: caPath, + } + + if err := r.ensureValidCA(ctx); err != nil { + return nil, trace.Wrap(err) + } + + return r, nil +} + +// GetCertificate generates and returns TLS certificate for incoming +// connection. Implements tls.Config.GetCertificate. +func (r *LocalCertGenerator) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { + if err := r.ensureValidCA(clientHello.Context()); err != nil { + return nil, trace.Wrap(err) + } + + cert, err := r.generateCert(clientHello.ServerName) + if err != nil { + return nil, trace.WrapWithMessage(err, "failed to generate certificate for %q: %v", clientHello.ServerName, err) + } + + return cert, nil +} + +// generateCert generates a new certificate for the specified host. +func (r *LocalCertGenerator) generateCert(host string) (*tls.Certificate, error) { + r.mu.Lock() + defer r.mu.Unlock() + if cert, found := r.certsByHost[host]; found { + return cert, nil + } + + certKey, err := rsa.GenerateKey(rand.Reader, constants.RSAKeySize) + if err != nil { + return nil, trace.Wrap(err) + } + + certAuthority, err := tlsca.FromTLSCertificate(r.ca) + if err != nil { + return nil, trace.Wrap(err) + } + + subject := certAuthority.Cert.Subject + subject.CommonName = host + + certPem, err := certAuthority.GenerateCertificate(tlsca.CertificateRequest{ + PublicKey: &certKey.PublicKey, + Subject: subject, + NotAfter: certAuthority.Cert.NotAfter, + DNSNames: []string{host}, + }) + if err != nil { + return nil, trace.Wrap(err) + } + + cert, err := tls.X509KeyPair(certPem, tlsca.MarshalPrivateKeyPEM(certKey)) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := utils.InitCertLeaf(&cert); err != nil { + return nil, trace.Wrap(err) + } + + r.certsByHost[host] = &cert + return &cert, nil +} + +// ensureValidCA checks if the CA is valid. If it is no longer valid, generate a new +// CA and clear the host cert cache. +func (r *LocalCertGenerator) ensureValidCA(ctx context.Context) error { + r.mu.Lock() + defer r.mu.Unlock() + + // Check if the CA is invalid (expired) + if err := r.checkCA(); err == nil { + return nil + } + + // Generate a new CA from a valid remote cert. + remoteTLSCert, err := r.certChecker.GetOrIssueCert(ctx) + if err != nil { + return trace.Wrap(err) + } + + caTLSCert, err := generateSelfSignedCAFromCert(remoteTLSCert, r.caPath) + if err != nil { + return trace.Wrap(err) + } + + if err := utils.InitCertLeaf(&caTLSCert); err != nil { + return trace.Wrap(err) + } + + certTTL := time.Until(caTLSCert.Leaf.NotAfter).Round(time.Minute) + log.Debugf("Local CA renewed: valid until %s [valid for %v]", caTLSCert.Leaf.NotAfter.Format(time.RFC3339), certTTL) + + // Clear cert cache and use CA for hostnames in the CA. + r.certsByHost = make(map[string]*tls.Certificate) + for _, host := range caTLSCert.Leaf.DNSNames { + r.certsByHost[host] = &caTLSCert + } + + // Requests to IPs have no server names. Default to CA. + r.certsByHost[""] = &caTLSCert + + r.ca = caTLSCert + return nil +} + +func (r *LocalCertGenerator) checkCA() error { + caCert, err := utils.TLSCertLeaf(r.ca) + if err != nil { + return trace.Wrap(err) + } + + err = utils.VerifyCertificateExpiry(caCert, nil /*real clock*/) + return trace.Wrap(err) +} + +// generateSelfSignedCA generates a new self-signed CA for localhost +// and saves/overwrites the local CA file in the given path. +func generateSelfSignedCAFromCert(cert tls.Certificate, caPath string) (tls.Certificate, error) { + certExpiry, err := getTLSCertExpireTime(cert) + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + signer, ok := cert.PrivateKey.(crypto.Signer) + if !ok { + return tls.Certificate{}, trace.BadParameter("private key type %T does not implement crypto.Signer", cert.PrivateKey) + } + + certPem, err := tlsca.GenerateSelfSignedCAWithConfig(tlsca.GenerateCAConfig{ + Entity: pkix.Name{ + CommonName: "localhost", + Organization: []string{"Teleport"}, + }, + Signer: signer, + DNSNames: []string{"localhost"}, + IPAddresses: []net.IP{net.ParseIP(defaults.Localhost)}, + TTL: time.Until(certExpiry), + }) + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + if _, err := utils.EnsureLocalPath(caPath, "", ""); err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + if err = os.WriteFile(caPath, certPem, 0o600); err != nil { + return tls.Certificate{}, trace.ConvertSystemError(err) + } + + keyPem, err := keys.MarshalPrivateKey(signer) + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + caCert, err := tls.X509KeyPair(certPem, keyPem) + return caCert, trace.Wrap(err) +} + +// getTLSCertExpireTime returns the certificate NotAfter time. +func getTLSCertExpireTime(cert tls.Certificate) (time.Time, error) { + x509cert, err := utils.TLSCertLeaf(cert) + if err != nil { + return time.Time{}, trace.Wrap(err) + } + return x509cert.NotAfter, nil +} diff --git a/lib/client/local_proxy_middleware_test.go b/lib/client/local_proxy_middleware_test.go new file mode 100644 index 0000000000000..bc32ab4b16e32 --- /dev/null +++ b/lib/client/local_proxy_middleware_test.go @@ -0,0 +1,173 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package client_test + +import ( + "context" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "path/filepath" + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/lib/auth/native" + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/tlsca" +) + +func TestCertChecker(t *testing.T) { + ctx := context.Background() + clock := clockwork.NewFakeClock() + certIssuer := newMockCertIssuer(t, clock) + certChecker := client.NewCertChecker(certIssuer, clock) + + // certChecker should issue a new cert on first request. + cert, err := certChecker.GetOrIssueCert(ctx) + require.NoError(t, err) + + // subsequent calls should return the same cert. + sameCert, err := certChecker.GetOrIssueCert(ctx) + require.NoError(t, err) + require.Equal(t, cert, sameCert) + + // If the current cert expires it should be reissued. + clock.Advance(2 * time.Minute) + expiredCert := cert + + cert, err = certChecker.GetOrIssueCert(ctx) + require.NoError(t, err) + require.NotEqual(t, cert, expiredCert) + + // If the current cert fails certIssuer checks, a new one should be issued. + certIssuer.checkErr = trace.BadParameter("bad cert") + badCert := cert + + cert, err = certChecker.GetOrIssueCert(ctx) + require.NoError(t, err) + require.NotEqual(t, cert, badCert) + + // If issuing a new cert fails, an error is returned. + certIssuer.issueErr = trace.BadParameter("failed to issue cert") + _, err = certChecker.GetOrIssueCert(ctx) + require.ErrorIs(t, err, certIssuer.issueErr, "expected error %v but got %v", certIssuer.issueErr, err) +} + +func TestLocalCertGenerator(t *testing.T) { + ctx := context.Background() + clock := clockwork.NewFakeClock() + certIssuer := newMockCertIssuer(t, clock) + certChecker := client.NewCertChecker(certIssuer, clock) + caPath := filepath.Join(t.TempDir(), "localca.pem") + + localCertGenerator, err := client.NewLocalCertGenerator(ctx, certChecker, caPath) + require.NoError(t, err) + + // The cert generator should return the local CA cert for SNIs "localhost" or empty (plain ip). + caCert, err := localCertGenerator.GetCertificate(&tls.ClientHelloInfo{ + ServerName: "localhost", + }) + require.NoError(t, err) + require.Equal(t, []string{"localhost"}, caCert.Leaf.DNSNames) + + cert, err := localCertGenerator.GetCertificate(&tls.ClientHelloInfo{ + ServerName: "", + }) + require.NoError(t, err) + require.Equal(t, caCert, cert) + + // The cert generator should issue new certs from the local CA for other SNIs. + exampleCert, err := localCertGenerator.GetCertificate(&tls.ClientHelloInfo{ + ServerName: "example.com", + }) + require.NoError(t, err) + require.Equal(t, []string{"example.com"}, exampleCert.Leaf.DNSNames) +} + +type mockCertIssuer struct { + ca *tlsca.CertAuthority + clock clockwork.Clock + checkErr error + issueErr error +} + +func newMockCertIssuer(t *testing.T, clock clockwork.Clock) *mockCertIssuer { + certIssuer := &mockCertIssuer{ + clock: clock, + } + + certIssuer.initCA(t) + return certIssuer +} + +func (c *mockCertIssuer) initCA(t *testing.T) { + priv, err := native.GeneratePrivateKey() + require.NoError(t, err) + + cert, err := tlsca.GenerateSelfSignedCAWithConfig(tlsca.GenerateCAConfig{ + Signer: priv, + Entity: pkix.Name{ + CommonName: "root", + Organization: []string{"teleport"}, + }, + TTL: defaults.CATTL, + Clock: c.clock, + }) + require.NoError(t, err) + + c.ca, err = tlsca.FromCertAndSigner(cert, priv) + require.NoError(t, err) +} + +func (c *mockCertIssuer) CheckCert(cert *x509.Certificate) error { + return trace.Wrap(c.checkErr) +} + +func (c *mockCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) { + if c.issueErr != nil { + return tls.Certificate{}, trace.Wrap(c.issueErr) + } + + priv, err := native.GeneratePrivateKey() + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + certPem, err := c.ca.GenerateCertificate(tlsca.CertificateRequest{ + PublicKey: priv.Public(), + Subject: pkix.Name{ + CommonName: "user", + Organization: []string{"teleport"}, + }, + NotAfter: c.clock.Now().Add(time.Minute), + }) + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + tlsCert, err := tls.X509KeyPair(certPem, priv.PrivateKeyPEM()) + if err != nil { + return tls.Certificate{}, trace.Wrap(err) + } + + return tlsCert, nil +} diff --git a/lib/srv/alpnproxy/local_proxy.go b/lib/srv/alpnproxy/local_proxy.go index f76e421c073be..0aa7e75a193f2 100644 --- a/lib/srv/alpnproxy/local_proxy.go +++ b/lib/srv/alpnproxy/local_proxy.go @@ -165,20 +165,21 @@ func NewLocalProxy(cfg LocalProxyConfig, opts ...LocalProxyConfigOpt) (*LocalPro // Start starts the LocalProxy. func (l *LocalProxy) Start(ctx context.Context) error { + if l.cfg.Middleware != nil { + if err := l.cfg.Middleware.OnStart(ctx, l); err != nil { + return trace.Wrap(err) + } + } + if l.cfg.HTTPMiddleware != nil { - return trace.Wrap(l.StartHTTPAccessProxy(ctx)) + return trace.Wrap(l.startHTTPAccessProxy(ctx)) } + return trace.Wrap(l.start(ctx)) } // start starts the LocalProxy for raw TCP or raw TLS (non-HTTP) connections. func (l *LocalProxy) start(ctx context.Context) error { - if l.cfg.Middleware != nil { - err := l.cfg.Middleware.OnStart(ctx, l) - if err != nil { - return trace.Wrap(err) - } - } for { select { case <-ctx.Done(): @@ -342,23 +343,26 @@ func (l *LocalProxy) makeHTTPReverseProxy(certs ...tls.Certificate) *httputil.Re } } -// StartHTTPAccessProxy starts the local HTTP access proxy. -func (l *LocalProxy) StartHTTPAccessProxy(ctx context.Context) error { - if l.cfg.HTTPMiddleware == nil { - return trace.BadParameter("Missing HTTPMiddleware in configuration") - } - +// startHTTPAccessProxy starts the local HTTP access proxy. +func (l *LocalProxy) startHTTPAccessProxy(ctx context.Context) error { if err := l.cfg.HTTPMiddleware.CheckAndSetDefaults(); err != nil { return trace.Wrap(err) } l.cfg.Log.Info("Starting HTTP access proxy") defer l.cfg.Log.Info("HTTP access proxy stopped") - defaultProxy := l.makeHTTPReverseProxy(l.getCert()) server := &http.Server{ ReadHeaderTimeout: defaults.ReadHeadersTimeout, Handler: http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if l.cfg.Middleware != nil { + if err := l.cfg.Middleware.OnNewConnection(ctx, l); err != nil { + l.cfg.Log.WithError(err).Error("Middleware failed to handle client request.") + trace.WriteError(rw, trace.Wrap(err)) + return + } + } + if l.cfg.HTTPMiddleware.HandleRequest(rw, req) { return } @@ -371,7 +375,7 @@ func (l *LocalProxy) StartHTTPAccessProxy(ctx context.Context) error { req.Header.Del("X-Forwarded-Host") } - proxy, err := l.getHTTPReverseProxyForReq(req, defaultProxy) + proxy, err := l.getHTTPReverseProxyForReq(req) if err != nil { l.cfg.Log.Warnf("Failed to get reverse proxy: %v.", err) trace.WriteError(rw, trace.Wrap(err)) @@ -396,49 +400,25 @@ func (l *LocalProxy) StartHTTPAccessProxy(ctx context.Context) error { return nil } -func (l *LocalProxy) getHTTPReverseProxyForReq(req *http.Request, defaultProxy *httputil.ReverseProxy) (*httputil.ReverseProxy, error) { +func (l *LocalProxy) getHTTPReverseProxyForReq(req *http.Request) (*httputil.ReverseProxy, error) { certs, err := l.cfg.HTTPMiddleware.OverwriteClientCerts(req) - if err != nil { - if trace.IsNotImplemented(err) { - return defaultProxy, nil - } + if trace.IsNotImplemented(err) { + return l.makeHTTPReverseProxy(l.getCert()), nil + } else if err != nil { return nil, trace.Wrap(err) } + + l.cfg.Log.Debug("overwrote certs") return l.makeHTTPReverseProxy(certs...), nil } -// getCerts returns the local proxy's configured TLS certificates. -// For thread-safety, it is important that the returned slice and its contents -// are not be mutated by callers, therefore this method is not exported. +// getCert returns the local proxy's configured TLS certificate. func (l *LocalProxy) getCert() tls.Certificate { l.certMu.RLock() defer l.certMu.RUnlock() return l.cfg.Cert } -// CheckCertExpiry checks the proxy certificates for expiration and runs given checking function. -func (l *LocalProxy) CheckCert(checkCert func(cert *x509.Certificate) error) error { - l.cfg.Log.Debug("checking local proxy certs") - l.certMu.RLock() - defer l.certMu.RUnlock() - - if len(l.cfg.Cert.Certificate) == 0 { - return trace.NotFound("local proxy has no TLS certificates configured") - } - - cert, err := utils.TLSCertLeaf(l.cfg.Cert) - if err != nil { - return trace.Wrap(err) - } - - // Check for cert expiration. - if err := utils.VerifyCertificateExpiry(cert, l.cfg.Clock); err != nil { - return trace.Wrap(err) - } - - return trace.Wrap(checkCert(cert)) -} - // CheckDBCert checks the proxy certificates for expiration and that the cert subject matches a database route. func (l *LocalProxy) CheckDBCert(dbRoute tlsca.RouteToDatabase) error { l.cfg.Log.Debug("checking local proxy database certs") diff --git a/lib/srv/alpnproxy/local_proxy_config_opt.go b/lib/srv/alpnproxy/local_proxy_config_opt.go index 8ff16404e5b72..7b520ce37611f 100644 --- a/lib/srv/alpnproxy/local_proxy_config_opt.go +++ b/lib/srv/alpnproxy/local_proxy_config_opt.go @@ -76,7 +76,9 @@ func WithClusterCAs(ctx context.Context, getClusterCertPool GetClusterCACertPool } // WithClientCert is a LocalProxyConfigOpt that sets the client certs used to -// connect to the remote Teleport Proxy. +// connect to the remote Teleport Proxy. Note that when paired with middleware +// that overwrites the cert, like the CertChecker middleware, this cert will +// not have a chance to be used. func WithClientCert(cert tls.Certificate) LocalProxyConfigOpt { return func(config *LocalProxyConfig) error { config.Cert = cert diff --git a/lib/srv/alpnproxy/local_proxy_test.go b/lib/srv/alpnproxy/local_proxy_test.go index b5ba5b1582b92..8054622c5b303 100644 --- a/lib/srv/alpnproxy/local_proxy_test.go +++ b/lib/srv/alpnproxy/local_proxy_test.go @@ -595,7 +595,7 @@ func createAWSAccessProxySuite(t *testing.T, cred *credentials.Credentials) *Loc hs.Close() }) go func() { - err := lp.StartHTTPAccessProxy(context.Background()) + err := lp.Start(context.Background()) assert.NoError(t, err) }() return lp diff --git a/tool/tsh/common/app.go b/tool/tsh/common/app.go index 385ad05d0c24f..cb40d148d6111 100644 --- a/tool/tsh/common/app.go +++ b/tool/tsh/common/app.go @@ -20,16 +20,13 @@ package common import ( "context" - "crypto/tls" - "crypto/x509/pkix" "fmt" "io" - "net" "os" "os/exec" "strings" + "sync" "text/template" - "time" "github.com/ghodss/yaml" "github.com/gravitational/trace" @@ -38,11 +35,9 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" - "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/lib/asciitable" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/client" - "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" ) @@ -54,25 +49,20 @@ func onAppLogin(cf *CLIConf) error { return trace.Wrap(err) } - profile, err := tc.ProfileStatus() - if err != nil { - return trace.Wrap(err) - } - - app, err := getRegisteredApp(cf, tc) + appInfo, err := getAppInfo(cf, tc, nil /*matchRouteToApp*/) if err != nil { return trace.Wrap(err) } - routeToApp, err := getRouteToApp(cf, tc, profile, app) + app, err := appInfo.GetApp(cf.Context, tc) if err != nil { return trace.Wrap(err) } appCertParams := client.ReissueParams{ RouteToCluster: tc.SiteName, - RouteToApp: routeToApp, - AccessRequests: profile.ActiveRequests.AccessRequests, + RouteToApp: appInfo.RouteToApp, + AccessRequests: appInfo.profile.ActiveRequests.AccessRequests, } clusterClient, err := tc.ConnectToCluster(cf.Context) @@ -93,7 +83,7 @@ func onAppLogin(cf *CLIConf) error { return trace.Wrap(err) } - if err := printAppCommand(cf, tc, app, routeToApp); err != nil { + if err := printAppCommand(cf, tc, app, appInfo.RouteToApp); err != nil { return trace.Wrap(err) } @@ -119,46 +109,6 @@ func appLogin( return key, trace.Wrap(err) } -func getRouteToApp(cf *CLIConf, tc *client.TeleportClient, profile *client.ProfileStatus, app types.Application) (proto.RouteToApp, error) { - var awsRoleARN string - if app.IsAWSConsole() { - var err error - awsRoleARN, err = getARNFromFlags(cf, profile, app) - if err != nil { - return proto.RouteToApp{}, trace.Wrap(err) - } - } - - var azureIdentity string - if app.IsAzureCloud() { - var err error - azureIdentity, err = getAzureIdentityFromFlags(cf, profile) - if err != nil { - return proto.RouteToApp{}, trace.Wrap(err) - } - log.Debugf("Azure identity is %q", azureIdentity) - } - - var gcpServiceAccount string - if app.IsGCP() { - var err error - gcpServiceAccount, err = getGCPServiceAccountFromFlags(cf, profile) - if err != nil { - return proto.RouteToApp{}, trace.Wrap(err) - } - log.Debugf("GCP service account is %q", gcpServiceAccount) - } - - return proto.RouteToApp{ - Name: app.GetName(), - PublicAddr: app.GetPublicAddr(), - ClusterName: tc.SiteName, - AWSRoleARN: awsRoleARN, - AzureIdentity: azureIdentity, - GCPServiceAccount: gcpServiceAccount, - }, nil -} - func localProxyRequiredForApp(tc *client.TeleportClient) bool { return tc.TLSRoutingConnUpgradeRequired } @@ -313,26 +263,6 @@ Your service account: {{.serviceAccount}} Example command: tsh gcloud compute instances list `)) -// getRegisteredApp returns the registered application with the specified name. -func getRegisteredApp(cf *CLIConf, tc *client.TeleportClient) (app types.Application, err error) { - var apps []types.Application - err = client.RetryWithRelogin(cf.Context, tc, func() error { - apps, err = tc.ListApps(cf.Context, &proto.ListResourcesRequest{ - Namespace: tc.Namespace, - ResourceType: types.KindAppServer, - PredicateExpression: fmt.Sprintf(`name == "%s"`, cf.AppName), - }) - return trace.Wrap(err) - }) - if err != nil { - return nil, trace.Wrap(err) - } - if len(apps) == 0 { - return nil, trace.NotFound("app %q not found, use `tsh apps ls` to see registered apps", cf.AppName) - } - return apps[0], nil -} - // onAppLogout implements "tsh apps logout" command. func onAppLogout(cf *CLIConf) error { tc, err := makeClient(cf) @@ -424,6 +354,23 @@ func onAppConfig(cf *CLIConf) error { return nil } +const ( + // appFormatURI prints app URI. + appFormatURI = "uri" + // appFormatCA prints app CA cert path. + appFormatCA = "ca" + // appFormatCert prints app cert path. + appFormatCert = "cert" + // appFormatKey prints app key path. + appFormatKey = "key" + // appFormatCURL prints app curl command. + appFormatCURL = "curl" + // appFormatJSON prints app URI, CA cert path, cert path, key path, and curl command in JSON format. + appFormatJSON = "json" + // appFormatYAML prints app URI, CA cert path, cert path, key path, and curl command in YAML format. + appFormatYAML = "yaml" +) + func formatAppConfig(tc *client.TeleportClient, profile *client.ProfileStatus, routeToApp proto.RouteToApp, format string) (string, error) { var uri string if port := tc.WebProxyPort(); port == teleport.StandardHTTPSPort { @@ -534,126 +481,207 @@ func serializeAppConfig(configInfo *appConfigInfo, format string) (string, error return string(out), trace.Wrap(err) } -// pickActiveApp returns the app the current profile is logged into. -// -// If logged into multiple apps, returns an error unless one was specified -// explicitly on CLI. -func pickActiveApp(cf *CLIConf, activeRoutes []tlsca.RouteToApp) (*tlsca.RouteToApp, error) { - if cf.AppName == "" { - switch len(activeRoutes) { - case 0: - return nil, trace.NotFound("please login using 'tsh apps login' first") - case 1: - return &activeRoutes[0], nil - default: - var appNames []string - for _, r := range activeRoutes { - appNames = append(appNames, r.Name) +// getAppInfo fetches app information using the user's tsh profile, +// command line args, and the ListApps endpoint if necessary. If +// provided, the matcher will be used to filter active apps in the +// tsh profile. getAppInfo will also perform re-login if necessary. +func getAppInfo(cf *CLIConf, tc *client.TeleportClient, matchRouteToApp func(tlsca.RouteToApp) bool) (*appInfo, error) { + var profile *client.ProfileStatus + if err := client.RetryWithRelogin(cf.Context, tc, func() error { + var err error + profile, err = tc.ProfileStatus() + return trace.Wrap(err) + }); err != nil { + return nil, trace.Wrap(err) + } + + activeRoutes := profile.Apps + if matchRouteToApp != nil { + var filteredRoutes []tlsca.RouteToApp + for _, route := range profile.Apps { + if matchRouteToApp(route) { + filteredRoutes = append(filteredRoutes, route) } - return nil, trace.BadParameter("multiple apps are available (%v), please specify one via CLI argument", - strings.Join(appNames, ", ")) } + activeRoutes = filteredRoutes } - for _, r := range activeRoutes { - if r.Name == cf.AppName { - return &r, nil - } + if route, err := pickActiveApp(cf, activeRoutes); err == nil { + info := &appInfo{RouteToApp: route, isActive: true} + return info, info.checkAndSetDefaults(cf, tc, profile) + } else if !trace.IsNotFound(err) { + return nil, trace.Wrap(err) } - return nil, trace.NotFound("not logged into app %q", cf.AppName) -} -// loadAppSelfSignedCA loads self-signed CA for provided app, or tries to -// generate a new CA if first load fails. -func loadAppSelfSignedCA(profile *client.ProfileStatus, tc *client.TeleportClient, appName string) (tls.Certificate, error) { - appCerts, _, err := loadAppCertificate(tc, appName) + // If we didn't find an active profile for the app, get info from server. + app, err := getApp(cf.Context, tc, cf.AppName) if err != nil { - return tls.Certificate{}, trace.Wrap(err) + return nil, trace.Wrap(err) } - appCertsExpireAt, err := getTLSCertExpireTime(appCerts) - if err != nil { - return tls.Certificate{}, trace.Wrap(err) + + info := &appInfo{ + RouteToApp: proto.RouteToApp{ + Name: app.GetName(), + PublicAddr: app.GetPublicAddr(), + ClusterName: tc.SiteName, + }, + app: app, } - cert, err := loadSelfSignedCA(profile.AppLocalCAPath(tc.SiteName, appName), profile.KeyPath(), appCertsExpireAt, "localhost") - return cert, trace.Wrap(err) + return info, info.checkAndSetDefaults(cf, tc, profile) +} + +// appInfo wraps a RouteToApp and the corresponding app. +// Its purpose is to prevent repeated fetches of the same app, +// by lazily fetching and caching the app for use as needed. +type appInfo struct { + proto.RouteToApp + // app corresponds to the app route and may be nil, so use GetApp + // instead of accessing it directly. + app types.Application + // isActive indicates an active app matched this app info. + isActive bool + mu sync.Mutex + + // profile is a cached profile status for the current login session. + profile *client.ProfileStatus } -func loadSelfSignedCA(caPath, keyPath string, validUntil time.Time, dnsNames ...string) (tls.Certificate, error) { - caTLSCert, err := keys.LoadX509KeyPair(caPath, keyPath) - if err == nil { - if expire, err := getTLSCertExpireTime(caTLSCert); err == nil && time.Now().Before(expire) { - return caTLSCert, nil +// checkAndSetDefaults checks the app route, applies cli flags, and sets defaults. +func (a *appInfo) checkAndSetDefaults(cf *CLIConf, tc *client.TeleportClient, profile *client.ProfileStatus) error { + a.profile = profile + + switch { + case a.IsAWSConsole(): + app, err := a.GetApp(cf.Context, tc) + if err != nil { + return trace.Wrap(err) } + + awsRoleARN, err := getARNFromFlags(cf, profile, app) + if err != nil { + return trace.Wrap(err) + } + a.AWSRoleARN = awsRoleARN + + case a.IsAzureCloud(): + azureIdentity, err := getAzureIdentityFromFlags(cf, profile) + if err != nil { + return trace.Wrap(err) + } + log.Debugf("Azure identity is %q", azureIdentity) + a.AzureIdentity = azureIdentity + + case a.IsGCP(): + gcpServiceAccount, err := getGCPServiceAccountFromFlags(cf, profile) + if err != nil { + return trace.Wrap(err) + } + log.Debugf("GCP service account is %q", gcpServiceAccount) + a.GCPServiceAccount = gcpServiceAccount } - if err != nil && !trace.IsNotFound(err) { - log.WithError(err).Debugf("Failed to load certificate from %v.", caPath) - } - // Generate and load again. - if err = generateSelfSignedCA(caPath, keyPath, validUntil, dnsNames...); err != nil { - return tls.Certificate{}, err + return nil +} + +func (a *appInfo) IsAWSConsole() bool { + if a.app != nil { + return a.app.IsAWSConsole() } + return a.RouteToApp.AWSRoleARN != "" +} - caTLSCert, err = keys.LoadX509KeyPair(caPath, keyPath) - if err != nil { - return tls.Certificate{}, trace.Wrap(err) +func (a *appInfo) IsAzureCloud() bool { + if a.app != nil { + return a.app.IsAzureCloud() } - return caTLSCert, nil + return a.RouteToApp.AzureIdentity != "" } -// generateSelfSignedCA generates a new self-signed CA for provided dnsNames -// and saves/overwrites the local CA file in the profile directory. -func generateSelfSignedCA(caPath, keyPath string, validUntil time.Time, dnsNames ...string) error { - log.Debugf("Generating local self signed CA at %v", caPath) - keyPem, err := utils.ReadPath(keyPath) - if err != nil { - return trace.Wrap(err) +func (a *appInfo) IsGCP() bool { + if a.app != nil { + return a.app.IsGCP() } + return a.RouteToApp.GCPServiceAccount != "" +} - key, err := keys.ParsePrivateKey(keyPem) +func (a *appInfo) appLocalCAPath(cluster string) string { + return a.profile.AppLocalCAPath(cluster, a.RouteToApp.Name) +} + +// GetApp returns the cached app or fetches it using the app route and +// caches the result. +func (a *appInfo) GetApp(ctx context.Context, tc *client.TeleportClient) (types.Application, error) { + a.mu.Lock() + defer a.mu.Unlock() + if a.app != nil { + return a.app.Copy(), nil + } + // holding mutex across the api call to avoid multiple redundant api calls. + app, err := getApp(ctx, tc, a.Name) if err != nil { - return trace.Wrap(err) + return nil, trace.Wrap(err) } + a.app = app + return a.app.Copy(), nil +} - certPem, err := tlsca.GenerateSelfSignedCAWithConfig(tlsca.GenerateCAConfig{ - Entity: pkix.Name{ - CommonName: "localhost", - Organization: []string{"Teleport"}, - }, - Signer: key, - DNSNames: dnsNames, - IPAddresses: []net.IP{net.ParseIP(defaults.Localhost)}, - TTL: time.Until(validUntil), +// getApp returns the registered application with the specified name. +func getApp(ctx context.Context, tc *client.TeleportClient, name string) (app types.Application, err error) { + var apps []types.Application + err = client.RetryWithRelogin(ctx, tc, func() error { + apps, err = tc.ListApps(ctx, &proto.ListResourcesRequest{ + Namespace: tc.Namespace, + ResourceType: types.KindAppServer, + PredicateExpression: fmt.Sprintf(`name == "%s"`, name), + }) + return trace.Wrap(err) }) if err != nil { - return trace.Wrap(err) + return nil, trace.Wrap(err) + } + if len(apps) == 0 { + return nil, trace.NotFound("app %q not found, use `tsh apps ls` to see registered apps", name) } + return apps[0], nil +} - if _, err := utils.EnsureLocalPath(caPath, "", ""); err != nil { - return trace.Wrap(err) +// pickActiveApp returns the app the current profile is logged into. +// +// If logged into multiple apps, returns an error unless one was specified +// explicitly on CLI. +func pickActiveApp(cf *CLIConf, activeRoutes []tlsca.RouteToApp) (proto.RouteToApp, error) { + if cf.AppName == "" { + switch len(activeRoutes) { + case 0: + return proto.RouteToApp{}, trace.NotFound("please login using 'tsh apps login' first") + case 1: + return tlscaRouteToAppToProto(activeRoutes[0]), nil + default: + var appNames []string + for _, r := range activeRoutes { + appNames = append(appNames, r.Name) + } + return proto.RouteToApp{}, trace.BadParameter("multiple apps are available (%v), please specify one via CLI argument", + strings.Join(appNames, ", ")) + } } - // WriteFile truncates existing file before writing. - if err = os.WriteFile(caPath, certPem, 0o600); err != nil { - return trace.ConvertSystemError(err) + for _, r := range activeRoutes { + if r.Name == cf.AppName { + return tlscaRouteToAppToProto(r), nil + } } - return nil + return proto.RouteToApp{}, trace.NotFound("not logged into app %q", cf.AppName) } -const ( - // appFormatURI prints app URI. - appFormatURI = "uri" - // appFormatCA prints app CA cert path. - appFormatCA = "ca" - // appFormatCert prints app cert path. - appFormatCert = "cert" - // appFormatKey prints app key path. - appFormatKey = "key" - // appFormatCURL prints app curl command. - appFormatCURL = "curl" - // appFormatJSON prints app URI, CA cert path, cert path, key path, and curl command in JSON format. - appFormatJSON = "json" - // appFormatYAML prints app URI, CA cert path, cert path, key path, and curl command in YAML format. - appFormatYAML = "yaml" -) +func tlscaRouteToAppToProto(route tlsca.RouteToApp) proto.RouteToApp { + return proto.RouteToApp{ + Name: route.Name, + PublicAddr: route.PublicAddr, + ClusterName: route.ClusterName, + AWSRoleARN: route.AWSRoleARN, + AzureIdentity: route.AzureIdentity, + GCPServiceAccount: route.GCPServiceAccount, + } +} diff --git a/tool/tsh/common/app_aws.go b/tool/tsh/common/app_aws.go index 3bedd2a613f3e..7a05bdb271916 100644 --- a/tool/tsh/common/app_aws.go +++ b/tool/tsh/common/app_aws.go @@ -19,8 +19,8 @@ package common import ( + "context" "fmt" - "net" "os" "os/exec" "strings" @@ -54,7 +54,7 @@ func onAWS(cf *CLIConf) error { cf.AWSEndpointURLMode = true } - err = awsApp.StartLocalProxies() + err = awsApp.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -130,28 +130,25 @@ func isAWSFlag(args []string, i int) bool { // awsApp is an AWS app that can start local proxies to serve AWS APIs. type awsApp struct { - cf *CLIConf - profile *client.ProfileStatus - appName string - - localALPNProxy *alpnproxy.LocalProxy - localForwardProxy *alpnproxy.ForwardProxy - credentials *credentials.Credentials - credentialsOnce sync.Once + *localProxyApp + + cf *CLIConf + + credentials *credentials.Credentials + credentialsOnce sync.Once } // newAWSApp creates a new AWS app. -func newAWSApp(cf *CLIConf, profile *client.ProfileStatus, route tlsca.RouteToApp) (*awsApp, error) { +func newAWSApp(tc *client.TeleportClient, cf *CLIConf, appInfo *appInfo) (*awsApp, error) { return &awsApp{ - cf: cf, - profile: profile, - appName: route.Name, + localProxyApp: newLocalProxyApp(tc, appInfo, cf.LocalProxyPort, cf.InsecureSkipVerify), + cf: cf, }, nil } // GetAppName returns the app name. func (a *awsApp) GetAppName() string { - return a.appName + return a.appInfo.RouteToApp.Name } // StartLocalProxies sets up local proxies for serving AWS clients. @@ -168,36 +165,25 @@ func (a *awsApp) GetAppName() string { // // The first method is always preferred as the original hostname is preserved // through forward proxy. -func (a *awsApp) StartLocalProxies() error { - // AWS endpoint URL mode - if a.cf.AWSEndpointURLMode { - if err := a.startLocalALPNProxy(a.cf.LocalProxyPort); err != nil { - return trace.Wrap(err) - } - - return nil +func (a *awsApp) StartLocalProxies(ctx context.Context, opts ...alpnproxy.LocalProxyConfigOpt) error { + cred, err := a.GetAWSCredentials() + if err != nil { + return trace.Wrap(err) } - // HTTPS proxy mode - if err := a.startLocalALPNProxy(""); err != nil { - return trace.Wrap(err) + awsMiddleware := &alpnproxy.AWSAccessMiddleware{ + AWSCredentials: cred, } - if err := a.startLocalForwardProxy(a.cf.LocalProxyPort); err != nil { + + // AWS endpoint URL mode + if a.cf.AWSEndpointURLMode { + err := a.StartLocalProxyWithTLS(ctx, alpnproxy.WithHTTPMiddleware(awsMiddleware)) return trace.Wrap(err) } - return nil -} -// close makes all necessary close calls. -func (a *awsApp) Close() error { - var errs []error - if a.localALPNProxy != nil { - errs = append(errs, a.localALPNProxy.Close()) - } - if a.localForwardProxy != nil { - errs = append(errs, a.localForwardProxy.Close()) - } - return trace.NewAggregate(errs...) + // HTTPS proxy mode + err = a.StartLocalProxyWithForwarder(ctx, alpnproxy.MatchAWSRequests, alpnproxy.WithHTTPMiddleware(awsMiddleware)) + return trace.Wrap(err) } // GetAWSCredentials generates fake AWS credentials that are used for @@ -248,7 +234,7 @@ func (a *awsApp) GetEnvVars() (map[string]string, error) { // https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html "AWS_ACCESS_KEY_ID": credValues.AccessKeyID, "AWS_SECRET_ACCESS_KEY": credValues.SecretAccessKey, - "AWS_CA_BUNDLE": a.profile.AppLocalCAPath(a.cf.SiteName, a.appName), + "AWS_CA_BUNDLE": a.appInfo.appLocalCAPath(a.cf.SiteName), } // Set proxy settings. @@ -298,114 +284,6 @@ func (a *awsApp) RunCommand(cmd *exec.Cmd) error { return nil } -// startLocalALPNProxy starts the local ALPN proxy. -func (a *awsApp) startLocalALPNProxy(port string) error { - tc, err := makeClient(a.cf) - if err != nil { - return trace.Wrap(err) - } - - appCert, err := loadAppCertificateWithAppLogin(a.cf, tc, a.appName) - if err != nil { - return trace.Wrap(err) - } - - localCA, err := loadAppSelfSignedCA(a.profile, tc, a.appName) - if err != nil { - return trace.Wrap(err) - } - - cred, err := a.GetAWSCredentials() - if err != nil { - return trace.Wrap(err) - } - - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Create a listener that is able to sign certificates when receiving AWS - // requests tunneled from the local forward proxy. - listener, err := alpnproxy.NewCertGenListener(alpnproxy.CertGenListenerConfig{ - ListenAddr: listenAddr, - CA: localCA, - }) - if err != nil { - return trace.Wrap(err) - } - - a.localALPNProxy, err = alpnproxy.NewLocalProxy( - makeBasicLocalProxyConfig(a.cf, tc, listener), - alpnproxy.WithClientCert(appCert), - alpnproxy.WithClusterCAsIfConnUpgrade(a.cf.Context, tc.RootClusterCACertPool), - alpnproxy.WithHTTPMiddleware(&alpnproxy.AWSAccessMiddleware{ - AWSCredentials: cred, - }), - ) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localALPNProxy.StartHTTPAccessProxy(a.cf.Context); err != nil { - log.WithError(err).Errorf("Failed to start local ALPN proxy.") - } - }() - return nil -} - -// startLocalForwardProxy starts the local forward proxy. -func (a *awsApp) startLocalForwardProxy(port string) error { - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Note that the created forward proxy serves HTTP instead of HTTPS, to - // eliminate the need to install temporary CA for various AWS clients. - listener, err := net.Listen("tcp", listenAddr) - if err != nil { - return trace.Wrap(err) - } - - a.localForwardProxy, err = alpnproxy.NewForwardProxy(alpnproxy.ForwardProxyConfig{ - Listener: listener, - CloseContext: a.cf.Context, - Handlers: []alpnproxy.ConnectRequestHandler{ - // Forward AWS requests to ALPN proxy. - alpnproxy.NewForwardToHostHandler(alpnproxy.ForwardToHostHandlerConfig{ - MatchFunc: alpnproxy.MatchAWSRequests, - Host: a.localALPNProxy.GetAddr(), - }), - - // Forward non-AWS requests to user's system proxy, if configured. - alpnproxy.NewForwardToSystemProxyHandler(alpnproxy.ForwardToSystemProxyHandlerConfig{ - InsecureSystemProxy: a.cf.InsecureSkipVerify, - }), - - // Forward non-AWS requests to their original hosts. - alpnproxy.NewForwardToOriginalHostHandler(), - }, - }) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localForwardProxy.Start(); err != nil { - log.WithError(err).Errorf("Failed to start local forward proxy.") - } - }() - return nil -} - func printAWSRoles(roles awsutils.Roles) { if len(roles) == 0 { return @@ -467,6 +345,15 @@ func matchAWSApp(app tlsca.RouteToApp) bool { } func pickAWSApp(cf *CLIConf) (*awsApp, error) { - app, err := pickCloudApp(cf, types.CloudAWS, matchAWSApp, newAWSApp) - return app, trace.Wrap(err) + tc, err := makeClient(cf) + if err != nil { + return nil, trace.Wrap(err) + } + + appInfo, err := getAppInfo(cf, tc, matchAWSApp) + if err != nil { + return nil, trace.Wrap(err) + } + + return newAWSApp(tc, cf, appInfo) } diff --git a/tool/tsh/common/app_azure.go b/tool/tsh/common/app_azure.go index a3c615ea52b34..c547650e667d7 100644 --- a/tool/tsh/common/app_azure.go +++ b/tool/tsh/common/app_azure.go @@ -19,9 +19,9 @@ package common import ( + "context" "crypto" "fmt" - "net" "os" "os/exec" "path" @@ -50,7 +50,7 @@ func onAzure(cf *CLIConf) error { return trace.Wrap(err) } - err = app.StartLocalProxies() + err = app.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -69,26 +69,30 @@ func onAzure(cf *CLIConf) error { // azureApp is an Azure app that can start local proxies to serve Azure APIs. type azureApp struct { + *localProxyApp + cf *CLIConf - profile *client.ProfileStatus - app tlsca.RouteToApp + signer crypto.Signer msiSecret string - - localALPNProxy *alpnproxy.LocalProxy - localForwardProxy *alpnproxy.ForwardProxy } // newAzureApp creates a new Azure app. -func newAzureApp(cf *CLIConf, profile *client.ProfileStatus, app tlsca.RouteToApp) (*azureApp, error) { +func newAzureApp(tc *client.TeleportClient, cf *CLIConf, appInfo *appInfo) (*azureApp, error) { + key, err := tc.LocalAgent().GetCoreKey() + if err != nil { + return nil, trace.Wrap(err) + } + msiSecret, err := getMSISecret() if err != nil { return nil, err } + return &azureApp{ - cf: cf, - profile: profile, - app: app, - msiSecret: msiSecret, + localProxyApp: newLocalProxyApp(tc, appInfo, cf.LocalProxyPort, cf.InsecureSkipVerify), + cf: cf, + signer: key.PrivateKey, + msiSecret: msiSecret, }, nil } @@ -127,27 +131,20 @@ func getMSISecret() (string, error) { // However, with MSI_ENDPOINT variable set, clients will reach out to this address for tokens. // We intercept calls to https://azure-msi.teleport.dev using alpnproxy.AzureMSIMiddleware. // These calls are served entirely locally, which helps the overall performance experienced by the user. -func (a *azureApp) StartLocalProxies() error { - // HTTPS proxy mode - if err := a.startLocalALPNProxy(""); err != nil { - return trace.Wrap(err) +func (a *azureApp) StartLocalProxies(ctx context.Context) error { + azureMiddleware := &alpnproxy.AzureMSIMiddleware{ + Key: a.signer, + Secret: a.msiSecret, + // we could, in principle, get the actual TenantID either from live data or from static configuration, + // but at this moment there is no clear advantage over simply issuing a new random identifier. + TenantID: uuid.New().String(), + ClientID: uuid.New().String(), + Identity: a.appInfo.RouteToApp.AzureIdentity, } - if err := a.startLocalForwardProxy(a.cf.LocalProxyPort); err != nil { - return trace.Wrap(err) - } - return nil -} -// Close makes all necessary close calls. -func (a *azureApp) Close() error { - var errs []error - if a.localALPNProxy != nil { - errs = append(errs, a.localALPNProxy.Close()) - } - if a.localForwardProxy != nil { - errs = append(errs, a.localForwardProxy.Close()) - } - return trace.NewAggregate(errs...) + // HTTPS proxy mode + err := a.StartLocalProxyWithForwarder(ctx, alpnproxy.MatchAzureRequests, alpnproxy.WithHTTPMiddleware(azureMiddleware)) + return trace.Wrap(err) } // GetEnvVars returns required environment variables to configure the @@ -158,7 +155,7 @@ func (a *azureApp) GetEnvVars() (map[string]string, error) { // 1. `tsh az login` in one console // 2. `az ...` in another console // without custom config dir the second invocation will hang, attempting to connect to (inaccessible without configuration) MSI. - "AZURE_CONFIG_DIR": path.Join(profile.FullProfilePath(a.cf.HomePath), "azure", a.app.ClusterName, a.app.Name), + "AZURE_CONFIG_DIR": path.Join(profile.FullProfilePath(a.cf.HomePath), "azure", a.appInfo.RouteToApp.ClusterName, a.appInfo.RouteToApp.Name), // setting MSI_ENDPOINT instructs Azure CLI to make managed identity calls on this address. // the requests will be handled by tsh proxy. "MSI_ENDPOINT": "https://" + types.TeleportAzureMSIEndpoint + "/" + a.msiSecret, @@ -167,7 +164,7 @@ func (a *azureApp) GetEnvVars() (map[string]string, error) { // This isn't portable and applications other than az CLI may have to set different env variables, // add the application cert to system root store (not recommended, ultimate fallback) // or use equivalent of --insecure flag. - "REQUESTS_CA_BUNDLE": a.profile.AppLocalCAPath(a.cf.SiteName, a.app.Name), + "REQUESTS_CA_BUNDLE": a.appInfo.appLocalCAPath(a.cf.SiteName), } // Set proxy settings. @@ -200,120 +197,6 @@ func (a *azureApp) RunCommand(cmd *exec.Cmd) error { return nil } -// startLocalALPNProxy starts the local ALPN proxy. -func (a *azureApp) startLocalALPNProxy(port string) error { - tc, err := makeClient(a.cf) - if err != nil { - return trace.Wrap(err) - } - - appCert, err := loadAppCertificateWithAppLogin(a.cf, tc, a.app.Name) - if err != nil { - return trace.Wrap(err) - } - - localCA, err := loadAppSelfSignedCA(a.profile, tc, a.app.Name) - if err != nil { - return trace.Wrap(err) - } - - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Create a listener that is able to sign certificates when receiving Azure - // requests tunneled from the local forward proxy. - listener, err := alpnproxy.NewCertGenListener(alpnproxy.CertGenListenerConfig{ - ListenAddr: listenAddr, - CA: localCA, - }) - if err != nil { - return trace.Wrap(err) - } - - signer, ok := appCert.PrivateKey.(crypto.Signer) - if !ok { - return trace.BadParameter("private key type %T does not implement crypto.Signer (this is a bug)", appCert.PrivateKey) - } - - a.localALPNProxy, err = alpnproxy.NewLocalProxy( - makeBasicLocalProxyConfig(a.cf, tc, listener), - alpnproxy.WithClientCert(appCert), - alpnproxy.WithClusterCAsIfConnUpgrade(a.cf.Context, tc.RootClusterCACertPool), - alpnproxy.WithHTTPMiddleware(&alpnproxy.AzureMSIMiddleware{ - Key: signer, - Secret: a.msiSecret, - // we could, in principle, get the actual TenantID either from live data or from static configuration, - // but at this moment there is no clear advantage over simply issuing a new random identifier. - TenantID: uuid.New().String(), - ClientID: uuid.New().String(), - Identity: a.app.AzureIdentity, - }), - ) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localALPNProxy.StartHTTPAccessProxy(a.cf.Context); err != nil { - log.WithError(err).Errorf("Failed to start local ALPN proxy.") - } - }() - return nil -} - -// startLocalForwardProxy starts the local forward proxy. -func (a *azureApp) startLocalForwardProxy(port string) error { - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Note that the created forward proxy serves HTTP instead of HTTPS, to - // eliminate the need to install temporary CA for various Azure clients. - listener, err := net.Listen("tcp", listenAddr) - if err != nil { - return trace.Wrap(err) - } - - a.localForwardProxy, err = alpnproxy.NewForwardProxy(alpnproxy.ForwardProxyConfig{ - Listener: listener, - CloseContext: a.cf.Context, - Handlers: []alpnproxy.ConnectRequestHandler{ - // Forward Azure requests to ALPN proxy. - alpnproxy.NewForwardToHostHandler(alpnproxy.ForwardToHostHandlerConfig{ - MatchFunc: alpnproxy.MatchAzureRequests, - Host: a.localALPNProxy.GetAddr(), - }), - - // Forward non-Azure requests to user's system proxy, if configured. - alpnproxy.NewForwardToSystemProxyHandler(alpnproxy.ForwardToSystemProxyHandlerConfig{ - InsecureSystemProxy: a.cf.InsecureSkipVerify, - }), - - // Forward non-Azure requests to their original hosts. - alpnproxy.NewForwardToOriginalHostHandler(), - }, - }) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localForwardProxy.Start(); err != nil { - log.WithError(err).Errorf("Failed to start local forward proxy.") - } - }() - return nil -} - func printAzureIdentities(identities []string) { fmt.Println(formatAzureIdentities(identities)) } @@ -386,6 +269,15 @@ func matchAzureApp(app tlsca.RouteToApp) bool { } func pickAzureApp(cf *CLIConf) (*azureApp, error) { - app, err := pickCloudApp(cf, types.CloudAzure, matchAzureApp, newAzureApp) - return app, trace.Wrap(err) + tc, err := makeClient(cf) + if err != nil { + return nil, trace.Wrap(err) + } + + appInfo, err := getAppInfo(cf, tc, matchAzureApp) + if err != nil { + return nil, trace.Wrap(err) + } + + return newAzureApp(tc, cf, appInfo) } diff --git a/tool/tsh/common/app_cloud.go b/tool/tsh/common/app_cloud.go deleted file mode 100644 index 1594b6ce563c8..0000000000000 --- a/tool/tsh/common/app_cloud.go +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package common - -import ( - "strings" - - "github.com/gravitational/trace" - - "github.com/gravitational/teleport/lib/client" - "github.com/gravitational/teleport/lib/tlsca" -) - -func defaultValue[t any]() t { - var def t - return def -} - -// pickCloudApp will attempt to find an active cloud app, automatically logging the user to the selected application if possible. -func pickCloudApp[cloudApp any](cf *CLIConf, cloudFriendlyName string, matchRouteToApp func(tlsca.RouteToApp) bool, newCloudApp func(cf *CLIConf, profile *client.ProfileStatus, appRoute tlsca.RouteToApp) (cloudApp, error)) (cloudApp, error) { - app, needLogin, err := pickActiveCloudApp[cloudApp](cf, cloudFriendlyName, matchRouteToApp, newCloudApp) - if err != nil { - if !needLogin { - return defaultValue[cloudApp](), trace.Wrap(err) - } - log.WithError(err).Debugf("Failed to pick an active %v app, attempting to login into app %q", cloudFriendlyName, cf.AppName) - quiet := cf.Quiet - cf.Quiet = true - errLogin := onAppLogin(cf) - cf.Quiet = quiet - if errLogin != nil { - log.WithError(errLogin).Debugf("App login attempt failed") - // combine errors - return defaultValue[cloudApp](), trace.NewAggregate(err, errLogin) - } - // another attempt - app, _, err = pickActiveCloudApp[cloudApp](cf, cloudFriendlyName, matchRouteToApp, newCloudApp) - return app, trace.Wrap(err) - } - return app, nil -} - -func pickActiveCloudApp[cloudApp any](cf *CLIConf, cloudFriendlyName string, matchRouteToApp func(tlsca.RouteToApp) bool, newCloudApp func(cf *CLIConf, profile *client.ProfileStatus, appRoute tlsca.RouteToApp) (cloudApp, error)) (cApp cloudApp, needLogin bool, err error) { - profile, err := cf.ProfileStatus() - if err != nil { - return defaultValue[cloudApp](), false, trace.Wrap(err) - } - if len(profile.Apps) == 0 { - if cf.AppName == "" { - return defaultValue[cloudApp](), false, trace.NotFound("please login to %v app using 'tsh apps login' first", cloudFriendlyName) - } - return defaultValue[cloudApp](), true, trace.NotFound("please login to %v app using 'tsh apps login %v' first", cloudFriendlyName, cf.AppName) - } - name := cf.AppName - if name != "" { - app, err := findApp(profile.Apps, name) - if err != nil { - if trace.IsNotFound(err) { - return defaultValue[cloudApp](), true, trace.NotFound("please login to %v app using 'tsh apps login %v' first", cloudFriendlyName, name) - } - return defaultValue[cloudApp](), false, trace.Wrap(err) - } - if !matchRouteToApp(*app) { - return defaultValue[cloudApp](), false, trace.BadParameter( - "selected app %q is not an %v application", name, cloudFriendlyName, - ) - } - - cApp, err := newCloudApp(cf, profile, *app) - return cApp, false, trace.Wrap(err) - } - - filteredApps := filterApps(matchRouteToApp, profile.Apps) - if len(filteredApps) == 0 { - // no app name to use for attempted login. - return defaultValue[cloudApp](), false, trace.NotFound("please login to %v App using 'tsh apps login' first", cloudFriendlyName) - } - if len(filteredApps) > 1 { - names := strings.Join(getAppNames(filteredApps), ", ") - return defaultValue[cloudApp](), false, trace.BadParameter( - "multiple %v apps are available (%v), please specify one using --app CLI argument", cloudFriendlyName, names, - ) - } - cApp, err = newCloudApp(cf, profile, filteredApps[0]) - return cApp, false, trace.Wrap(err) -} - -func filterApps(matchRouteToApp func(tlsca.RouteToApp) bool, apps []tlsca.RouteToApp) []tlsca.RouteToApp { - var out []tlsca.RouteToApp - for _, app := range apps { - if matchRouteToApp(app) { - out = append(out, app) - } - } - return out -} - -func getAppNames(apps []tlsca.RouteToApp) []string { - var out []string - for _, app := range apps { - out = append(out, app.Name) - } - return out -} - -func findApp(apps []tlsca.RouteToApp, name string) (*tlsca.RouteToApp, error) { - for _, app := range apps { - if app.Name == name { - return &app, nil - } - } - return nil, trace.NotFound("failed to find app with %q name", name) -} diff --git a/tool/tsh/common/app_cloud_test.go b/tool/tsh/common/app_cloud_test.go deleted file mode 100644 index b2a10a7e5cdd5..0000000000000 --- a/tool/tsh/common/app_cloud_test.go +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Teleport - * Copyright (C) 2023 Gravitational, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package common - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/gravitational/teleport/lib/tlsca" -) - -func Test_filterApps(t *testing.T) { - t.Parallel() - - tests := []struct { - name string - matchRouteToApp func(tlsca.RouteToApp) bool - apps []tlsca.RouteToApp - want []tlsca.RouteToApp - }{ - { - name: "aws", - matchRouteToApp: matchAWSApp, - apps: []tlsca.RouteToApp{ - {Name: "none"}, - {Name: "aws1", AWSRoleARN: "dummy"}, - {Name: "aws2", AWSRoleARN: "dummy"}, - {Name: "aws3", AWSRoleARN: "dummy"}, - {Name: "azure", AzureIdentity: "dummy"}, - {Name: "gcp", GCPServiceAccount: "dummy"}, - }, - want: []tlsca.RouteToApp{ - {Name: "aws1", AWSRoleARN: "dummy"}, - {Name: "aws2", AWSRoleARN: "dummy"}, - {Name: "aws3", AWSRoleARN: "dummy"}, - }, - }, - { - name: "azure", - matchRouteToApp: matchAzureApp, - apps: []tlsca.RouteToApp{ - {Name: "none"}, - {Name: "aws", AWSRoleARN: "dummy"}, - {Name: "azure1", AzureIdentity: "dummy"}, - {Name: "azure2", AzureIdentity: "dummy"}, - {Name: "azure3", AzureIdentity: "dummy"}, - {Name: "gcp", GCPServiceAccount: "dummy"}, - }, - want: []tlsca.RouteToApp{ - {Name: "azure1", AzureIdentity: "dummy"}, - {Name: "azure2", AzureIdentity: "dummy"}, - {Name: "azure3", AzureIdentity: "dummy"}, - }, - }, - { - name: "gcp", - matchRouteToApp: matchGCPApp, - apps: []tlsca.RouteToApp{ - {Name: "none"}, - {Name: "aws", AWSRoleARN: "dummy"}, - {Name: "azure", AzureIdentity: "dummy"}, - {Name: "gcp1", GCPServiceAccount: "dummy"}, - {Name: "gcp2", GCPServiceAccount: "dummy"}, - {Name: "gcp3", GCPServiceAccount: "dummy"}, - }, - want: []tlsca.RouteToApp{ - {Name: "gcp1", GCPServiceAccount: "dummy"}, - {Name: "gcp2", GCPServiceAccount: "dummy"}, - {Name: "gcp3", GCPServiceAccount: "dummy"}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.want, filterApps(tt.matchRouteToApp, tt.apps)) - }) - } -} diff --git a/tool/tsh/common/app_gcp.go b/tool/tsh/common/app_gcp.go index ffa194b4619ff..641a13d4a336d 100644 --- a/tool/tsh/common/app_gcp.go +++ b/tool/tsh/common/app_gcp.go @@ -19,9 +19,9 @@ package common import ( + "context" "fmt" "hash/fnv" - "net" "os" "os/exec" "path" @@ -32,7 +32,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/profile" - "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/asciitable" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/defaults" @@ -53,7 +52,7 @@ func onGcloud(cf *CLIConf) error { return trace.Wrap(err) } - err = app.StartLocalProxies() + err = app.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -76,7 +75,7 @@ func onGsutil(cf *CLIConf) error { return trace.Wrap(err) } - err = app.StartLocalProxies() + err = app.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -95,20 +94,18 @@ func onGsutil(cf *CLIConf) error { // gcpApp is an GCP app that can start local proxies to serve GCP APIs. type gcpApp struct { - cf *CLIConf - profile *client.ProfileStatus - app tlsca.RouteToApp - secret string + *localProxyApp + + cf *CLIConf + + secret string // prefix is a prefix added to the name of configuration files, allowing two instances of gcpApp // to run concurrently without overwriting each other files. prefix string - - localALPNProxy *alpnproxy.LocalProxy - localForwardProxy *alpnproxy.ForwardProxy } // newGCPApp creates a new GCP app. -func newGCPApp(cf *CLIConf, profile *client.ProfileStatus, app tlsca.RouteToApp) (*gcpApp, error) { +func newGCPApp(tc *client.TeleportClient, cf *CLIConf, appInfo *appInfo) (*gcpApp, error) { secret, err := getGCPSecret() if err != nil { return nil, err @@ -119,11 +116,10 @@ func newGCPApp(cf *CLIConf, profile *client.ProfileStatus, app tlsca.RouteToApp) prefix := fmt.Sprintf("%x", h.Sum32()) return &gcpApp{ - cf: cf, - profile: profile, - app: app, - secret: secret, - prefix: prefix, + localProxyApp: newLocalProxyApp(tc, appInfo, cf.LocalProxyPort, cf.InsecureSkipVerify), + cf: cf, + secret: secret, + prefix: prefix, }, nil } @@ -144,39 +140,29 @@ func getGCPSecret() (string, error) { // // The request flow to remote server (i.e. GCP APIs) looks like this: // clients -> local forward proxy -> local ALPN proxy -> remote server -func (a *gcpApp) StartLocalProxies() error { +func (a *gcpApp) StartLocalProxies(ctx context.Context) error { // configuration files if err := a.writeBotoConfig(); err != nil { return trace.Wrap(err) } - // HTTPS proxy mode - if err := a.startLocalALPNProxy(""); err != nil { - return trace.Wrap(err) + gcpMiddleware := &alpnproxy.AuthorizationCheckerMiddleware{ + Secret: a.secret, } - if err := a.startLocalForwardProxy(a.cf.LocalProxyPort); err != nil { - return trace.Wrap(err) - } - return nil + + // HTTPS proxy mode + err := a.StartLocalProxyWithForwarder(ctx, alpnproxy.MatchGCPRequests, alpnproxy.WithHTTPMiddleware(gcpMiddleware)) + return trace.Wrap(err) } // Close makes all necessary close calls. func (a *gcpApp) Close() error { - var errs []error - // close proxies - if a.localALPNProxy != nil { - errs = append(errs, a.localALPNProxy.Close()) - } - if a.localForwardProxy != nil { - errs = append(errs, a.localForwardProxy.Close()) - } - // remove boto config - errs = append(errs, a.removeBotoConfig()...) + errs := append([]error{a.localProxyApp.Close()}, a.removeBotoConfig()...) return trace.NewAggregate(errs...) } func (a *gcpApp) getGcloudConfigPath() string { - return path.Join(profile.FullProfilePath(a.cf.HomePath), "gcp", a.app.ClusterName, a.app.Name, "gcloud") + return path.Join(profile.FullProfilePath(a.cf.HomePath), "gcp", a.appInfo.RouteToApp.ClusterName, a.appInfo.RouteToApp.Name, "gcloud") } // removeBotoConfig removes config files written by WriteBotoConfig. @@ -189,7 +175,7 @@ func (a *gcpApp) removeBotoConfig() []error { } func (a *gcpApp) getBotoConfigDir() string { - return path.Join(profile.FullProfilePath(a.cf.HomePath), "gcp", a.app.ClusterName, a.app.Name) + return path.Join(profile.FullProfilePath(a.cf.HomePath), "gcp", a.appInfo.RouteToApp.ClusterName, a.appInfo.RouteToApp.Name) } func (a *gcpApp) getBotoConfigPath() string { @@ -238,7 +224,7 @@ func (a *gcpApp) writeBotoConfig() error { // GetEnvVars returns required environment variables to configure the // clients. func (a *gcpApp) GetEnvVars() (map[string]string, error) { - projectID, err := gcp.ProjectIDFromServiceAccountName(a.app.GCPServiceAccount) + projectID, err := gcp.ProjectIDFromServiceAccountName(a.appInfo.RouteToApp.GCPServiceAccount) if err != nil { return nil, trace.Wrap(err) } @@ -250,7 +236,7 @@ func (a *gcpApp) GetEnvVars() (map[string]string, error) { // Set core.custom_ca_certs_file via env variable, customizing the path to CA certs file. // https://cloud.google.com/sdk/gcloud/reference/config/set#:~:text=custom_ca_certs_file - "CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE": a.profile.AppLocalCAPath(a.cf.SiteName, a.app.Name), + "CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE": a.appInfo.appLocalCAPath(a.cf.SiteName), // We need to set project ID. This is sourced from the account name. // https://cloud.google.com/sdk/gcloud/reference/config#GROUP:~:text=authentication%20to%20gsutil.-,project,-Project%20ID%20of @@ -295,110 +281,6 @@ func (a *gcpApp) RunCommand(cmd *exec.Cmd) error { return nil } -// startLocalALPNProxy starts the local ALPN proxy. -func (a *gcpApp) startLocalALPNProxy(port string) error { - tc, err := makeClient(a.cf) - if err != nil { - return trace.Wrap(err) - } - - appCert, err := loadAppCertificateWithAppLogin(a.cf, tc, a.app.Name) - if err != nil { - return trace.Wrap(err) - } - - localCA, err := loadAppSelfSignedCA(a.profile, tc, a.app.Name) - if err != nil { - return trace.Wrap(err) - } - - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Create a listener that is able to sign certificates when receiving GCP - // requests tunneled from the local forward proxy. - listener, err := alpnproxy.NewCertGenListener(alpnproxy.CertGenListenerConfig{ - ListenAddr: listenAddr, - CA: localCA, - }) - if err != nil { - return trace.Wrap(err) - } - - a.localALPNProxy, err = alpnproxy.NewLocalProxy( - makeBasicLocalProxyConfig(a.cf, tc, listener), - alpnproxy.WithClientCert(appCert), - alpnproxy.WithClusterCAsIfConnUpgrade(a.cf.Context, tc.RootClusterCACertPool), - alpnproxy.WithHTTPMiddleware(&alpnproxy.AuthorizationCheckerMiddleware{ - Secret: a.secret, - }), - ) - - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localALPNProxy.StartHTTPAccessProxy(a.cf.Context); err != nil { - log.WithError(err).Errorf("Failed to start local ALPN proxy.") - } - }() - return nil -} - -// startLocalForwardProxy starts the local forward proxy. -func (a *gcpApp) startLocalForwardProxy(port string) error { - listenAddr := "localhost:0" - if port != "" { - listenAddr = fmt.Sprintf("localhost:%s", port) - } - - // Note that the created forward proxy serves HTTP instead of HTTPS, to - // eliminate the need to install temporary CA for various GCP clients. - listener, err := net.Listen("tcp", listenAddr) - if err != nil { - return trace.Wrap(err) - } - - a.localForwardProxy, err = alpnproxy.NewForwardProxy(alpnproxy.ForwardProxyConfig{ - Listener: listener, - CloseContext: a.cf.Context, - Handlers: []alpnproxy.ConnectRequestHandler{ - // Forward GCP requests to ALPN proxy. - alpnproxy.NewForwardToHostHandler(alpnproxy.ForwardToHostHandlerConfig{ - MatchFunc: alpnproxy.MatchGCPRequests, - Host: a.localALPNProxy.GetAddr(), - }), - - // Forward non-GCP requests to user's system proxy, if configured. - alpnproxy.NewForwardToSystemProxyHandler(alpnproxy.ForwardToSystemProxyHandlerConfig{ - InsecureSystemProxy: a.cf.InsecureSkipVerify, - }), - - // Forward non-GCP requests to their original hosts. - alpnproxy.NewForwardToOriginalHostHandler(), - }, - }) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) - } - return trace.Wrap(err) - } - - go func() { - if err := a.localForwardProxy.Start(); err != nil { - log.WithError(err).Errorf("Failed to start local forward proxy.") - } - }() - return nil -} - func printGCPServiceAccounts(accounts []string) { fmt.Println(formatGCPServiceAccounts(accounts)) } @@ -482,6 +364,15 @@ func matchGCPApp(app tlsca.RouteToApp) bool { } func pickGCPApp(cf *CLIConf) (*gcpApp, error) { - app, err := pickCloudApp(cf, types.CloudGCP, matchGCPApp, newGCPApp) - return app, trace.Wrap(err) + tc, err := makeClient(cf) + if err != nil { + return nil, trace.Wrap(err) + } + + appInfo, err := getAppInfo(cf, tc, matchGCPApp) + if err != nil { + return nil, trace.Wrap(err) + } + + return newGCPApp(tc, cf, appInfo) } diff --git a/tool/tsh/common/app_gcp_test.go b/tool/tsh/common/app_gcp_test.go index 0e277fd8f836b..5a84950327486 100644 --- a/tool/tsh/common/app_gcp_test.go +++ b/tool/tsh/common/app_gcp_test.go @@ -26,8 +26,8 @@ import ( "github.com/gravitational/trace" "github.com/stretchr/testify/require" + "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/lib/client" - "github.com/gravitational/teleport/lib/tlsca" ) func Test_getGCPServiceAccountFromFlags(t *testing.T) { @@ -186,7 +186,7 @@ test-0@other-999999.iam.gserviceaccount.com func Test_gcpApp_Config(t *testing.T) { cf := &CLIConf{HomePath: t.TempDir()} profile := &client.ProfileStatus{} - route := tlsca.RouteToApp{ + route := proto.RouteToApp{ ClusterName: "test.teleport.io", Name: "myapp", GCPServiceAccount: "test@myproject-123456.iam.gserviceaccount.com", @@ -194,7 +194,10 @@ func Test_gcpApp_Config(t *testing.T) { t.Setenv("TELEPORT_GCLOUD_SECRET", "my_secret") - app, err := newGCPApp(cf, profile, route) + app, err := newGCPApp(nil, cf, &appInfo{ + RouteToApp: route, + profile: profile, + }) require.NoError(t, err) require.NotNil(t, app) diff --git a/tool/tsh/common/app_local_proxy.go b/tool/tsh/common/app_local_proxy.go new file mode 100644 index 0000000000000..ab7fba8de5a86 --- /dev/null +++ b/tool/tsh/common/app_local_proxy.go @@ -0,0 +1,208 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "cmp" + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/lib/client" + "github.com/gravitational/teleport/lib/srv/alpnproxy" +) + +// localProxyApp is a generic app that can start local proxies. +type localProxyApp struct { + tc *client.TeleportClient + appInfo *appInfo + insecure bool + port string + + localALPNProxy *alpnproxy.LocalProxy + localForwardProxy *alpnproxy.ForwardProxy +} + +type requestMatcher func(req *http.Request) bool + +// newLocalProxyApp creates a new generic app. +func newLocalProxyApp(tc *client.TeleportClient, appInfo *appInfo, port string, insecure bool) *localProxyApp { + return &localProxyApp{ + tc: tc, + appInfo: appInfo, + port: port, + insecure: insecure, + } +} + +// StartLocalProxy sets up local proxies for serving app clients. +func (a *localProxyApp) StartLocalProxy(ctx context.Context, opts ...alpnproxy.LocalProxyConfigOpt) error { + if err := a.startLocalALPNProxy(ctx, a.port, false /*withTLS*/, opts...); err != nil { + return trace.Wrap(err) + } + + if a.port == "" { + fmt.Println("To avoid port randomization, you can choose the listening port using the --port flag.") + } + return nil +} + +// StartLocalProxy sets up local proxies for serving app clients. +func (a *localProxyApp) StartLocalProxyWithTLS(ctx context.Context, opts ...alpnproxy.LocalProxyConfigOpt) error { + if err := a.startLocalALPNProxy(ctx, a.port, true /*withTLS*/, opts...); err != nil { + return trace.Wrap(err) + } + + if a.port == "" { + fmt.Println("To avoid port randomization, you can choose the listening port using the --port flag.") + } + return nil +} + +// StartLocalProxy sets up local proxies for serving app clients. +func (a *localProxyApp) StartLocalProxyWithForwarder(ctx context.Context, forwardMatcher requestMatcher, opts ...alpnproxy.LocalProxyConfigOpt) error { + if err := a.startLocalALPNProxy(ctx, "", true /*withTLS*/, opts...); err != nil { + return trace.Wrap(err) + } + + if err := a.startLocalForwardProxy(ctx, a.port, forwardMatcher); err != nil { + return trace.Wrap(err) + } + + if a.port == "" { + fmt.Println("To avoid port randomization, you can choose the listening port using the --port flag.") + } + return nil +} + +// Close makes all necessary close calls. +func (a *localProxyApp) Close() error { + var errs []error + if a.localALPNProxy != nil { + errs = append(errs, a.localALPNProxy.Close()) + } + if a.localForwardProxy != nil { + errs = append(errs, a.localForwardProxy.Close()) + } + return trace.NewAggregate(errs...) +} + +// startLocalALPNProxy starts the local ALPN proxy. +func (a *localProxyApp) startLocalALPNProxy(ctx context.Context, port string, withTLS bool, opts ...alpnproxy.LocalProxyConfigOpt) error { + // Create an app cert checker to check and reissue app certs for the local app proxy. + appCertChecker := client.NewAppCertChecker(a.tc, a.appInfo.RouteToApp, nil) + + // If a stored cert is found for the app, try using it. + // Otherwise, let the checker reissue one as needed. + cert, err := loadAppCertificate(a.tc, a.appInfo.RouteToApp.Name) + if err == nil { + appCertChecker.SetCert(cert) + } + + listenAddr := fmt.Sprintf("localhost:%s", cmp.Or(port, "0")) + + var listener net.Listener + if withTLS { + appLocalCAPath := a.appInfo.appLocalCAPath(a.tc.SiteName) + localCertGenerator, err := client.NewLocalCertGenerator(ctx, appCertChecker, appLocalCAPath) + if err != nil { + return trace.Wrap(err) + } + + if listener, err = tls.Listen("tcp", listenAddr, &tls.Config{ + GetCertificate: localCertGenerator.GetCertificate, + }); err != nil { + return trace.Wrap(err) + } + } else { + if listener, err = net.Listen("tcp", listenAddr); err != nil { + return trace.Wrap(err) + } + } + + a.localALPNProxy, err = alpnproxy.NewLocalProxy( + makeBasicLocalProxyConfig(ctx, a.tc, listener, a.insecure), + append(opts, + alpnproxy.WithClusterCAsIfConnUpgrade(ctx, a.tc.RootClusterCACertPool), + alpnproxy.WithMiddleware(appCertChecker), + )..., + ) + if err != nil { + if cerr := listener.Close(); cerr != nil { + return trace.NewAggregate(err, cerr) + } + return trace.Wrap(err) + } + + fmt.Printf("Proxying connections to %s on %v\n", a.appInfo.RouteToApp.Name, a.localALPNProxy.GetAddr()) + + go func() { + if err = a.localALPNProxy.Start(ctx); err != nil { + log.WithError(err).Errorf("Failed to start local ALPN proxy.") + } + }() + return nil +} + +// startLocalForwardProxy starts a local forward proxy that forwards matching requests +// to the local ALPN proxy and unmatched requests to their original hosts. +func (a *localProxyApp) startLocalForwardProxy(ctx context.Context, port string, forwardMatcher requestMatcher) error { + listenAddr := fmt.Sprintf("localhost:%s", cmp.Or(port, "0")) + listener, err := net.Listen("tcp", listenAddr) + if err != nil { + return trace.Wrap(err) + } + + a.localForwardProxy, err = alpnproxy.NewForwardProxy(alpnproxy.ForwardProxyConfig{ + Listener: listener, + CloseContext: ctx, + Handlers: []alpnproxy.ConnectRequestHandler{ + // Forward matched requests to ALPN proxy. + alpnproxy.NewForwardToHostHandler(alpnproxy.ForwardToHostHandlerConfig{ + MatchFunc: forwardMatcher, + Host: a.localALPNProxy.GetAddr(), + }), + + // Forward unmatched requests to user's system proxy, if configured. + alpnproxy.NewForwardToSystemProxyHandler(alpnproxy.ForwardToSystemProxyHandlerConfig{ + InsecureSystemProxy: a.insecure, + }), + + // Forward unmatched requests to their original hosts. + alpnproxy.NewForwardToOriginalHostHandler(), + }, + }) + if err != nil { + if cerr := listener.Close(); cerr != nil { + return trace.NewAggregate(err, cerr) + } + return trace.Wrap(err) + } + + go func() { + if err := a.localForwardProxy.Start(); err != nil { + log.WithError(err).Errorf("Failed to start local forward proxy.") + } + }() + return nil +} diff --git a/tool/tsh/common/app_test.go b/tool/tsh/common/app_test.go index 1fd57a2234b5d..76c6e54eedc1e 100644 --- a/tool/tsh/common/app_test.go +++ b/tool/tsh/common/app_test.go @@ -60,7 +60,7 @@ func startDummyHTTPServer(t *testing.T, name string) string { return srv.URL } -func testDummyAppConn(t require.TestingT, name string, addr string, tlsCerts ...tls.Certificate) { +func testDummyAppConn(t require.TestingT, addr string, tlsCerts ...tls.Certificate) (resp *http.Response) { clt := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ @@ -72,12 +72,7 @@ func testDummyAppConn(t require.TestingT, name string, addr string, tlsCerts ... resp, err := clt.Get(addr) assert.NoError(t, err) - if err != nil { - return - } - assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, name, resp.Header.Get("Server")) - _ = resp.Body.Close() + return resp } // TestAppCommands tests the following basic app command functionality for registered root and leaf apps. @@ -261,7 +256,10 @@ func TestAppCommands(t *testing.T) { clientCert, err := tls.LoadX509KeyPair(info.Cert, info.Key) require.NoError(t, err) - testDummyAppConn(t, app.name, fmt.Sprintf("https://%v", rootProxyAddr.Addr), clientCert) + resp := testDummyAppConn(t, fmt.Sprintf("https://%v", rootProxyAddr.Addr), clientCert) + resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, app.name, resp.Header.Get("Server")) // app logout. err = Run(ctx, []string{ @@ -291,20 +289,25 @@ func TestAppCommands(t *testing.T) { }() assert.EventuallyWithT(t, func(t *assert.CollectT) { - testDummyAppConn(t, app.name, fmt.Sprintf("http://127.0.0.1:%v", localProxyPort)) + resp := testDummyAppConn(t, fmt.Sprintf("http://127.0.0.1:%v", localProxyPort)) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, app.name, resp.Header.Get("Server")) + resp.Body.Close() }, 10*time.Second, time.Second) proxyCancel() assert.NoError(t, <-errC) - // proxy certs should not be saved to disk. - err = Run(context.Background(), []string{ - "app", - "config", - app.name, - "--cluster", app.cluster, - }, setHomePath(loginPath)) - assert.True(t, trace.IsNotFound(err), "expected not found error but got: %v", err) + // proxy certs should not be saved to disk if mfa was used.. + if requireMFAType == types.RequireMFAType_SESSION { + err = Run(context.Background(), []string{ + "app", + "config", + app.name, + "--cluster", app.cluster, + }, setHomePath(loginPath)) + assert.True(t, trace.IsNotFound(err), "expected not found error but got: %v", err) + } }) }) } diff --git a/tool/tsh/common/db.go b/tool/tsh/common/db.go index 0acf41d1bc1f8..1301f6fb34f44 100644 --- a/tool/tsh/common/db.go +++ b/tool/tsh/common/db.go @@ -628,7 +628,7 @@ func maybeStartLocalProxy(ctx context.Context, cf *CLIConf, return nil, trace.Wrap(err) } - lp, err := alpnproxy.NewLocalProxy(makeBasicLocalProxyConfig(cf, tc, listener), opts...) + lp, err := alpnproxy.NewLocalProxy(makeBasicLocalProxyConfig(cf.Context, tc, listener, cf.InsecureSkipVerify), opts...) if err != nil { return nil, trace.Wrap(err) } @@ -706,7 +706,7 @@ func prepareLocalProxyOptions(arg *localProxyConfig) ([]alpnproxy.LocalProxyConf // proxy starts instead. cert, err := loadDBCertificate(arg.tc, arg.dbInfo.ServiceName) if err == nil { - opts = append(opts, alpnproxy.WithClientCert(cert)) + cc.SetCert(cert) } return opts, nil } @@ -1020,7 +1020,7 @@ func (d *databaseInfo) GetDatabase(ctx context.Context, tc *client.TeleportClien d.mu.Lock() defer d.mu.Unlock() if d.database != nil { - return d.database, nil + return d.database.Copy(), nil } // holding mutex across the api call to avoid multiple redundant api calls. database, err := getDatabase(ctx, tc, d.ServiceName) @@ -1028,7 +1028,7 @@ func (d *databaseInfo) GetDatabase(ctx context.Context, tc *client.TeleportClien return nil, trace.Wrap(err) } d.database = database - return d.database, nil + return d.database.Copy(), nil } // chooseOneDatabase is a helper func that returns either the only database in a diff --git a/tool/tsh/common/hardware_key_test.go b/tool/tsh/common/hardware_key_test.go index 1fb819d55b9d8..7e4bcd4cbc233 100644 --- a/tool/tsh/common/hardware_key_test.go +++ b/tool/tsh/common/hardware_key_test.go @@ -26,9 +26,9 @@ import ( "crypto/tls" "encoding/json" "fmt" + "net/http" "os/user" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -350,7 +350,7 @@ func TestHardwareKeyApp(t *testing.T) { require.NoError(t, err) registerDeviceForUser(t, authServer, device, accessUser.GetName(), origin) - // Login before adding hardware key requirement + // Login before adding hardware key requirement and verify we can connect to the app. tmpHomePath := t.TempDir() err = Run(ctx, []string{ "login", @@ -359,7 +359,36 @@ func TestHardwareKeyApp(t *testing.T) { }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName())) require.NoError(t, err) - // Require hardware key touch for the user. + err = Run(ctx, []string{ + "app", + "login", + "myapp", + "--insecure", + "--proxy", proxyAddr.String(), + }, setHomePath(tmpHomePath)) + require.NoError(t, err) + + confOut := new(bytes.Buffer) + err = Run(ctx, []string{ + "app", + "config", + "myapp", + "--format", "json", + }, setHomePath(tmpHomePath), setOverrideStdout(confOut)) + require.NoError(t, err) + + var info appConfigInfo + require.NoError(t, json.Unmarshal(confOut.Bytes(), &info)) + + clientCert, err := tls.LoadX509KeyPair(info.Cert, info.Key) + require.NoError(t, err) + + resp := testDummyAppConn(t, fmt.Sprintf("https://%v", proxyAddr.Addr), clientCert) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "myapp", resp.Header.Get("Server")) + resp.Body.Close() + + // Require hardware key touch for the user. The user's current app certs should fail. accessRole, err := authServer.GetRole(ctx, "access") require.NoError(t, err) accessRole.SetOptions(types.RoleOptions{ @@ -369,7 +398,10 @@ func TestHardwareKeyApp(t *testing.T) { require.NoError(t, err) testModules.MockAttestationData = nil - tmpHomePath = t.TempDir() + + resp = testDummyAppConn(t, fmt.Sprintf("https://%v", proxyAddr.Addr), clientCert) + assert.Equal(t, http.StatusBadRequest, resp.StatusCode) + resp.Body.Close() // App login fails without an attested hardware key login. err = Run(ctx, []string{ @@ -381,25 +413,12 @@ func TestHardwareKeyApp(t *testing.T) { }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName())) require.Error(t, err) - // Proxy app fails without an attested hardware key login. - proxyCtx, proxyCancel := context.WithTimeout(ctx, 10*time.Second) - defer proxyCancel() - - err = Run(proxyCtx, []string{ - "proxy", - "app", - "myapp", - "--insecure", - "--proxy", proxyAddr.String(), - }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName())) - require.Error(t, err) - // Set MockAttestationData to attest the expected key policy and try again. testModules.MockAttestationData = &keys.AttestationData{ PrivateKeyPolicy: keys.PrivateKeyPolicyHardwareKeyTouch, } - // App commands will still fail without MFA, since the app sessions will + // App Login will still fail without MFA, since the app sessions will // only be attested as "web_session". webauthnLoginOpt := setupWebAuthnChallengeSolver(device, false /* success */) @@ -412,22 +431,10 @@ func TestHardwareKeyApp(t *testing.T) { }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName()), webauthnLoginOpt) require.Error(t, err) - proxyCtx, proxyCancel = context.WithTimeout(ctx, 10*time.Second) - defer proxyCancel() - - err = Run(proxyCtx, []string{ - "proxy", - "app", - "myapp", - "--insecure", - "--proxy", proxyAddr.String(), - }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName()), webauthnLoginOpt) - require.Error(t, err) - // App commands will succeed with MFA. webauthnLoginOpt = setupWebAuthnChallengeSolver(device, true /* success */) - // Test App login success. + // Test App login success and connect. err = Run(ctx, []string{ "app", "login", @@ -437,8 +444,7 @@ func TestHardwareKeyApp(t *testing.T) { }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName()), webauthnLoginOpt) require.NoError(t, err) - // Retrieve the app login config (private key, ca, and cert). - confOut := new(bytes.Buffer) + confOut = new(bytes.Buffer) err = Run(ctx, []string{ "app", "config", @@ -447,36 +453,13 @@ func TestHardwareKeyApp(t *testing.T) { }, setHomePath(tmpHomePath), setOverrideStdout(confOut)) require.NoError(t, err) - // Verify that we can connect to the app using the generated app cert. - var info appConfigInfo require.NoError(t, json.Unmarshal(confOut.Bytes(), &info)) - clientCert, err := tls.LoadX509KeyPair(info.Cert, info.Key) + clientCert, err = tls.LoadX509KeyPair(info.Cert, info.Key) require.NoError(t, err) - testDummyAppConn(t, "myapp", fmt.Sprintf("https://%v", proxyAddr.Addr), clientCert) - - // Test Proxy app success. - localProxyPort := ports.Pop() - proxyCtx, proxyCancel = context.WithTimeout(ctx, 10*time.Second) - defer proxyCancel() - - errC := make(chan error) - go func() { - errC <- Run(proxyCtx, []string{ - "proxy", - "app", - "myapp", - "--port", localProxyPort, - "--insecure", - "--proxy", proxyAddr.String(), - }, setHomePath(tmpHomePath), setMockSSOLogin(authServer, accessUser, connector.GetName()), webauthnLoginOpt) - }() - - assert.EventuallyWithT(t, func(t *assert.CollectT) { - testDummyAppConn(t, "myapp", fmt.Sprintf("http://127.0.0.1:%v", localProxyPort)) - }, 10*time.Second, time.Second) - - proxyCancel() - assert.NoError(t, <-errC) + resp = testDummyAppConn(t, fmt.Sprintf("https://%v", proxyAddr.Addr), clientCert) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "myapp", resp.Header.Get("Server")) + resp.Body.Close() } diff --git a/tool/tsh/common/kube_proxy.go b/tool/tsh/common/kube_proxy.go index d2b23b1f73612..4dc8845b4b23d 100644 --- a/tool/tsh/common/kube_proxy.go +++ b/tool/tsh/common/kube_proxy.go @@ -345,7 +345,7 @@ func makeKubeLocalProxy(cf *CLIConf, tc *client.TeleportClient, clusters kubecon }) localProxy, err := alpnproxy.NewLocalProxy( - makeBasicLocalProxyConfig(cf, tc, lpListener), + makeBasicLocalProxyConfig(cf.Context, tc, lpListener, cf.InsecureSkipVerify), alpnproxy.WithHTTPMiddleware(kubeMiddleware), alpnproxy.WithSNI(client.GetKubeTLSServerName(tc.WebProxyHost())), alpnproxy.WithClusterCAs(cf.Context, tc.RootClusterCACertPool), @@ -388,7 +388,7 @@ func (k *kubeLocalProxy) Start(ctx context.Context) error { errChan <- k.forwardProxy.Start() }() go func() { - errChan <- k.localProxy.StartHTTPAccessProxy(ctx) + errChan <- k.localProxy.Start(ctx) }() select { diff --git a/tool/tsh/common/proxy.go b/tool/tsh/common/proxy.go index abe25adb60976..53866dede32ec 100644 --- a/tool/tsh/common/proxy.go +++ b/tool/tsh/common/proxy.go @@ -30,7 +30,6 @@ import ( "strconv" "strings" "text/template" - "time" "unicode" "github.com/gravitational/trace" @@ -211,7 +210,7 @@ func onProxyCommandDB(cf *CLIConf) error { return trace.Wrap(err) } - lp, err := alpnproxy.NewLocalProxy(makeBasicLocalProxyConfig(cf, tc, listener), proxyOpts...) + lp, err := alpnproxy.NewLocalProxy(makeBasicLocalProxyConfig(cf.Context, tc, listener, cf.InsecureSkipVerify), proxyOpts...) if err != nil { return trace.Wrap(err) } @@ -382,80 +381,29 @@ func onProxyCommandApp(cf *CLIConf) error { return trace.Wrap(err) } - app, err := getRegisteredApp(cf, tc) + appInfo, err := getAppInfo(cf, tc, nil /*matchRouteToApp*/) if err != nil { return trace.Wrap(err) } - profile, err := tc.ProfileStatus() + app, err := appInfo.GetApp(cf.Context, tc) if err != nil { return trace.Wrap(err) } - routeToApp, err := getRouteToApp(cf, tc, profile, app) - if err != nil { + proxyApp := newLocalProxyApp(tc, appInfo, cf.LocalProxyPort, cf.InsecureSkipVerify) + if err := proxyApp.StartLocalProxy(cf.Context, alpnproxy.WithALPNProtocol(alpnProtocolForApp(app))); err != nil { return trace.Wrap(err) } - opts := []alpnproxy.LocalProxyConfigOpt{ - alpnproxy.WithALPNProtocol(alpnProtocolForApp(app)), - alpnproxy.WithClusterCAsIfConnUpgrade(cf.Context, tc.RootClusterCACertPool), - alpnproxy.WithMiddleware(libclient.NewAppCertChecker(tc, routeToApp, nil)), - } - - // Virtual profiles (e.g. indirect use via `tbot proxy app`) will attempt - // relogin which is not possible. For these, we'll need to load the app - // certificate manually and prepend the config option. - // TODO(timothyb89): Remove this workaround in favor of - // https://github.com/gravitational/teleport/pull/40985 once it is merged. - if profile.IsVirtual { - cert, needLogin, err := loadAppCertificate(tc, app.GetName()) - if err != nil { - return trace.Wrap(err) - } - - if needLogin { - return trace.BadParameter("app identity requires relogin but this is impossible with a virtual profile") - } - - opts = append([]alpnproxy.LocalProxyConfigOpt{ - alpnproxy.WithClientCert(cert), - }, opts...) - } - - addr := "localhost:0" - if cf.LocalProxyPort != "" { - addr = fmt.Sprintf("127.0.0.1:%s", cf.LocalProxyPort) - } - - listener, err := net.Listen("tcp", addr) - if err != nil { - return trace.Wrap(err) - } - - lp, err := alpnproxy.NewLocalProxy(makeBasicLocalProxyConfig(cf, tc, listener), opts...) - if err != nil { - if cerr := listener.Close(); cerr != nil { - return trace.NewAggregate(err, cerr) + defer func() { + if err := proxyApp.Close(); err != nil { + log.WithError(err).Error("Failed to close app proxy.") } - return trace.Wrap(err) - } - - fmt.Printf("Proxying connections to %s on %v\n", cf.AppName, lp.GetAddr()) - if cf.LocalProxyPort == "" { - fmt.Println("To avoid port randomization, you can choose the listening port using the --port flag.") - } - - go func() { - <-cf.Context.Done() - lp.Close() }() - defer lp.Close() - if err = lp.Start(cf.Context); err != nil { - return trace.Wrap(err) - } - + // Proxy connections until the client terminates the command. + <-cf.Context.Done() return nil } @@ -470,7 +418,7 @@ func onProxyCommandAWS(cf *CLIConf) error { return trace.Wrap(err) } - err = awsApp.StartLocalProxies() + err = awsApp.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -484,6 +432,7 @@ func onProxyCommandAWS(cf *CLIConf) error { if err := printProxyAWSTemplate(cf, awsApp); err != nil { return trace.Wrap(err) } + <-cf.Context.Done() return nil } @@ -562,7 +511,7 @@ func onProxyCommandAzure(cf *CLIConf) error { return trace.Wrap(err) } - err = azApp.StartLocalProxies() + err = azApp.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -593,7 +542,7 @@ func onProxyCommandGCloud(cf *CLIConf) error { return trace.Wrap(err) } - err = gcpApp.StartLocalProxies() + err = gcpApp.StartLocalProxies(cf.Context) if err != nil { return trace.Wrap(err) } @@ -617,59 +566,20 @@ func onProxyCommandGCloud(cf *CLIConf) error { return nil } -// loadAppCertificateWithAppLogin is a wrapper around loadAppCertificate that will attempt to login the user to -// the app of choice at most once, if the return value from loadAppCertificate call indicates that app login -// should fix the problem. -func loadAppCertificateWithAppLogin(cf *CLIConf, tc *libclient.TeleportClient, appName string) (tls.Certificate, error) { - cert, needLogin, err := loadAppCertificate(tc, appName) - if err != nil { - if !needLogin { - return tls.Certificate{}, trace.Wrap(err) - } - log.WithError(err).Debugf("Loading app certificate failed, attempting to login to app %q", appName) - quiet := cf.Quiet - cf.Quiet = true - errLogin := onAppLogin(cf) - cf.Quiet = quiet - if errLogin != nil { - log.WithError(errLogin).Debugf("Login attempt failed") - // combine errors - return tls.Certificate{}, trace.NewAggregate(err, errLogin) - } - // another attempt - cert, _, err = loadAppCertificate(tc, appName) - return cert, trace.Wrap(err) - } - return cert, nil -} - -// loadAppCertificate loads the app certificate for the provided app. -// Returns tuple (certificate, needLogin, err). -// The boolean `needLogin` will be true if the error returned should go away with successful `tsh app login `. -func loadAppCertificate(tc *libclient.TeleportClient, appName string) (certificate tls.Certificate, needLogin bool, err error) { +func loadAppCertificate(tc *libclient.TeleportClient, appName string) (tls.Certificate, error) { key, err := tc.LocalAgent().GetKey(tc.SiteName, libclient.WithAppCerts{}) if err != nil { - return tls.Certificate{}, false, trace.Wrap(err) + return tls.Certificate{}, trace.Wrap(err) } appCert, err := key.AppTLSCert(appName) if trace.IsNotFound(err) { - return tls.Certificate{}, true, trace.NotFound("please login into the application first: 'tsh apps login %v'", appName) + return tls.Certificate{}, trace.NotFound("please login into the application first: 'tsh apps login %v'", appName) } else if err != nil { - return tls.Certificate{}, false, trace.Wrap(err) - } - - expiresAt, err := getTLSCertExpireTime(appCert) - if err != nil { - return tls.Certificate{}, true, trace.WrapWithMessage(err, "invalid certificate - please login to the application again: 'tsh apps login %v'", appName) - } - if time.Until(expiresAt) < 5*time.Second { - return tls.Certificate{}, true, trace.BadParameter( - "application %s certificate has expired, please re-login to the app using 'tsh apps login %v'", appName, - appName) + return tls.Certificate{}, trace.Wrap(err) } - return appCert, false, nil + return appCert, nil } func loadDBCertificate(tc *libclient.TeleportClient, dbName string) (tls.Certificate, error) { @@ -688,15 +598,6 @@ func loadDBCertificate(tc *libclient.TeleportClient, dbName string) (tls.Certifi return dbCert, nil } -// getTLSCertExpireTime returns the certificate NotAfter time. -func getTLSCertExpireTime(cert tls.Certificate) (time.Time, error) { - x509cert, err := utils.TLSCertLeaf(cert) - if err != nil { - return time.Time{}, trace.Wrap(err) - } - return x509cert.NotAfter, nil -} - func getEnvOrDefault(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value @@ -704,11 +605,11 @@ func getEnvOrDefault(key, defaultValue string) string { return defaultValue } -func makeBasicLocalProxyConfig(cf *CLIConf, tc *libclient.TeleportClient, listener net.Listener) alpnproxy.LocalProxyConfig { +func makeBasicLocalProxyConfig(ctx context.Context, tc *libclient.TeleportClient, listener net.Listener, insecure bool) alpnproxy.LocalProxyConfig { return alpnproxy.LocalProxyConfig{ RemoteProxyAddr: tc.WebProxyAddr, - InsecureSkipVerify: cf.InsecureSkipVerify, - ParentContext: cf.Context, + InsecureSkipVerify: insecure, + ParentContext: ctx, Listener: listener, ALPNConnUpgradeRequired: tc.TLSRoutingConnUpgradeRequired, } From 43d39cb2ab9f9e6f00922ab9c914bd6733271e56 Mon Sep 17 00:00:00 2001 From: Jakub Nyckowski Date: Thu, 20 Jun 2024 16:59:57 -0400 Subject: [PATCH 26/30] Add Teleport Assist config option removal. (#43313) * Add Teleport Assist config option removal. * Update CHANGELOG.md Co-authored-by: Paul Gottschling --------- Co-authored-by: Paul Gottschling --- CHANGELOG.md | 5 ++++- .../includes/config-reference/auth-service.yaml | 13 ------------- .../includes/config-reference/proxy-service.yaml | 7 ------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c85d96808f91..575770837f3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,10 @@ for setup instructions. #### Teleport Assist has been removed -Teleport Assist chat has been removed from Teleport 16. +Teleport Assist chat has been removed from Teleport 16. `auth_service.assist` and `proxy_service.assist` +options have been removed from the configuration. Teleport will not start if these options are present. + +During the migration from v15 to v16, the options mentioned above should be removed from the configuration. #### DynamoDB permission requirements have changed diff --git a/docs/pages/includes/config-reference/auth-service.yaml b/docs/pages/includes/config-reference/auth-service.yaml index d18fbdf1cf7b8..5463de6b34486 100644 --- a/docs/pages/includes/config-reference/auth-service.yaml +++ b/docs/pages/includes/config-reference/auth-service.yaml @@ -412,19 +412,6 @@ auth_service: # characters in their hostnames. case_insensitive_routing: false - # Configuration for the Teleport Assist functionality - assist: - openai: - # An absolute path to the file containing the API token for OpenAI. - # This is required for Assist functionality. - api_token_path: /etc/teleport/openai_key - - # When executing commands on servers through Teleport Assist, - # this is the maximum number of servers that Assist will connect to in parallel. - # This only applies in the context of a single command execution - - # if multiple users are using Assist concurrently, more connections may be made. - command_execution_workers: 30 - # AccessMonitoring is a set of options related to the Access Monitoring feature. access_monitoring: # Turn on Access Monitoring. Default is 'no'. diff --git a/docs/pages/includes/config-reference/proxy-service.yaml b/docs/pages/includes/config-reference/proxy-service.yaml index d2dec48df8462..6439ed28df221 100644 --- a/docs/pages/includes/config-reference/proxy-service.yaml +++ b/docs/pages/includes/config-reference/proxy-service.yaml @@ -169,13 +169,6 @@ proxy_service: # one IPs will be rejected. trust_x_forwarded_for: false - # Configuration for the Teleport Assist functionality - assist: - openai: - # An absolute path to the file containing the API token for OpenAI. - # This is required for Assist functionality. - api_token_path: /etc/teleport/openai_key - # Configuration for the built-in version server for agent automatic updates. # If you leave this configuration unset, a default channel is created and # serves the Teleport version run by the Proxy Service. From e673a7ab333a655fe2334e990e9e5d310d21db44 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 20 Jun 2024 18:21:04 -0300 Subject: [PATCH 27/30] fix: Use correct libfido2 version on Dockerfile-centos7 (#43317) --- build.assets/Dockerfile-centos7 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.assets/Dockerfile-centos7 b/build.assets/Dockerfile-centos7 index afbb9a4dd6bc9..414b8c227bbb7 100644 --- a/build.assets/Dockerfile-centos7 +++ b/build.assets/Dockerfile-centos7 @@ -278,7 +278,7 @@ COPY --from=libfido2 \ /usr/local/lib64/libcrypto.a \ /usr/local/lib64/libcrypto.so.3 \ /usr/local/lib64/libfido2.a \ - /usr/local/lib64/libfido2.so.1.14.0 \ + /usr/local/lib64/libfido2.so.1.15.0 \ /usr/local/lib64/libssl.a \ /usr/local/lib64/libssl.so.3 \ /usr/local/lib64/libudev.a \ @@ -286,7 +286,7 @@ COPY --from=libfido2 \ # Re-create usual lib64 links. RUN cd /usr/local/lib64 && \ ln -s libcrypto.so.3 libcrypto.so && \ - ln -s libfido2.so.1.14.0 libfido2.so.1 && \ + ln -s libfido2.so.1.15.0 libfido2.so.1 && \ ln -s libfido2.so.1 libfido2.so && \ ln -s libssl.so.3 libssl.so && \ # Update ld. From 7dd14a1713b7f9e977f1b48aeb83112298ad40bd Mon Sep 17 00:00:00 2001 From: Paul Gottschling Date: Thu, 20 Jun 2024 17:51:32 -0400 Subject: [PATCH 28/30] Mention `--[no-]fips` flag in tbot reference (#42103) Closes #38141 --- docs/pages/reference/cli/tbot.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/reference/cli/tbot.mdx b/docs/pages/reference/cli/tbot.mdx index 104b60e460b2e..fdea4fece32d9 100644 --- a/docs/pages/reference/cli/tbot.mdx +++ b/docs/pages/reference/cli/tbot.mdx @@ -201,6 +201,7 @@ Starts the Machine ID client `tbot`, fetching and writing certificates to disk a |----------------------|------------------------------------------------------------------------------------------------| | `-d/--debug` | Enable verbose logging to stderr. | | `-c/--config` | Path to a Machine ID configuration file. | +| `--[no-]fips` | Whether to run tbot in FIPS compliance mode. This requires the FIPS `tbot` binary. | | `-a/--auth-server` | Address of the Teleport Auth Service. Prefer using --proxy-server where possible | | `--proxy-server` | Address of the Teleport Proxy Server. | | `--token` | A bot join token, if attempting to onboard a new bot; used on first connect. Can also be an absolute path to a file containing the token. | @@ -252,4 +253,4 @@ detected on the system. | Flag | Description | |----------------------|------------------------------------| -| `-d/--debug` | Enable verbose logging to stderr. | \ No newline at end of file +| `-d/--debug` | Enable verbose logging to stderr. | From 1111bd88af719c3df70c84e0fdbcad4300d49b90 Mon Sep 17 00:00:00 2001 From: Sakshyam Shah Date: Thu, 20 Jun 2024 17:58:35 -0400 Subject: [PATCH 29/30] Docs: update SAML IdP GCP workforce guide with IAM role prerequisite and new input label copy (#43138) * mention gcp workforce admin role prerequisites * update gcp input screenshot * reflect input label changes * update image link * Update docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx Co-authored-by: Paul Gottschling --------- Co-authored-by: Paul Gottschling --- .../gcp-workforce/generate-command.png | Bin 0 -> 207587 bytes .../saml-idp/gcp-workforce/generate-script.png | Bin 505952 -> 0 bytes .../saml-gcp-workforce-identity-federation.mdx | 12 +++++++----- 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 docs/img/access-controls/saml-idp/gcp-workforce/generate-command.png delete mode 100644 docs/img/access-controls/saml-idp/gcp-workforce/generate-script.png diff --git a/docs/img/access-controls/saml-idp/gcp-workforce/generate-command.png b/docs/img/access-controls/saml-idp/gcp-workforce/generate-command.png new file mode 100644 index 0000000000000000000000000000000000000000..4521de5d16f10869b2513e91c7a21c64d371dde7 GIT binary patch literal 207587 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 E>h9$ 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 OPx`Xlzfvx0J^nv@gov#G diff --git a/docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx b/docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx index d60297bb46d42..c3d7e6d440d82 100644 --- a/docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx +++ b/docs/pages/access-controls/idps/saml-gcp-workforce-identity-federation.mdx @@ -27,6 +27,8 @@ SAML IdP, so users can sign in into GCP web console by authenticating with Telep Reference](./saml-reference.mdx) before proceeding. - User with permission to create service provider resource. The preset `editor` role has this permission. - Access to GCP IAM API, with permission to create workforce identity pool, pool provider and an IAM policy. +At a minimum, both the "IAM Workforce Pool Admin" and "Organization Viewer" [GCP roles](https://cloud.google.com/iam/docs/configuring-workforce-identity-federation#required-roles) +are required (assigned at the GCP organization level) to configure GCP Workforce Identity Federation. Teleport Web UI offers both the guided and manual configuration flow for GCP Workforce Identity @@ -47,15 +49,15 @@ Now follow the steps listed below. ## Step 1/3. Configure workforce pool As a first step, provide the following information to the script generator. -![Test the IdP](../../../img/access-controls/saml-idp/gcp-workforce/generate-script.png) +![Test the IdP](../../../img/access-controls/saml-idp/gcp-workforce/generate-command.png) - **Organization ID:** Organization ID of GCP account. The ID is required to create a workforce pool. -- **Pool Name:** Name of the workforce pool to be created. Name should follow [GCP resource naming +- **Workforce pool name:** Name of the workforce pool to be created. Name should follow [GCP resource naming convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format). -- **Pool Provider Name:** Name of the workforce pool provider to be created. Pool provider name -will also be used as SAML service provider name in the next step. Name should follow +- **App name - Workforce pool provider name:** SAML app name. The name +will also be used as a workforce pool provider name in the GCP. Name should follow [GCP resource naming convention](https://cloud.google.com/compute/docs/naming-resources#resource-name-format). -Click on **Generate Script** button. Teleport Web UI will now show you a copyable bash script. +Click on the **Generate Command** button. The Teleport Web UI will now show you a copyable bash script. Open GCP [Cloud Shell](https://shell.cloud.google.com/?show=terminal) and inside the Cloud Shell terminal, paste the bash script you copied above. From d13061b584ec6390fd46b6f4518479a2c41e3982 Mon Sep 17 00:00:00 2001 From: Brian Joerger Date: Thu, 20 Jun 2024 17:32:17 -0700 Subject: [PATCH 30/30] Check if listener is nil before wrapping. (#43201) --- lib/limiter/limiter.go | 2 +- lib/limiter/limiter_test.go | 3 ++- lib/limiter/listener.go | 8 ++++++-- lib/service/service.go | 28 ++++++++++++++++++++++++---- lib/sshutils/server.go | 7 ++++++- 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/lib/limiter/limiter.go b/lib/limiter/limiter.go index 0134d9487fe00..9528caac2bdb5 100644 --- a/lib/limiter/limiter.go +++ b/lib/limiter/limiter.go @@ -180,7 +180,7 @@ func (l *Limiter) StreamServerInterceptor(srv interface{}, serverStream grpc.Ser // WrapListener returns a [Listener] that wraps the provided listener // with one that limits connections -func (l *Limiter) WrapListener(ln net.Listener) *Listener { +func (l *Limiter) WrapListener(ln net.Listener) (*Listener, error) { return NewListener(ln, l.ConnectionsLimiter) } diff --git a/lib/limiter/limiter_test.go b/lib/limiter/limiter_test.go index 1c5208836f98d..cdd48bb9672da 100644 --- a/lib/limiter/limiter_test.go +++ b/lib/limiter/limiter_test.go @@ -407,7 +407,8 @@ func TestListener(t *testing.T) { limiter, err := NewConnectionsLimiter(test.config) require.NoError(t, err) - ln := NewListener(test.listener, limiter) + ln, err := NewListener(test.listener, limiter) + require.NoError(t, err) // open connections without closing to enforce limits conns := make([]net.Conn, 0, connLimit) diff --git a/lib/limiter/listener.go b/lib/limiter/listener.go index 74741ac4d6316..e93325ddc2eee 100644 --- a/lib/limiter/listener.go +++ b/lib/limiter/listener.go @@ -35,11 +35,15 @@ type Listener struct { // NewListener creates a [Listener] that enforces the limits of // the provided [ConnectionsLimiter] on the all connections accepted // by the provided [net.Listener]. -func NewListener(ln net.Listener, limiter *ConnectionsLimiter) *Listener { +func NewListener(ln net.Listener, limiter *ConnectionsLimiter) (*Listener, error) { + if ln == nil { + return nil, trace.BadParameter("listener cannot be nil") + } + return &Listener{ Listener: ln, limiter: limiter, - } + }, nil } // Accept waits for and returns the next connection to the listener diff --git a/lib/service/service.go b/lib/service/service.go index 20458cd14770a..6ccd5aeae4dde 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -2824,7 +2824,12 @@ func (process *TeleportProcess) initSSH() error { }() defer mux.Close() - go s.Serve(limiter.WrapListener(mux.SSH())) + listener, err = limiter.WrapListener(mux.SSH()) + if err != nil { + return trace.Wrap(err) + } + + go s.Serve(listener) } else { // Start the SSH server. This kicks off updating labels and starting the // heartbeat. @@ -4093,6 +4098,11 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { } } + rtListener, err := reverseTunnelLimiter.WrapListener(listeners.reverseTunnel) + if err != nil { + return trace.Wrap(err) + } + tsrv, err = reversetunnel.NewServer( reversetunnel.Config{ Context: process.ExitContext(), @@ -4100,7 +4110,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { ID: process.Config.HostUUID, ClusterName: clusterName, ClientTLS: clientTLSConfig, - Listener: reverseTunnelLimiter.WrapListener(listeners.reverseTunnel), + Listener: rtListener, GetHostSigners: sshutils.StaticHostSigners(conn.ServerIdentity.KeySigner), LocalAuthClient: conn.Client, LocalAccessPoint: accessPoint, @@ -4614,14 +4624,24 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { // start ssh server go func() { - if err := sshProxy.Serve(proxyLimiter.WrapListener(listeners.ssh)); err != nil && !utils.IsOKNetworkError(err) { + listener, err := proxyLimiter.WrapListener(listeners.ssh) + if err != nil { + logger.ErrorContext(process.ExitContext(), "Failed to set up SSH proxy server", "error", err) + return + } + if err := sshProxy.Serve(listener); err != nil && !utils.IsOKNetworkError(err) { logger.ErrorContext(process.ExitContext(), "SSH proxy server terminated unexpectedly", "error", err) } }() // start grpc server go func() { - if err := sshGRPCServer.Serve(proxyLimiter.WrapListener(listeners.sshGRPC)); err != nil && !utils.IsOKNetworkError(err) && !errors.Is(err, grpc.ErrServerStopped) { + listener, err := proxyLimiter.WrapListener(listeners.sshGRPC) + if err != nil { + logger.ErrorContext(process.ExitContext(), "Failed to set up SSH proxy server", "error", err) + return + } + if err := sshGRPCServer.Serve(listener); err != nil && !utils.IsOKNetworkError(err) && !errors.Is(err, grpc.ErrServerStopped) { logger.ErrorContext(process.ExitContext(), "SSH gRPC server terminated unexpectedly", "error", err) } }() diff --git a/lib/sshutils/server.go b/lib/sshutils/server.go index 7faedf42c0c98..fb1a431105aa6 100644 --- a/lib/sshutils/server.go +++ b/lib/sshutils/server.go @@ -335,7 +335,12 @@ func (s *Server) Start() error { return trace.ConvertSystemError(err) } - if err := s.SetListener(s.limiter.WrapListener(listener)); err != nil { + listener, err = s.limiter.WrapListener(listener) + if err != nil { + return trace.Wrap(err) + } + + if err := s.SetListener(listener); err != nil { return trace.Wrap(err) } }

fouK_XDwLZ)`w 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