tracebit-python 0.1.1__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tracebit_python-0.1.1/src/tracebit_python.egg-info → tracebit_python-0.1.2}/PKG-INFO +82 -23
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/README.md +81 -22
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/pyproject.toml +1 -1
- tracebit_python-0.1.2/src/tracebit/__init__.py +1 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/api.py +1 -1
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/aws.py +8 -0
- tracebit_python-0.1.2/src/tracebit/cli.py +763 -0
- tracebit_python-0.1.2/src/tracebit/ssh.py +126 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/state.py +14 -3
- {tracebit_python-0.1.1 → tracebit_python-0.1.2/src/tracebit_python.egg-info}/PKG-INFO +82 -23
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/SOURCES.txt +2 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_api.py +1 -1
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_aws.py +15 -0
- tracebit_python-0.1.2/tests/test_ssh.py +197 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_state.py +30 -0
- tracebit_python-0.1.1/src/tracebit/__init__.py +0 -1
- tracebit_python-0.1.1/src/tracebit/cli.py +0 -457
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/LICENSE +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/setup.cfg +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/config.py +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/dependency_links.txt +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/entry_points.txt +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/requires.txt +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/top_level.txt +0 -0
- {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tracebit-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: CLI for managing Tracebit canary credentials on headless servers
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Repository, https://github.com/SiteRelEnby/tracebit-python
|
|
@@ -76,33 +76,46 @@ Or use an environment variable:
|
|
|
76
76
|
export TRACEBIT_API_TOKEN=your-token-here
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
### 3. Deploy
|
|
79
|
+
### 3. Deploy canaries
|
|
80
|
+
|
|
81
|
+
**AWS credentials:**
|
|
80
82
|
|
|
81
83
|
```bash
|
|
82
84
|
tracebit deploy aws --profile staging
|
|
83
85
|
```
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
Writes canary AWS credentials to `~/.aws/credentials` under the given profile.
|
|
88
|
+
Any AWS API call using these credentials triggers an alert.
|
|
89
|
+
|
|
90
|
+
**SSH key:**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
tracebit deploy ssh --key-file id_backup --ssh-host backup-server.internal
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Writes a canary SSH private key to `~/.ssh/id_backup` and adds a `Host` block
|
|
97
|
+
to `~/.ssh/config` pointing `backup-server.internal` at Tracebit's honeypot.
|
|
98
|
+
Any SSH connection attempt using this key triggers an alert.
|
|
99
|
+
|
|
100
|
+
Choose names that look realistic to an attacker — `staging`, `id_backup`,
|
|
101
|
+
`backup-server.internal`. The whole point is that they look like real credentials.
|
|
89
102
|
|
|
90
103
|
### 4. Test it
|
|
91
104
|
|
|
92
105
|
```bash
|
|
93
|
-
tracebit trigger aws
|
|
106
|
+
tracebit trigger aws # uses aws sts get-caller-identity
|
|
107
|
+
tracebit trigger ssh # connects to Tracebit's honeypot
|
|
94
108
|
```
|
|
95
109
|
|
|
96
|
-
|
|
97
|
-
see an alert on the Tracebit dashboard within a few minutes.
|
|
110
|
+
You should see an alert on the Tracebit dashboard within a few minutes.
|
|
98
111
|
|
|
99
112
|
### 5. Keep credentials fresh
|
|
100
113
|
|
|
101
|
-
Canary credentials expire after ~12 hours. Set up a cron job
|
|
114
|
+
Canary credentials expire after ~12 hours. Set up a cron job:
|
|
102
115
|
|
|
103
116
|
```bash
|
|
104
|
-
# crontab
|
|
105
|
-
|
|
117
|
+
tracebit install-cron # prints a ready-to-paste crontab line
|
|
118
|
+
tracebit install-cron --install # adds it to your crontab automatically
|
|
106
119
|
```
|
|
107
120
|
|
|
108
121
|
## Commands
|
|
@@ -124,8 +137,25 @@ Issue and deploy canary AWS credentials.
|
|
|
124
137
|
| `--labels` | | Metadata as `key=value` pairs |
|
|
125
138
|
| `--force` | | Replace existing profile (expires old canary first) |
|
|
126
139
|
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
### `tracebit deploy ssh`
|
|
141
|
+
|
|
142
|
+
Issue and deploy a canary SSH private key.
|
|
143
|
+
|
|
144
|
+
| Option | Default | Description |
|
|
145
|
+
|--------|---------|-------------|
|
|
146
|
+
| `--name` | hostname | Credential name (shown on Tracebit dashboard) |
|
|
147
|
+
| `--key-file` | from API | Key filename in `~/.ssh/` |
|
|
148
|
+
| `--ssh-host` | honeypot IP | Hostname alias for `~/.ssh/config` Host entry |
|
|
149
|
+
| `--ssh-config-file` | `~/.ssh/config` | SSH config file to write Host entry into |
|
|
150
|
+
| `--labels` | | Metadata as `key=value` pairs |
|
|
151
|
+
| `--force` | | Replace existing key/config entry |
|
|
152
|
+
|
|
153
|
+
The `--ssh-host` alias is what makes the canary effective: an attacker finding
|
|
154
|
+
`~/.ssh/config` with `Host backup-server.internal` pointing somewhere will try
|
|
155
|
+
to connect there, firing the alert. If omitted, the honeypot IP is used directly.
|
|
156
|
+
|
|
157
|
+
Use `--ssh-config-file` if your `~/.ssh/config` is tracked in git and you keep
|
|
158
|
+
local overrides in a separate file (e.g. `~/.ssh/config.local`).
|
|
129
159
|
|
|
130
160
|
### `tracebit refresh`
|
|
131
161
|
|
|
@@ -138,16 +168,24 @@ from cron.
|
|
|
138
168
|
|
|
139
169
|
### `tracebit trigger aws`
|
|
140
170
|
|
|
141
|
-
Test-fire
|
|
171
|
+
Test-fire an AWS canary by calling `aws sts get-caller-identity` with the canary
|
|
142
172
|
profile. Requires the AWS CLI to be installed.
|
|
143
173
|
|
|
144
174
|
| Option | Default | Description |
|
|
145
175
|
|--------|---------|-------------|
|
|
146
176
|
| `--name` | first found | Credential name to trigger |
|
|
147
177
|
|
|
178
|
+
### `tracebit trigger ssh`
|
|
179
|
+
|
|
180
|
+
Test-fire an SSH canary by connecting to Tracebit's honeypot with the canary key.
|
|
181
|
+
|
|
182
|
+
| Option | Default | Description |
|
|
183
|
+
|--------|---------|-------------|
|
|
184
|
+
| `--name` | first found | Credential name to trigger |
|
|
185
|
+
|
|
148
186
|
### `tracebit show`
|
|
149
187
|
|
|
150
|
-
Display deployed canary credentials, their profiles, and expiration status.
|
|
188
|
+
Display deployed canary credentials, their profiles/keys, and expiration status.
|
|
151
189
|
|
|
152
190
|
### `tracebit remove`
|
|
153
191
|
|
|
@@ -157,6 +195,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
|
|
|
157
195
|
|--------|---------|-------------|
|
|
158
196
|
| `--name` | all | Name of credential to remove |
|
|
159
197
|
|
|
198
|
+
### `tracebit install-cron`
|
|
199
|
+
|
|
200
|
+
Print or install a cron job that runs `tracebit refresh --quiet` on a schedule.
|
|
201
|
+
|
|
202
|
+
| Option | Default | Description |
|
|
203
|
+
|--------|---------|-------------|
|
|
204
|
+
| `--schedule` | `*/30 * * * *` | Cron schedule expression |
|
|
205
|
+
| `--install` | | Add entry to current user's crontab |
|
|
206
|
+
| `--system` | | Write `/etc/cron.d/tracebit` (requires root) |
|
|
207
|
+
|
|
160
208
|
## Global Options
|
|
161
209
|
|
|
162
210
|
| Option | Description |
|
|
@@ -164,6 +212,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
|
|
|
164
212
|
| `--token TOKEN` | API token (overrides env var and config file) |
|
|
165
213
|
| `--base-url URL` | Override Tracebit API URL |
|
|
166
214
|
| `--json` | JSON output (where supported) |
|
|
215
|
+
| `-q / --quiet` | Suppress informational output (errors still go to stderr) |
|
|
167
216
|
|
|
168
217
|
## Token Resolution
|
|
169
218
|
|
|
@@ -175,22 +224,32 @@ The API token is resolved in this order:
|
|
|
175
224
|
|
|
176
225
|
## How It Works
|
|
177
226
|
|
|
227
|
+
**AWS canaries:**
|
|
228
|
+
|
|
178
229
|
1. **Issue** — requests canary AWS credentials from the Tracebit API
|
|
179
230
|
2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
monitoring for usage
|
|
183
|
-
4. **Alert** — any AWS API call using these credentials triggers a detection
|
|
184
|
-
on the Tracebit dashboard
|
|
231
|
+
3. **Confirm** — tells Tracebit the credentials are live
|
|
232
|
+
4. **Alert** — any AWS API call using these credentials fires a detection
|
|
185
233
|
|
|
186
234
|
The credentials have an explicit deny policy — they can't actually do anything
|
|
187
|
-
in AWS. But any attempt to use them
|
|
188
|
-
|
|
235
|
+
in AWS. But any attempt to use them is logged and alerted on.
|
|
236
|
+
|
|
237
|
+
**SSH canaries:**
|
|
238
|
+
|
|
239
|
+
1. **Issue** — requests a canary SSH private key from the Tracebit API
|
|
240
|
+
2. **Deploy** — writes the key to `~/.ssh/<key-file>` and adds a `Host` block
|
|
241
|
+
to `~/.ssh/config` pointing the chosen hostname at Tracebit's honeypot
|
|
242
|
+
3. **Confirm** — tells Tracebit the key is deployed
|
|
243
|
+
4. **Alert** — any SSH connection attempt presenting this key to the honeypot
|
|
244
|
+
fires a detection
|
|
189
245
|
|
|
190
246
|
## File Permissions
|
|
191
247
|
|
|
192
248
|
- `~/.aws/` directory: `0700`
|
|
193
249
|
- `~/.aws/credentials`, `~/.aws/config`: `0600`
|
|
250
|
+
- `~/.ssh/` directory: `0700`
|
|
251
|
+
- `~/.ssh/<key-file>`: `0600`
|
|
252
|
+
- `~/.ssh/config`: `0600`
|
|
194
253
|
- `~/.config/tracebit/token`: `0600`
|
|
195
254
|
- `~/.config/tracebit/state.json`: `0600`
|
|
196
255
|
|
|
@@ -49,33 +49,46 @@ Or use an environment variable:
|
|
|
49
49
|
export TRACEBIT_API_TOKEN=your-token-here
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
### 3. Deploy
|
|
52
|
+
### 3. Deploy canaries
|
|
53
|
+
|
|
54
|
+
**AWS credentials:**
|
|
53
55
|
|
|
54
56
|
```bash
|
|
55
57
|
tracebit deploy aws --profile staging
|
|
56
58
|
```
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
Writes canary AWS credentials to `~/.aws/credentials` under the given profile.
|
|
61
|
+
Any AWS API call using these credentials triggers an alert.
|
|
62
|
+
|
|
63
|
+
**SSH key:**
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
tracebit deploy ssh --key-file id_backup --ssh-host backup-server.internal
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Writes a canary SSH private key to `~/.ssh/id_backup` and adds a `Host` block
|
|
70
|
+
to `~/.ssh/config` pointing `backup-server.internal` at Tracebit's honeypot.
|
|
71
|
+
Any SSH connection attempt using this key triggers an alert.
|
|
72
|
+
|
|
73
|
+
Choose names that look realistic to an attacker — `staging`, `id_backup`,
|
|
74
|
+
`backup-server.internal`. The whole point is that they look like real credentials.
|
|
62
75
|
|
|
63
76
|
### 4. Test it
|
|
64
77
|
|
|
65
78
|
```bash
|
|
66
|
-
tracebit trigger aws
|
|
79
|
+
tracebit trigger aws # uses aws sts get-caller-identity
|
|
80
|
+
tracebit trigger ssh # connects to Tracebit's honeypot
|
|
67
81
|
```
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
see an alert on the Tracebit dashboard within a few minutes.
|
|
83
|
+
You should see an alert on the Tracebit dashboard within a few minutes.
|
|
71
84
|
|
|
72
85
|
### 5. Keep credentials fresh
|
|
73
86
|
|
|
74
|
-
Canary credentials expire after ~12 hours. Set up a cron job
|
|
87
|
+
Canary credentials expire after ~12 hours. Set up a cron job:
|
|
75
88
|
|
|
76
89
|
```bash
|
|
77
|
-
# crontab
|
|
78
|
-
|
|
90
|
+
tracebit install-cron # prints a ready-to-paste crontab line
|
|
91
|
+
tracebit install-cron --install # adds it to your crontab automatically
|
|
79
92
|
```
|
|
80
93
|
|
|
81
94
|
## Commands
|
|
@@ -97,8 +110,25 @@ Issue and deploy canary AWS credentials.
|
|
|
97
110
|
| `--labels` | | Metadata as `key=value` pairs |
|
|
98
111
|
| `--force` | | Replace existing profile (expires old canary first) |
|
|
99
112
|
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
### `tracebit deploy ssh`
|
|
114
|
+
|
|
115
|
+
Issue and deploy a canary SSH private key.
|
|
116
|
+
|
|
117
|
+
| Option | Default | Description |
|
|
118
|
+
|--------|---------|-------------|
|
|
119
|
+
| `--name` | hostname | Credential name (shown on Tracebit dashboard) |
|
|
120
|
+
| `--key-file` | from API | Key filename in `~/.ssh/` |
|
|
121
|
+
| `--ssh-host` | honeypot IP | Hostname alias for `~/.ssh/config` Host entry |
|
|
122
|
+
| `--ssh-config-file` | `~/.ssh/config` | SSH config file to write Host entry into |
|
|
123
|
+
| `--labels` | | Metadata as `key=value` pairs |
|
|
124
|
+
| `--force` | | Replace existing key/config entry |
|
|
125
|
+
|
|
126
|
+
The `--ssh-host` alias is what makes the canary effective: an attacker finding
|
|
127
|
+
`~/.ssh/config` with `Host backup-server.internal` pointing somewhere will try
|
|
128
|
+
to connect there, firing the alert. If omitted, the honeypot IP is used directly.
|
|
129
|
+
|
|
130
|
+
Use `--ssh-config-file` if your `~/.ssh/config` is tracked in git and you keep
|
|
131
|
+
local overrides in a separate file (e.g. `~/.ssh/config.local`).
|
|
102
132
|
|
|
103
133
|
### `tracebit refresh`
|
|
104
134
|
|
|
@@ -111,16 +141,24 @@ from cron.
|
|
|
111
141
|
|
|
112
142
|
### `tracebit trigger aws`
|
|
113
143
|
|
|
114
|
-
Test-fire
|
|
144
|
+
Test-fire an AWS canary by calling `aws sts get-caller-identity` with the canary
|
|
115
145
|
profile. Requires the AWS CLI to be installed.
|
|
116
146
|
|
|
117
147
|
| Option | Default | Description |
|
|
118
148
|
|--------|---------|-------------|
|
|
119
149
|
| `--name` | first found | Credential name to trigger |
|
|
120
150
|
|
|
151
|
+
### `tracebit trigger ssh`
|
|
152
|
+
|
|
153
|
+
Test-fire an SSH canary by connecting to Tracebit's honeypot with the canary key.
|
|
154
|
+
|
|
155
|
+
| Option | Default | Description |
|
|
156
|
+
|--------|---------|-------------|
|
|
157
|
+
| `--name` | first found | Credential name to trigger |
|
|
158
|
+
|
|
121
159
|
### `tracebit show`
|
|
122
160
|
|
|
123
|
-
Display deployed canary credentials, their profiles, and expiration status.
|
|
161
|
+
Display deployed canary credentials, their profiles/keys, and expiration status.
|
|
124
162
|
|
|
125
163
|
### `tracebit remove`
|
|
126
164
|
|
|
@@ -130,6 +168,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
|
|
|
130
168
|
|--------|---------|-------------|
|
|
131
169
|
| `--name` | all | Name of credential to remove |
|
|
132
170
|
|
|
171
|
+
### `tracebit install-cron`
|
|
172
|
+
|
|
173
|
+
Print or install a cron job that runs `tracebit refresh --quiet` on a schedule.
|
|
174
|
+
|
|
175
|
+
| Option | Default | Description |
|
|
176
|
+
|--------|---------|-------------|
|
|
177
|
+
| `--schedule` | `*/30 * * * *` | Cron schedule expression |
|
|
178
|
+
| `--install` | | Add entry to current user's crontab |
|
|
179
|
+
| `--system` | | Write `/etc/cron.d/tracebit` (requires root) |
|
|
180
|
+
|
|
133
181
|
## Global Options
|
|
134
182
|
|
|
135
183
|
| Option | Description |
|
|
@@ -137,6 +185,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
|
|
|
137
185
|
| `--token TOKEN` | API token (overrides env var and config file) |
|
|
138
186
|
| `--base-url URL` | Override Tracebit API URL |
|
|
139
187
|
| `--json` | JSON output (where supported) |
|
|
188
|
+
| `-q / --quiet` | Suppress informational output (errors still go to stderr) |
|
|
140
189
|
|
|
141
190
|
## Token Resolution
|
|
142
191
|
|
|
@@ -148,22 +197,32 @@ The API token is resolved in this order:
|
|
|
148
197
|
|
|
149
198
|
## How It Works
|
|
150
199
|
|
|
200
|
+
**AWS canaries:**
|
|
201
|
+
|
|
151
202
|
1. **Issue** — requests canary AWS credentials from the Tracebit API
|
|
152
203
|
2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
monitoring for usage
|
|
156
|
-
4. **Alert** — any AWS API call using these credentials triggers a detection
|
|
157
|
-
on the Tracebit dashboard
|
|
204
|
+
3. **Confirm** — tells Tracebit the credentials are live
|
|
205
|
+
4. **Alert** — any AWS API call using these credentials fires a detection
|
|
158
206
|
|
|
159
207
|
The credentials have an explicit deny policy — they can't actually do anything
|
|
160
|
-
in AWS. But any attempt to use them
|
|
161
|
-
|
|
208
|
+
in AWS. But any attempt to use them is logged and alerted on.
|
|
209
|
+
|
|
210
|
+
**SSH canaries:**
|
|
211
|
+
|
|
212
|
+
1. **Issue** — requests a canary SSH private key from the Tracebit API
|
|
213
|
+
2. **Deploy** — writes the key to `~/.ssh/<key-file>` and adds a `Host` block
|
|
214
|
+
to `~/.ssh/config` pointing the chosen hostname at Tracebit's honeypot
|
|
215
|
+
3. **Confirm** — tells Tracebit the key is deployed
|
|
216
|
+
4. **Alert** — any SSH connection attempt presenting this key to the honeypot
|
|
217
|
+
fires a detection
|
|
162
218
|
|
|
163
219
|
## File Permissions
|
|
164
220
|
|
|
165
221
|
- `~/.aws/` directory: `0700`
|
|
166
222
|
- `~/.aws/credentials`, `~/.aws/config`: `0600`
|
|
223
|
+
- `~/.ssh/` directory: `0700`
|
|
224
|
+
- `~/.ssh/<key-file>`: `0600`
|
|
225
|
+
- `~/.ssh/config`: `0600`
|
|
167
226
|
- `~/.config/tracebit/token`: `0600`
|
|
168
227
|
- `~/.config/tracebit/state.json`: `0600`
|
|
169
228
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.2"
|
|
@@ -10,6 +10,14 @@ CONFIG_FILE = AWS_DIR / "config"
|
|
|
10
10
|
|
|
11
11
|
def _ensure_aws_dir():
|
|
12
12
|
AWS_DIR.mkdir(mode=0o700, exist_ok=True)
|
|
13
|
+
mode = AWS_DIR.stat().st_mode & 0o777
|
|
14
|
+
if mode != 0o700:
|
|
15
|
+
import sys
|
|
16
|
+
print(
|
|
17
|
+
f"Warning: ~/.aws/ has permissions {oct(mode)} (expected 0700). "
|
|
18
|
+
f"Consider running: chmod 700 ~/.aws",
|
|
19
|
+
file=sys.stderr,
|
|
20
|
+
)
|
|
13
21
|
|
|
14
22
|
|
|
15
23
|
def _read_ini(path):
|