Skip to content

Commit f3fbfa2

Browse files
committed
support: redact secrets from the collected configuration
Private keys, password hashes and RADIUS secrets are of no use to support and a hazard in transit. Export the datastores with copy -r and drop the environment dump. --no-redact keeps them, the RPC always redacts. Signed-off-by: Mattias Walström <lazzer@gmail.com>
1 parent 022dcb8 commit f3fbfa2

6 files changed

Lines changed: 191 additions & 58 deletions

File tree

‎doc/ChangeLog.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ All notable changes to the project are documented in this file.
1616
- Document the release and maintenance policy: which versions receive
1717
updates, what may go into a patch release, and the levels of long-term
1818
maintenance available, see [Releases & Support][relsup]
19+
- `support collect` now redacts private keys, password hashes and other
20+
secrets from the configuration files in the archive, use `--no-redact`
21+
to keep them. The environment dump is no longer collected
22+
- Add `copy -r` to export a datastore without its secrets, every node the
23+
YANG models tag `nacm:default-deny-all` and user passwords are dropped
1924

2025
### Added
2126

‎doc/support.md‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ admin@host:~$ sudo support collect -o /var/lib/support
6363

6464
Given a directory, the file gets the canonical name shown above. Given a
6565
file name, that name is used. Either way the file is created with mode
66-
0600, since the archive contains password hashes and keys.
66+
0600, the archive still holds the full configuration and all logs.
6767

6868
## Collecting over NETCONF or RESTCONF
6969

@@ -115,6 +115,7 @@ A few things to know about this path:
115115
descriptor and never appears in the process list. Devices built
116116
without the `BR2_PACKAGE_SUPPORT_ENCRYPT` option have no gpg and reject
117117
the request.
118+
- The configuration files in the archive are always redacted, see below.
118119
- `confd` is busy for the duration of the collection, like it is during a
119120
software upgrade, so a configuration change made at the same time has to
120121
wait for the collection to finish.
@@ -182,10 +183,27 @@ $ gpg -d support-data.tar.gz.gpg | tar xz
182183
The support archive includes:
183184

184185
- System identification (hostname, uptime, kernel version)
185-
- Running and operational configuration (sysrepo datastores)
186+
- Running, operational and startup configuration, with secrets redacted
186187
- System logs (`/var/log` directory and live tail of messages log)
187188
- Network configuration and state (interfaces, routes, neighbors, bridges)
188189
- FRRouting information (OSPF, BFD status)
189190
- Container information (podman containers and their configuration)
190191
- System resource usage (CPU, memory, disk, processes)
191192
- Hardware information (PCI, USB devices, network interfaces)
193+
194+
## Secrets in the Configuration
195+
196+
The configuration holds private keys for SSH, TLS and WireGuard, user
197+
password hashes and RADIUS secrets. None of them help anyone
198+
troubleshoot, so `support collect` exports the configuration with
199+
`copy -r`, which drops every node the YANG models tag
200+
`nacm:default-deny-all`, plus user passwords, before writing the
201+
file. New models that tag their secrets are covered without changes
202+
here. The rest of the configuration is left intact.
203+
204+
Pass `--no-redact` to keep them, for instance when the archive is for
205+
your own use and stays on your workstation. The RPC always redacts.
206+
207+
The archive still contains every log on the device, which may hold
208+
usernames, addresses and other details of your network. Treat it as
209+
confidential and encrypt it before it leaves your control.

