Skip to content

Commit

Permalink
[v8]: Desktop Access backports for 8.1.0 (#9678)
Browse files Browse the repository at this point in the history
* Tweak LDAPS troubleshooting docs

Make it clear that an LDAP connection reset can be due to attempting
to connect on port 389 (which is what our original instructions advised)

* Update example username desktop service to single quotes

* Update rdp-rs (#9344)

This includes gravitational/rdp-rs#5 which will show a better
error message for protocol negotiation failures.

Also bump the libc dependency while we're at it.
All other crates are still up to date.

* Allow locking a desktop

Prior to this change, desktop access only respected locks
on users or roles. This introduces a desktop as a lock target,
preventing new connections and terminating existing connections
to a locked desktop.

Note: when a lock is created, connection attempts will fail
with the generic "websocket connection failed" error.
This will be addressed with #8584.

Updates #8742

* Update locking guide to include Windows Desktops

* Emit the correct session ID for SessionLeave events

Fixes #9574

* Adds the windows_desktop_service section to the meta teleport.yaml (#9573)

* fixes mdx comment style (#9599)

* fixes mdx comment style. leaves a test of the previous comment style in there to see how it got past CI

* removing bad comment

* Disable RDP client on ARM 32 bit (#9667)

Disable RDP client on ARM to remove libatomic dependency on Linux.

* Update e ref

Co-authored-by: Steven Martin <[email protected]>
Co-authored-by: Isaiah Becker-Mayer <[email protected]>
Co-authored-by: Jakub Nyckowski <[email protected]>
  • Loading branch information
4 people authored Jan 7, 2022
1 parent bd9acab commit 80122c9
Show file tree
Hide file tree
Showing 19 changed files with 840 additions and 693 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,14 @@ ROLETESTER_MESSAGE := "with access tester"
ROLETESTER_TAG := roletester
ROLETESTER_BUILDDIR := lib/datalog/roletester/Cargo.toml

ifneq ("$(ARCH)","arm")
# Do not build RDP client on ARM. The client includes OpenSSL which requires libatomic on ARM 32bit.
with_rdpclient := yes
RDPCLIENT_MESSAGE := "with Windows RDP client"
RDPCLIENT_TAG := desktop_access_rdp
endif
endif
endif

# Reproducible builds are only available on select targets, and only when OS=linux.
REPRODUCIBLE ?=
Expand Down
3 changes: 3 additions & 0 deletions api/types/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ func (t LockTarget) Match(lock Lock) bool {
if t.MFADevice != "" && lockTarget.MFADevice != t.MFADevice {
return false
}
if t.WindowsDesktop != "" && lockTarget.WindowsDesktop != t.WindowsDesktop {
return false
}
return true
}

Expand Down
1,342 changes: 694 additions & 648 deletions api/types/types.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions api/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,9 @@ message LockTarget {

// MFADevice specifies the UUID of a user MFA device.
string MFADevice = 5 [ (gogoproto.jsontag) = "mfa_device,omitempty" ];

// WindowsDesktop specifies the name of a Windows desktop.
string WindowsDesktop = 6 [ (gogoproto.jsontag) = "windows_desktop,omitempty" ];
}

// AddressCondition represents a set of addresses. Presently the addresses are specfied
Expand Down
68 changes: 50 additions & 18 deletions docs/pages/access-controls/guides/locking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,61 @@ matching the lock's target.

A lock can target the following objects or attributes:

- a Teleport user by the user's name,
- a Teleport [RBAC](../reference.mdx) role by the role's name,
- an MFA device by the device's UUID,
- an OS/UNIX login,
- a Teleport user by the user's name
- a Teleport [RBAC](../reference.mdx) role by the role's name
- an MFA device by the device's UUID
- an OS/UNIX login
- a Teleport node by the node's UUID (effectively unregistering it from the
cluster).
cluster)
- a Windows desktop by the desktop's name

## Prerequisites

- Installed [Teleport](../getting-started.mdx) >= (=teleport.version=) or [Teleport Cloud](../../cloud/introduction.mdx).
- [Tctl admin tool](https://goteleport.com/teleport/download) >= (=teleport.version=).
- Installed [Teleport](../getting-started.mdx) >= (=teleport.version=) or [Teleport Cloud](../../cloud/introduction.mdx)
- [Tctl admin tool](https://goteleport.com/teleport/download) >= (=teleport.version=)

(!docs/pages/includes/tctl.mdx!)

## Step 1/2. Create a lock

To create a new lock, one can run the `tctl lock` command:

```code
$ tctl lock [email protected] --message="Suspicious activity." --ttl=10h
# Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```
<Tabs>
<TabItem label="Username">
```code
$ tctl lock [email protected] --message="Suspicious activity." --ttl=10h
# Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```
</TabItem>
<TabItem label="Role">
All users with assigned roles matching the target role will be locked.
```code
$ tctl lock --role=contractor --message="All contractor access is disabled for 10h." --ttl=10h
# Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```
</TabItem>
<TabItem label="Multi-factor device">
All connections initated with per-session MFA matching the device ID will be locked.
```code
$ tctl lock --mfa-device=d6c06a18-e147-4232-9dfe-6f83a28d5850 --message="All contractor access is disabled for 10h." --ttl=10h
# Created a lock with name "d6c06a18-e147-4232-9dfe-6f83a28d5850".
```
</TabItem>
<TabItem label="Node">
All connections to the specified node will be locked.
```code
$ tctl lock --node=363256df-f78a-4d99-803c-bae19da9ede4 --message="The node is under investigation." --ttl=10h
# Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```
</TabItem>
<TabItem label="Windows Desktop">
All connections to the specified Windows Desktop will be locked.
```code
$ tctl lock --windows-desktop=WIN-FMPFM5UF1SS-teleport-example-com --ttl=10h
# Created a lock with name "dc7cee9d-fe5e-4534-a90d-db770f0234a1".
```
</TabItem>
</Tabs>

<Details
title="Troubleshooting: failed to create a lock?"
Expand Down Expand Up @@ -75,7 +108,7 @@ spec:
```
```code
$ tctl create -f locksmith.yaml
$ tctl create -f locksmith.yaml
# role 'locksmith' has been created
```

Expand Down Expand Up @@ -146,8 +179,8 @@ If a Teleport node or proxy cannot properly synchronize its local lock view
with the backend, there is a decision to be made about whether to rely on the
last known locks. This decision strategy is encoded as one of the two modes:
- `strict` mode causes all interactions to be terminated when the locks are not
guaranteed to be up to date;
- `best_effort` mode keeps relying on the most recent locks.
guaranteed to be up to date
- `best_effort` mode keeps relying on the most recent locks

The cluster-wide mode defaults to `best_effort`.
You can set up default locking mode via API or CLI using resource `cluster_auth_preference`
Expand All @@ -156,7 +189,7 @@ or static configuration file:
<Tabs>
<TabItem label="API or CLI">
Create a YAML file `cap.yaml` or get the existing file using `tctl get cap`

```yaml
kind: cluster_auth_preference
metadata:
Expand All @@ -165,9 +198,9 @@ or static configuration file:
locking_mode: best_effort
version: v2
```

Create a resource:

```code
$ tctl create -f cap.yaml
# cluster auth preference has been updated
Expand Down Expand Up @@ -204,4 +237,3 @@ there is no user involved, the mode is taken from the cluster-wide setting.
With multiple potentially conflicting locking modes (the cluster-wide default
and the individual per-role settings) a single occurrence of `strict` suffices
for the local lock view to become evaluated strictly.

12 changes: 6 additions & 6 deletions docs/pages/desktop-access/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ trusted repository or provide the filepath to the `der_ca_file` configuration va
In order to enable Desktop Access in Teleport, add the
following section in `teleport.yaml` on your Linux server:

````yaml
```yaml
windows_desktop_service:
enabled: yes
# This is the address that windows_desktop_service will listen on.
Expand All @@ -300,13 +300,14 @@ windows_desktop_service:
#
# For example, if your domain is "example.com", the NetBIOS name for it is
# likely "EXAMPLE". When connecting as the "svc-teleport" user, you should
# use the format: "EXAMPLE\svc-teleport".
# use the format: 'EXAMPLE\svc-teleport'.
# Note the use of single quotes due to the \ character
#
# If you are unsure of your NetBIOS name, you can find it by opening a PowerShell command prompt
# and running:
# ```
#
# (Get-ADDomain).NetBIOSName
# ```
#
username: "$LDAP_USERNAME"
# Plain text file containing the LDAP password for authentication. This is the password that was
# randomly generated and saved to $OutputFile in Step 1, which you will need to transfer
Expand Down Expand Up @@ -338,15 +339,14 @@ windows_desktop_service:
# These are only needed to connect to desktops that aren't covered by the discovery setting.
- "100.104.52.89"
- "another-example.com"
````
```
After updating `teleport.yaml`, start Teleport as usual using `teleport start`.

## Step 6/6. Log in using Teleport

### Create a Teleport user/role for Windows Desktop Access

{/* TODO: remove the "/ver/8.0/" in the link once these docs are the primary version */}
In order to gain access to a remote desktop, a Teleport user needs to have the appropriate permissions for that desktop.
For example, you can create a role that gives its users access to all Windows desktop labels and the `"Administrator"` user:

Expand Down
2 changes: 2 additions & 0 deletions docs/pages/desktop-access/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ description: Teleport Desktop Access configuration and CLI reference.

`teleport.yaml` fields related to Desktop Access:

{/* NOTE to devs: If you update this reference yaml, you likely want to mirror the changes in docs/pages/setup/reference/config.mdx */}

```yaml
# Main service responsible for Desktop Access.
#
Expand Down
13 changes: 8 additions & 5 deletions docs/pages/desktop-access/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ For desktops that are automatically discovered via LDAP, Teleport makes DNS
queries against the LDAP server in order to resolve the hostname to an IP
address.

Ensure that your firewalls allow inbound DNS traffic on port 53 from the
Ensure that your firewalls allow inbound DNS traffic on port `53` from the
instance(s) running Teleport's Windows Desktop Service to the LDAP server
(Active Directory Domain Controller).

Expand Down Expand Up @@ -163,11 +163,14 @@ connecting to LDAP server: unable to read LDAP response packet: read tcp 172.18.

**Solution:** Enable LDAPS

This means you do not have an LDAP certificate installed on your LDAP servers.
You can resolve this by
[installing Active Directory Certificate Services](https://docs.microsoft.com/en-us/windows-server/networking/core-network-guide/cncg/server-certs/install-the-certification-authority)
This means you do not have an LDAP certificate installed on your LDAP servers,
or you are trying to make an insecure connection on port `389`. Teleport requires
secure LDAPS connections, which are typically on port `636`. First, confirm that
you are connecting to the correct LDAPS port. If that doesn't resolve your
issue, you can
[instal Active Directory Certificate Services](https://docs.microsoft.com/en-us/windows-server/networking/core-network-guide/cncg/server-certs/install-the-certification-authority)
(AD CS) or
[importing](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority)
[import](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority)
your own third party certificate. Note that Active Directory is
[extremely picky](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority#requirements-for-an-ldaps-certificate)
so take care to generate your certificates correctly.
50 changes: 49 additions & 1 deletion docs/pages/setup/reference/config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ kubernetes_service:
command: ['curl', 'http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster-name', '-H', 'Metadata-Flavor: Google']
period: 1m0s

# This section configures the database service.
# This section configures the 'database service'.
db_service:
# Enables the database service. Default is "no".
enabled: "yes"
Expand Down Expand Up @@ -694,4 +694,52 @@ db_service:
- name: "hostname"
command: ["hostname"]
period: 1m0s

# This section configures the 'windows desktop service'
windows_desktop_service:
enabled: yes
# This is the address that windows_desktop_service will listen on.
listen_addr: "localhost:3028"
# (optional) This is the address that windows_desktop_service will advertise
# to the rest of Teleport for incoming connections. Only proxy_service should
# connect to windows_desktop_service, users connect to the proxy's web UI
# instead.
public_addr: "desktop-access.example.com:3028"
ldap:
# Address of the Domain Controller for LDAP connections. Usually, this
# address will use port 389, like: domain-controller.example.com:389.
addr: '$LDAP_SERVER_ADDRESS'
# Active Directory domain name you are connecting to.
domain: '$LDAP_DOMAIN_NAME'
# LDAP username for authentication. This username must include the domain
# NetBIOS name.
#
# For example, if your domain is "example.com", the NetBIOS name for it is
# likely "EXAMPLE". When connecting as the "Administrator" user, you should
# use the format: "EXAMPLE\Administrator".
username: '$LDAP_USERNAME'
# Plain text file containing the LDAP password for authentication.
# This is usually the same password you use to login to the Domain Controller.
password_file: /var/lib/ldap-pass
# (optional) settings for enabling automatic desktop discovery via LDAP
discovery:
# The wildcard '*' character tells Teleport to discover all the hosts in
# the Active Directory Domain. To refine the search, specify a custom DN.
# To disable automatic discovery, leave this field blank.
base_dn: '*'
# (optional) LDAP filters for further customizing the LDAP search.
# See https://ldap.com/ldap-filters for details on LDAP filter syntax.
filters:
- '(location=Oakland)'
- '(!(primaryGroupID=516))' # exclude domain controllers
# Rules for applying labels to Windows hosts based on regular expressions
# matched against the host name. If multiple rules match, the desktop will
# get the union of all matching labels.
host_labels:
- match: '^.*\.dev\.example\.com$'
labels:
environment: dev
- match: '^.*\.prod\.example\.com$'
labels:
environment: prod
```
2 changes: 1 addition & 1 deletion e
Submodule e updated from c7ed09 to c7d5bf
8 changes: 4 additions & 4 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ func testAuditOn(t *testing.T, suite *integrationTestSuite) {
start := findByType(events.SessionStartEvent)
require.Equal(t, first, start)
require.Equal(t, 0, start.GetInt("bytes"))
require.NotEmpty(t, start.GetString(events.SessionEventID))
require.Equal(t, string(sessionID), start.GetString(events.SessionEventID))
require.NotEmpty(t, start.GetString(events.TerminalSize))

// If session are being recorded at nodes, the SessionServerID should contain
Expand All @@ -510,15 +510,15 @@ func testAuditOn(t *testing.T, suite *integrationTestSuite) {
end := findByType(events.SessionEndEvent)
require.NotNil(t, end)
require.Equal(t, 0, end.GetInt("bytes"))
require.NotEmpty(t, end.GetString(events.SessionEventID))
require.Equal(t, string(sessionID), end.GetString(events.SessionEventID))

// there should always be 'session.leave' event
leave := findByType(events.SessionLeaveEvent)
require.NotNil(t, leave)
require.Equal(t, 0, leave.GetInt("bytes"))
require.NotEmpty(t, leave.GetString(events.SessionEventID))
require.Equal(t, string(sessionID), leave.GetString(events.SessionEventID))

// all of them should have a proper time:
// all of them should have a proper time
for _, e := range history {
require.False(t, e.GetTime("time").IsZero())
}
Expand Down
1 change: 1 addition & 0 deletions lib/service/desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func (process *TeleportProcess) initWindowsDesktopServiceRegistered(log *logrus.
ResourceWatcherConfig: services.ResourceWatcherConfig{
Component: teleport.ComponentWindowsDesktop,
Log: log,
Clock: cfg.Clock,
Client: conn.Client,
},
})
Expand Down
6 changes: 3 additions & 3 deletions lib/srv/desktop/rdp/rdpclient/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions lib/srv/desktop/rdp/rdpclient/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rdp-client"
version = "0.1.0"
authors = ["Andrew Lytvynov <[email protected]>"]
authors = ["Andrew Lytvynov <[email protected]>", "Zac Bergquist <[email protected]>"]
edition = "2018"

[lib]
Expand All @@ -21,13 +21,13 @@ byteorder = "1.4.3"
env_logger = "0.9.0"
iso7816 = "0.1.0-alpha.1"
iso7816-tlv = "0.4.2"
libc = "0.2.106"
libc = "0.2.110"
log = "0.4.14"
num-derive = "0.3.3"
num-traits = "0.2.14"
# Ideally, we'd use RustCrypto/RSA instead of linking OpenSSL. Unfortunately,
# RustCrypto doesn't expose the low-level primitives we need for the smartcard
# challenge signing (see src/piv.rs for details).
openssl = { version = "0.10.38", features = ["vendored"] }
rdp-rs = { git = "https://github.com/gravitational/rdp-rs", rev = "755e950dcff0fc6965aa518c4596b995ede3417d" }
rdp-rs = { git = "https://github.com/gravitational/rdp-rs", rev = "cb61119d2803f647b60e6c9b2ef05ab587cc1966" }
uuid = { version = "0.8.2", features = ["v4"] }
2 changes: 1 addition & 1 deletion lib/srv/desktop/rdp/rdpclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ package rdpclient
#cgo linux,amd64 LDFLAGS: -L${SRCDIR}/target/x86_64-unknown-linux-gnu/release
#cgo linux,arm LDFLAGS: -L${SRCDIR}/target/arm-unknown-linux-gnueabihf/release
#cgo linux,arm64 LDFLAGS: -L${SRCDIR}/target/aarch64-unknown-linux-gnu/release
#cgo linux LDFLAGS: -l:librdp_client.a -lpthread -ldl -lm -latomic
#cgo linux LDFLAGS: -l:librdp_client.a -lpthread -ldl -lm
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/target/x86_64-apple-darwin/release
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/target/aarch64-apple-darwin/release
#cgo darwin LDFLAGS: -framework CoreFoundation -framework Security -lrdp_client -lpthread -ldl -lm
Expand Down
Loading

0 comments on commit 80122c9

Please sign in to comment.