Skip to content

Commit 1a5ff47

Browse files
committed
[Server] add XrdSecssh plugin with tests and packaging
Add the new TLS-only XrdSecssh security plugin with key, agent and certificate support. 3on tokenizer buffer. Link test binary against OpenSSL::Crypto for new 3only ran during OpInit), remove unused rawPub field from TrustedKey, 3can drive the output length negative. 3Made-with: Cursor 3[Tests] Move XrdSecSSH tests to dedicated xrdsecssh-unit-tests target
1 parent 45d86e4 commit 1a5ff47

11 files changed

Lines changed: 2682 additions & 2 deletions

File tree

debian/xrootd-plugins.install

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
/usr/lib/*/libXrdSecgsiAUTHZVO-5.so
77
/usr/lib/*/libXrdSecgsiGMAPDN-5.so
88
/usr/lib/*/libXrdSeckrb5-5.so
9+
/usr/lib/*/libXrdSecssh-5.so
910
/usr/lib/*/libXrdSecpwd-5.so
1011
/usr/lib/*/libXrdSecsss-5.so
1112
/usr/lib/*/libXrdSecunix-5.so

python/docs/source/install.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ In this case, the structure is a bit different than before::
166166
| |-- libXrdSecgsiAUTHZVO-5.so
167167
| |-- libXrdSecgsiGMAPDN-5.so
168168
| |-- libXrdSeckrb5-5.so
169+
| |-- libXrdSecssh-5.so
169170
| |-- libXrdSecpwd-5.so
170171
| |-- libXrdSecsss-5.so
171172
| |-- libXrdSecunix-5.so

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ add_subdirectory( XrdPosix )
5555
add_subdirectory( XrdSec )
5656
add_subdirectory( XrdSecgsi )
5757
add_subdirectory( XrdSeckrb5 )
58+
add_subdirectory( XrdSecssh )
5859
add_subdirectory( XrdSecpwd )
5960
add_subdirectory( XrdSecsss )
6061
add_subdirectory( XrdSecunix )

src/XrdSecssh/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
set(XrdSecssh XrdSecssh-${PLUGIN_VERSION})
2+
3+
find_package(OpenSSL REQUIRED)
4+
5+
add_library(${XrdSecssh} MODULE XrdSecProtocolssh.cc)
6+
target_link_libraries(${XrdSecssh} PRIVATE XrdUtils OpenSSL::Crypto)
7+
8+
install(TARGETS ${XrdSecssh} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

src/XrdSecssh/README.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# XrdSecssh
2+
3+
`XrdSecssh` is an experimental XRootD security protocol plugin (`sec.protocol ssh`)
4+
for SSH-key-based authentication over TLS.
5+
6+
## V1 behavior
7+
8+
- Raw key mode and OpenSSH user certificate mode
9+
- Server trust source:
10+
- `keys-file` for raw key -> user mapping
11+
- optional `ca-keys-file` for user certificate validation
12+
- Supported raw key algorithms: `ssh-ed25519`, `ssh-rsa`
13+
- Supported user certificate algorithms: `ssh-ed25519-cert-v01@openssh.com`,
14+
`ssh-rsa-cert-v01@openssh.com`
15+
- Two-step handshake:
16+
1. client sends user + SSH key/certificate blob
17+
2. server sends nonce challenge
18+
3. client signs challenge with private key
19+
4. server verifies signature and maps to local username
20+
21+
## Server configuration
22+
23+
```conf
24+
sec.protocol ssh \
25+
-keys-file /etc/xrootd/ssh_authorized_keys \
26+
-ca-keys-file /etc/xrootd/ssh_ca_keys \
27+
-principal-as-user \
28+
-principal-map \
29+
-maxsz 8192 \
30+
-nonce-ttl 30 \
31+
-debug
32+
```
33+
34+
`keys-file` security checks:
35+
36+
- must be a regular file
37+
- must be owned by effective xrootd uid
38+
- must not be group/other writable
39+
40+
The same security checks apply to `ca-keys-file` when configured.
41+
The same security checks apply to `principal-map-file` when configured.
42+
43+
### keys-file format
44+
45+
Accepted line formats:
46+
47+
1. Explicit user mapping:
48+
49+
```text
50+
foo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
51+
foo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
52+
```
53+
54+
2. Authorized-keys style fallback mapping (username extracted from comment prefix before `@`):
55+
56+
```text
57+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... foo@host
58+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... foo@host
59+
```
60+
61+
### ca-keys-file format (optional)
62+
63+
Each line should contain a CA public key:
64+
65+
```text
66+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
67+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
68+
```
69+
70+
Also accepted:
71+
72+
```text
73+
cert-authority ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
74+
```
75+
76+
When a user certificate is presented, the server validates:
77+
78+
- certificate signature against trusted CA key
79+
- certificate type is user (`type=1`)
80+
- validity window (`valid_after` / `valid_before`)
81+
- principals contain requested user (if principals list is non-empty)
82+
83+
### Principal mapping options (cert mode)
84+
85+
Server options:
86+
87+
- `-principal-as-user`:
88+
map a certificate principal directly to local account if it is a valid
89+
local username or uid.
90+
- `-principal-map`:
91+
enable principal mapping file at default path (no argument)
92+
`/etc/xrootd/ssh_principals.map`.
93+
- `-principal-map-file <path>`:
94+
use a custom principal mapping file.
95+
96+
If both direct and file mapping are enabled, direct principal->local-user
97+
mapping is tried first, then the map file.
98+
99+
Map file format:
100+
101+
```text
102+
principal-a alice
103+
principal-b 1001
104+
```
105+
106+
Each line is `<principal> <username|uid>`.
107+
108+
The principal map file is monitored during authentication and is reloaded
109+
automatically if its inode or mtime changes.
110+
111+
## Client configuration
112+
113+
Default mode uses a private key file (PEM/PKCS8 format; supported key types: ed25519, rsa):
114+
115+
```sh
116+
export XRD_SSH_KEY_FILE=/path/to/ed25519-private.pem
117+
```
118+
119+
Client `ssh-agent` mode is also supported:
120+
121+
```sh
122+
export SSH_AUTH_SOCK=/run/user/1000/ssh-agent.socket
123+
export XRD_SSH_AGENT=1
124+
```
125+
126+
When `XRD_SSH_AGENT=1`, the client picks a supported identity from the agent
127+
and signs the server challenge via agent.
128+
129+
Supported agent identities:
130+
131+
- raw keys: `ssh-ed25519`, `ssh-rsa`
132+
- user certificates: `ssh-ed25519-cert-v01@openssh.com`,
133+
`ssh-rsa-cert-v01@openssh.com`
134+
135+
Optional key selection by fingerprint:
136+
137+
```sh
138+
export XRD_SSH_AGENT_FINGERPRINT='SHA256:base64fingerprint'
139+
```
140+
141+
Fallback behavior:
142+
143+
- if `XRD_SSH_AGENT` is not set, key-file mode is tried first
144+
- if key-file is not configured and `SSH_AUTH_SOCK` exists, agent mode is used
145+
- if not in agent mode, no key-file env is set, and `XRD_SSH_USER` is not set,
146+
the client also tries default key files in order:
147+
- `~/.ssh/id_ed25519`
148+
- `~/.ssh/id_rsa`
149+
- if all methods fail, authentication fails with a detailed error
150+
151+
Optional username override:
152+
153+
```sh
154+
export XRD_SSH_USER=foo
155+
```
156+
157+
If `XRD_SSH_USER` is not set, `USER` is used.
158+
159+
## Notes
160+
161+
- TLS is mandatory (`needTLS() == true`)
162+
- handshake nonce is single-use and expires after `-nonce-ttl`
163+
- debug logging can be enabled via `-debug` or `XrdSecDEBUG=1`; it prints
164+
loaded key metadata (alg/user/fingerprint) and authentication key selection

0 commit comments

Comments
 (0)