penguins-eggs 25.11.29 → 25.12.7
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/.oclif.manifest.json +1 -1
- package/README.md +72 -110
- package/README.pdf +11041 -10623
- package/conf/derivatives.yaml +2 -1
- package/conf/exclude.list.d/var.list +11 -6
- package/dist/appimage/dependency-manager.js +1 -1
- package/dist/classes/cli-autologin.js +77 -52
- package/dist/classes/compressors.d.ts +7 -10
- package/dist/classes/compressors.js +44 -31
- package/dist/classes/distro.js +2 -2
- package/dist/classes/diversions.js +2 -3
- package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +2 -5
- package/dist/classes/incubation/fisherman-helper/initcpio.js +7 -4
- package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
- package/dist/classes/incubation/fisherman.js +1 -1
- package/dist/classes/incubation/incubator.js +1 -1
- package/dist/classes/ovary.d/create-xdg-autostart.js +1 -1
- package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -12
- package/dist/classes/ovary.d/edit-live-fs.js +129 -135
- package/dist/classes/ovary.d/make-dot-disk.js +1 -1
- package/dist/classes/ovary.d/produce.js +1 -1
- package/dist/classes/ovary.d/user-create-live.d.ts +4 -10
- package/dist/classes/ovary.d/user-create-live.js +82 -84
- package/dist/classes/ovary.d/users-remove.d.ts +5 -6
- package/dist/classes/ovary.d/users-remove.js +61 -31
- package/dist/classes/ovary.d.ts +2 -2
- package/dist/classes/ovary.js +2 -2
- package/dist/classes/pacman.d/alpine.js +2 -2
- package/dist/classes/pacman.d/archlinux.js +2 -2
- package/dist/classes/pacman.d/debian.js +2 -3
- package/dist/classes/pacman.d/fedora.js +2 -3
- package/dist/classes/pacman.d/openmamba.js +2 -3
- package/dist/classes/pacman.d/opensuse.js +2 -3
- package/dist/classes/pacman.d.ts +0 -5
- package/dist/classes/pacman.js +3 -16
- package/dist/classes/pve-live.js +1 -1
- package/dist/classes/settings.js +1 -1
- package/dist/classes/sys-users.d.ts +76 -0
- package/dist/classes/sys-users.js +206 -0
- package/dist/classes/utils.d/kernel.js +3 -3
- package/dist/classes/utils.d.ts +15 -6
- package/dist/classes/utils.js +79 -46
- package/dist/classes/xdg.js +1 -1
- package/dist/classes/yolk.js +2 -4
- package/dist/commands/export/appimage.js +3 -3
- package/dist/commands/export/pkg.js +3 -3
- package/dist/commands/export/tarballs.js +3 -3
- package/dist/commands/krill.js +1 -1
- package/dist/commands/produce.js +9 -4
- package/dist/commands/setup/install.js +1 -1
- package/dist/commands/setup/purge.js +1 -1
- package/dist/commands/tools/yolk.js +1 -1
- package/dist/commands/update.js +1 -2
- package/dist/interfaces/i-exec.d.ts +1 -0
- package/dist/krill/classes/prepare.d/location.js +1 -1
- package/dist/krill/classes/prepare.d/partitions.js +1 -1
- package/dist/krill/classes/prepare.d/users.js +2 -2
- package/dist/krill/classes/prepare.js +5 -5
- package/dist/krill/classes/sequence.d/add_user.d.ts +3 -15
- package/dist/krill/classes/sequence.d/add_user.js +87 -57
- package/dist/krill/classes/sequence.d/change_password.d.ts +5 -7
- package/dist/krill/classes/sequence.d/change_password.js +25 -10
- package/dist/krill/classes/sequence.d/del_live_user.d.ts +5 -7
- package/dist/krill/classes/sequence.d/del_live_user.js +39 -25
- package/dist/krill/classes/sequence.d/fstab.js +1 -1
- package/dist/krill/classes/sequence.d/grubcfg.d.ts +3 -7
- package/dist/krill/classes/sequence.d/grubcfg.js +33 -13
- package/dist/krill/classes/sequence.d/mkfs.js +1 -2
- package/dist/krill/classes/sequence.d/unpackfs.d.ts +2 -4
- package/dist/krill/classes/sequence.d/unpackfs.js +8 -5
- package/dist/krill/classes/sequence.js +2 -3
- package/dist/krill/components/title.js +2 -2
- package/dist/krill/lib/select_installation_device.js +1 -1
- package/dist/krill/lib/select_replaced_partition.js +1 -1
- package/dist/lib/utils.d.ts +51 -19
- package/dist/lib/utils.js +225 -20
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +8 -8
- package/package.json +9 -9
- package/perrisbrewery/template/dependencies.yaml +1 -0
- package/scripts/boot-encrypted-root.sh +220 -0
- package/scripts/mount-encrypted-home.sh +324 -0
- package/dracut/create-symlink +0 -71
- package/dracut/dracut-log.txt +0 -3
- package/dracut/export +0 -4
- package/dracut/export-dracut-analysis +0 -51
- package/dracut/export-dracut-log +0 -2
- package/dracut/mkisofs +0 -10
- package/dracut/renew-initramfs +0 -17
- package/dracut/sbin2bin +0 -10
- package/dracut/update-dracut-conf-d +0 -2
- package/dracut/update-dracut-modules +0 -62
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ./src/classes/ovary.d/edit-live-fs.ts
|
|
3
|
-
* penguins-eggs v.25.
|
|
3
|
+
* penguins-eggs v.25.12.5 / ecmascript 2020
|
|
4
4
|
* author: Piero Proietti
|
|
5
5
|
* email: piero.proietti@gmail.com
|
|
6
6
|
* license: MIT
|
|
@@ -9,76 +9,45 @@
|
|
|
9
9
|
import fs from 'fs';
|
|
10
10
|
import os from 'os';
|
|
11
11
|
import path from 'node:path';
|
|
12
|
-
import shx from '
|
|
12
|
+
import { shx } from '../../lib/utils.js';
|
|
13
13
|
import Utils from '../utils.js';
|
|
14
14
|
import Pacman from '../pacman.js';
|
|
15
15
|
import Systemctl from '../systemctl.js';
|
|
16
16
|
import { exec } from '../../lib/utils.js';
|
|
17
17
|
// _dirname
|
|
18
18
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
19
|
-
/**
|
|
20
|
-
* editLiveFs
|
|
21
|
-
* - Mark if is_clone or is_clone_crypted
|
|
22
|
-
* - Truncate logs, remove archived log
|
|
23
|
-
* - Allow all fixed drives to be mounted with pmount
|
|
24
|
-
* - Enable or disable password login trhough ssh for users (not root)
|
|
25
|
-
* - Create an empty /etc/fstab
|
|
26
|
-
* - Blanck /etc/machine-id
|
|
27
|
-
* - Add some basic files to /dev
|
|
28
|
-
* - Clear configs from /etc/network/interfaces, wicd and NetworkManager and netman
|
|
29
|
-
*/
|
|
30
19
|
export async function editLiveFs(clone = false) {
|
|
31
|
-
if (this.verbose)
|
|
20
|
+
if (this.verbose)
|
|
32
21
|
console.log('Ovary: editLiveFs');
|
|
33
|
-
}
|
|
34
22
|
const workDir = this.settings.work_dir.merged;
|
|
35
|
-
/**
|
|
36
|
-
* /etc/penguins-eggs.d/is_clone file created on live
|
|
37
|
-
*/
|
|
38
23
|
if (clone) {
|
|
39
24
|
await exec(`touch ${workDir}/etc/penguins-eggs.d/is_clone`, this.echo);
|
|
40
25
|
}
|
|
41
|
-
/**
|
|
42
|
-
* /etc/default/epoptes-client created on live
|
|
43
|
-
*/
|
|
44
26
|
if (Pacman.packageIsInstalled('epoptes')) {
|
|
45
27
|
const file = `${workDir}/etc/default/epoptes-client`;
|
|
46
28
|
const text = `SERVER=${os.hostname}.local\n`;
|
|
47
29
|
fs.writeFileSync(file, text);
|
|
48
30
|
}
|
|
49
31
|
if (this.familyId === 'debian') {
|
|
50
|
-
// Aggiungo UMASK=0077 in /etc/initramfs-tools/conf.d/calamares-safe-initramfs.conf
|
|
51
32
|
const text = 'UMASK=0077\n';
|
|
52
33
|
const file = '/etc/initramfs-tools/conf.d/eggs-safe-initramfs.conf';
|
|
53
34
|
Utils.write(file, text);
|
|
54
35
|
}
|
|
55
|
-
// Truncate logs
|
|
36
|
+
// Truncate logs
|
|
56
37
|
let cmd = `find ${workDir}/var/log -name "*gz" -print0 | xargs -0r rm -f`;
|
|
57
38
|
await exec(cmd, this.echo);
|
|
58
39
|
cmd = `find ${workDir}/var/log/ -type f -exec truncate -s 0 {} \\;`;
|
|
59
40
|
await exec(cmd, this.echo);
|
|
60
41
|
// =========================================================================
|
|
61
|
-
// FIX
|
|
42
|
+
// FIX DEFINITIVO PER DEVUAN/SYSVINIT (Init Script Hardening)
|
|
62
43
|
// =========================================================================
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`${workDir}/var/spool/rsyslog`, // Fondamentale per rsyslog
|
|
68
|
-
`${workDir}/var/spool/cron/crontabs` // Fondamentale per cron
|
|
69
|
-
];
|
|
70
|
-
for (const dir of dirsToCreate) {
|
|
71
|
-
if (!fs.existsSync(dir)) {
|
|
72
|
-
await exec(`mkdir -p ${dir}`, this.echo);
|
|
73
|
-
// Assicuriamo permessi corretti (dbus vuole 755 root:root di base)
|
|
74
|
-
await exec(`chmod 755 ${dir}`, this.echo);
|
|
75
|
-
}
|
|
44
|
+
if (Utils.isSysvinit()) {
|
|
45
|
+
if (this.verbose)
|
|
46
|
+
console.log('SysVinit detected: Hardening init scripts...');
|
|
47
|
+
await patchInitScripts(workDir, this.verbose);
|
|
76
48
|
}
|
|
77
49
|
// =========================================================================
|
|
78
|
-
//
|
|
79
|
-
// =========================================================================
|
|
80
|
-
// Su Debian/Devuan moderni, /var/run DEVE essere un symlink a /run.
|
|
81
|
-
// Se rsync lo ha copiato come directory, D-Bus e altri servizi falliscono.
|
|
50
|
+
// Fix Symlinks /var/run e /var/lock
|
|
82
51
|
const varRun = `${workDir}/var/run`;
|
|
83
52
|
if (fs.existsSync(varRun) && !fs.lstatSync(varRun).isSymbolicLink()) {
|
|
84
53
|
if (this.verbose)
|
|
@@ -93,20 +62,14 @@ export async function editLiveFs(clone = false) {
|
|
|
93
62
|
await exec(`rm -rf ${varLock}`, this.echo);
|
|
94
63
|
await exec(`ln -s /run/lock ${varLock}`, this.echo);
|
|
95
64
|
}
|
|
96
|
-
//
|
|
97
|
-
// Allow all fixed drives to be mounted with pmount
|
|
65
|
+
// Altri fix standard
|
|
98
66
|
if (this.settings.config.pmount_fixed && fs.existsSync(`${workDir}/etc/pmount.allow`)) {
|
|
99
|
-
// MX aggiunto /etc
|
|
100
67
|
await exec(`sed -i 's:#/dev/sd\[a-z\]:/dev/sd\[a-z\]:' ${workDir}/etc/pmount.allow`, this.echo);
|
|
101
68
|
}
|
|
102
|
-
// Remove obsolete live-config file
|
|
103
69
|
if (fs.existsSync(`${workDir}lib/live/config/1161-openssh-server`)) {
|
|
104
70
|
await exec(`rm -f ${workDir}/lib/live/config/1161-openssh-server`, this.echo);
|
|
105
71
|
}
|
|
106
72
|
if (fs.existsSync(`${workDir}/etc/ssh/sshd_config`)) {
|
|
107
|
-
/**
|
|
108
|
-
* enable/disable SSH root/users password login
|
|
109
|
-
*/
|
|
110
73
|
await exec(`sed -i '/PermitRootLogin/d' ${workDir}/etc/ssh/sshd_config`);
|
|
111
74
|
await exec(`sed -i '/PasswordAuthentication/d' ${workDir}/etc/ssh/sshd_config`);
|
|
112
75
|
if (this.settings.config.ssh_pass) {
|
|
@@ -117,111 +80,53 @@ export async function editLiveFs(clone = false) {
|
|
|
117
80
|
await exec(`echo 'PasswordAuthentication no' | tee -a ${workDir}/etc/ssh/sshd_config`, this.echo);
|
|
118
81
|
}
|
|
119
82
|
}
|
|
120
|
-
/**
|
|
121
|
-
* /etc/fstab should exist, even if it's empty,
|
|
122
|
-
* to prevent error messages at boot
|
|
123
|
-
*/
|
|
124
83
|
await exec(`rm ${workDir}/etc/fstab`, this.echo);
|
|
125
84
|
await exec(`touch ${workDir}/etc/fstab`, this.echo);
|
|
126
|
-
/**
|
|
127
|
-
* Remove crypttab if exists
|
|
128
|
-
* this is crucial for tpm systems.
|
|
129
|
-
*/
|
|
130
85
|
if (fs.existsSync(`${workDir}/etc/crypttab`)) {
|
|
131
86
|
await exec(`rm ${workDir}/etc/crypttab`, this.echo);
|
|
132
87
|
}
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
/**
|
|
137
|
-
* Blank out systemd machine id.
|
|
138
|
-
* SU SYSTEMD: File vuoto = rigenerazione.
|
|
139
|
-
* SU SYSVINIT (Devuan): File NON deve esistere o deve essere 0 bytes.
|
|
140
|
-
*/
|
|
141
|
-
// 1. Pulisci /etc/machine-id
|
|
88
|
+
// 🔧 [MODIFICA 1] Machine ID cleanup
|
|
89
|
+
// Cancelliamo SEMPRE il machine-id, anche su SysVinit.
|
|
90
|
+
// Questo garantisce che lo script patchato (dbus) trovi il file mancante e lo rigeneri.
|
|
142
91
|
if (fs.existsSync(`${workDir}/etc/machine-id`)) {
|
|
143
92
|
await exec(`rm ${workDir}/etc/machine-id`, this.echo);
|
|
144
|
-
|
|
145
|
-
// Per Devuan va bene vuoto (lo riempie dbus-uuidgen)
|
|
146
|
-
await exec(`touch ${workDir}/etc/machine-id`, this.echo);
|
|
93
|
+
await exec(`touch ${workDir}/etc/machine-id`, this.echo); // Lo ricreiamo vuoto
|
|
147
94
|
}
|
|
148
|
-
//
|
|
149
|
-
// Questo è il file "vero" per dbus su sistemi non-systemd.
|
|
150
|
-
// Deve sparire per essere rigenerato al boot.
|
|
95
|
+
// Rimuoviamo anche quello in /var/lib/dbus per forzare la rigenerazione
|
|
151
96
|
if (fs.existsSync(`${workDir}/var/lib/dbus/machine-id`)) {
|
|
152
97
|
await exec(`rm ${workDir}/var/lib/dbus/machine-id`, this.echo);
|
|
153
98
|
}
|
|
154
|
-
// =========================================================================
|
|
155
|
-
/**
|
|
156
|
-
* LMDE4: utilizza UbuntuMono16.pf2
|
|
157
|
-
* aggiungo un link a /boot/grub/fonts/UbuntuMono16.pf2
|
|
158
|
-
*/
|
|
159
99
|
if (fs.existsSync(`${workDir}/boot/grub/fonts/unicode.pf2`)) {
|
|
160
100
|
shx.cp(`${workDir}/boot/grub/fonts/unicode.pf2`, `${workDir}/boot/grub/fonts/UbuntuMono16.pf2`);
|
|
161
101
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
*/
|
|
165
|
-
const resolvFile = `${workDir}/etc/resolv.conf`;
|
|
166
|
-
shx.rm(resolvFile);
|
|
167
|
-
/**
|
|
168
|
-
* Per tutte le distro systemd
|
|
169
|
-
*/
|
|
102
|
+
shx.rm(`${workDir}/etc/resolv.conf`);
|
|
103
|
+
// Systemd cleanup
|
|
170
104
|
if (Utils.isSystemd()) {
|
|
171
105
|
const systemdctl = new Systemctl(this.verbose);
|
|
172
|
-
|
|
173
|
-
* Arch: /ci/minimal/arch-minimal.sh:
|
|
174
|
-
* systemctl set-default multi-user.target
|
|
175
|
-
* systemctl enable getty@tty1.service
|
|
176
|
-
* systemctl enable systemd-networkd.service
|
|
177
|
-
* systemctl enable 'systemd-resolved.service
|
|
178
|
-
*/
|
|
179
|
-
if (await systemdctl.isEnabled('remote-cryptsetup.target')) {
|
|
106
|
+
if (await systemdctl.isEnabled('remote-cryptsetup.target'))
|
|
180
107
|
await systemdctl.disable('remote-cryptsetup.target', workDir, true);
|
|
181
|
-
|
|
182
|
-
if (await systemdctl.isEnabled('speech-dispatcherd.service')) {
|
|
108
|
+
if (await systemdctl.isEnabled('speech-dispatcherd.service'))
|
|
183
109
|
await systemdctl.disable('speech-dispatcherd.service', workDir, true);
|
|
184
|
-
|
|
185
|
-
if (await systemdctl.isEnabled('wpa_supplicant-nl80211@.service')) {
|
|
110
|
+
if (await systemdctl.isEnabled('wpa_supplicant-nl80211@.service'))
|
|
186
111
|
await systemdctl.disable('wpa_supplicant-nl80211@.service', workDir, true);
|
|
187
|
-
|
|
188
|
-
if (await systemdctl.isEnabled('wpa_supplicant@.service')) {
|
|
112
|
+
if (await systemdctl.isEnabled('wpa_supplicant@.service'))
|
|
189
113
|
await systemdctl.disable('wpa_supplicant@.service', workDir, true);
|
|
190
|
-
|
|
191
|
-
if (await systemdctl.isEnabled('wpa_supplicant-wired@.service')) {
|
|
114
|
+
if (await systemdctl.isEnabled('wpa_supplicant-wired@.service'))
|
|
192
115
|
await systemdctl.disable('wpa_supplicant-wired@.service', workDir, true);
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* All systemd distros
|
|
196
|
-
*/
|
|
197
116
|
await exec(`rm -f ${workDir}/var/lib/wicd/configurations/*`, this.echo);
|
|
198
117
|
await exec(`rm -f ${workDir}/etc/wicd/wireless-settings.conf`, this.echo);
|
|
199
118
|
await exec(`rm -f ${workDir}/etc/NetworkManager/system-connections/*`, this.echo);
|
|
200
119
|
await exec(`rm -f ${workDir}/etc/network/wifi/*`, this.echo);
|
|
201
|
-
/**
|
|
202
|
-
* removing from /etc/network/:
|
|
203
|
-
* if-down.d if-post-down.d if-pre-up.d if-up.d interfaces interfaces.d
|
|
204
|
-
*/
|
|
205
120
|
const cleanDirs = ['if-down.d', 'if-post-down.d', 'if-pre-up.d', 'if-up.d', 'interfaces.d'];
|
|
206
|
-
|
|
207
|
-
for (cleanDir of cleanDirs) {
|
|
121
|
+
for (const cleanDir of cleanDirs) {
|
|
208
122
|
await exec(`rm -f ${workDir}/etc/network/${cleanDir}/wpasupplicant`, this.echo);
|
|
209
123
|
}
|
|
210
124
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Clear configs from /etc/network/interfaces, wicd and NetworkManager
|
|
213
|
-
* and netman, so they aren't stealthily included in the snapshot.
|
|
214
|
-
*/
|
|
215
125
|
if (this.familyId === 'debian') {
|
|
216
126
|
if (fs.existsSync(`${workDir}/etc/network/interfaces`)) {
|
|
217
127
|
await exec(`rm -f ${workDir}/etc/network/interfaces`, this.echo);
|
|
218
128
|
Utils.write(`${workDir}/etc/network/interfaces`, 'auto lo\niface lo inet loopback');
|
|
219
129
|
}
|
|
220
|
-
/**
|
|
221
|
-
* add some basic files to /dev
|
|
222
|
-
*/
|
|
223
|
-
// Ho condensato i controlli ripetitivi su mknod per leggibilità
|
|
224
|
-
// Nota: Questo è safe da eseguire, anche se devtmpfs solitamente gestisce tutto.
|
|
225
130
|
const devNodes = [
|
|
226
131
|
{ path: 'console', m: '622', type: 'c', major: 5, minor: 1 },
|
|
227
132
|
{ path: 'null', m: '666', type: 'c', major: 1, minor: 3 },
|
|
@@ -236,10 +141,9 @@ export async function editLiveFs(clone = false) {
|
|
|
236
141
|
await exec(`mknod -m ${node.m} ${workDir}/dev/${node.path} ${node.type} ${node.major} ${node.minor}`, this.echo);
|
|
237
142
|
}
|
|
238
143
|
}
|
|
239
|
-
if (!fs.existsSync(`${workDir}/dev/
|
|
144
|
+
if (!fs.existsSync(`${workDir}/dev/console`)) {
|
|
240
145
|
await exec(`chown -v root:tty ${workDir}/dev/{console,ptmx,tty}`, this.echo);
|
|
241
146
|
}
|
|
242
|
-
// Link simbolici standard
|
|
243
147
|
const links = [
|
|
244
148
|
{ src: '/proc/self/fd', dest: 'fd' },
|
|
245
149
|
{ src: '/proc/self/fd/0', dest: 'stdin' },
|
|
@@ -252,24 +156,114 @@ export async function editLiveFs(clone = false) {
|
|
|
252
156
|
await exec(`ln -sv ${link.src} ${workDir}/dev/${link.dest}`, this.echo);
|
|
253
157
|
}
|
|
254
158
|
}
|
|
255
|
-
if (!fs.existsSync(`${workDir}/dev/shm`))
|
|
159
|
+
if (!fs.existsSync(`${workDir}/dev/shm`))
|
|
256
160
|
await exec(`mkdir -v ${workDir}/dev/shm`, this.echo);
|
|
257
|
-
}
|
|
258
|
-
if (!fs.existsSync(`${workDir}/dev/pts`)) {
|
|
161
|
+
if (!fs.existsSync(`${workDir}/dev/pts`))
|
|
259
162
|
await exec(`mkdir -v ${workDir}/dev/pts`, this.echo);
|
|
163
|
+
await exec(`chmod 1777 ${workDir}/dev/shm`, this.echo);
|
|
164
|
+
if (!fs.existsSync(`${workDir}/tmp`))
|
|
165
|
+
await exec(`mkdir ${workDir}/tmp`, this.echo);
|
|
166
|
+
await exec(`chmod 1777 ${workDir}/tmp`, this.echo);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Patcha direttamente gli script di init in /etc/init.d/
|
|
171
|
+
*/
|
|
172
|
+
async function patchInitScripts(workDir, verbose) {
|
|
173
|
+
// 1. PATCH DBUS (Il più importante)
|
|
174
|
+
const dbusScript = `${workDir}/etc/init.d/dbus`;
|
|
175
|
+
if (fs.existsSync(dbusScript)) {
|
|
176
|
+
if (verbose)
|
|
177
|
+
console.log(`Patching ${dbusScript} to fix missing directories and RO fs...`);
|
|
178
|
+
let content = fs.readFileSync(dbusScript, 'utf8');
|
|
179
|
+
let modified = false;
|
|
180
|
+
// PATCH A: Header con gestione Ramdisk Fallback e Mount Proc
|
|
181
|
+
// Questa intestazione viene inserita all'inizio e prova a montare tmpfs se non può scrivere
|
|
182
|
+
const dbusFix = `
|
|
183
|
+
### EGGS-FIX-START
|
|
184
|
+
# 1. Assicuriamoci che /proc sia montato (necessario per leggere uuid kernel)
|
|
185
|
+
if ! mountpoint -q /proc/; then
|
|
186
|
+
mount -t proc proc /proc
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# 2. Gestione Filesystem Read-Only (RO)
|
|
190
|
+
# Se non possiamo scrivere in /var/lib/dbus, montiamo un tmpfs (RAM) sopra.
|
|
191
|
+
# Questo bypassa il blocco dell'overlayfs non ancora pronto tipico delle build AppImage.
|
|
192
|
+
if ! mkdir -p /var/lib/dbus 2>/dev/null || ! touch /var/lib/dbus/.rw_check 2>/dev/null; then
|
|
193
|
+
echo "EGGS-DEBUG: Filesystem Read-Only detected! Mounting tmpfs on /var/lib/dbus" > /dev/console
|
|
194
|
+
mount -t tmpfs -o size=1m tmpfs /var/lib/dbus
|
|
195
|
+
fi
|
|
196
|
+
rm -f /var/lib/dbus/.rw_check
|
|
197
|
+
|
|
198
|
+
# 3. Creazione Directory Runtime
|
|
199
|
+
mkdir -p /var/run/dbus /var/lib/dbus
|
|
200
|
+
chmod 755 /var/run/dbus /var/lib/dbus
|
|
201
|
+
|
|
202
|
+
# 4. Generazione Machine ID (Non-Blocking Strategy)
|
|
203
|
+
# Se il file non esiste (o è vuoto), lo creiamo.
|
|
204
|
+
if [ ! -s /var/lib/dbus/machine-id ]; then
|
|
205
|
+
# Prova A: Usa UUID del kernel (Istantaneo, non blocca)
|
|
206
|
+
if [ -f /proc/sys/kernel/random/uuid ]; then
|
|
207
|
+
cat /proc/sys/kernel/random/uuid | tr -d '-' > /var/lib/dbus/machine-id
|
|
208
|
+
# Prova B: Fallback statico
|
|
209
|
+
else
|
|
210
|
+
echo "00000000000000000000000000000001" > /var/lib/dbus/machine-id
|
|
211
|
+
fi
|
|
212
|
+
chmod 644 /var/lib/dbus/machine-id
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# 5. Sync /etc/machine-id (Best effort, ignora errori se /etc è RO)
|
|
216
|
+
if [ ! -s /etc/machine-id ] && [ -s /var/lib/dbus/machine-id ]; then
|
|
217
|
+
cp /var/lib/dbus/machine-id /etc/machine-id 2>/dev/null || true
|
|
218
|
+
fi
|
|
219
|
+
### EGGS-FIX-END
|
|
220
|
+
`;
|
|
221
|
+
if (!content.includes('EGGS-FIX-START')) {
|
|
222
|
+
content = content.replace('#!/bin/sh', `#!/bin/sh\n${dbusFix}`);
|
|
223
|
+
modified = true;
|
|
260
224
|
}
|
|
261
|
-
|
|
262
|
-
|
|
225
|
+
// PATCH B: SABOTAGE PREVENTION (Questa è quella che mancava!)
|
|
226
|
+
// Impediamo che create_machineid cancelli il file che abbiamo appena creato
|
|
227
|
+
// perché l'uptime è basso.
|
|
228
|
+
if (content.includes('rm -f "${MACHINEID}"')) {
|
|
229
|
+
if (verbose)
|
|
230
|
+
console.log('Patching dbus: disabling auto-delete of machine-id on boot');
|
|
231
|
+
content = content.replace('rm -f "${MACHINEID}"', ': # EGGS-PATCH: Prevent deletion of valid machine-id');
|
|
232
|
+
modified = true;
|
|
263
233
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
234
|
+
if (modified) {
|
|
235
|
+
fs.writeFileSync(dbusScript, content, 'utf8');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// 2. PATCH RSYSLOG
|
|
239
|
+
const rsyslogScript = `${workDir}/etc/init.d/rsyslog`;
|
|
240
|
+
if (fs.existsSync(rsyslogScript)) {
|
|
241
|
+
let content = fs.readFileSync(rsyslogScript, 'utf8');
|
|
242
|
+
const fix = `
|
|
243
|
+
### EGGS-FIX-START
|
|
244
|
+
mkdir -p /var/spool/rsyslog
|
|
245
|
+
chmod 755 /var/spool/rsyslog
|
|
246
|
+
### EGGS-FIX-END
|
|
247
|
+
`;
|
|
248
|
+
if (!content.includes('EGGS-FIX-START')) {
|
|
249
|
+
content = content.replace('#!/bin/sh', `#!/bin/sh\n${fix}`);
|
|
250
|
+
fs.writeFileSync(rsyslogScript, content, 'utf8');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// 3. PATCH CRON
|
|
254
|
+
const cronScript = `${workDir}/etc/init.d/cron`;
|
|
255
|
+
if (fs.existsSync(cronScript)) {
|
|
256
|
+
let content = fs.readFileSync(cronScript, 'utf8');
|
|
257
|
+
const fix = `
|
|
258
|
+
### EGGS-FIX-START
|
|
259
|
+
mkdir -p /var/spool/cron/crontabs
|
|
260
|
+
chmod 1730 /var/spool/cron/crontabs
|
|
261
|
+
chown root:crontab /var/spool/cron/crontabs 2>/dev/null || true
|
|
262
|
+
### EGGS-FIX-END
|
|
263
|
+
`;
|
|
264
|
+
if (!content.includes('EGGS-FIX-START')) {
|
|
265
|
+
content = content.replace('#!/bin/sh', `#!/bin/sh\n${fix}`);
|
|
266
|
+
fs.writeFileSync(cronScript, content, 'utf8');
|
|
269
267
|
}
|
|
270
|
-
/**
|
|
271
|
-
* Assegno 1777 a /tmp creava problemi con MXLINUX
|
|
272
|
-
*/
|
|
273
|
-
await exec(`chmod 1777 ${workDir}/tmp`, this.echo);
|
|
274
268
|
}
|
|
275
269
|
}
|
|
@@ -9,7 +9,7 @@ import chalk from 'chalk';
|
|
|
9
9
|
import mustache from 'mustache';
|
|
10
10
|
// packages
|
|
11
11
|
import fs from 'node:fs';
|
|
12
|
-
import shx from '
|
|
12
|
+
import { shx } from '../../lib/utils.js';
|
|
13
13
|
import path from 'path';
|
|
14
14
|
// libraries
|
|
15
15
|
import { exec } from '../../lib/utils.js';
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/classes/ovary.d/user-create-live.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Creates the live user directly in the merged filesystem safely.
|
|
7
6
|
*/
|
|
8
7
|
import Ovary from '../ovary.js';
|
|
9
|
-
|
|
10
|
-
* list degli utenti: grep -E 1[0-9]{3} /etc/passwd | sed s/:/\ / | awk '{print $1}'
|
|
11
|
-
* create la home per user_opt
|
|
12
|
-
* @param verbose
|
|
13
|
-
*/
|
|
14
|
-
export declare function userCreateLive(this: Ovary): Promise<void>;
|
|
8
|
+
export default function userCreateLive(this: Ovary): Promise<void>;
|
|
@@ -1,97 +1,95 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/classes/ovary.d/user-create-live.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Creates the live user directly in the merged filesystem safely.
|
|
7
6
|
*/
|
|
8
|
-
// packages
|
|
9
7
|
import fs from 'fs';
|
|
10
|
-
import path from '
|
|
11
|
-
import yaml from 'js-yaml';
|
|
12
|
-
// functions
|
|
8
|
+
import path from 'path';
|
|
13
9
|
import { exec } from '../../lib/utils.js';
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* @param verbose
|
|
22
|
-
*/
|
|
23
|
-
export async function userCreateLive() {
|
|
24
|
-
if (this.verbose) {
|
|
25
|
-
console.log('Ovary: userCreateLive');
|
|
10
|
+
import SysUsers from '../sys-users.js';
|
|
11
|
+
export default async function userCreateLive() {
|
|
12
|
+
// Target: la directory "merged" dell'overlayfs
|
|
13
|
+
let target = this.settings.work_dir.merged;
|
|
14
|
+
if (!target || !fs.existsSync(target)) {
|
|
15
|
+
console.error(`SysUsers Error: Target directory not found at: ${target}`);
|
|
16
|
+
return;
|
|
26
17
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (fs.existsSync('/
|
|
38
|
-
|
|
18
|
+
const familyId = this.distro?.familyId || this.familyId;
|
|
19
|
+
console.log(`Creating LIVE user in snapshot at ${target} (Family: ${familyId})...`);
|
|
20
|
+
// 1. CARICAMENTO CONFIGURAZIONE ESISTENTE
|
|
21
|
+
const sysUsers = new SysUsers(target, familyId);
|
|
22
|
+
sysUsers.load();
|
|
23
|
+
// 2. DEFINIZIONE UTENTE LIVE
|
|
24
|
+
const username = this.settings.config.user_opt || 'live';
|
|
25
|
+
const password = 'evolution'; // Password default live
|
|
26
|
+
// Shell detection
|
|
27
|
+
let shell = '/bin/bash';
|
|
28
|
+
if (!fs.existsSync(path.join(target, 'bin/bash')) && fs.existsSync(path.join(target, 'bin/ash'))) {
|
|
29
|
+
shell = '/bin/ash';
|
|
39
30
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
case 'debian': {
|
|
58
|
-
cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG sudo ${this.settings.config.user_opt}`, this.verbose));
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
case 'fedora': {
|
|
62
|
-
cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG wheel ${this.settings.config.user_opt}`, this.verbose));
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
case 'openmamba': {
|
|
66
|
-
cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG sysadmin ${this.settings.config.user_opt}`, this.verbose));
|
|
67
|
-
cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG autologin ${this.settings.config.user_opt}`, this.verbose));
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
case 'opensuse': {
|
|
71
|
-
cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG wheel ${this.settings.config.user_opt}`, this.verbose));
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
// No default
|
|
31
|
+
const liveUser = {
|
|
32
|
+
username: username,
|
|
33
|
+
password: 'x',
|
|
34
|
+
uid: '1000', // Live user è sempre 1000
|
|
35
|
+
gid: '1000',
|
|
36
|
+
gecos: 'Live User,,,',
|
|
37
|
+
home: `/home/${username}`,
|
|
38
|
+
shell: shell
|
|
39
|
+
};
|
|
40
|
+
// 3. CREAZIONE LOGICA (IN MEMORIA)
|
|
41
|
+
// Rimuove eventuali residui precedenti e aggiunge il nuovo
|
|
42
|
+
sysUsers.addUser(liveUser, password);
|
|
43
|
+
// Aggiungi ai gruppi amministrativi
|
|
44
|
+
let adminGroup = 'wheel';
|
|
45
|
+
if (['debian', 'ubuntu', 'linuxmint', 'pop', 'neon'].includes(familyId)) {
|
|
46
|
+
adminGroup = 'sudo';
|
|
75
47
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
*/
|
|
79
|
-
let usersConf = '/etc/calamares/modules/users.conf';
|
|
80
|
-
if (!fs.existsSync(usersConf)) {
|
|
81
|
-
usersConf = '/etc/penguins-eggs.d/krill/modules/users.conf';
|
|
48
|
+
else if (familyId === 'openmamba') {
|
|
49
|
+
adminGroup = 'sysadmin';
|
|
82
50
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
51
|
+
sysUsers.addUserToGroup(username, adminGroup);
|
|
52
|
+
// GRUPPO AUTOLOGIN (Fondamentale per la live!)
|
|
53
|
+
// Creiamo il gruppo se non esiste (logica semplificata: lo aggiungiamo a sysUsers se manca?)
|
|
54
|
+
// SysUsers.addUserToGroup fallisce silenziosamente se il gruppo non c'è.
|
|
55
|
+
// Per sicurezza su Fedora/Arch, autologin di solito esiste o va creato.
|
|
56
|
+
// Proviamo ad aggiungerlo:
|
|
57
|
+
sysUsers.addUserToGroup(username, 'autologin'); // <--- PUNTO E VIRGOLA FONDAMENTALE QUI!
|
|
58
|
+
// Aggiungiamo anche ai gruppi standard audio/video/network se esistono
|
|
59
|
+
['video', 'audio', 'network', 'input', 'lp', 'storage', 'optical'].forEach(grp => {
|
|
60
|
+
sysUsers.addUserToGroup(username, grp);
|
|
61
|
+
});
|
|
62
|
+
// 4. SALVATAGGIO ATOMICO SU DISCO
|
|
63
|
+
await sysUsers.save();
|
|
64
|
+
// 5. CREAZIONE FISICA HOME DIRECTORY
|
|
65
|
+
const homeDir = path.join(target, 'home', username);
|
|
66
|
+
// Cleanup
|
|
67
|
+
if (fs.existsSync(homeDir))
|
|
68
|
+
await exec(`rm -rf ${homeDir}`, this.echo);
|
|
69
|
+
// Scheletro (/etc/skel)
|
|
70
|
+
const skelPath = path.join(target, 'etc', 'skel');
|
|
71
|
+
if (fs.existsSync(skelPath)) {
|
|
72
|
+
await exec(`mkdir -p ${homeDir}`, this.echo);
|
|
73
|
+
await exec(`cp -rT ${skelPath} ${homeDir}`, this.echo);
|
|
92
74
|
}
|
|
93
75
|
else {
|
|
94
|
-
|
|
95
|
-
|
|
76
|
+
await exec(`mkdir -p ${homeDir}`, this.echo);
|
|
77
|
+
}
|
|
78
|
+
// Permessi
|
|
79
|
+
await exec(`chown -R 1000:1000 ${homeDir}`, this.echo);
|
|
80
|
+
// Per la live va bene anche 755, ma 700 è più sicuro. Lasciamo standard.
|
|
81
|
+
await exec(`chmod 755 ${homeDir}`, this.echo);
|
|
82
|
+
// 6. FIX SELINUX SPECIFICO PER HOME LIVE
|
|
83
|
+
if (['fedora', 'rhel', 'centos', 'almalinux', 'rocky'].includes(familyId)) {
|
|
84
|
+
try {
|
|
85
|
+
await exec(`chcon -R -t user_home_t ${homeDir}`, { echo: false }).catch(() => { });
|
|
86
|
+
// Nota: .autorelabel nella root della live potrebbe rallentare il boot,
|
|
87
|
+
// ma è meglio averlo se i contesti sono dubbi.
|
|
88
|
+
// await exec(`touch ${target}/.autorelabel`, { echo: false })
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
console.error('SELinux home fix warning:', e);
|
|
92
|
+
}
|
|
96
93
|
}
|
|
94
|
+
console.log(`Live user '${username}' created successfully via SysUser Master.`);
|
|
97
95
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/classes/ovary.d/users-remove.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Cleans up host users from the ISO filesystem safely.
|
|
7
6
|
*/
|
|
8
|
-
import Ovary from '
|
|
9
|
-
export
|
|
7
|
+
import Ovary from '../ovary.js';
|
|
8
|
+
export default function usersRemove(this: Ovary): Promise<void>;
|