create-tunnlo 0.1.1
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.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +264 -0
- package/dist/index.js.map +1 -0
- package/package.json +14 -0
- package/templates/security-monitor/tunnlo.yaml +53 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { createInterface } from 'node:readline';
|
|
5
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
6
|
+
let rlClosed = false;
|
|
7
|
+
rl.on('close', () => { rlClosed = true; });
|
|
8
|
+
function ask(question) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (rlClosed)
|
|
11
|
+
return resolve('');
|
|
12
|
+
rl.question(question, (a) => resolve(a.trim()));
|
|
13
|
+
rl.once('close', () => resolve(''));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function choose(question, options) {
|
|
17
|
+
console.log(question);
|
|
18
|
+
options.forEach((opt, i) => console.log(` ${i + 1}) ${opt.label}`));
|
|
19
|
+
const answer = await ask(` Choice [1]: `);
|
|
20
|
+
const index = parseInt(answer || '1', 10) - 1;
|
|
21
|
+
return (index >= 0 && index < options.length) ? options[index].value : options[0].value;
|
|
22
|
+
}
|
|
23
|
+
// ── Config generators ──────────────────────────────────────────────────────
|
|
24
|
+
function stdinConfig(model) {
|
|
25
|
+
return `# Tunnlo Pipeline Configuration
|
|
26
|
+
# Docs: https://tunnlo.dev
|
|
27
|
+
|
|
28
|
+
sources:
|
|
29
|
+
- id: stdin-input
|
|
30
|
+
adapter: native/stdin
|
|
31
|
+
config: {}
|
|
32
|
+
|
|
33
|
+
# ─── Alternative: Wireshark / tshark ────────────────────────────────────────
|
|
34
|
+
# To monitor live network traffic instead, replace the source above with:
|
|
35
|
+
#
|
|
36
|
+
# Prerequisite: install tshark — https://www.wireshark.org/download.html
|
|
37
|
+
# macOS: brew install wireshark
|
|
38
|
+
# Ubuntu: sudo apt install tshark
|
|
39
|
+
#
|
|
40
|
+
# sources:
|
|
41
|
+
# - id: network-traffic
|
|
42
|
+
# adapter: native/tshark
|
|
43
|
+
# config:
|
|
44
|
+
# interface: en0 # find yours: ip link (Linux) or networksetup -listallnetworkservices (macOS)
|
|
45
|
+
# capture_filter: tcp # optional BPF filter, e.g. "tcp port 443"
|
|
46
|
+
# output_format: json
|
|
47
|
+
# ────────────────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
filters:
|
|
50
|
+
- type: rate-limiter
|
|
51
|
+
max_events_per_minute: 30
|
|
52
|
+
|
|
53
|
+
- type: dedup
|
|
54
|
+
window_seconds: 10
|
|
55
|
+
key_fields:
|
|
56
|
+
- payload.data
|
|
57
|
+
|
|
58
|
+
agent:
|
|
59
|
+
runtime: direct-llm
|
|
60
|
+
model: ${model}
|
|
61
|
+
system_prompt: |
|
|
62
|
+
You are a monitoring agent. Analyze incoming events and respond with
|
|
63
|
+
observations, potential issues, and recommended actions.
|
|
64
|
+
|
|
65
|
+
If you want to trigger a webhook action, include a JSON block like:
|
|
66
|
+
\`\`\`json:actions
|
|
67
|
+
[{"type": "webhook", "config": {}, "payload": {"message": "your alert"}}]
|
|
68
|
+
\`\`\`
|
|
69
|
+
token_budget:
|
|
70
|
+
max_per_hour: 50000
|
|
71
|
+
max_per_event: 4000
|
|
72
|
+
|
|
73
|
+
behavior:
|
|
74
|
+
on_llm_unreachable: drop_and_alert
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
function tsharkConfig(model, iface, captureFilter) {
|
|
78
|
+
const filterLine = captureFilter ? ` capture_filter: "${captureFilter}"` : ` # capture_filter: tcp # optional BPF filter, e.g. "tcp port 443"`;
|
|
79
|
+
return `# Tunnlo Pipeline Configuration — Network Monitor
|
|
80
|
+
# Docs: https://tunnlo.dev
|
|
81
|
+
#
|
|
82
|
+
# Prerequisite: tshark must be installed.
|
|
83
|
+
# macOS: brew install wireshark
|
|
84
|
+
# Ubuntu: sudo apt install tshark
|
|
85
|
+
# Windows: install Wireshark from https://www.wireshark.org/download.html
|
|
86
|
+
|
|
87
|
+
sources:
|
|
88
|
+
- id: network-traffic
|
|
89
|
+
adapter: native/tshark
|
|
90
|
+
config:
|
|
91
|
+
interface: ${iface}
|
|
92
|
+
${filterLine}
|
|
93
|
+
output_format: json
|
|
94
|
+
|
|
95
|
+
filters:
|
|
96
|
+
- type: dedup
|
|
97
|
+
window_seconds: 30
|
|
98
|
+
key_fields:
|
|
99
|
+
- payload.src_ip
|
|
100
|
+
- payload.dst_port
|
|
101
|
+
|
|
102
|
+
- type: rate-limiter
|
|
103
|
+
max_events_per_minute: 20
|
|
104
|
+
|
|
105
|
+
agent:
|
|
106
|
+
runtime: direct-llm
|
|
107
|
+
model: ${model}
|
|
108
|
+
system_prompt: |
|
|
109
|
+
You are a network security analyst monitoring live traffic.
|
|
110
|
+
For each packet event, assess:
|
|
111
|
+
1. Is this normal traffic or potentially suspicious?
|
|
112
|
+
2. What kind of activity does this represent?
|
|
113
|
+
3. Should an alert be raised?
|
|
114
|
+
|
|
115
|
+
If you detect suspicious activity, trigger a webhook alert:
|
|
116
|
+
\`\`\`json:actions
|
|
117
|
+
[{"type": "webhook", "config": {}, "payload": {"severity": "high", "message": "description"}}]
|
|
118
|
+
\`\`\`
|
|
119
|
+
token_budget:
|
|
120
|
+
max_per_hour: 100000
|
|
121
|
+
max_per_event: 4000
|
|
122
|
+
|
|
123
|
+
behavior:
|
|
124
|
+
on_llm_unreachable: drop_and_alert
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
function logConfig(model, logPath) {
|
|
128
|
+
return `# Tunnlo Pipeline Configuration — Log Monitor
|
|
129
|
+
# Docs: https://tunnlo.dev
|
|
130
|
+
|
|
131
|
+
sources:
|
|
132
|
+
- id: log-file
|
|
133
|
+
adapter: native/log-tailer
|
|
134
|
+
config:
|
|
135
|
+
path: ${logPath}
|
|
136
|
+
# poll_interval_ms: 500 # how often to check for new lines
|
|
137
|
+
|
|
138
|
+
filters:
|
|
139
|
+
- type: rate-limiter
|
|
140
|
+
max_events_per_minute: 30
|
|
141
|
+
|
|
142
|
+
- type: dedup
|
|
143
|
+
window_seconds: 10
|
|
144
|
+
key_fields:
|
|
145
|
+
- payload.data
|
|
146
|
+
|
|
147
|
+
agent:
|
|
148
|
+
runtime: direct-llm
|
|
149
|
+
model: ${model}
|
|
150
|
+
system_prompt: |
|
|
151
|
+
You are a log analysis agent. Monitor incoming log lines and identify
|
|
152
|
+
errors, warnings, anomalies, or patterns worth flagging.
|
|
153
|
+
token_budget:
|
|
154
|
+
max_per_hour: 50000
|
|
155
|
+
max_per_event: 4000
|
|
156
|
+
|
|
157
|
+
behavior:
|
|
158
|
+
on_llm_unreachable: drop_and_alert
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
function envExample(model) {
|
|
162
|
+
if (model.startsWith('anthropic/'))
|
|
163
|
+
return 'ANTHROPIC_API_KEY=\n';
|
|
164
|
+
if (model.startsWith('openai/'))
|
|
165
|
+
return 'OPENAI_API_KEY=\n';
|
|
166
|
+
// ollama — no key needed
|
|
167
|
+
return '# Ollama runs locally — no API key required.\n# Make sure ollama is running: ollama serve\n';
|
|
168
|
+
}
|
|
169
|
+
function startInstructions(source, projectName, model) {
|
|
170
|
+
const lines = [
|
|
171
|
+
'',
|
|
172
|
+
`Done! To get started:`,
|
|
173
|
+
'',
|
|
174
|
+
` cd ${projectName}`,
|
|
175
|
+
` npm install`,
|
|
176
|
+
];
|
|
177
|
+
if (!model.startsWith('ollama/')) {
|
|
178
|
+
lines.push(` cp .env.example .env # add your API key`);
|
|
179
|
+
}
|
|
180
|
+
if (source === 'tshark') {
|
|
181
|
+
lines.push('', ' # tshark must be installed:', ' # macOS: brew install wireshark', ' # Ubuntu: sudo apt install tshark');
|
|
182
|
+
}
|
|
183
|
+
lines.push(` npm start`, '');
|
|
184
|
+
return lines.join('\n');
|
|
185
|
+
}
|
|
186
|
+
// ── Main ───────────────────────────────────────────────────────────────────
|
|
187
|
+
async function main() {
|
|
188
|
+
const projectName = process.argv[2];
|
|
189
|
+
if (!projectName) {
|
|
190
|
+
console.log('Usage: npm create tunnlo <project-name>');
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(projectName)) {
|
|
194
|
+
console.error('Error: project name must only contain letters, numbers, hyphens, and underscores.');
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const projectDir = join(process.cwd(), projectName);
|
|
198
|
+
console.log(`\nCreating Tunnlo project: ${projectName}\n`);
|
|
199
|
+
// ── Prompts ──
|
|
200
|
+
const source = await choose('What data source will you use?', [
|
|
201
|
+
{ label: 'Standard input (stdin) — pipe data in manually', value: 'stdin' },
|
|
202
|
+
{ label: 'Wireshark / tshark — monitor live network traffic', value: 'tshark' },
|
|
203
|
+
{ label: 'Log file — tail a log file on disk', value: 'log' },
|
|
204
|
+
]);
|
|
205
|
+
let iface = 'en0';
|
|
206
|
+
let captureFilter = '';
|
|
207
|
+
let logPath = '/var/log/syslog';
|
|
208
|
+
if (source === 'tshark') {
|
|
209
|
+
iface = await ask(' Network interface (e.g. en0, eth0) [en0]: ') || 'en0';
|
|
210
|
+
captureFilter = await ask(' Capture filter — leave blank for all traffic (e.g. tcp, "tcp port 443") [none]: ');
|
|
211
|
+
}
|
|
212
|
+
else if (source === 'log') {
|
|
213
|
+
logPath = await ask(' Path to log file [/var/log/syslog]: ') || '/var/log/syslog';
|
|
214
|
+
}
|
|
215
|
+
console.log('');
|
|
216
|
+
const model = await choose('Which LLM will you use?', [
|
|
217
|
+
{ label: 'Anthropic Claude (requires ANTHROPIC_API_KEY)', value: 'anthropic/claude-sonnet-4-5' },
|
|
218
|
+
{ label: 'OpenAI GPT-4o (requires OPENAI_API_KEY)', value: 'openai/gpt-4o' },
|
|
219
|
+
{ label: 'Ollama — local models, no API key needed', value: 'ollama/llama3.1:8b' },
|
|
220
|
+
]);
|
|
221
|
+
rl.close();
|
|
222
|
+
// ── Generate config ──
|
|
223
|
+
let tunnloYaml;
|
|
224
|
+
if (source === 'tshark') {
|
|
225
|
+
tunnloYaml = tsharkConfig(model, iface, captureFilter);
|
|
226
|
+
}
|
|
227
|
+
else if (source === 'log') {
|
|
228
|
+
tunnloYaml = logConfig(model, logPath);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
tunnloYaml = stdinConfig(model);
|
|
232
|
+
}
|
|
233
|
+
// ── Scaffold files ──
|
|
234
|
+
await mkdir(projectDir, { recursive: true });
|
|
235
|
+
const pkg = {
|
|
236
|
+
name: projectName,
|
|
237
|
+
version: '0.1.0',
|
|
238
|
+
private: true,
|
|
239
|
+
type: 'module',
|
|
240
|
+
scripts: {
|
|
241
|
+
start: 'tunnlo start tunnlo.yaml',
|
|
242
|
+
validate: 'tunnlo validate tunnlo.yaml',
|
|
243
|
+
},
|
|
244
|
+
dependencies: {
|
|
245
|
+
'@tunnlo/cli': '^0.1.0',
|
|
246
|
+
'@tunnlo/core': '^0.1.0',
|
|
247
|
+
'@tunnlo/adapters': '^0.1.0',
|
|
248
|
+
'@tunnlo/filters': '^0.1.0',
|
|
249
|
+
'@tunnlo/bridge-llm': '^0.1.0',
|
|
250
|
+
'@tunnlo/actions': '^0.1.0',
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
await writeFile(join(projectDir, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
254
|
+
await writeFile(join(projectDir, 'tunnlo.yaml'), tunnloYaml);
|
|
255
|
+
await writeFile(join(projectDir, '.gitignore'), 'node_modules/\n.env\n.env.*\n');
|
|
256
|
+
await writeFile(join(projectDir, '.env.example'), envExample(model));
|
|
257
|
+
console.log(startInstructions(source, projectName, model));
|
|
258
|
+
}
|
|
259
|
+
main().catch((err) => {
|
|
260
|
+
rl.close();
|
|
261
|
+
console.error('Error:', err.message);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
});
|
|
264
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-tunnlo",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Scaffolding tool for new Tunnlo projects",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-tunnlo": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -b"
|
|
12
|
+
},
|
|
13
|
+
"files": ["dist", "templates"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Tunnlo Security Monitor Template
|
|
2
|
+
# Monitors network traffic via tshark and sends alerts to LLM
|
|
3
|
+
|
|
4
|
+
sources:
|
|
5
|
+
- id: wireshark-capture
|
|
6
|
+
adapter: native/tshark
|
|
7
|
+
config:
|
|
8
|
+
interface: eth0
|
|
9
|
+
capture_filter: "tcp port 80 or tcp port 443"
|
|
10
|
+
output_format: json
|
|
11
|
+
|
|
12
|
+
filters:
|
|
13
|
+
- type: content-filter
|
|
14
|
+
rules:
|
|
15
|
+
- field: payload.flags
|
|
16
|
+
match: "SYN"
|
|
17
|
+
- field: payload.dst_port
|
|
18
|
+
in: [22, 3389, 445]
|
|
19
|
+
mode: any
|
|
20
|
+
|
|
21
|
+
- type: dedup
|
|
22
|
+
window_seconds: 30
|
|
23
|
+
key_fields:
|
|
24
|
+
- payload.src_ip
|
|
25
|
+
- payload.dst_port
|
|
26
|
+
|
|
27
|
+
- type: rate-limiter
|
|
28
|
+
max_events_per_minute: 20
|
|
29
|
+
|
|
30
|
+
agent:
|
|
31
|
+
runtime: direct-llm
|
|
32
|
+
model: anthropic/claude-sonnet-4-5
|
|
33
|
+
system_prompt: |
|
|
34
|
+
You are a security monitoring agent analyzing network traffic events.
|
|
35
|
+
|
|
36
|
+
For each event, assess:
|
|
37
|
+
1. Is this normal traffic or potentially suspicious?
|
|
38
|
+
2. What kind of activity does this represent?
|
|
39
|
+
3. Should an alert be raised?
|
|
40
|
+
|
|
41
|
+
If you detect suspicious activity, trigger a webhook alert:
|
|
42
|
+
```json:actions
|
|
43
|
+
[{"type": "webhook", "config": {}, "payload": {"severity": "high", "message": "description"}}]
|
|
44
|
+
```
|
|
45
|
+
token_budget:
|
|
46
|
+
max_per_hour: 100000
|
|
47
|
+
max_per_event: 4000
|
|
48
|
+
actions:
|
|
49
|
+
- type: webhook
|
|
50
|
+
url: "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
|
|
51
|
+
|
|
52
|
+
behavior:
|
|
53
|
+
on_llm_unreachable: drop_and_alert
|