Skip to content

Commit a345666

Browse files
Merge pull request #475 from community-scripts/fix/438
Fix PBS certificate validation (Fixes #438)
2 parents 578fa28 + 4628e67 commit a345666

3 files changed

Lines changed: 27 additions & 15 deletions

File tree

src/app/_components/PBSCredentialsModal.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,21 @@ export function PBSCredentialsModal({
270270
htmlFor="pbs-fingerprint"
271271
className="text-foreground mb-1 block text-sm font-medium"
272272
>
273-
Fingerprint <span className="text-error">*</span>
273+
Fingerprint
274274
</label>
275275
<input
276276
type="text"
277277
id="pbs-fingerprint"
278278
value={pbsFingerprint}
279279
onChange={(e) => setPbsFingerprint(e.target.value)}
280-
required
281280
disabled={isLoading}
282281
className="bg-card text-foreground placeholder-muted-foreground focus:ring-ring focus:border-ring border-border w-full rounded-md border px-3 py-2 shadow-sm focus:ring-2 focus:outline-none"
283282
placeholder="e.g., 7b:e5:87:38:5e:16:05:d1:12:22:7f:73:d2:e2:d0:cf:8c:cb:28:e2:74:0c:78:91:1a:71:74:2e:79:20:5a:02"
284283
/>
285284
<p className="text-muted-foreground mt-1 text-xs">
286-
Server fingerprint for auto-acceptance. You can find this on
287-
your PBS dashboard by clicking the &quot;Show Fingerprint&quot;
288-
button.
285+
Leave empty if PBS uses a trusted CA (e.g. Let&apos;s Encrypt).
286+
For self-signed certificates, enter the server fingerprint from
287+
the PBS dashboard (&quot;Show Fingerprint&quot;).
289288
</p>
290289
</div>
291290

src/server/services/backupService.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -327,13 +327,16 @@ class BackupService {
327327
// PBS supports PBS_PASSWORD and PBS_REPOSITORY environment variables for non-interactive login
328328
const repository = `root@pam@${pbsIp}:${pbsDatastore}`;
329329

330-
// Escape password for shell safety (single quotes)
330+
// Escape password and fingerprint for shell safety (single quotes)
331331
const escapedPassword = credential.pbs_password.replace(/'/g, "'\\''");
332-
333-
// Use PBS_PASSWORD environment variable for non-interactive authentication
334-
// Auto-accept fingerprint by piping "y" to stdin
335-
// PBS will use PBS_PASSWORD env var if available, avoiding interactive prompt
336-
const fullCommand = `echo "y" | PBS_PASSWORD='${escapedPassword}' PBS_REPOSITORY='${repository}' timeout 10 proxmox-backup-client login --repository ${repository} 2>&1`;
332+
const fingerprint = credential.pbs_fingerprint?.trim() ?? '';
333+
const escapedFingerprint = fingerprint ? fingerprint.replace(/'/g, "'\\''") : '';
334+
const envParts = [`PBS_PASSWORD='${escapedPassword}'`, `PBS_REPOSITORY='${repository}'`];
335+
if (escapedFingerprint) {
336+
envParts.push(`PBS_FINGERPRINT='${escapedFingerprint}'`);
337+
}
338+
const envStr = envParts.join(' ');
339+
const fullCommand = `${envStr} timeout 10 proxmox-backup-client login --repository ${repository} 2>&1`;
337340

338341
console.log(`[BackupService] Logging into PBS: ${repository}`);
339342

@@ -419,9 +422,12 @@ class BackupService {
419422

420423
// Build full repository string: root@pam@<IP>:<DATASTORE>
421424
const repository = `root@pam@${pbsIp}:${pbsDatastore}`;
422-
425+
const fingerprint = credential.pbs_fingerprint?.trim() ?? '';
426+
const escapedFingerprint = fingerprint ? fingerprint.replace(/'/g, "'\\''") : '';
427+
const snapshotEnvParts = escapedFingerprint ? [`PBS_FINGERPRINT='${escapedFingerprint}'`] : [];
428+
const snapshotEnvStr = snapshotEnvParts.length ? snapshotEnvParts.join(' ') + ' ' : '';
423429
// Use correct command: snapshot list ct/<CT_ID> --repository <full_repo_string>
424-
const command = `timeout 30 proxmox-backup-client snapshot list ct/${ctId} --repository ${repository} 2>&1 || echo "PBS_ERROR"`;
430+
const command = `${snapshotEnvStr}timeout 30 proxmox-backup-client snapshot list ct/${ctId} --repository ${repository} 2>&1 || echo "PBS_ERROR"`;
425431
let output = '';
426432

427433
console.log(`[BackupService] Discovering PBS backups for CT ${ctId} on repository ${repository}`);

src/server/services/restoreService.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,16 @@ class RestoreService {
250250
const targetFolder = `/var/lib/vz/dump/vzdump-lxc-${ctId}-${snapshotNameForPath}`;
251251
const targetTar = `${targetFolder}.tar`;
252252

253-
// Use PBS_PASSWORD env var and add timeout for long downloads
253+
// Use PBS_PASSWORD env var and add timeout for long downloads; PBS_FINGERPRINT when set for cert validation
254254
const escapedPassword = credential.pbs_password.replace(/'/g, "'\\''");
255-
const restoreCommand = `PBS_PASSWORD='${escapedPassword}' PBS_REPOSITORY='${repository}' timeout 300 proxmox-backup-client restore "${snapshotPath}" root.pxar "${targetFolder}" --repository '${repository}' 2>&1`;
255+
const fingerprint = credential.pbs_fingerprint?.trim() ?? '';
256+
const escapedFingerprint = fingerprint ? fingerprint.replace(/'/g, "'\\''") : '';
257+
const restoreEnvParts = [`PBS_PASSWORD='${escapedPassword}'`, `PBS_REPOSITORY='${repository}'`];
258+
if (escapedFingerprint) {
259+
restoreEnvParts.push(`PBS_FINGERPRINT='${escapedFingerprint}'`);
260+
}
261+
const restoreEnvStr = restoreEnvParts.join(' ');
262+
const restoreCommand = `${restoreEnvStr} timeout 300 proxmox-backup-client restore "${snapshotPath}" root.pxar "${targetFolder}" --repository '${repository}' 2>&1`;
256263

257264
let output = '';
258265
let exitCode = 0;

0 commit comments

Comments
 (0)