‎src/confd/yang/confd/infix-system.yang‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -944,16 +944,19 @@ module infix-system {
944944
945945
The archive holds what the support(1) tool gathers: system and
946946
kernel logs, running and operational configuration, network and
947-
hardware state. Collection runs in RAM, so a call that returns
948-
the archive inline leaves nothing behind on the device.
947+
hardware state. Private keys, password hashes and other secrets
948+
are redacted from the configuration files. Collection runs in
949+
RAM, so a call that returns the archive inline leaves nothing
950+
behind on the device.
949951
950952
The system log is tailed for 5 seconds during collection, to
951953
keep the whole operation inside the caller's RPC timeout, see
952954
CONFD_TIMEOUT in /etc/default/confd.
953955
954-
Access is denied by default, the archive contains password
955-
hashes, keys, and logs. Only groups with an explicit NACM
956-
permit rule, 'admin' in the factory configuration, may call it.";
956+
Access is denied by default, the archive contains logs and the
957+
full configuration, redaction notwithstanding. Only groups with
958+
an explicit NACM permit rule, 'admin' in the factory
959+
configuration, may call it.";
957960
input {
958961
leaf password {
959962
type string {

‎src/support/support‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ cmd_collect()
1818
LOG_TAIL_SEC=30
1919
PASSWORD=""
2020
OUTPUT=""
21+
REDACT=1
2122
CMD_TIMEOUT=30
2223
HOOK_TIMEOUT=120
2324

@@ -66,9 +67,13 @@ cmd_collect()
6667
OUTPUT="$2"
6768
shift 2
6869
;;
70+
--no-redact|-R)
71+
REDACT=0
72+
shift
73+
;;
6974
*)
7075
echo "Error: Unknown option '$1'" >&2
71-
echo "Usage: $prognm collect [-s N] [-p PASSWORD] [-o FILE]" >&2
76+
echo "Usage: $prognm collect [-s N] [-p PASSWORD] [-o FILE] [-R]" >&2
7277
exit 1
7378
;;
7479
esac
@@ -210,21 +215,18 @@ cmd_collect()
210215
collect hostname.txt hostname
211216
collect uptime.txt uptime
212217

213-
# Configuration files
214-
collect running-config.json copy running
215-
collect operational-config.json copy operational
218+
# Configuration, copy -r drops the secrets, see 'copy -h'
219+
CP=""
220+
[ "$REDACT" -eq 1 ] && CP="-r"
221+
collect running-config.json copy $CP running
222+
collect operational-config.json copy $CP operational
223+
collect startup-config.cfg copy $CP startup
216224

217225
# Sysrepo YANG modules
218226
if command -v sysrepoctl >/dev/null 2>&1; then
219227
collect sysrepo-modules.txt sysrepoctl -l
220228
fi
221229

222-
# Startup config (may not exist on first boot)
223-
if [ -f /cfg/startup-config.cfg ]; then
224-
cp /cfg/startup-config.cfg "${COLLECT_DIR}/startup-config.cfg" 2>> "${EXEC_LOG}"
225-
else
226-
echo "No startup-config.cfg found" > "${COLLECT_DIR}/startup-config.cfg"
227-
fi
228230

229231
# System logs and runtime data
230232
if [ -d /var/log ]; then
@@ -399,9 +401,6 @@ cmd_collect()
399401
collect system/pstree.txt ps fax
400402
fi
401403

402-
# Environment and versions
403-
collect system/env.txt env
404-
405404
# Network sockets
406405
if command -v netstat >/dev/null 2>&1; then
407406
collect system/netstat.txt netstat -tunlp
@@ -628,6 +627,8 @@ usage()
628627
echo " -p, --password [PASS] Encrypt output with GPG. If PASS is omitted, prompts"
629628
echo " interactively or reads from stdin, so possible to do"
630629
echo " echo "\$MYSECRET" | ... (recommended for security)"
630+
echo " -R, --no-redact Keep private keys, password hashes and other secrets"
631+
echo " in the collected configuration, see 'copy -h'"
631632
echo ""
632633
echo "Options for clean:"
633634
echo " -n, --dry-run Show what would be deleted without deleting"
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
=== Support Data Collection
22

3-
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/misc/support_collect]
3+
ifdef::topdoc[:imagesdir: {topdoc}../../misc/support_collect]
44

55
==== Description
66

77
Verify that the support-collect RPC returns a valid archive with the
8-
expected content, that the archive can be GPG encrypted, and that NACM
9-
denies the RPC to users outside the admin group.
8+
expected content, that private keys and login hashes are removed from
9+
the configuration in it, that the archive can be GPG encrypted, and
10+
that NACM denies the RPC to users outside the admin group.
1011

1112
==== Topology
1213

@@ -15,9 +16,17 @@ image::topology.svg[Support Data Collection topology, align=center, scaledwidth=
1516
==== Sequence
1617

1718
. Set up topology and attach to target DUT
18-
. Collect support data with the support-collect RPC
19-
. Verify the archive returned by the RPC
20-
. Add user 'supportless', outside the admin NACM group
21-
. Verify user 'supportless' is denied the support-collect RPC
22-
. Collect an encrypted archive with the support-collect RPC
23-
. Decrypt the encrypted archive and verify it
19+
. Call the infix-system:support-collect RPC without a password
20+
. Base64 decode the 'data' reply to a .tar.gz file, verify its length matches the 'size' reply
21+
. Verify the archive holds collection.log, running-config.json, operational-config.json, system/dmesg.txt, system/meminfo.txt and network/ip/addr.json
22+
. Verify running-config.json in the archive has the ietf-keystore:keystore container and the admin user
23+
. Verify the admin user in running-config.json has no password leaf
24+
. Verify neither running-config.json nor operational-config.json has any password, cleartext-private-key, cleartext-symmetric-key or shared-secret leaf
25+
. Add user 'supportless' with password 'supportless-password', member of no NACM group
26+
. Verify the support-collect RPC is denied when called as 'supportless'
27+
. Call the support-collect RPC with password 'test-support-password-123'
28+
. Base64 decode the reply to a .gpg file, decrypt it with gpg and the same password
29+
. Verify the decrypted archive holds the same files as the first one
30+
. Verify the decrypted archive has the same secrets removed
31+
32+

0 commit comments

Comments
 (0)