@ebowwa/hetzner 0.3.1 → 0.3.2
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/actions.d.ts +355 -0
- package/dist/auth.d.ts +6 -0
- package/dist/bootstrap/cloud-init.d.ts +78 -0
- package/dist/bootstrap/firewall.d.ts +118 -0
- package/dist/bootstrap/genesis.d.ts +82 -0
- package/dist/bootstrap/index.d.ts +29 -0
- package/dist/bootstrap/kernel-hardening.d.ts +69 -0
- package/dist/bootstrap/security-audit.d.ts +45 -0
- package/dist/bootstrap/ssh-hardening.d.ts +67 -0
- package/dist/client.d.ts +62 -0
- package/dist/config.d.ts +4 -0
- package/dist/cpufeatures-mvwrkyaq.node +0 -0
- package/dist/errors.d.ts +170 -0
- package/dist/index.d.ts +21 -0
- package/dist/onboarding/claude.d.ts +37 -0
- package/dist/onboarding/cpufeatures-mvwrkyaq.node +0 -0
- package/dist/onboarding/doppler.d.ts +37 -0
- package/dist/onboarding/git.d.ts +38 -0
- package/dist/onboarding/index.d.ts +19 -0
- package/dist/onboarding/onboarding.d.ts +41 -0
- package/dist/onboarding/sshcrypto-6mayxj08.node +0 -0
- package/dist/onboarding/tailscale.d.ts +38 -0
- package/dist/onboarding/types.d.ts +111 -0
- package/dist/pricing.d.ts +330 -0
- package/dist/schemas.d.ts +6629 -0
- package/dist/server-status.d.ts +25 -0
- package/dist/servers.d.ts +164 -0
- package/dist/ssh-keys.d.ts +35 -0
- package/dist/ssh-setup.d.ts +47 -0
- package/dist/sshcrypto-6mayxj08.node +0 -0
- package/dist/types.d.ts +303 -0
- package/dist/volumes.d.ts +105 -0
- package/package.json +1 -50
- package/dist/bootstrap/index.js.map +0 -15
- package/dist/index.js.map +0 -31
- package/dist/onboarding/index.js.map +0 -14
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hetzner Cloud API action polling and management
|
|
3
|
+
*
|
|
4
|
+
* Provides a robust polling service for monitoring async Hetzner actions
|
|
5
|
+
* with progress tracking, error handling, and cancellation support.
|
|
6
|
+
*/
|
|
7
|
+
import type { HetznerClient } from "./client.js";
|
|
8
|
+
import type { HetznerAction, ActionPollingOptions, RateLimitInfo } from "./types.js";
|
|
9
|
+
import { ActionStatus, ActionCommand } from "./types.js";
|
|
10
|
+
import { HetznerActionError } from "./errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Enhanced options for action polling with more granular control
|
|
13
|
+
*/
|
|
14
|
+
export interface EnhancedActionPollingOptions {
|
|
15
|
+
/** Polling interval in milliseconds (default: 2000) */
|
|
16
|
+
pollInterval?: number;
|
|
17
|
+
/** Maximum number of polling attempts before timeout */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
/** Maximum time to wait in milliseconds before timeout */
|
|
20
|
+
timeout?: number;
|
|
21
|
+
/** Callback fired on each progress update */
|
|
22
|
+
onProgress?: (action: HetznerAction) => void;
|
|
23
|
+
/** Callback fired when action completes successfully */
|
|
24
|
+
onComplete?: (action: HetznerAction) => void;
|
|
25
|
+
/** Callback fired when action fails */
|
|
26
|
+
onError?: (error: HetznerActionError, action: HetznerAction) => void;
|
|
27
|
+
/** Callback fired on each retry attempt */
|
|
28
|
+
onRetry?: (attempt: number, delay: number) => void;
|
|
29
|
+
/** Abort signal for cancellation */
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
/** Whether to use adaptive polling intervals (default: false) */
|
|
32
|
+
adaptive?: boolean;
|
|
33
|
+
/** Concurrency limit for multiple actions (default: 5) */
|
|
34
|
+
concurrency?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Result of a polling operation
|
|
38
|
+
*/
|
|
39
|
+
export interface PollingResult<T = HetznerAction> {
|
|
40
|
+
/** Whether the operation completed successfully */
|
|
41
|
+
success: boolean;
|
|
42
|
+
/** The final action state (if successful) */
|
|
43
|
+
action?: HetznerAction;
|
|
44
|
+
/** Error that occurred (if failed) */
|
|
45
|
+
error?: Error;
|
|
46
|
+
/** Number of polling attempts made */
|
|
47
|
+
attempts: number;
|
|
48
|
+
/** Total time elapsed in milliseconds */
|
|
49
|
+
elapsed: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Result for batch polling operations
|
|
53
|
+
*/
|
|
54
|
+
export interface BatchPollingResult {
|
|
55
|
+
/** Map of action ID to result */
|
|
56
|
+
results: Map<number, PollingResult>;
|
|
57
|
+
/** Count of successful actions */
|
|
58
|
+
successful: number;
|
|
59
|
+
/** Count of failed actions */
|
|
60
|
+
failed: number;
|
|
61
|
+
/** Total time elapsed in milliseconds */
|
|
62
|
+
elapsed: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Action operations for the Hetzner Cloud API
|
|
66
|
+
*
|
|
67
|
+
* Provides methods for managing and polling actions with enhanced
|
|
68
|
+
* polling capabilities including cancellation, progress tracking,
|
|
69
|
+
* and batch operations.
|
|
70
|
+
*/
|
|
71
|
+
export declare class ActionOperations {
|
|
72
|
+
private client;
|
|
73
|
+
constructor(client: HetznerClient);
|
|
74
|
+
/**
|
|
75
|
+
* Get a specific action by ID
|
|
76
|
+
*
|
|
77
|
+
* @param id - Action ID
|
|
78
|
+
* @returns Action details
|
|
79
|
+
*/
|
|
80
|
+
get(id: number): Promise<HetznerAction>;
|
|
81
|
+
/**
|
|
82
|
+
* List all actions
|
|
83
|
+
*
|
|
84
|
+
* @param options - Optional filters (status, sort, server_id, etc.)
|
|
85
|
+
* @returns Array of actions
|
|
86
|
+
*/
|
|
87
|
+
list(options?: {
|
|
88
|
+
status?: ActionStatus;
|
|
89
|
+
sort?: string;
|
|
90
|
+
page?: number;
|
|
91
|
+
per_page?: number;
|
|
92
|
+
server_id?: number;
|
|
93
|
+
}): Promise<HetznerAction[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Poll a single action until completion (enhanced version)
|
|
96
|
+
*
|
|
97
|
+
* This is the main polling service method with full feature support:
|
|
98
|
+
* - Progress tracking with onProgress callback
|
|
99
|
+
* - Success/failure callbacks
|
|
100
|
+
* - Cancellation via AbortSignal
|
|
101
|
+
* - Adaptive polling intervals
|
|
102
|
+
* - Comprehensive error handling
|
|
103
|
+
*
|
|
104
|
+
* @param actionId - Action ID to poll
|
|
105
|
+
* @param options - Polling options
|
|
106
|
+
* @returns Promise resolving to the completed action
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const action = await client.actions.poll(123, {
|
|
111
|
+
* onProgress: (a) => console.log(`Progress: ${a.progress}%`),
|
|
112
|
+
* onComplete: (a) => console.log('Done!'),
|
|
113
|
+
* onError: (e) => console.error('Failed:', e.message),
|
|
114
|
+
* timeout: 300000, // 5 minutes
|
|
115
|
+
* signal: abortController.signal
|
|
116
|
+
* });
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
poll(actionId: number, options?: EnhancedActionPollingOptions): Promise<HetznerAction>;
|
|
120
|
+
/**
|
|
121
|
+
* Poll multiple actions until completion
|
|
122
|
+
*
|
|
123
|
+
* Handles concurrent polling of multiple actions with optional
|
|
124
|
+
* concurrency limit and individual action tracking.
|
|
125
|
+
*
|
|
126
|
+
* @param actionIds - Array of action IDs to poll
|
|
127
|
+
* @param options - Polling options
|
|
128
|
+
* @returns Promise resolving to array of completed actions
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const actions = await client.actions.pollMany([1, 2, 3], {
|
|
133
|
+
* onProgress: (a) => updateUI(a),
|
|
134
|
+
* concurrency: 3, // Poll 3 at a time
|
|
135
|
+
* signal: abortController.signal
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
pollMany(actionIds: number[], options?: EnhancedActionPollingOptions): Promise<HetznerAction[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Poll multiple actions with detailed result tracking
|
|
142
|
+
*
|
|
143
|
+
* Returns a BatchPollingResult with success/failure counts and
|
|
144
|
+
* per-action results for better error handling.
|
|
145
|
+
*
|
|
146
|
+
* @param actionIds - Array of action IDs to poll
|
|
147
|
+
* @param options - Polling options
|
|
148
|
+
* @returns Batch polling result with detailed status
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* const result = await client.actions.pollManyDetailed([1, 2, 3], {
|
|
153
|
+
* concurrency: 2
|
|
154
|
+
* });
|
|
155
|
+
* console.log(`Success: ${result.successful}, Failed: ${result.failed}`);
|
|
156
|
+
* for (const [id, r] of result.results) {
|
|
157
|
+
* if (r.error) console.error(`Action ${id} failed:`, r.error);
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
pollManyDetailed(actionIds: number[], options?: EnhancedActionPollingOptions): Promise<BatchPollingResult>;
|
|
162
|
+
/**
|
|
163
|
+
* Wait for an action to complete (backward compatible alias)
|
|
164
|
+
*
|
|
165
|
+
* @param id - Action ID
|
|
166
|
+
* @param options - Polling options
|
|
167
|
+
* @returns Completed action
|
|
168
|
+
* @deprecated Use poll() instead for new code
|
|
169
|
+
*/
|
|
170
|
+
waitFor(id: number, options?: ActionPollingOptions): Promise<HetznerAction>;
|
|
171
|
+
/**
|
|
172
|
+
* Wait for multiple actions to complete (backward compatible alias)
|
|
173
|
+
*
|
|
174
|
+
* @param ids - Array of action IDs
|
|
175
|
+
* @param options - Polling options
|
|
176
|
+
* @returns Array of completed actions
|
|
177
|
+
* @deprecated Use pollMany() instead for new code
|
|
178
|
+
*/
|
|
179
|
+
waitForMany(ids: number[], options?: ActionPollingOptions): Promise<HetznerAction[]>;
|
|
180
|
+
/**
|
|
181
|
+
* Batch check multiple actions (no polling, single fetch)
|
|
182
|
+
*
|
|
183
|
+
* @param ids - Array of action IDs
|
|
184
|
+
* @returns Map of action ID to action
|
|
185
|
+
*/
|
|
186
|
+
batchCheck(ids: number[]): Promise<Map<number, HetznerAction>>;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Default timeouts for different action types (in milliseconds)
|
|
190
|
+
* Adjusted based on typical operation durations
|
|
191
|
+
*/
|
|
192
|
+
export declare const ACTION_TIMEOUTS: Record<ActionCommand, number>;
|
|
193
|
+
/**
|
|
194
|
+
* Get default timeout for an action command
|
|
195
|
+
*/
|
|
196
|
+
export declare function getActionTimeout(command: ActionCommand): number;
|
|
197
|
+
/**
|
|
198
|
+
* Poll for an action to complete with full feature support
|
|
199
|
+
*
|
|
200
|
+
* This is the core polling service function that provides:
|
|
201
|
+
* - Progress tracking via onProgress callback
|
|
202
|
+
* - Success/error notification via onComplete/onError
|
|
203
|
+
* - Cancellation support via AbortSignal
|
|
204
|
+
* - Adaptive polling intervals
|
|
205
|
+
* - Retry logic with exponential backoff
|
|
206
|
+
*
|
|
207
|
+
* @param client - Hetzner API client
|
|
208
|
+
* @param actionId - Action ID to poll
|
|
209
|
+
* @param options - Polling options
|
|
210
|
+
* @returns Completed action
|
|
211
|
+
* @throws {HetznerActionError} If action fails
|
|
212
|
+
* @throws {HetznerTimeoutError} If action times out
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const action = await pollAction(client, 123, {
|
|
217
|
+
* onProgress: (a) => console.log(`Progress: ${a.progress}%`),
|
|
218
|
+
* onComplete: (a) => console.log('Completed:', a.command),
|
|
219
|
+
* onError: (e) => console.error('Failed:', e.message),
|
|
220
|
+
* timeout: 60000,
|
|
221
|
+
* signal: abortSignal
|
|
222
|
+
* });
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export declare function pollAction(client: HetznerClient, actionId: number, options?: EnhancedActionPollingOptions): Promise<HetznerAction>;
|
|
226
|
+
/**
|
|
227
|
+
* Poll multiple actions concurrently
|
|
228
|
+
*
|
|
229
|
+
* Manages polling of multiple actions with optional concurrency limit.
|
|
230
|
+
* Each action is polled independently with shared callbacks.
|
|
231
|
+
*
|
|
232
|
+
* @param client - Hetzner API client
|
|
233
|
+
* @param actionIds - Array of action IDs to poll
|
|
234
|
+
* @param options - Polling options
|
|
235
|
+
* @returns Array of completed actions in same order as input
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const actions = await pollActions(client, [1, 2, 3], {
|
|
240
|
+
* onProgress: (a) => console.log(`Action ${a.id}: ${a.progress}%`),
|
|
241
|
+
* onComplete: (a) => console.log(`Action ${a.id} complete`),
|
|
242
|
+
* concurrency: 3 // Poll 3 actions at a time
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export declare function pollActions(client: HetznerClient, actionIds: number[], options?: EnhancedActionPollingOptions): Promise<HetznerAction[]>;
|
|
247
|
+
/**
|
|
248
|
+
* Poll multiple actions with detailed result tracking
|
|
249
|
+
*
|
|
250
|
+
* Similar to pollActions but returns a BatchPollingResult with
|
|
251
|
+
* success/failure counts and per-action results for better
|
|
252
|
+
* error handling and monitoring.
|
|
253
|
+
*
|
|
254
|
+
* @param client - Hetzner API client
|
|
255
|
+
* @param actionIds - Array of action IDs to poll
|
|
256
|
+
* @param options - Polling options
|
|
257
|
+
* @returns Batch polling result with detailed status
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const result = await pollActionsDetailed(client, [1, 2, 3], {
|
|
262
|
+
* onProgress: (a) => updateProgressBar(a)
|
|
263
|
+
* });
|
|
264
|
+
*
|
|
265
|
+
* console.log(`Completed: ${result.successful}/${actionIds.length}`);
|
|
266
|
+
* for (const [id, r] of result.results) {
|
|
267
|
+
* if (r.error) {
|
|
268
|
+
* console.error(`Action ${id} failed:`, r.error.message);
|
|
269
|
+
* }
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export declare function pollActionsDetailed(client: HetznerClient, actionIds: number[], options?: EnhancedActionPollingOptions): Promise<BatchPollingResult>;
|
|
274
|
+
/**
|
|
275
|
+
* Poll for an action to complete (backward compatible)
|
|
276
|
+
*
|
|
277
|
+
* @deprecated Use pollAction() instead for new code
|
|
278
|
+
*/
|
|
279
|
+
export declare function waitForAction(client: HetznerClient, actionId: number, options?: ActionPollingOptions): Promise<HetznerAction>;
|
|
280
|
+
/**
|
|
281
|
+
* Poll for multiple actions concurrently (backward compatible)
|
|
282
|
+
*
|
|
283
|
+
* @deprecated Use pollActions() instead for new code
|
|
284
|
+
*/
|
|
285
|
+
export declare function waitForMultipleActions(client: HetznerClient, actionIds: number[], options?: ActionPollingOptions): Promise<HetznerAction[]>;
|
|
286
|
+
/**
|
|
287
|
+
* Poll for multiple actions with concurrency limit (backward compatible)
|
|
288
|
+
*
|
|
289
|
+
* @deprecated Use pollActions() with concurrency option instead
|
|
290
|
+
*/
|
|
291
|
+
export declare function waitForMultipleActionsWithLimit(client: HetznerClient, actionIds: number[], concurrency?: number, options?: ActionPollingOptions): Promise<HetznerAction[]>;
|
|
292
|
+
/**
|
|
293
|
+
* Batch check multiple actions in a single API call
|
|
294
|
+
*
|
|
295
|
+
* Uses the /actions?id=42&id=43 endpoint to fetch multiple actions at once
|
|
296
|
+
*
|
|
297
|
+
* @param client - Hetzner API client
|
|
298
|
+
* @param actionIds - Array of action IDs to check
|
|
299
|
+
* @returns Map of action ID to action
|
|
300
|
+
*/
|
|
301
|
+
export declare function batchCheckActions(client: HetznerClient, actionIds: number[]): Promise<Map<number, HetznerAction>>;
|
|
302
|
+
/**
|
|
303
|
+
* Check if an action is running
|
|
304
|
+
*/
|
|
305
|
+
export declare function isActionRunning(action: HetznerAction): boolean;
|
|
306
|
+
/**
|
|
307
|
+
* Check if an action completed successfully
|
|
308
|
+
*/
|
|
309
|
+
export declare function isActionSuccess(action: HetznerAction): boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Check if an action failed
|
|
312
|
+
*/
|
|
313
|
+
export declare function isActionError(action: HetznerAction): boolean;
|
|
314
|
+
/**
|
|
315
|
+
* Format action progress for display
|
|
316
|
+
*/
|
|
317
|
+
export declare function formatActionProgress(action: HetznerAction): string;
|
|
318
|
+
/**
|
|
319
|
+
* Get human-readable action description
|
|
320
|
+
*/
|
|
321
|
+
export declare function getActionDescription(command: ActionCommand | string): string;
|
|
322
|
+
/**
|
|
323
|
+
* Get adaptive polling interval based on operation type
|
|
324
|
+
*/
|
|
325
|
+
export declare function getPollInterval(command: ActionCommand): number;
|
|
326
|
+
/**
|
|
327
|
+
* Get adaptive polling interval based on action progress
|
|
328
|
+
*/
|
|
329
|
+
export declare function getAdaptivePollInterval(progress: number): number;
|
|
330
|
+
/**
|
|
331
|
+
* Poll with adaptive intervals (backward compatible)
|
|
332
|
+
*
|
|
333
|
+
* @deprecated Use pollAction() with adaptive: true option instead
|
|
334
|
+
*/
|
|
335
|
+
export declare function waitForActionAdaptive(client: HetznerClient, actionId: number, command: ActionCommand, options?: ActionPollingOptions): Promise<HetznerAction>;
|
|
336
|
+
/**
|
|
337
|
+
* Parse rate limit headers from response
|
|
338
|
+
*/
|
|
339
|
+
export declare function parseRateLimitHeaders(headers: Headers): RateLimitInfo | null;
|
|
340
|
+
/**
|
|
341
|
+
* Check if rate limit is low (should warn user)
|
|
342
|
+
*/
|
|
343
|
+
export declare function isRateLimitLow(info: RateLimitInfo, threshold?: number): boolean;
|
|
344
|
+
/**
|
|
345
|
+
* Get human-readable rate limit status
|
|
346
|
+
*/
|
|
347
|
+
export declare function formatRateLimitStatus(info: RateLimitInfo): string;
|
|
348
|
+
/**
|
|
349
|
+
* Wait for rate limit to reset
|
|
350
|
+
*/
|
|
351
|
+
export declare function waitForRateLimitReset(info: RateLimitInfo): Promise<void>;
|
|
352
|
+
/**
|
|
353
|
+
* Create a progress logger for actions
|
|
354
|
+
*/
|
|
355
|
+
export declare function createProgressLogger(prefix?: string): (action: HetznerAction) => void;
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud-Init Bootstrap Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates cloud-init YAML scripts for first-boot server provisioning.
|
|
5
|
+
* Handles seed repository installation and initial setup.
|
|
6
|
+
*
|
|
7
|
+
* Security Integration:
|
|
8
|
+
* This module integrates all security modules in the correct order:
|
|
9
|
+
* 1. UFW Firewall (network-level defense)
|
|
10
|
+
* 2. Kernel Hardening (system-level hardening)
|
|
11
|
+
* 3. SSH Hardening (service-level hardening)
|
|
12
|
+
* 4. Security Audit (verification and reporting)
|
|
13
|
+
*/
|
|
14
|
+
export interface BootstrapOptions {
|
|
15
|
+
/** Seed repository URL (default: https://github.com/ebowwa/seed) */
|
|
16
|
+
seedRepo?: string;
|
|
17
|
+
/** Seed repository branch (default: dev) */
|
|
18
|
+
seedBranch?: string;
|
|
19
|
+
/** Installation path (default: /root/seed) */
|
|
20
|
+
seedPath?: string;
|
|
21
|
+
/** Whether to run setup.sh non-interactively (default: true) */
|
|
22
|
+
runSetup?: boolean;
|
|
23
|
+
/** Additional environment variables for setup.sh */
|
|
24
|
+
setupEnv?: Record<string, string>;
|
|
25
|
+
/** Additional packages to install */
|
|
26
|
+
packages?: string[];
|
|
27
|
+
/** Additional commands to run after seed installation */
|
|
28
|
+
additionalCommands?: string[];
|
|
29
|
+
/** Enable security hardening (default: true) */
|
|
30
|
+
enableSecurity?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generate a cloud-init YAML script for seed installation
|
|
34
|
+
*
|
|
35
|
+
* @param options - Bootstrap configuration options
|
|
36
|
+
* @returns Cloud-init YAML string
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateSeedBootstrap(options?: BootstrapOptions): string;
|
|
39
|
+
/**
|
|
40
|
+
* Generate a minimal cloud-init script that uses #include to fetch from a URL
|
|
41
|
+
*
|
|
42
|
+
* This is useful for larger bootstrap scripts or when you want to update
|
|
43
|
+
* the bootstrap without code changes.
|
|
44
|
+
*
|
|
45
|
+
* @param url - URL to fetch the cloud-init config from
|
|
46
|
+
* @returns Cloud-init YAML string with #include directive
|
|
47
|
+
*/
|
|
48
|
+
export declare function generateRemoteBootstrap(url: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Bootstrap configuration presets for common scenarios
|
|
51
|
+
*/
|
|
52
|
+
export declare const BootstrapPresets: {
|
|
53
|
+
/**
|
|
54
|
+
* Default seed installation with setup.sh and full security hardening
|
|
55
|
+
*/
|
|
56
|
+
readonly default: () => string;
|
|
57
|
+
/**
|
|
58
|
+
* Seed installation with full security hardening and verbose logging
|
|
59
|
+
*/
|
|
60
|
+
readonly secure: () => string;
|
|
61
|
+
/**
|
|
62
|
+
* Seed installation without running setup.sh (useful for debugging)
|
|
63
|
+
*/
|
|
64
|
+
readonly cloneOnly: () => string;
|
|
65
|
+
/**
|
|
66
|
+
* Development bootstrap without security hardening (for testing)
|
|
67
|
+
*/
|
|
68
|
+
readonly development: () => string;
|
|
69
|
+
/**
|
|
70
|
+
* Verbose bootstrap with logging enabled
|
|
71
|
+
*/
|
|
72
|
+
readonly verbose: () => string;
|
|
73
|
+
};
|
|
74
|
+
export { generateGenesisBootstrap, generateRemoteGenesisBootstrap, GenesisBootstrapPresets, type GenesisBootstrapOptions, } from "./genesis";
|
|
75
|
+
export { sshdHardeningPackages, sshdHardeningWriteFiles, sshdHardeningRunCmd, } from "./ssh-hardening";
|
|
76
|
+
export { ufwFirewallPackages, ufwFirewallWriteFiles, ufwFirewallRunCmd, DEFAULT_UFW_WORKER_OPTIONS, DEFAULT_UFW_GENESIS_OPTIONS, generateUFWFirewallForGenesis, generateUFWFirewallForWorker, type UFWFirewallOptions, } from "./firewall";
|
|
77
|
+
export { kernelHardeningPackages, kernelHardeningWriteFiles, kernelHardeningRunCmd, } from "./kernel-hardening";
|
|
78
|
+
export { securityAuditPackages, securityAuditWriteFiles, securityAuditRunCmd, } from "./security-audit";
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UFW Firewall Cloud-Init Components
|
|
3
|
+
*
|
|
4
|
+
* Composable cloud-init blocks for securing servers with UFW (Uncomplicated Firewall).
|
|
5
|
+
* Includes: default deny incoming, allow outgoing, rate limiting, and logging.
|
|
6
|
+
*
|
|
7
|
+
* Background: Hetzner public IPs face constant scanning and brute-force attacks.
|
|
8
|
+
* UFW provides a simple interface to iptables/nftables with secure defaults.
|
|
9
|
+
*
|
|
10
|
+
* This module is imported by cloud-init.ts (seed/worker nodes) and genesis.ts
|
|
11
|
+
* (control plane) so every new server gets firewall protection at first boot.
|
|
12
|
+
*
|
|
13
|
+
* Three composable functions return cloud-init line arrays for splicing into
|
|
14
|
+
* the appropriate YAML sections:
|
|
15
|
+
* - ufwFirewallPackages() → packages: section
|
|
16
|
+
* - ufwFirewallWriteFiles() → write_files: section
|
|
17
|
+
* - ufwFirewallRunCmd() → runcmd: section
|
|
18
|
+
*
|
|
19
|
+
* Security Policy:
|
|
20
|
+
* - Default: deny incoming, allow outgoing (stateful)
|
|
21
|
+
* - SSH (22): rate limited to prevent brute-force
|
|
22
|
+
* - HTTP/HTTPS (80/443): allowed for web services
|
|
23
|
+
* - Node Agent (8911): allowed for internal communication
|
|
24
|
+
* - Tailscale (41641): allowed for VPN
|
|
25
|
+
* - Logging: enabled with rate limiting to prevent log flooding
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* UFW firewall configuration options.
|
|
29
|
+
*/
|
|
30
|
+
export interface UFWFirewallOptions {
|
|
31
|
+
/** Allow SSH from specific IPs/CIDRs (default: allow from anywhere) */
|
|
32
|
+
allowSSHFrom?: string[];
|
|
33
|
+
/** Allow HTTP (port 80) */
|
|
34
|
+
allowHTTP?: boolean;
|
|
35
|
+
/** Allow HTTPS (port 443) */
|
|
36
|
+
allowHTTPS?: boolean;
|
|
37
|
+
/** Allow Node Agent port (8911) */
|
|
38
|
+
allowNodeAgent?: boolean;
|
|
39
|
+
/** Additional ports to allow */
|
|
40
|
+
additionalPorts?: Array<{
|
|
41
|
+
port: number;
|
|
42
|
+
protocol?: string;
|
|
43
|
+
comment?: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** Enable verbose logging (default: rate-limited logging) */
|
|
46
|
+
verboseLogging?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Default firewall options for Genesis control plane servers.
|
|
50
|
+
*/
|
|
51
|
+
export declare const DEFAULT_UFW_GENESIS_OPTIONS: UFWFirewallOptions;
|
|
52
|
+
/**
|
|
53
|
+
* Default firewall options for worker/seed servers.
|
|
54
|
+
*/
|
|
55
|
+
export declare const DEFAULT_UFW_WORKER_OPTIONS: UFWFirewallOptions;
|
|
56
|
+
/**
|
|
57
|
+
* Packages required for UFW firewall.
|
|
58
|
+
* Returns cloud-init YAML lines for the `packages:` section.
|
|
59
|
+
*
|
|
60
|
+
* - ufw: Uncomplicated Firewall interface to iptables/nftables
|
|
61
|
+
*/
|
|
62
|
+
export declare function ufwFirewallPackages(): string[];
|
|
63
|
+
/**
|
|
64
|
+
* Files to write at first boot for UFW firewall configuration.
|
|
65
|
+
* Returns cloud-init YAML lines for the `write_files:` section.
|
|
66
|
+
*
|
|
67
|
+
* Drops 2 files onto the server:
|
|
68
|
+
*
|
|
69
|
+
* 1. /etc/ufw/before.rules
|
|
70
|
+
* - Custom before rules for stateful firewall behavior
|
|
71
|
+
* - Allows loopback, established/related connections
|
|
72
|
+
* - Drops invalid packets early
|
|
73
|
+
*
|
|
74
|
+
* 2. /etc/ufw/sysctl.conf
|
|
75
|
+
* - Enables kernel network security parameters
|
|
76
|
+
* - IP spoofing protection
|
|
77
|
+
* - ICMP redirect protection
|
|
78
|
+
* - Log martian packets
|
|
79
|
+
*/
|
|
80
|
+
export declare function ufwFirewallWriteFiles(options?: UFWFirewallOptions): string[];
|
|
81
|
+
/**
|
|
82
|
+
* Commands to configure and activate UFW firewall at first boot.
|
|
83
|
+
* Returns cloud-init YAML lines for the `runcmd:` section.
|
|
84
|
+
*
|
|
85
|
+
* Order matters:
|
|
86
|
+
* 1. Set default policies (deny incoming, allow outgoing)
|
|
87
|
+
* 2. Allow loopback interface
|
|
88
|
+
* 3. Allow SSH with rate limiting (prevents brute-force)
|
|
89
|
+
* 4. Allow HTTP/HTTPS if enabled
|
|
90
|
+
* 5. Allow Node Agent port if enabled
|
|
91
|
+
* 6. Allow Tailscale port (required for VPN)
|
|
92
|
+
* 7. Enable logging with rate limiting
|
|
93
|
+
* 8. Enable and reload UFW
|
|
94
|
+
* 9. Display firewall status
|
|
95
|
+
*/
|
|
96
|
+
export declare function ufwFirewallRunCmd(options?: UFWFirewallOptions): string[];
|
|
97
|
+
/**
|
|
98
|
+
* Generate complete UFW firewall configuration for Genesis servers.
|
|
99
|
+
*
|
|
100
|
+
* @param options - UFW firewall options (uses DEFAULT_UFW_GENESIS_OPTIONS if not provided)
|
|
101
|
+
* @returns Object with packages, writeFiles, and runCmd arrays
|
|
102
|
+
*/
|
|
103
|
+
export declare function generateUFWFirewallForGenesis(options?: UFWFirewallOptions): {
|
|
104
|
+
packages: string[];
|
|
105
|
+
writeFiles: string[];
|
|
106
|
+
runCmd: string[];
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Generate complete UFW firewall configuration for worker/seed servers.
|
|
110
|
+
*
|
|
111
|
+
* @param options - UFW firewall options (uses DEFAULT_UFW_WORKER_OPTIONS if not provided)
|
|
112
|
+
* @returns Object with packages, writeFiles, and runCmd arrays
|
|
113
|
+
*/
|
|
114
|
+
export declare function generateUFWFirewallForWorker(options?: UFWFirewallOptions): {
|
|
115
|
+
packages: string[];
|
|
116
|
+
writeFiles: string[];
|
|
117
|
+
runCmd: string[];
|
|
118
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis Server Bootstrap Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates cloud-init YAML scripts for Genesis server provisioning.
|
|
5
|
+
* Genesis is a bootstrap/control plane node that runs com.hetzner.codespaces
|
|
6
|
+
* and manages Hetzner VPS worker nodes.
|
|
7
|
+
*
|
|
8
|
+
* Security Integration:
|
|
9
|
+
* This module integrates all security modules in the correct order:
|
|
10
|
+
* 1. UFW Firewall (network-level defense)
|
|
11
|
+
* 2. Kernel Hardening (system-level hardening)
|
|
12
|
+
* 3. SSH Hardening (service-level hardening)
|
|
13
|
+
* 4. Security Audit (verification and reporting)
|
|
14
|
+
*/
|
|
15
|
+
export interface GenesisBootstrapOptions {
|
|
16
|
+
/** Admin SSH public key for genesis user */
|
|
17
|
+
adminSSHKey: string;
|
|
18
|
+
/** Genesis repository URL (default: https://github.com/ebowwa/com.hetzner.codespaces) */
|
|
19
|
+
genesisRepo?: string;
|
|
20
|
+
/** Genesis repository branch or tag */
|
|
21
|
+
genesisBranch?: string;
|
|
22
|
+
/** Genesis server hostname (default: genesis) */
|
|
23
|
+
hostname?: string;
|
|
24
|
+
/** Default Hetzner server type for workers */
|
|
25
|
+
defaultServerType?: string;
|
|
26
|
+
/** Default Hetzner location */
|
|
27
|
+
defaultLocation?: string;
|
|
28
|
+
/** Maximum concurrent workers */
|
|
29
|
+
maxWorkers?: string;
|
|
30
|
+
/** Additional packages to install */
|
|
31
|
+
packages?: string[];
|
|
32
|
+
/** Additional commands to run after genesis setup */
|
|
33
|
+
additionalCommands?: string[];
|
|
34
|
+
/** Enable security hardening (default: true) */
|
|
35
|
+
enableSecurity?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Generate a cloud-init YAML script for Genesis server bootstrap
|
|
39
|
+
*
|
|
40
|
+
* @param options - Genesis bootstrap configuration options
|
|
41
|
+
* @returns Cloud-init YAML string
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateGenesisBootstrap(options: GenesisBootstrapOptions): string;
|
|
44
|
+
/**
|
|
45
|
+
* Generate a minimal cloud-init script that uses #include to fetch from a URL
|
|
46
|
+
*
|
|
47
|
+
* This is useful for larger bootstrap scripts or when you want to update
|
|
48
|
+
* the bootstrap without code changes.
|
|
49
|
+
*
|
|
50
|
+
* @param url - URL to fetch the cloud-init config from
|
|
51
|
+
* @returns Cloud-init YAML string with #include directive
|
|
52
|
+
*/
|
|
53
|
+
export declare function generateRemoteGenesisBootstrap(url: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Genesis bootstrap configuration presets for common scenarios
|
|
56
|
+
*/
|
|
57
|
+
export declare const GenesisBootstrapPresets: {
|
|
58
|
+
/**
|
|
59
|
+
* Default Genesis server with standard configuration and full security
|
|
60
|
+
*/
|
|
61
|
+
readonly default: (adminSSHKey: string) => string;
|
|
62
|
+
/**
|
|
63
|
+
* Genesis server with ARM architecture (CAX series - best €/performance)
|
|
64
|
+
*/
|
|
65
|
+
readonly arm: (adminSSHKey: string) => string;
|
|
66
|
+
/**
|
|
67
|
+
* Genesis server with high-performance CPU (CPX series)
|
|
68
|
+
*/
|
|
69
|
+
readonly performance: (adminSSHKey: string) => string;
|
|
70
|
+
/**
|
|
71
|
+
* Genesis server with dedicated CPU (CCX series)
|
|
72
|
+
*/
|
|
73
|
+
readonly dedicated: (adminSSHKey: string) => string;
|
|
74
|
+
/**
|
|
75
|
+
* Development Genesis server without security hardening
|
|
76
|
+
*/
|
|
77
|
+
readonly development: (adminSSHKey: string) => string;
|
|
78
|
+
/**
|
|
79
|
+
* Secure Genesis server with full hardening and verbose logging
|
|
80
|
+
*/
|
|
81
|
+
readonly secure: (adminSSHKey: string) => string;
|
|
82
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap Security Modules
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive security hardening for cloud-init server provisioning.
|
|
5
|
+
* All modules are composable and can be integrated independently.
|
|
6
|
+
*
|
|
7
|
+
* Security Module Order:
|
|
8
|
+
* 1. UFW Firewall (network-level defense)
|
|
9
|
+
* 2. Kernel Hardening (system-level hardening)
|
|
10
|
+
* 3. SSH Hardening (service-level hardening)
|
|
11
|
+
* 4. Security Audit (verification and reporting)
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { generateSeedBootstrap } from './bootstrap';
|
|
16
|
+
*
|
|
17
|
+
* const cloudInit = generateSeedBootstrap({
|
|
18
|
+
* enableSecurity: true,
|
|
19
|
+
* seedRepo: 'https://github.com/ebowwa/seed',
|
|
20
|
+
* seedBranch: 'dev',
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export { generateSeedBootstrap, generateRemoteBootstrap, BootstrapPresets, type BootstrapOptions, } from './cloud-init';
|
|
25
|
+
export { generateGenesisBootstrap, generateRemoteGenesisBootstrap, GenesisBootstrapPresets, type GenesisBootstrapOptions, } from './genesis';
|
|
26
|
+
export { ufwFirewallPackages, ufwFirewallWriteFiles, ufwFirewallRunCmd, DEFAULT_UFW_WORKER_OPTIONS, DEFAULT_UFW_GENESIS_OPTIONS, generateUFWFirewallForGenesis, generateUFWFirewallForWorker, type UFWFirewallOptions, } from './firewall';
|
|
27
|
+
export { kernelHardeningPackages, kernelHardeningWriteFiles, kernelHardeningRunCmd, } from './kernel-hardening';
|
|
28
|
+
export { sshdHardeningPackages, sshdHardeningWriteFiles, sshdHardeningRunCmd, } from './ssh-hardening';
|
|
29
|
+
export { securityAuditPackages, securityAuditWriteFiles, securityAuditRunCmd, } from './security-audit';
|