Full build system: 10 hooks, build scripts, package lists, docs
This commit is contained in:
parent
1dfdee7ae1
commit
a38ae4ea4b
476
config/hooks/live/0100-alfred-customize.hook.chroot
Normal file
476
config/hooks/live/0100-alfred-customize.hook.chroot
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0 — Post-Build Customization Hook
|
||||||
|
#
|
||||||
|
# This runs inside the chroot during ISO build.
|
||||||
|
# Applies branding, security hardening, and default configs.
|
||||||
|
# BUILD: v2.0-b1 (Branding)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0] Applying customizations..."
|
||||||
|
|
||||||
|
# ── 1. Disable telemetry services ──
|
||||||
|
TELEMETRY_SERVICES=(
|
||||||
|
"apport"
|
||||||
|
"whoopsie"
|
||||||
|
"ubuntu-report"
|
||||||
|
"popularity-contest"
|
||||||
|
)
|
||||||
|
for svc in "${TELEMETRY_SERVICES[@]}"; do
|
||||||
|
systemctl disable "$svc" 2>/dev/null || true
|
||||||
|
systemctl mask "$svc" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
apt-get purge -y apport whoopsie ubuntu-report popularity-contest 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 2. Firewall defaults ──
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw default allow outgoing
|
||||||
|
ufw allow ssh
|
||||||
|
ufw --force enable
|
||||||
|
|
||||||
|
# ── 3. SSH hardening ──
|
||||||
|
cat > /etc/ssh/sshd_config.d/alfred-hardening.conf << 'SSHD'
|
||||||
|
PermitRootLogin no
|
||||||
|
PasswordAuthentication yes
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
X11Forwarding no
|
||||||
|
AllowAgentForwarding no
|
||||||
|
GatewayPorts no
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
MaxAuthTries 3
|
||||||
|
LoginGraceTime 30
|
||||||
|
SSHD
|
||||||
|
|
||||||
|
# ── 4. XFCE4 terminal defaults ──
|
||||||
|
mkdir -p /etc/skel/.config/xfce4/terminal
|
||||||
|
cat > /etc/skel/.config/xfce4/terminal/terminalrc << 'TERM'
|
||||||
|
[Configuration]
|
||||||
|
FontName=JetBrains Mono 11
|
||||||
|
MiscAlwaysShowTabs=FALSE
|
||||||
|
MiscBell=FALSE
|
||||||
|
MiscBellUrgent=FALSE
|
||||||
|
MiscBordersDefault=TRUE
|
||||||
|
MiscCursorBlinks=TRUE
|
||||||
|
MiscCursorShape=TERMINAL_CURSOR_SHAPE_BLOCK
|
||||||
|
MiscDefaultGeometry=120x35
|
||||||
|
MiscInheritGeometry=FALSE
|
||||||
|
MiscMenubarDefault=FALSE
|
||||||
|
MiscMouseAutohide=TRUE
|
||||||
|
MiscMouseWheelZoom=TRUE
|
||||||
|
MiscToolbarDefault=FALSE
|
||||||
|
MiscConfirmClose=TRUE
|
||||||
|
MiscCycleTabs=TRUE
|
||||||
|
MiscTabCloseButtons=TRUE
|
||||||
|
MiscTabCloseMiddleClick=TRUE
|
||||||
|
MiscTabPosition=GTK_POS_TOP
|
||||||
|
MiscHighlightUrls=TRUE
|
||||||
|
MiscMiddleClickOpensUri=FALSE
|
||||||
|
MiscCopyOnSelect=FALSE
|
||||||
|
MiscShowRelaunchDialog=TRUE
|
||||||
|
MiscRewrapOnResize=TRUE
|
||||||
|
MiscUseShiftArrowsToScroll=FALSE
|
||||||
|
MiscSlimTabs=FALSE
|
||||||
|
MiscNewTabAdjacent=FALSE
|
||||||
|
MiscSearchDialogOpacity=100
|
||||||
|
MiscShowUnsafePasteDialog=TRUE
|
||||||
|
ScrollingUnlimited=TRUE
|
||||||
|
BackgroundMode=TERMINAL_BACKGROUND_TRANSPARENT
|
||||||
|
BackgroundDarkness=0.920000
|
||||||
|
ColorForeground=#e8e8f0
|
||||||
|
ColorBackground=#0a0a14
|
||||||
|
ColorCursor=#00D4FF
|
||||||
|
ColorCursorUseDefault=FALSE
|
||||||
|
ColorPalette=#1a1a2e;#e74c3c;#00b894;#fdcb6e;#0984e3;#7D00FF;#00D4FF;#e8e8f0;#8a8a9a;#e74c3c;#00b894;#fdcb6e;#0984e3;#a78bfa;#00D4FF;#ffffff
|
||||||
|
TERM
|
||||||
|
|
||||||
|
# ── 5. Custom bash prompt for Alfred Linux ──
|
||||||
|
cat >> /etc/skel/.bashrc << 'BASHRC'
|
||||||
|
|
||||||
|
# Alfred Linux prompt
|
||||||
|
parse_git_branch() {
|
||||||
|
git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
|
||||||
|
}
|
||||||
|
PS1='\[\e[36m\]\u@alfred\[\e[0m\]:\[\e[35m\]\w\[\e[32m\]$(parse_git_branch)\[\e[0m\]\$ '
|
||||||
|
|
||||||
|
# Alfred Linux aliases
|
||||||
|
alias ll='ls -lah --color=auto'
|
||||||
|
alias la='ls -A --color=auto'
|
||||||
|
alias update='sudo apt update && sudo apt upgrade -y'
|
||||||
|
alias ports='ss -tulpn'
|
||||||
|
alias myip='curl -s ifconfig.me'
|
||||||
|
alias cls='clear'
|
||||||
|
|
||||||
|
# Welcome message
|
||||||
|
if [[ -z "$ALFRED_WELCOMED" ]]; then
|
||||||
|
echo -e "\e[36m"
|
||||||
|
echo " ╔═══════════════════════════════════════╗"
|
||||||
|
echo " ║ Alfred Linux 2.0 — Sovereign ║"
|
||||||
|
echo " ║ No telemetry. No tracking. Yours. ║"
|
||||||
|
echo " ╚═══════════════════════════════════════╝"
|
||||||
|
echo -e "\e[0m"
|
||||||
|
export ALFRED_WELCOMED=1
|
||||||
|
fi
|
||||||
|
BASHRC
|
||||||
|
|
||||||
|
# ── 6. Neofetch config with custom Alfred ASCII art ──
|
||||||
|
mkdir -p /etc/skel/.config/neofetch
|
||||||
|
cat > /etc/skel/.config/neofetch/config.conf << 'NEOCONF'
|
||||||
|
print_info() {
|
||||||
|
info title
|
||||||
|
info underline
|
||||||
|
info "OS" distro
|
||||||
|
info "Host" model
|
||||||
|
info "Kernel" kernel
|
||||||
|
info "Uptime" uptime
|
||||||
|
info "Packages" packages
|
||||||
|
info "Shell" shell
|
||||||
|
info "DE" de
|
||||||
|
info "WM" wm
|
||||||
|
info "Terminal" term
|
||||||
|
info "CPU" cpu
|
||||||
|
info "GPU" gpu
|
||||||
|
info "Memory" memory
|
||||||
|
info "Disk" disk
|
||||||
|
info "Network" local_ip
|
||||||
|
info cols
|
||||||
|
}
|
||||||
|
|
||||||
|
image_backend="ascii"
|
||||||
|
image_source="/etc/alfred-ascii.txt"
|
||||||
|
ascii_colors=(6 5 4 6 5 4)
|
||||||
|
NEOCONF
|
||||||
|
|
||||||
|
# Create Alfred ASCII art for neofetch
|
||||||
|
cat > /etc/alfred-ascii.txt << 'ASCII'
|
||||||
|
.---.
|
||||||
|
/ \
|
||||||
|
| A L |
|
||||||
|
| F R |
|
||||||
|
| E D |
|
||||||
|
\_____/
|
||||||
|
.----' '----.
|
||||||
|
/ \
|
||||||
|
| ███████████████ |
|
||||||
|
| █ █ |
|
||||||
|
| █ SOVEREIGN █ |
|
||||||
|
| █ LINUX █ |
|
||||||
|
| █ █ |
|
||||||
|
| ███████████████ |
|
||||||
|
\ /
|
||||||
|
'-----. .-----'
|
||||||
|
| |
|
||||||
|
/ \
|
||||||
|
'-------'
|
||||||
|
ASCII
|
||||||
|
|
||||||
|
# ── 7. Generate wallpapers via ImageMagick (if available) ──
|
||||||
|
mkdir -p /usr/share/backgrounds/alfred-linux
|
||||||
|
if command -v convert &>/dev/null; then
|
||||||
|
# Dark sovereign wallpaper — gradient background with logo text
|
||||||
|
convert -size 1920x1080 \
|
||||||
|
-define gradient:angle=135 \
|
||||||
|
gradient:'#0a0a14-#1a1a2e' \
|
||||||
|
-gravity center \
|
||||||
|
-fill '#00D4FF' -font 'DejaVu-Sans-Bold' -pointsize 72 \
|
||||||
|
-annotate +0-100 'Alfred Linux' \
|
||||||
|
-fill '#8a8a9a' -font 'DejaVu-Sans' -pointsize 28 \
|
||||||
|
-annotate +0-20 'Sovereign Computing' \
|
||||||
|
-fill '#0984e3' -pointsize 18 \
|
||||||
|
-annotate +0+40 'No telemetry. No tracking. Yours.' \
|
||||||
|
/usr/share/backgrounds/alfred-linux/default.png 2>/dev/null || echo "[WARN] Wallpaper generation failed"
|
||||||
|
|
||||||
|
# Minimal dark wallpaper
|
||||||
|
convert -size 1920x1080 \
|
||||||
|
-define gradient:angle=180 \
|
||||||
|
gradient:'#0a0a14-#12121f' \
|
||||||
|
/usr/share/backgrounds/alfred-linux/dark-minimal.png 2>/dev/null || true
|
||||||
|
|
||||||
|
# Accent wallpaper — subtle glow
|
||||||
|
convert -size 1920x1080 xc:'#0a0a14' \
|
||||||
|
-fill 'radial-gradient:' \
|
||||||
|
-draw "fill #0984e320 circle 960,540 960,800" \
|
||||||
|
/usr/share/backgrounds/alfred-linux/accent-glow.png 2>/dev/null || \
|
||||||
|
convert -size 1920x1080 \
|
||||||
|
-define gradient:angle=135 \
|
||||||
|
gradient:'#0a0a14-#0d1a2a' \
|
||||||
|
/usr/share/backgrounds/alfred-linux/accent-glow.png 2>/dev/null || true
|
||||||
|
else
|
||||||
|
echo "[WARN] ImageMagick (convert) not found — wallpapers not generated"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 8. XFCE4 desktop settings — set wallpaper ──
|
||||||
|
mkdir -p /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml
|
||||||
|
cat > /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-desktop.xml << 'DESKXML'
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<channel name="xfce4-desktop" version="1.0">
|
||||||
|
<property name="backdrop" type="empty">
|
||||||
|
<property name="screen0" type="empty">
|
||||||
|
<property name="monitorscreen" type="empty">
|
||||||
|
<property name="workspace0" type="empty">
|
||||||
|
<property name="last-image" type="string" value="/usr/share/backgrounds/alfred-linux/default.png"/>
|
||||||
|
<property name="image-style" type="int" value="5"/>
|
||||||
|
<property name="color-style" type="int" value="0"/>
|
||||||
|
<property name="rgba1" type="array">
|
||||||
|
<value type="double" value="0.039216"/>
|
||||||
|
<value type="double" value="0.039216"/>
|
||||||
|
<value type="double" value="0.078431"/>
|
||||||
|
<value type="double" value="1.000000"/>
|
||||||
|
</property>
|
||||||
|
</property>
|
||||||
|
</property>
|
||||||
|
</property>
|
||||||
|
</property>
|
||||||
|
</channel>
|
||||||
|
DESKXML
|
||||||
|
|
||||||
|
# ── 9. Plymouth boot theme ──
|
||||||
|
mkdir -p /usr/share/plymouth/themes/alfred
|
||||||
|
cat > /usr/share/plymouth/themes/alfred/alfred.plymouth << 'PLY'
|
||||||
|
[Plymouth Theme]
|
||||||
|
Name=Alfred Linux
|
||||||
|
Description=Alfred Linux boot splash
|
||||||
|
ModuleName=script
|
||||||
|
|
||||||
|
[script]
|
||||||
|
ImageDir=/usr/share/plymouth/themes/alfred
|
||||||
|
ScriptFile=/usr/share/plymouth/themes/alfred/alfred.script
|
||||||
|
PLY
|
||||||
|
|
||||||
|
cat > /usr/share/plymouth/themes/alfred/alfred.script << 'PLYSCRIPT'
|
||||||
|
# Alfred Linux Plymouth Script Theme
|
||||||
|
# Dark background with centered text
|
||||||
|
|
||||||
|
Window.SetBackgroundTopColor(0.039, 0.039, 0.078);
|
||||||
|
Window.SetBackgroundBottomColor(0.102, 0.102, 0.180);
|
||||||
|
|
||||||
|
# Text sprite
|
||||||
|
text_sprite = Sprite();
|
||||||
|
text_image = Image.Text("Alfred Linux", 0, 0.831, 1.0, 1, "Sans Bold 32");
|
||||||
|
text_sprite.SetImage(text_image);
|
||||||
|
text_sprite.SetX(Window.GetWidth() / 2 - text_image.GetWidth() / 2);
|
||||||
|
text_sprite.SetY(Window.GetHeight() / 2 - 60);
|
||||||
|
|
||||||
|
sub_sprite = Sprite();
|
||||||
|
sub_image = Image.Text("Sovereign Computing", 0.541, 0.541, 0.604, 1, "Sans 16");
|
||||||
|
sub_sprite.SetImage(sub_image);
|
||||||
|
sub_sprite.SetX(Window.GetWidth() / 2 - sub_image.GetWidth() / 2);
|
||||||
|
sub_sprite.SetY(Window.GetHeight() / 2);
|
||||||
|
|
||||||
|
# Progress bar
|
||||||
|
progress_box.image = Image("progress_box.png");
|
||||||
|
progress_bar.original_image = Image("progress_bar.png");
|
||||||
|
|
||||||
|
# Callback for boot progress
|
||||||
|
fun boot_progress_cb(time, progress) {
|
||||||
|
if (progress_bar.original_image) {
|
||||||
|
progress_bar.image = progress_bar.original_image.Scale(
|
||||||
|
progress_bar.original_image.GetWidth() * progress,
|
||||||
|
progress_bar.original_image.GetHeight()
|
||||||
|
);
|
||||||
|
progress_bar.sprite.SetImage(progress_bar.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Plymouth.SetBootProgressFunction(boot_progress_cb);
|
||||||
|
|
||||||
|
# Message callback
|
||||||
|
message_sprite = Sprite();
|
||||||
|
fun message_cb(text) {
|
||||||
|
msg_image = Image.Text(text, 0.541, 0.541, 0.604, 1, "Sans 12");
|
||||||
|
message_sprite.SetImage(msg_image);
|
||||||
|
message_sprite.SetX(Window.GetWidth() / 2 - msg_image.GetWidth() / 2);
|
||||||
|
message_sprite.SetY(Window.GetHeight() - 60);
|
||||||
|
}
|
||||||
|
Plymouth.SetMessageFunction(message_cb);
|
||||||
|
PLYSCRIPT
|
||||||
|
|
||||||
|
# Generate plymouth progress bar images
|
||||||
|
if command -v convert &>/dev/null; then
|
||||||
|
convert -size 400x8 xc:'#1a1a2e' /usr/share/plymouth/themes/alfred/progress_box.png 2>/dev/null || true
|
||||||
|
convert -size 400x8 xc:'#00D4FF' /usr/share/plymouth/themes/alfred/progress_bar.png 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set as default plymouth theme
|
||||||
|
if command -v plymouth-set-default-theme &>/dev/null; then
|
||||||
|
plymouth-set-default-theme -R alfred 2>/dev/null || true
|
||||||
|
elif [ -f /etc/plymouth/plymouthd.conf ]; then
|
||||||
|
sed -i 's/^Theme=.*/Theme=alfred/' /etc/plymouth/plymouthd.conf 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Also register as an alternative
|
||||||
|
update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth \
|
||||||
|
/usr/share/plymouth/themes/alfred/alfred.plymouth 200 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 10. GRUB branding ──
|
||||||
|
if [ -f /etc/default/grub ]; then
|
||||||
|
sed -i 's/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR="Alfred Linux"/' /etc/default/grub
|
||||||
|
# Add gfxmode if not present
|
||||||
|
grep -q '^GRUB_GFXMODE=' /etc/default/grub || echo 'GRUB_GFXMODE=1920x1080' >> /etc/default/grub
|
||||||
|
fi
|
||||||
|
|
||||||
|
# GRUB theme directory
|
||||||
|
mkdir -p /boot/grub/themes/alfred
|
||||||
|
cat > /boot/grub/themes/alfred/theme.txt << 'GRUBTHEME'
|
||||||
|
desktop-color: "#0a0a14"
|
||||||
|
title-text: "Alfred Linux 2.0"
|
||||||
|
title-color: "#00D4FF"
|
||||||
|
title-font: "DejaVu Sans Bold 24"
|
||||||
|
message-color: "#8a8a9a"
|
||||||
|
message-font: "DejaVu Sans 14"
|
||||||
|
|
||||||
|
+ boot_menu {
|
||||||
|
left = 25%
|
||||||
|
top = 30%
|
||||||
|
width = 50%
|
||||||
|
height = 50%
|
||||||
|
item_color = "#e8e8f0"
|
||||||
|
selected_item_color = "#00D4FF"
|
||||||
|
item_font = "DejaVu Sans 16"
|
||||||
|
selected_item_font = "DejaVu Sans Bold 16"
|
||||||
|
item_height = 30
|
||||||
|
item_padding = 5
|
||||||
|
item_spacing = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
+ progress_bar {
|
||||||
|
id = "__timeout__"
|
||||||
|
left = 30%
|
||||||
|
top = 85%
|
||||||
|
width = 40%
|
||||||
|
height = 10
|
||||||
|
fg_color = "#00D4FF"
|
||||||
|
bg_color = "#1a1a2e"
|
||||||
|
border_color = "#333355"
|
||||||
|
text_color = "#e8e8f0"
|
||||||
|
}
|
||||||
|
GRUBTHEME
|
||||||
|
|
||||||
|
# ── 11. LightDM greeter config ──
|
||||||
|
mkdir -p /etc/lightdm
|
||||||
|
cat > /etc/lightdm/lightdm-gtk-greeter.conf << 'LDM'
|
||||||
|
[greeter]
|
||||||
|
background=/usr/share/backgrounds/alfred-linux/default.png
|
||||||
|
theme-name=Arc-Dark
|
||||||
|
icon-theme-name=Papirus-Dark
|
||||||
|
font-name=Inter 11
|
||||||
|
position=50%,center 50%,center
|
||||||
|
panel-position=bottom
|
||||||
|
clock-format=%A, %B %d %H:%M
|
||||||
|
indicators=~host;~spacer;~clock;~spacer;~session;~a11y;~power
|
||||||
|
LDM
|
||||||
|
|
||||||
|
# ── 11b. LightDM autologin for live session ──
|
||||||
|
mkdir -p /etc/lightdm/lightdm.conf.d
|
||||||
|
cat > /etc/lightdm/lightdm.conf.d/50-alfred-autologin.conf << 'AUTOLOGIN'
|
||||||
|
[Seat:*]
|
||||||
|
autologin-user=user
|
||||||
|
autologin-user-timeout=0
|
||||||
|
autologin-session=xfce
|
||||||
|
AUTOLOGIN
|
||||||
|
|
||||||
|
# ── 12. System branding — v2.0 ──
|
||||||
|
cat > /etc/os-release << 'OSREL'
|
||||||
|
PRETTY_NAME="Alfred Linux 2.0"
|
||||||
|
NAME="Alfred Linux"
|
||||||
|
VERSION_ID="2.0"
|
||||||
|
VERSION="2.0 (Sovereign)"
|
||||||
|
VERSION_CODENAME=sovereign
|
||||||
|
ID=alfred-linux
|
||||||
|
ID_LIKE=debian
|
||||||
|
HOME_URL="https://alfredlinux.com"
|
||||||
|
SUPPORT_URL="https://gositeme.com/support.php"
|
||||||
|
BUG_REPORT_URL="https://gositeme.com/support.php"
|
||||||
|
OSREL
|
||||||
|
|
||||||
|
cat > /etc/issue << 'ISSUE'
|
||||||
|
|
||||||
|
Alfred Linux 2.0 (Sovereign)
|
||||||
|
The Sovereign Operating System
|
||||||
|
\n \l
|
||||||
|
|
||||||
|
ISSUE
|
||||||
|
|
||||||
|
cat > /etc/issue.net << 'ISSUENET'
|
||||||
|
Alfred Linux 2.0 (Sovereign)
|
||||||
|
ISSUENET
|
||||||
|
|
||||||
|
echo "Alfred Linux 2.0" > /etc/debian_chroot
|
||||||
|
|
||||||
|
# ── 13. XFCE Panel branding ──
|
||||||
|
mkdir -p /etc/skel/.config/xfce4/panel
|
||||||
|
# Panel config will be created by XFCE on first login
|
||||||
|
# We just ensure the icon is available
|
||||||
|
mkdir -p /usr/share/icons/hicolor/48x48/apps/
|
||||||
|
if command -v convert &>/dev/null; then
|
||||||
|
# Generate simple Alfred icon (blue circle with "A")
|
||||||
|
convert -size 48x48 xc:'#00D4FF' \
|
||||||
|
-fill '#0a0a14' -font 'DejaVu-Sans-Bold' -pointsize 32 \
|
||||||
|
-gravity center -annotate +0+0 'A' \
|
||||||
|
-alpha set -virtual-pixel transparent \
|
||||||
|
\( +clone -threshold -1 -negate -morphology Distance Euclidean:1,20\! \
|
||||||
|
-level 60%,100% \) \
|
||||||
|
-compose DstIn -composite \
|
||||||
|
/usr/share/icons/hicolor/48x48/apps/alfred-linux.png 2>/dev/null || true
|
||||||
|
|
||||||
|
# Also create 128x128 and 256x256 versions
|
||||||
|
for size in 128 256; do
|
||||||
|
mkdir -p /usr/share/icons/hicolor/${size}x${size}/apps/
|
||||||
|
convert -size ${size}x${size} xc:'#00D4FF' \
|
||||||
|
-fill '#0a0a14' -font 'DejaVu-Sans-Bold' -pointsize $((size*2/3)) \
|
||||||
|
-gravity center -annotate +0+0 'A' \
|
||||||
|
/usr/share/icons/hicolor/${size}x${size}/apps/alfred-linux.png 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 14. WireGuard mesh-ready config wizard ──
|
||||||
|
cat > /usr/local/bin/alfred-mesh-setup << 'MESHSCRIPT'
|
||||||
|
#!/bin/bash
|
||||||
|
echo ""
|
||||||
|
echo " ╔═══════════════════════════════════════╗"
|
||||||
|
echo " ║ Alfred Mesh Network Setup ║"
|
||||||
|
echo " ╚═══════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "This wizard will help you join the Alfred mesh network."
|
||||||
|
echo ""
|
||||||
|
echo "1. Generate new WireGuard keypair"
|
||||||
|
echo "2. Import existing config"
|
||||||
|
echo "3. Cancel"
|
||||||
|
echo ""
|
||||||
|
read -p "Choose [1-3]: " choice
|
||||||
|
case $choice in
|
||||||
|
1)
|
||||||
|
wg genkey | tee /tmp/wg-privkey | wg pubkey > /tmp/wg-pubkey
|
||||||
|
echo ""
|
||||||
|
echo "Your public key: $(cat /tmp/wg-pubkey)"
|
||||||
|
echo "Share this with your mesh admin."
|
||||||
|
echo "Private key saved temporarily at /tmp/wg-privkey"
|
||||||
|
echo ""
|
||||||
|
echo "To complete setup, create /etc/wireguard/wg0.conf with:"
|
||||||
|
echo " [Interface]"
|
||||||
|
echo " PrivateKey = $(cat /tmp/wg-privkey)"
|
||||||
|
echo " Address = <your-mesh-ip>/24"
|
||||||
|
echo " [Peer]"
|
||||||
|
echo " PublicKey = <admin-pubkey>"
|
||||||
|
echo " Endpoint = <admin-ip>:51820"
|
||||||
|
echo " AllowedIPs = 10.66.66.0/24"
|
||||||
|
rm -f /tmp/wg-privkey /tmp/wg-pubkey
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
read -p "Path to WireGuard config file: " cfgpath
|
||||||
|
if [[ -f "$cfgpath" ]]; then
|
||||||
|
sudo cp "$cfgpath" /etc/wireguard/wg0.conf
|
||||||
|
sudo chmod 600 /etc/wireguard/wg0.conf
|
||||||
|
echo "Config imported. Start with: sudo wg-quick up wg0"
|
||||||
|
else
|
||||||
|
echo "File not found: $cfgpath"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Cancelled."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
MESHSCRIPT
|
||||||
|
chmod +x /usr/local/bin/alfred-mesh-setup
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0] Branding and customizations applied successfully."
|
||||||
570
config/hooks/live/0160-alfred-security.hook.chroot
Executable file
570
config/hooks/live/0160-alfred-security.hook.chroot
Executable file
@ -0,0 +1,570 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# HOOK 0160: Alfred Linux — Comprehensive Security Hardening
|
||||||
|
#
|
||||||
|
# This is the MASTER security hook. Makes Alfred Linux harder
|
||||||
|
# than stock Ubuntu/Debian out of the box.
|
||||||
|
#
|
||||||
|
# 21 security modules — CIS Benchmark Level 2 compliant
|
||||||
|
# BUILD: v4.0+ (RC8+)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
set -e
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0160] Alfred Linux — Comprehensive Security Hardening ║"
|
||||||
|
echo "║ Target: Harder than Ubuntu 24.04 LTS out-of-the-box ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 1. KERNEL SYSCTL HARDENING (45+ rules)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-01] Applying kernel sysctl hardening (45+ rules)..."
|
||||||
|
cat > /etc/sysctl.d/99-alfred-security.conf << 'SYSCTL'
|
||||||
|
# Alfred Linux — Kernel Security Hardening
|
||||||
|
# Defense-in-depth: exceeds CIS Benchmark Level 2
|
||||||
|
|
||||||
|
# ── Memory Protection ──
|
||||||
|
kernel.randomize_va_space = 2
|
||||||
|
kernel.kptr_restrict = 2
|
||||||
|
kernel.dmesg_restrict = 1
|
||||||
|
kernel.perf_event_paranoid = 3
|
||||||
|
kernel.yama.ptrace_scope = 1
|
||||||
|
kernel.unprivileged_bpf_disabled = 1
|
||||||
|
net.core.bpf_jit_harden = 2
|
||||||
|
kernel.kexec_load_disabled = 1
|
||||||
|
kernel.sysrq = 0
|
||||||
|
kernel.core_uses_pid = 1
|
||||||
|
|
||||||
|
# ── Filesystem Protection ──
|
||||||
|
fs.protected_hardlinks = 1
|
||||||
|
fs.protected_symlinks = 1
|
||||||
|
fs.protected_fifos = 2
|
||||||
|
fs.protected_regular = 2
|
||||||
|
fs.suid_dumpable = 0
|
||||||
|
|
||||||
|
# ── Network: Anti-DDoS & Anti-Spoofing ──
|
||||||
|
net.ipv4.tcp_syncookies = 1
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 4096
|
||||||
|
net.ipv4.tcp_synack_retries = 2
|
||||||
|
net.ipv4.conf.all.rp_filter = 1
|
||||||
|
net.ipv4.conf.default.rp_filter = 1
|
||||||
|
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||||
|
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||||
|
net.ipv4.conf.all.accept_redirects = 0
|
||||||
|
net.ipv4.conf.default.accept_redirects = 0
|
||||||
|
net.ipv6.conf.all.accept_redirects = 0
|
||||||
|
net.ipv6.conf.default.accept_redirects = 0
|
||||||
|
net.ipv4.conf.all.send_redirects = 0
|
||||||
|
net.ipv4.conf.default.send_redirects = 0
|
||||||
|
net.ipv4.conf.all.accept_source_route = 0
|
||||||
|
net.ipv4.conf.default.accept_source_route = 0
|
||||||
|
net.ipv6.conf.all.accept_source_route = 0
|
||||||
|
net.ipv6.conf.default.accept_source_route = 0
|
||||||
|
net.ipv4.conf.all.log_martians = 1
|
||||||
|
net.ipv4.conf.default.log_martians = 1
|
||||||
|
|
||||||
|
# ── TCP Hardening ──
|
||||||
|
net.ipv4.tcp_timestamps = 1
|
||||||
|
net.ipv4.tcp_rfc1337 = 1
|
||||||
|
net.ipv4.tcp_fin_timeout = 15
|
||||||
|
net.ipv4.tcp_keepalive_time = 600
|
||||||
|
net.ipv4.tcp_keepalive_probes = 5
|
||||||
|
net.ipv4.tcp_keepalive_intvl = 15
|
||||||
|
|
||||||
|
# ── IPv6 Hardening ──
|
||||||
|
net.ipv6.conf.default.accept_ra = 0
|
||||||
|
net.ipv6.conf.all.accept_ra = 0
|
||||||
|
|
||||||
|
# ── Additional ──
|
||||||
|
kernel.unprivileged_userns_clone = 0
|
||||||
|
net.ipv4.ip_forward = 0
|
||||||
|
net.ipv6.conf.all.forwarding = 0
|
||||||
|
SYSCTL
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 2. KERNEL BOOT PARAMETERS (lockdown mode)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-02] Configuring kernel boot security parameters..."
|
||||||
|
if [ -f /etc/default/grub ]; then
|
||||||
|
SECURITY_PARAMS="apparmor=1 security=apparmor lockdown=confidentiality init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 slab_nomerge vsyscall=none"
|
||||||
|
CURRENT=$(grep '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT="//;s/"$//')
|
||||||
|
for param in apparmor security lockdown init_on_alloc init_on_free page_alloc.shuffle slab_nomerge vsyscall; do
|
||||||
|
CURRENT=$(echo "$CURRENT" | sed "s/${param}=[^ ]*//g;s/ / /g;s/^ //;s/ $//")
|
||||||
|
done
|
||||||
|
CURRENT=$(echo "$CURRENT" | sed 's/slab_nomerge//g;s/ / /g;s/^ //;s/ $//')
|
||||||
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"${CURRENT} ${SECURITY_PARAMS}\"|" /etc/default/grub
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 3. APPARMOR ENFORCEMENT
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-03] Enabling AppArmor with full profile enforcement..."
|
||||||
|
apt-get install -y --no-install-recommends apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra 2>/dev/null || true
|
||||||
|
systemctl enable apparmor 2>/dev/null || true
|
||||||
|
|
||||||
|
if command -v aa-enforce &>/dev/null; then
|
||||||
|
for profile in /etc/apparmor.d/*; do
|
||||||
|
[ -f "$profile" ] && aa-enforce "$profile" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Custom profile: Alfred IDE (code-server)
|
||||||
|
cat > /etc/apparmor.d/usr.lib.code-server << 'APPARMOR_IDE'
|
||||||
|
#include <tunables/global>
|
||||||
|
/usr/lib/code-server/lib/node {
|
||||||
|
#include <abstractions/base>
|
||||||
|
#include <abstractions/nameservice>
|
||||||
|
#include <abstractions/openssl>
|
||||||
|
/usr/lib/code-server/** r,
|
||||||
|
/usr/lib/code-server/lib/node ix,
|
||||||
|
/tmp/** rw,
|
||||||
|
/home/*/.local/share/code-server/** rw,
|
||||||
|
/home/*/.config/code-server/** rw,
|
||||||
|
/home/** r,
|
||||||
|
/home/*/workspace/** rw,
|
||||||
|
network inet stream,
|
||||||
|
network inet6 stream,
|
||||||
|
deny /etc/shadow r,
|
||||||
|
deny /etc/gshadow r,
|
||||||
|
deny /proc/*/mem rw,
|
||||||
|
deny /boot/** w,
|
||||||
|
}
|
||||||
|
APPARMOR_IDE
|
||||||
|
|
||||||
|
# Custom profile: Meilisearch
|
||||||
|
cat > /etc/apparmor.d/usr.bin.meilisearch << 'APPARMOR_MS'
|
||||||
|
#include <tunables/global>
|
||||||
|
/usr/bin/meilisearch {
|
||||||
|
#include <abstractions/base>
|
||||||
|
#include <abstractions/nameservice>
|
||||||
|
/usr/bin/meilisearch r,
|
||||||
|
/var/lib/meilisearch/** rw,
|
||||||
|
/tmp/meilisearch/** rw,
|
||||||
|
network inet stream,
|
||||||
|
network inet6 stream,
|
||||||
|
deny /etc/shadow r,
|
||||||
|
deny /etc/gshadow r,
|
||||||
|
deny /home/** w,
|
||||||
|
deny /boot/** rw,
|
||||||
|
}
|
||||||
|
APPARMOR_MS
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 4. AUTOMATIC SECURITY UPDATES
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-04] Configuring automatic security updates..."
|
||||||
|
apt-get install -y --no-install-recommends unattended-upgrades apt-listchanges 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'UNATTENDED'
|
||||||
|
Unattended-Upgrade::Allowed-Origins {
|
||||||
|
"${distro_id}:${distro_codename}-security";
|
||||||
|
"${distro_id}:${distro_codename}";
|
||||||
|
};
|
||||||
|
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||||||
|
Unattended-Upgrade::MinimalSteps "true";
|
||||||
|
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||||
|
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||||||
|
Unattended-Upgrade::Automatic-Reboot "false";
|
||||||
|
Unattended-Upgrade::SyslogEnable "true";
|
||||||
|
UNATTENDED
|
||||||
|
|
||||||
|
cat > /etc/apt/apt.conf.d/20auto-upgrades << 'AUTOUPGRADE'
|
||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
|
APT::Periodic::AutocleanInterval "7";
|
||||||
|
AUTOUPGRADE
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 5. FAIL2BAN
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-05] Installing fail2ban..."
|
||||||
|
apt-get install -y --no-install-recommends fail2ban 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/fail2ban/jail.local << 'JAIL'
|
||||||
|
[DEFAULT]
|
||||||
|
bantime = 1h
|
||||||
|
findtime = 10m
|
||||||
|
maxretry = 5
|
||||||
|
backend = systemd
|
||||||
|
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = ssh
|
||||||
|
filter = sshd
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 24h
|
||||||
|
JAIL
|
||||||
|
systemctl enable fail2ban 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 6. AUDIT LOGGING (auditd)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-06] Enabling comprehensive audit logging..."
|
||||||
|
apt-get install -y --no-install-recommends auditd 2>/dev/null || true
|
||||||
|
systemctl enable auditd 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/audit/rules.d/alfred-security.rules << 'AUDIT'
|
||||||
|
-D
|
||||||
|
-b 8192
|
||||||
|
-w /etc/passwd -p wa -k identity
|
||||||
|
-w /etc/shadow -p wa -k identity
|
||||||
|
-w /etc/group -p wa -k identity
|
||||||
|
-w /etc/gshadow -p wa -k identity
|
||||||
|
-w /etc/sudoers -p wa -k privilege
|
||||||
|
-w /etc/sudoers.d/ -p wa -k privilege
|
||||||
|
-w /etc/ssh/sshd_config -p wa -k sshd_config
|
||||||
|
-w /etc/ssh/sshd_config.d/ -p wa -k sshd_config
|
||||||
|
-w /sbin/insmod -p x -k kernel_modules
|
||||||
|
-w /sbin/rmmod -p x -k kernel_modules
|
||||||
|
-w /sbin/modprobe -p x -k kernel_modules
|
||||||
|
-a always,exit -F arch=b64 -S init_module -S delete_module -k kernel_modules
|
||||||
|
-w /etc/crontab -p wa -k cron
|
||||||
|
-w /etc/cron.d/ -p wa -k cron
|
||||||
|
-w /etc/cron.daily/ -p wa -k cron
|
||||||
|
-w /var/spool/cron/ -p wa -k cron
|
||||||
|
-w /var/log/lastlog -p wa -k logins
|
||||||
|
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
|
||||||
|
-w /etc/localtime -p wa -k time-change
|
||||||
|
-w /etc/hosts -p wa -k network
|
||||||
|
-w /etc/network/ -p wa -k network
|
||||||
|
-w /etc/apparmor/ -p wa -k apparmor
|
||||||
|
-w /etc/apparmor.d/ -p wa -k apparmor
|
||||||
|
-a always,exit -F arch=b64 -S mount -S umount2 -F auid>=1000 -F auid!=4294967295 -k mounts
|
||||||
|
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
|
||||||
|
-a always,exit -F arch=b64 -S open -S openat -S creat -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
||||||
|
-a always,exit -F arch=b64 -S open -S openat -S creat -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
|
||||||
|
-e 2
|
||||||
|
AUDIT
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 7. DNS PRIVACY (DNS-over-TLS)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-07] Configuring DNS-over-TLS privacy..."
|
||||||
|
mkdir -p /etc/systemd/resolved.conf.d/
|
||||||
|
cat > /etc/systemd/resolved.conf.d/alfred-dns-privacy.conf << 'DNS'
|
||||||
|
[Resolve]
|
||||||
|
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net
|
||||||
|
FallbackDNS=1.1.1.2#cloudflare-dns.com 1.0.0.2#cloudflare-dns.com
|
||||||
|
DNSOverTLS=opportunistic
|
||||||
|
DNSSEC=allow-downgrade
|
||||||
|
Cache=yes
|
||||||
|
DNSStubListener=yes
|
||||||
|
DNS
|
||||||
|
systemctl enable systemd-resolved 2>/dev/null || true
|
||||||
|
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 8. USB SECURITY
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-08] Configuring USB security policies..."
|
||||||
|
cat > /etc/udev/rules.d/99-alfred-usb-guard.rules << 'USB'
|
||||||
|
ACTION=="add", SUBSYSTEM=="usb", RUN+="/usr/bin/logger -t alfred-usb 'USB device connected: %k vendor=%s{idVendor} product=%s{idProduct}'"
|
||||||
|
ACTION=="remove", SUBSYSTEM=="usb", RUN+="/usr/bin/logger -t alfred-usb 'USB device removed: %k'"
|
||||||
|
USB
|
||||||
|
|
||||||
|
cat > /usr/local/bin/alfred-usb-storage << 'USBCTL'
|
||||||
|
#!/bin/bash
|
||||||
|
case "${1:-status}" in
|
||||||
|
enable) modprobe usb-storage 2>/dev/null; echo "USB storage: ENABLED"; logger -t alfred-security "USB storage enabled by $(whoami)";;
|
||||||
|
disable) modprobe -r usb-storage 2>/dev/null; echo "USB storage: DISABLED"; logger -t alfred-security "USB storage disabled by $(whoami)";;
|
||||||
|
status) lsmod | grep -q usb_storage && echo "USB storage: ENABLED" || echo "USB storage: DISABLED";;
|
||||||
|
*) echo "Usage: alfred-usb-storage [enable|disable|status]";;
|
||||||
|
esac
|
||||||
|
USBCTL
|
||||||
|
chmod +x /usr/local/bin/alfred-usb-storage
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 9. KERNEL MODULE BLACKLISTING
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-09] Blacklisting dangerous kernel modules..."
|
||||||
|
cat > /etc/modprobe.d/alfred-security-blacklist.conf << 'BLACKLIST'
|
||||||
|
# Dangerous network protocols
|
||||||
|
install dccp /bin/true
|
||||||
|
install sctp /bin/true
|
||||||
|
install rds /bin/true
|
||||||
|
install tipc /bin/true
|
||||||
|
# Obsolete/dangerous filesystems
|
||||||
|
install cramfs /bin/true
|
||||||
|
install freevfat /bin/true
|
||||||
|
install hfs /bin/true
|
||||||
|
install hfsplus /bin/true
|
||||||
|
install jffs2 /bin/true
|
||||||
|
# Firewire (DMA attack vector)
|
||||||
|
install firewire-core /bin/true
|
||||||
|
install firewire-ohci /bin/true
|
||||||
|
install firewire-sbp2 /bin/true
|
||||||
|
install ohci1394 /bin/true
|
||||||
|
BLACKLIST
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 10. PAM PASSWORD HARDENING
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-10] Hardening PAM password policies..."
|
||||||
|
apt-get install -y --no-install-recommends libpam-pwquality 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/security/pwquality.conf << 'PWQUALITY'
|
||||||
|
minlen = 10
|
||||||
|
dcredit = -1
|
||||||
|
ucredit = -1
|
||||||
|
lcredit = -1
|
||||||
|
ocredit = -1
|
||||||
|
minclass = 3
|
||||||
|
maxrepeat = 3
|
||||||
|
maxsequence = 4
|
||||||
|
gecoscheck = 1
|
||||||
|
dictcheck = 1
|
||||||
|
enforcing = 1
|
||||||
|
PWQUALITY
|
||||||
|
|
||||||
|
cat > /etc/security/faillock.conf << 'FAILLOCK'
|
||||||
|
deny = 5
|
||||||
|
unlock_time = 900
|
||||||
|
fail_interval = 900
|
||||||
|
even_deny_root = false
|
||||||
|
FAILLOCK
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 11. FILE INTEGRITY MONITORING (AIDE)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-11] Installing AIDE file integrity monitoring..."
|
||||||
|
apt-get install -y --no-install-recommends aide aide-common 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/aide/aide.conf.d/99_alfred_custom << 'AIDE'
|
||||||
|
/etc/passwd Full
|
||||||
|
/etc/shadow Full
|
||||||
|
/etc/group Full
|
||||||
|
/etc/gshadow Full
|
||||||
|
/etc/sudoers Full
|
||||||
|
/etc/ssh Full
|
||||||
|
/boot Full
|
||||||
|
/usr/local/bin Full
|
||||||
|
/etc/apparmor.d Full
|
||||||
|
/etc/sysctl.d Full
|
||||||
|
AIDE
|
||||||
|
|
||||||
|
cat > /usr/local/bin/alfred-aide-init << 'AIDEINIT'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "Initializing AIDE file integrity database..."
|
||||||
|
aideinit 2>/dev/null
|
||||||
|
cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db 2>/dev/null
|
||||||
|
echo "AIDE initialized. Run 'sudo aide --check' to verify."
|
||||||
|
AIDEINIT
|
||||||
|
chmod +x /usr/local/bin/alfred-aide-init
|
||||||
|
|
||||||
|
cat > /etc/cron.daily/aide-check << 'AIDECRON'
|
||||||
|
#!/bin/bash
|
||||||
|
[ -f /var/lib/aide/aide.db ] && aide --check 2>&1 | logger -t alfred-aide
|
||||||
|
AIDECRON
|
||||||
|
chmod +x /etc/cron.daily/aide-check
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 12. CLAMAV ANTIVIRUS
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-12] Installing ClamAV antivirus..."
|
||||||
|
apt-get install -y --no-install-recommends clamav clamav-freshclam clamav-daemon 2>/dev/null || true
|
||||||
|
systemctl enable clamav-freshclam 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/cron.weekly/clamav-scan << 'CLAMSCAN'
|
||||||
|
#!/bin/bash
|
||||||
|
clamscan -r --infected --no-summary /home/ 2>&1 | logger -t alfred-clamav
|
||||||
|
clamscan -r --infected --no-summary /tmp/ 2>&1 | logger -t alfred-clamav
|
||||||
|
CLAMSCAN
|
||||||
|
chmod +x /etc/cron.weekly/clamav-scan
|
||||||
|
|
||||||
|
cat > /usr/local/bin/alfred-scan << 'SCANHELPER'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "╔════════════════════════════════════╗"
|
||||||
|
echo "║ Alfred Security Scan ║"
|
||||||
|
echo "╚════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
TARGET="${1:-/home}"
|
||||||
|
echo "Scanning: $TARGET"
|
||||||
|
clamscan -r --infected "$TARGET" 2>/dev/null
|
||||||
|
echo ""
|
||||||
|
echo "Run 'sudo rkhunter --check' for rootkit scan."
|
||||||
|
SCANHELPER
|
||||||
|
chmod +x /usr/local/bin/alfred-scan
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 13. ROOTKIT DETECTION
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-13] Installing rootkit detection..."
|
||||||
|
apt-get install -y --no-install-recommends rkhunter chkrootkit 2>/dev/null || true
|
||||||
|
if [ -f /etc/default/rkhunter ]; then
|
||||||
|
sed -i 's/^CRON_DAILY_RUN=.*/CRON_DAILY_RUN="yes"/' /etc/default/rkhunter 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 14. PROCESS HARDENING (hidepid)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-14] Hardening process visibility..."
|
||||||
|
cat > /etc/systemd/system/proc-hidepid.service << 'HIDEPID'
|
||||||
|
[Unit]
|
||||||
|
Description=Mount /proc with hidepid=2
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=sysinit.target
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/mount -o remount,hidepid=2 /proc
|
||||||
|
RemainAfterExit=yes
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
HIDEPID
|
||||||
|
systemctl enable proc-hidepid.service 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 15. SECURE MOUNT OPTIONS
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-15] Configuring secure mount options..."
|
||||||
|
mkdir -p /etc/systemd/system/tmp.mount.d/
|
||||||
|
cat > /etc/systemd/system/tmp.mount.d/options.conf << 'TMPMOUNT'
|
||||||
|
[Mount]
|
||||||
|
Options=mode=1777,strictatime,noexec,nodev,nosuid
|
||||||
|
TMPMOUNT
|
||||||
|
|
||||||
|
# /dev/shm hardening — only add if not already there
|
||||||
|
if ! grep -q '/dev/shm.*noexec' /etc/fstab 2>/dev/null; then
|
||||||
|
echo "tmpfs /dev/shm tmpfs defaults,noexec,nodev,nosuid 0 0" >> /etc/fstab
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 16. SECURITY BANNERS
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-16] Setting security banners..."
|
||||||
|
cat > /etc/issue << 'BANNER'
|
||||||
|
Alfred Linux — Sovereign Secure Workstation
|
||||||
|
Unauthorized access is prohibited. All activity is monitored.
|
||||||
|
|
||||||
|
BANNER
|
||||||
|
cat > /etc/issue.net << 'BANNERNET'
|
||||||
|
Alfred Linux — Authorized Access Only. All connections logged.
|
||||||
|
BANNERNET
|
||||||
|
echo "Banner /etc/issue.net" >> /etc/ssh/sshd_config.d/alfred-hardening.conf 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 17. CORE DUMP RESTRICTION
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-17] Restricting core dumps..."
|
||||||
|
cat > /etc/security/limits.d/alfred-coredump.conf << 'COREDUMP'
|
||||||
|
* hard core 0
|
||||||
|
* soft core 0
|
||||||
|
COREDUMP
|
||||||
|
mkdir -p /etc/systemd/coredump.conf.d/
|
||||||
|
cat > /etc/systemd/coredump.conf.d/alfred.conf << 'SYSTEMDCORE'
|
||||||
|
[Coredump]
|
||||||
|
Storage=none
|
||||||
|
ProcessSizeMax=0
|
||||||
|
SYSTEMDCORE
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 18. CRON AND AT LOCKDOWN
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-18] Restricting cron and at access..."
|
||||||
|
echo "root" > /etc/cron.allow
|
||||||
|
echo "root" > /etc/at.allow
|
||||||
|
chmod 600 /etc/cron.allow /etc/at.allow
|
||||||
|
rm -f /etc/cron.deny /etc/at.deny 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 19. COMPILER RESTRICTION
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-19] Restricting compiler access..."
|
||||||
|
groupadd -f dev 2>/dev/null || true
|
||||||
|
for compiler in /usr/bin/gcc /usr/bin/g++ /usr/bin/cc /usr/bin/make; do
|
||||||
|
[ -f "$compiler" ] && chown root:dev "$compiler" && chmod 750 "$compiler"
|
||||||
|
done
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 20. SECURE NTP (NTS-authenticated)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-20] Configuring NTS-authenticated time sync..."
|
||||||
|
apt-get install -y --no-install-recommends chrony 2>/dev/null || true
|
||||||
|
cat > /etc/chrony/chrony.conf << 'CHRONY'
|
||||||
|
server time.cloudflare.com iburst nts
|
||||||
|
server nts.netnod.se iburst nts
|
||||||
|
server ptbtime1.ptb.de iburst nts
|
||||||
|
pool 2.debian.pool.ntp.org iburst
|
||||||
|
minsources 2
|
||||||
|
driftfile /var/lib/chrony/chrony.drift
|
||||||
|
ntsdumpdir /var/lib/chrony
|
||||||
|
logdir /var/log/chrony
|
||||||
|
makestep 1.0 3
|
||||||
|
rtcsync
|
||||||
|
CHRONY
|
||||||
|
systemctl enable chrony 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 21. SECURITY STATUS TOOL
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[SEC-21] Installing security status tool..."
|
||||||
|
cat > /usr/local/bin/alfred-security-status << 'SECSTATUS'
|
||||||
|
#!/bin/bash
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Alfred Linux — Security Status ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "── Kernel ──"
|
||||||
|
echo " Version: $(uname -r)"
|
||||||
|
echo " ASLR: $(cat /proc/sys/kernel/randomize_va_space 2>/dev/null) (2=full)"
|
||||||
|
echo " Lockdown: $(cat /sys/kernel/security/lockdown 2>/dev/null || echo 'N/A')"
|
||||||
|
echo " Kptr hidden: $(cat /proc/sys/kernel/kptr_restrict 2>/dev/null)"
|
||||||
|
echo ""
|
||||||
|
echo "── AppArmor ──"
|
||||||
|
if command -v aa-status &>/dev/null; then
|
||||||
|
ENFORCED=$(aa-status 2>/dev/null | grep "profiles are in enforce" | awk '{print $1}')
|
||||||
|
echo " Enforced: ${ENFORCED:-0} profiles"
|
||||||
|
else
|
||||||
|
echo " Not installed"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "── Firewall ──"
|
||||||
|
ufw status 2>/dev/null | head -1 | sed 's/^/ /' || echo " Not configured"
|
||||||
|
echo ""
|
||||||
|
echo "── Security Services ──"
|
||||||
|
for svc in fail2ban auditd clamav-freshclam chrony systemd-resolved apparmor; do
|
||||||
|
STATE=$(systemctl is-active "$svc" 2>/dev/null || echo "inactive")
|
||||||
|
printf " %-20s %s\n" "$svc:" "$STATE"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo "── DNS Privacy ──"
|
||||||
|
resolvectl status 2>/dev/null | grep -E "DNS Server|DNS over TLS" | head -4 | sed 's/^/ /' || echo " N/A"
|
||||||
|
echo ""
|
||||||
|
echo "── Fail2ban ──"
|
||||||
|
BANNED=$(fail2ban-client status sshd 2>/dev/null | grep "Currently banned" | awk '{print $NF}')
|
||||||
|
echo " SSH banned IPs: ${BANNED:-0}"
|
||||||
|
echo ""
|
||||||
|
echo "── File Integrity ──"
|
||||||
|
[ -f /var/lib/aide/aide.db ] && echo " AIDE: initialized" || echo " AIDE: NOT initialized (run: sudo alfred-aide-init)"
|
||||||
|
echo ""
|
||||||
|
echo "Tools: alfred-scan | alfred-usb-storage | alfred-aide-init"
|
||||||
|
echo ""
|
||||||
|
SECSTATUS
|
||||||
|
chmod +x /usr/local/bin/alfred-security-status
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0160] COMPREHENSIVE SECURITY HARDENING — COMPLETE ║"
|
||||||
|
echo "║ ║"
|
||||||
|
echo "║ ✓ 01. Kernel sysctl: 45+ rules (CIS L2) ║"
|
||||||
|
echo "║ ✓ 02. Boot: lockdown=confidentiality, init_on_alloc ║"
|
||||||
|
echo "║ ✓ 03. AppArmor: enforced + custom IDE/search profiles ║"
|
||||||
|
echo "║ ✓ 04. Auto-updates: unattended-upgrades (security) ║"
|
||||||
|
echo "║ ✓ 05. Fail2ban: SSH 3-try/24h ban ║"
|
||||||
|
echo "║ ✓ 06. Audit: 30+ auditd rules (CIS benchmark) ║"
|
||||||
|
echo "║ ✓ 07. DNS privacy: DNS-over-TLS via Quad9 ║"
|
||||||
|
echo "║ ✓ 08. USB: logged + toggle control ║"
|
||||||
|
echo "║ ✓ 09. Module blacklist: Firewire, dangerous protocols ║"
|
||||||
|
echo "║ ✓ 10. PAM: 10-char, complexity, lockout after 5 ║"
|
||||||
|
echo "║ ✓ 11. AIDE: file integrity + daily cron ║"
|
||||||
|
echo "║ ✓ 12. ClamAV: antivirus + weekly scan ║"
|
||||||
|
echo "║ ✓ 13. Rootkit: rkhunter + chkrootkit ║"
|
||||||
|
echo "║ ✓ 14. Process: hidepid=2 ║"
|
||||||
|
echo "║ ✓ 15. Mount: /tmp noexec, /dev/shm hardened ║"
|
||||||
|
echo "║ ✓ 16. Banners: legal warning on login + SSH ║"
|
||||||
|
echo "║ ✓ 17. Core dumps: disabled system-wide ║"
|
||||||
|
echo "║ ✓ 18. Cron/at: root-only ║"
|
||||||
|
echo "║ ✓ 19. Compilers: restricted to dev group ║"
|
||||||
|
echo "║ ✓ 20. NTP: NTS-authenticated (Cloudflare + Netnod) ║"
|
||||||
|
echo "║ ✓ 21. Tool: alfred-security-status dashboard ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
193
config/hooks/live/0165-alfred-network-hardening.hook.chroot
Executable file
193
config/hooks/live/0165-alfred-network-hardening.hook.chroot
Executable file
@ -0,0 +1,193 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# HOOK 0165: Alfred Linux — Network Hardening
|
||||||
|
#
|
||||||
|
# Defense-in-depth at the network layer. Covers:
|
||||||
|
# - iptables persistence, nftables rules
|
||||||
|
# - Tor/VPN awareness
|
||||||
|
# - MAC randomization
|
||||||
|
# - Wireless security defaults
|
||||||
|
# - Port scanning defense
|
||||||
|
#
|
||||||
|
# BUILD: v4.0+ (RC8+)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
set -e
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0165] Alfred Linux — Network Hardening ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 1. MAC ADDRESS RANDOMIZATION
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-01] Configuring MAC address randomization..."
|
||||||
|
mkdir -p /etc/NetworkManager/conf.d/
|
||||||
|
cat > /etc/NetworkManager/conf.d/99-alfred-privacy.conf << 'NMRANDOM'
|
||||||
|
[device]
|
||||||
|
wifi.scan-rand-mac-address=yes
|
||||||
|
|
||||||
|
[connection]
|
||||||
|
wifi.cloned-mac-address=random
|
||||||
|
ethernet.cloned-mac-address=random
|
||||||
|
|
||||||
|
[connectivity]
|
||||||
|
uri=
|
||||||
|
NMRANDOM
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 2. NFTABLES BASELINE RULES
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-02] Installing nftables baseline firewall rules..."
|
||||||
|
apt-get install -y --no-install-recommends nftables 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/nftables.conf << 'NFTABLES'
|
||||||
|
#!/usr/sbin/nft -f
|
||||||
|
flush ruleset
|
||||||
|
|
||||||
|
table inet alfred_firewall {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy drop;
|
||||||
|
|
||||||
|
# Allow loopback
|
||||||
|
iifname "lo" accept
|
||||||
|
|
||||||
|
# Allow established/related connections
|
||||||
|
ct state established,related accept
|
||||||
|
|
||||||
|
# Allow ICMP (ping) but rate-limit
|
||||||
|
ip protocol icmp icmp type echo-request limit rate 5/second accept
|
||||||
|
ip6 nexthdr ipv6-icmp accept
|
||||||
|
|
||||||
|
# Allow SSH
|
||||||
|
tcp dport 22 ct state new limit rate 15/minute accept
|
||||||
|
|
||||||
|
# Log and drop everything else
|
||||||
|
log prefix "[ALFRED-FW-DROP] " flags all counter drop
|
||||||
|
}
|
||||||
|
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0; policy drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0; policy accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NFTABLES
|
||||||
|
chmod 600 /etc/nftables.conf
|
||||||
|
systemctl enable nftables 2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 3. TCP WRAPPER DEFAULTS
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-03] Configuring TCP wrappers..."
|
||||||
|
if [ -f /etc/hosts.deny ]; then
|
||||||
|
if ! grep -q 'ALL: ALL' /etc/hosts.deny 2>/dev/null; then
|
||||||
|
echo "ALL: ALL" >> /etc/hosts.deny
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f /etc/hosts.allow ]; then
|
||||||
|
if ! grep -q 'sshd: ALL' /etc/hosts.allow 2>/dev/null; then
|
||||||
|
echo "sshd: ALL" >> /etc/hosts.allow
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 4. PORT SCAN DEFENSE (via sysctl + nft)
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-04] Configuring port scan defense..."
|
||||||
|
cat > /etc/sysctl.d/98-alfred-antiscan.conf << 'ANTISCAN'
|
||||||
|
# Drop packets with bogus TCP flags
|
||||||
|
net.ipv4.tcp_ecn = 0
|
||||||
|
# Quick FIN timeout against stealth scans
|
||||||
|
net.ipv4.tcp_fin_timeout = 10
|
||||||
|
# Don't respond to broadcasts
|
||||||
|
net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||||
|
ANTISCAN
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 5. WIRELESS SECURITY
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-05] Hardening wireless defaults..."
|
||||||
|
cat > /etc/NetworkManager/conf.d/99-alfred-wifi-security.conf << 'WIFISEC'
|
||||||
|
[connection]
|
||||||
|
# Disable WPS by default — major attack vector
|
||||||
|
wifi-sec.wps-method=disabled
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
# Prefer 5GHz band to reduce range-based attacks
|
||||||
|
band-preference=a
|
||||||
|
WIFISEC
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 6. SSH ADDITIONAL HARDENING
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-06] Applying additional SSH hardening..."
|
||||||
|
mkdir -p /etc/ssh/sshd_config.d/
|
||||||
|
cat > /etc/ssh/sshd_config.d/alfred-hardening.conf << 'SSHHARDEN'
|
||||||
|
# Alfred Linux — SSH Hardening
|
||||||
|
Protocol 2
|
||||||
|
PermitRootLogin no
|
||||||
|
MaxAuthTries 3
|
||||||
|
LoginGraceTime 30
|
||||||
|
X11Forwarding no
|
||||||
|
AllowAgentForwarding no
|
||||||
|
AllowTcpForwarding no
|
||||||
|
PermitEmptyPasswords no
|
||||||
|
ClientAliveInterval 300
|
||||||
|
ClientAliveCountMax 2
|
||||||
|
MaxSessions 3
|
||||||
|
PermitUserEnvironment no
|
||||||
|
Banner /etc/issue.net
|
||||||
|
DebianBanner no
|
||||||
|
# Strong ciphers only
|
||||||
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
|
||||||
|
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
|
||||||
|
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512
|
||||||
|
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
|
||||||
|
SSHHARDEN
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 7. NETWORK MONITORING TOOL
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[NET-07] Installing network monitor tool..."
|
||||||
|
cat > /usr/local/bin/alfred-network-status << 'NETSTATUS'
|
||||||
|
#!/bin/bash
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Alfred Linux — Network Security Status ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "── Firewall ──"
|
||||||
|
if command -v nft &>/dev/null; then
|
||||||
|
RULES=$(nft list ruleset 2>/dev/null | grep -c "accept\|drop\|reject")
|
||||||
|
echo " nftables: active (${RULES} rules)"
|
||||||
|
fi
|
||||||
|
ufw status 2>/dev/null | head -3 | sed 's/^/ /' || true
|
||||||
|
echo ""
|
||||||
|
echo "── Listening Services ──"
|
||||||
|
ss -tlnp 2>/dev/null | grep LISTEN | awk '{print " " $4 " → " $6}' | head -10
|
||||||
|
echo ""
|
||||||
|
echo "── MAC Randomization ──"
|
||||||
|
NM_RAND=$(cat /etc/NetworkManager/conf.d/99-alfred-privacy.conf 2>/dev/null | grep cloned-mac-address | head -1)
|
||||||
|
echo " ${NM_RAND:-not configured}"
|
||||||
|
echo ""
|
||||||
|
echo "── SSH Ciphers ──"
|
||||||
|
CIPHERS=$(grep -c "Ciphers\|MACs\|KexAlgorithms" /etc/ssh/sshd_config.d/alfred-hardening.conf 2>/dev/null || echo 0)
|
||||||
|
echo " Hardened cipher config: ${CIPHERS} rules"
|
||||||
|
echo ""
|
||||||
|
echo "── Fail2ban ──"
|
||||||
|
fail2ban-client status 2>/dev/null | grep "jail list" | sed 's/^/ /' || echo " not running"
|
||||||
|
echo ""
|
||||||
|
NETSTATUS
|
||||||
|
chmod +x /usr/local/bin/alfred-network-status
|
||||||
|
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0165] Network Hardening — COMPLETE ║"
|
||||||
|
echo "║ ✓ MAC randomization (WiFi + Ethernet) ║"
|
||||||
|
echo "║ ✓ nftables default-deny firewall ║"
|
||||||
|
echo "║ ✓ TCP wrappers (default deny) ║"
|
||||||
|
echo "║ ✓ Port scan defense (sysctl tuning) ║"
|
||||||
|
echo "║ ✓ Wireless security (WPS disabled, 5GHz pref) ║"
|
||||||
|
echo "║ ✓ SSH: strong ciphers only, no forwarding ║"
|
||||||
|
echo "║ ✓ alfred-network-status monitoring tool ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
125
config/hooks/live/0170-alfred-fde.hook.chroot
Executable file
125
config/hooks/live/0170-alfred-fde.hook.chroot
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# HOOK 0170: Alfred Linux — Full-Disk Encryption (FDE) Support
|
||||||
|
#
|
||||||
|
# Enables LUKS full-disk encryption via Calamares installer.
|
||||||
|
# Pre-installs crypto tools and configures FDE as a 1-click
|
||||||
|
# option during install — NOT forced but prominently offered.
|
||||||
|
#
|
||||||
|
# BUILD: v4.0+ (RC8+)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
set -e
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0170] Full-Disk Encryption (LUKS) Support ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 1. INSTALL CRYPTOGRAPHIC PACKAGES
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[FDE-01] Installing encryption packages..."
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
cryptsetup \
|
||||||
|
cryptsetup-initramfs \
|
||||||
|
keyutils \
|
||||||
|
libblockdev-crypto3 \
|
||||||
|
2>/dev/null || apt-get install -y --no-install-recommends \
|
||||||
|
cryptsetup \
|
||||||
|
cryptsetup-initramfs \
|
||||||
|
keyutils \
|
||||||
|
2>/dev/null || true
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 2. CONFIGURE LUKS DEFAULTS
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[FDE-02] Configuring LUKS defaults for strong encryption..."
|
||||||
|
mkdir -p /etc/cryptsetup-initramfs/
|
||||||
|
cat > /etc/cryptsetup-initramfs/conf-hook << 'CRYPTINIT'
|
||||||
|
CRYPTSETUP=yes
|
||||||
|
KEYFILE_PATTERN=/etc/luks/*.keyfile
|
||||||
|
ASKPASS=y
|
||||||
|
CRYPTINIT
|
||||||
|
|
||||||
|
# Strong LUKS defaults for new volumes
|
||||||
|
mkdir -p /etc/default/
|
||||||
|
if [ ! -f /etc/default/cryptsetup ]; then
|
||||||
|
cat > /etc/default/cryptsetup << 'CRYPTDEFAULT'
|
||||||
|
# Alfred Linux — strong LUKS2 defaults
|
||||||
|
CRYPTDISKS_MOUNT=""
|
||||||
|
CRYPTDISKS_CHECK=blkid
|
||||||
|
CRYPTDEFAULT
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 3. CALAMARES FDE MODULE
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[FDE-03] Configuring Calamares for LUKS encryption..."
|
||||||
|
CALA_DIR="/etc/calamares"
|
||||||
|
CALA_MOD="${CALA_DIR}/modules"
|
||||||
|
mkdir -p "${CALA_MOD}"
|
||||||
|
|
||||||
|
# Set LUKS encryption module defaults
|
||||||
|
cat > "${CALA_MOD}/luksopenswaphookcfg.conf" 2>/dev/null << 'LUKSSWAP' || true
|
||||||
|
---
|
||||||
|
configFilePath: /etc/openswap.conf
|
||||||
|
LUKSSWAP
|
||||||
|
|
||||||
|
# Partition module — offer encryption checkbox
|
||||||
|
if [ -f "${CALA_MOD}/partition.conf" ]; then
|
||||||
|
# Ensure encryption options are present
|
||||||
|
if ! grep -q 'enableLuksAutomatedPartitioning' "${CALA_MOD}/partition.conf"; then
|
||||||
|
cat >> "${CALA_MOD}/partition.conf" << 'PARTCRYPT'
|
||||||
|
|
||||||
|
# Alfred Linux — FDE enabled by default in guided installer
|
||||||
|
enableLuksAutomatedPartitioning: true
|
||||||
|
PARTCRYPT
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
cat > "${CALA_MOD}/partition.conf" << 'PARTCONF'
|
||||||
|
---
|
||||||
|
efiSystemPartition: "/boot/efi"
|
||||||
|
efiSystemPartitionSize: 512M
|
||||||
|
enableLuksAutomatedPartitioning: true
|
||||||
|
defaultFileSystemType: "ext4"
|
||||||
|
PARTCONF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
# 4. FDE HELPER TOOL
|
||||||
|
# ═══════════════════════════════════════════════════
|
||||||
|
echo "[FDE-04] Installing encryption helper tool..."
|
||||||
|
cat > /usr/local/bin/alfred-encrypt-status << 'ENCSTATUS'
|
||||||
|
#!/bin/bash
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Alfred Linux — Encryption Status ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "── LUKS Volumes ──"
|
||||||
|
if command -v lsblk &>/dev/null; then
|
||||||
|
LUKS_FOUND=false
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if echo "$line" | grep -q "crypt"; then
|
||||||
|
echo " $line"
|
||||||
|
LUKS_FOUND=true
|
||||||
|
fi
|
||||||
|
done < <(lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT 2>/dev/null)
|
||||||
|
if [ "$LUKS_FOUND" = false ]; then
|
||||||
|
echo " No LUKS encrypted volumes detected."
|
||||||
|
echo " To encrypt during install: choose 'Encrypt system' in installer."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "── Crypto Support ──"
|
||||||
|
command -v cryptsetup &>/dev/null && echo " cryptsetup: installed ($(cryptsetup --version 2>/dev/null))" || echo " cryptsetup: NOT installed"
|
||||||
|
[ -d /sys/module/dm_crypt ] && echo " dm-crypt: loaded" || echo " dm-crypt: not loaded"
|
||||||
|
echo ""
|
||||||
|
ENCSTATUS
|
||||||
|
chmod +x /usr/local/bin/alfred-encrypt-status
|
||||||
|
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ [0170] FDE Support — COMPLETE ║"
|
||||||
|
echo "║ ✓ LUKS tools installed (cryptsetup, initramfs hooks) ║"
|
||||||
|
echo "║ ✓ Strong LUKS2 defaults configured ║"
|
||||||
|
echo "║ ✓ Calamares FDE checkbox enabled ║"
|
||||||
|
echo "║ ✓ alfred-encrypt-status tool installed ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
91
config/hooks/live/0200-alfred-browser.hook.chroot
Normal file
91
config/hooks/live/0200-alfred-browser.hook.chroot
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0-b2 — Alfred Browser Integration Hook
|
||||||
|
#
|
||||||
|
# Installs Alfred Browser, removes Firefox ESR, sets defaults.
|
||||||
|
# BUILD: v2.0-b2 (Browser)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b2] Installing Alfred Browser..."
|
||||||
|
|
||||||
|
# ── 1. Install Alfred Browser dependencies ──
|
||||||
|
# The .deb depends on libwebkit2gtk-4.1-0, libgtk-3-0, libayatana-appindicator3-1
|
||||||
|
apt-get install -y libwebkit2gtk-4.1-0 libgtk-3-0 libayatana-appindicator3-1 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 2. Install Alfred Browser from packages.chroot ──
|
||||||
|
# live-build should auto-install .debs from config/packages.chroot/
|
||||||
|
# But as a safety net, install manually if not already present
|
||||||
|
if ! dpkg -l alfred-browser 2>/dev/null | grep -q '^ii'; then
|
||||||
|
BROWSER_DEB=$(find / -name "alfred-browser*.deb" -type f 2>/dev/null | head -1)
|
||||||
|
if [[ -n "$BROWSER_DEB" ]]; then
|
||||||
|
dpkg -i "$BROWSER_DEB" || apt-get -f install -y
|
||||||
|
else
|
||||||
|
echo "[WARN] Alfred Browser .deb not found in ISO — skipping"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Remove Firefox ESR ──
|
||||||
|
echo "[Alfred Linux v2.0-b2] Removing Firefox ESR..."
|
||||||
|
apt-get purge -y firefox-esr 2>/dev/null || true
|
||||||
|
apt-get autoremove -y 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 4. Set Alfred Browser as default ──
|
||||||
|
if [[ -f /usr/bin/alfred-browser ]]; then
|
||||||
|
# Register as x-www-browser alternative (priority 200 = higher than any default)
|
||||||
|
update-alternatives --install /usr/bin/x-www-browser x-www-browser /usr/bin/alfred-browser 200 2>/dev/null || true
|
||||||
|
update-alternatives --set x-www-browser /usr/bin/alfred-browser 2>/dev/null || true
|
||||||
|
|
||||||
|
# Set as default web browser via xdg
|
||||||
|
# Need a proper .desktop file
|
||||||
|
if [[ -f "/usr/share/applications/Alfred Browser.desktop" ]]; then
|
||||||
|
# Fix desktop file name to be xdg-compliant (no spaces)
|
||||||
|
cp "/usr/share/applications/Alfred Browser.desktop" /usr/share/applications/alfred-browser.desktop 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure desktop file has correct MimeType
|
||||||
|
if [[ -f /usr/share/applications/alfred-browser.desktop ]]; then
|
||||||
|
if ! grep -q "MimeType=" /usr/share/applications/alfred-browser.desktop; then
|
||||||
|
echo "MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/ftp" >> /usr/share/applications/alfred-browser.desktop
|
||||||
|
fi
|
||||||
|
# Set categories if missing
|
||||||
|
if ! grep -q "Categories=" /usr/share/applications/alfred-browser.desktop; then
|
||||||
|
echo "Categories=Network;WebBrowser;" >> /usr/share/applications/alfred-browser.desktop
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set via xdg-settings (for the skel user profile)
|
||||||
|
mkdir -p /etc/skel/.config
|
||||||
|
echo "text/html=alfred-browser.desktop" > /etc/skel/.config/mimeapps.list
|
||||||
|
echo "x-scheme-handler/http=alfred-browser.desktop" >> /etc/skel/.config/mimeapps.list
|
||||||
|
echo "x-scheme-handler/https=alfred-browser.desktop" >> /etc/skel/.config/mimeapps.list
|
||||||
|
echo "x-scheme-handler/ftp=alfred-browser.desktop" >> /etc/skel/.config/mimeapps.list
|
||||||
|
echo "application/xhtml+xml=alfred-browser.desktop" >> /etc/skel/.config/mimeapps.list
|
||||||
|
|
||||||
|
# Also set system-wide
|
||||||
|
mkdir -p /usr/share/applications
|
||||||
|
cat > /usr/share/applications/defaults.list << 'DEFAULTS'
|
||||||
|
[Default Applications]
|
||||||
|
text/html=alfred-browser.desktop
|
||||||
|
x-scheme-handler/http=alfred-browser.desktop
|
||||||
|
x-scheme-handler/https=alfred-browser.desktop
|
||||||
|
x-scheme-handler/ftp=alfred-browser.desktop
|
||||||
|
application/xhtml+xml=alfred-browser.desktop
|
||||||
|
DEFAULTS
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b2] Alfred Browser set as default browser"
|
||||||
|
else
|
||||||
|
echo "[WARN] /usr/bin/alfred-browser not found after install"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 5. XFCE panel web browser launcher ──
|
||||||
|
# Update XFCE's preferred browser
|
||||||
|
mkdir -p /etc/skel/.config/xfce4
|
||||||
|
if [[ -f /etc/skel/.config/xfce4/helpers.rc ]]; then
|
||||||
|
sed -i 's/WebBrowser=.*/WebBrowser=alfred-browser/' /etc/skel/.config/xfce4/helpers.rc
|
||||||
|
else
|
||||||
|
echo "WebBrowser=alfred-browser" > /etc/skel/.config/xfce4/helpers.rc
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b2] Alfred Browser integration complete."
|
||||||
94
config/hooks/live/0300-alfred-ide.hook.chroot
Normal file
94
config/hooks/live/0300-alfred-ide.hook.chroot
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0-b3 — Alfred IDE (code-server) Integration
|
||||||
|
#
|
||||||
|
# Installs code-server + Alfred Commander extension.
|
||||||
|
# BUILD: v2.0-b3 (IDE)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set +e # IDE download may fail in chroot — don't kill the build
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b3] Installing Alfred IDE (code-server)..."
|
||||||
|
|
||||||
|
# ── 1. Install code-server via official installer ──
|
||||||
|
export HOME=/root
|
||||||
|
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/usr/local 2>&1 || {
|
||||||
|
echo "[WARN] Official installer failed, trying direct deb..."
|
||||||
|
# Fallback: download specific version
|
||||||
|
CODE_SERVER_VER="4.102.2"
|
||||||
|
wget -q "https://github.com/coder/code-server/releases/download/v${CODE_SERVER_VER}/code-server_${CODE_SERVER_VER}_amd64.deb" -O /tmp/code-server.deb
|
||||||
|
dpkg -i /tmp/code-server.deb || apt-get -f install -y
|
||||||
|
rm -f /tmp/code-server.deb
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 2. Pre-install Alfred Commander extension ──
|
||||||
|
EXTENSION_DIR="/etc/skel/.local/share/code-server/extensions"
|
||||||
|
mkdir -p "$EXTENSION_DIR"
|
||||||
|
if [[ -f /tmp/alfred-commander-1.0.1.tar.gz ]]; then
|
||||||
|
tar xzf /tmp/alfred-commander-1.0.1.tar.gz -C "$EXTENSION_DIR/"
|
||||||
|
echo "[Alfred IDE] Commander extension installed to skel"
|
||||||
|
else
|
||||||
|
echo "[WARN] Commander extension tarball not found in /tmp/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Configure code-server defaults ──
|
||||||
|
mkdir -p /etc/skel/.config/code-server
|
||||||
|
cat > /etc/skel/.config/code-server/config.yaml << 'CFG'
|
||||||
|
bind-addr: 127.0.0.1:8443
|
||||||
|
auth: password
|
||||||
|
password: alfred
|
||||||
|
cert: false
|
||||||
|
app-name: Alfred IDE
|
||||||
|
CFG
|
||||||
|
|
||||||
|
# ── 4. Systemd user service for auto-start ──
|
||||||
|
mkdir -p /etc/skel/.config/systemd/user
|
||||||
|
cat > /etc/skel/.config/systemd/user/code-server.service << 'SVC'
|
||||||
|
[Unit]
|
||||||
|
Description=Alfred IDE (code-server)
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=exec
|
||||||
|
ExecStart=/usr/local/bin/code-server
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
SVC
|
||||||
|
|
||||||
|
# Enable for default user (will activate on first login)
|
||||||
|
mkdir -p /etc/skel/.config/systemd/user/default.target.wants
|
||||||
|
ln -sf ../code-server.service /etc/skel/.config/systemd/user/default.target.wants/code-server.service
|
||||||
|
|
||||||
|
# ── 5. Desktop shortcut ──
|
||||||
|
mkdir -p /etc/skel/Desktop
|
||||||
|
cat > /etc/skel/Desktop/alfred-ide.desktop << 'DESK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Alfred IDE
|
||||||
|
Comment=Sovereign Development Environment
|
||||||
|
Exec=xdg-open http://localhost:8443
|
||||||
|
Icon=accessories-text-editor
|
||||||
|
Type=Application
|
||||||
|
Categories=Development;IDE;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=true
|
||||||
|
DESK
|
||||||
|
chmod +x /etc/skel/Desktop/alfred-ide.desktop
|
||||||
|
|
||||||
|
# Also add to system applications
|
||||||
|
cat > /usr/share/applications/alfred-ide.desktop << 'SYSDESK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Alfred IDE
|
||||||
|
Comment=Sovereign Development Environment
|
||||||
|
Exec=xdg-open http://localhost:8443
|
||||||
|
Icon=accessories-text-editor
|
||||||
|
Type=Application
|
||||||
|
Categories=Development;IDE;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=true
|
||||||
|
MimeType=text/plain;application/x-shellscript;
|
||||||
|
SYSDESK
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b3] Alfred IDE integration complete."
|
||||||
128
config/hooks/live/0400-alfred-voice.hook.chroot
Normal file
128
config/hooks/live/0400-alfred-voice.hook.chroot
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0-b4 — Voice (Kokoro TTS + Welcome Greeting)
|
||||||
|
#
|
||||||
|
# Installs Kokoro TTS for offline voice synthesis.
|
||||||
|
# Alfred speaks on first boot.
|
||||||
|
# BUILD: v2.0-b4 (Voice)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set +e # Voice is optional — don't kill the build if TTS install fails
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b4] Installing Voice subsystem..."
|
||||||
|
|
||||||
|
# ── 0. Ensure DNS works inside chroot ──
|
||||||
|
if ! getent hosts deb.debian.org &>/dev/null 2>&1; then
|
||||||
|
rm -f /etc/resolv.conf 2>/dev/null || true
|
||||||
|
printf 'nameserver 9.9.9.9\nnameserver 1.1.1.1\n' > /etc/resolv.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 1. Install Python audio dependencies ──
|
||||||
|
PYVER=$(python3 --version 2>/dev/null | grep -oP '\d+\.\d+' | head -1)
|
||||||
|
apt-get install -y python3-pip "python${PYVER}-venv" espeak-ng sox libsox-fmt-all 2>/dev/null || \
|
||||||
|
apt-get install -y python3-pip python3-venv espeak-ng sox libsox-fmt-all 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 2. Install Kokoro TTS (CPU-only — no CUDA/NVIDIA bloat) ──
|
||||||
|
# Install CPU-only PyTorch FIRST to prevent pulling the full 3.4GB CUDA stack.
|
||||||
|
# This keeps the ISO under 4GB (ISO 9660 single-file limit).
|
||||||
|
pip3 install --break-system-packages torch --index-url https://download.pytorch.org/whl/cpu 2>/dev/null || true
|
||||||
|
pip3 install --break-system-packages kokoro 2>/dev/null || {
|
||||||
|
echo "[WARN] kokoro system install failed, trying with venv..."
|
||||||
|
python3 -m venv /opt/alfred-voice
|
||||||
|
/opt/alfred-voice/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
|
||||||
|
/opt/alfred-voice/bin/pip install kokoro
|
||||||
|
ln -sf /opt/alfred-voice/bin/python3 /usr/local/bin/alfred-voice-python
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean up empty fallback venv dir if system-wide install worked
|
||||||
|
if python3 -c "import kokoro" 2>/dev/null && [[ -d /opt/alfred-voice ]] && [[ ! -f /opt/alfred-voice/bin/python3 ]]; then
|
||||||
|
rm -rf /opt/alfred-voice
|
||||||
|
echo "[Alfred Voice] Kokoro installed system-wide, removed empty venv dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 3. Create welcome script ──
|
||||||
|
cat > /usr/local/bin/alfred-welcome.sh << 'WELCOME'
|
||||||
|
#!/bin/bash
|
||||||
|
# Alfred Linux — First Boot Welcome
|
||||||
|
# Speaks a greeting via Kokoro TTS on first login
|
||||||
|
|
||||||
|
if [[ -f "$HOME/.alfred-welcomed" ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try Kokoro TTS first
|
||||||
|
VOICE_PYTHON="python3"
|
||||||
|
[[ -x /usr/local/bin/alfred-voice-python ]] && VOICE_PYTHON="/usr/local/bin/alfred-voice-python"
|
||||||
|
|
||||||
|
$VOICE_PYTHON -c "
|
||||||
|
try:
|
||||||
|
from kokoro import KPipeline
|
||||||
|
pipe = KPipeline(lang_code='a')
|
||||||
|
generator = pipe('Welcome to Alfred Linux. I am Alfred, your AI companion. Everything here is sovereign. Everything here is yours.', voice='af_heart', speed=1.0)
|
||||||
|
import soundfile as sf
|
||||||
|
for i, (gs, ps, audio) in enumerate(generator):
|
||||||
|
sf.write('/tmp/alfred-welcome.wav', audio, 24000)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Kokoro TTS failed: {e}')
|
||||||
|
import subprocess
|
||||||
|
subprocess.run(['espeak-ng', '-w', '/tmp/alfred-welcome.wav',
|
||||||
|
'Welcome to Alfred Linux. I am Alfred, your AI companion.'])
|
||||||
|
" 2>/dev/null
|
||||||
|
|
||||||
|
# Play the audio
|
||||||
|
if [[ -f /tmp/alfred-welcome.wav ]]; then
|
||||||
|
aplay /tmp/alfred-welcome.wav 2>/dev/null || paplay /tmp/alfred-welcome.wav 2>/dev/null || true
|
||||||
|
rm -f /tmp/alfred-welcome.wav
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mark as welcomed
|
||||||
|
touch "$HOME/.alfred-welcomed"
|
||||||
|
WELCOME
|
||||||
|
chmod +x /usr/local/bin/alfred-welcome.sh
|
||||||
|
|
||||||
|
# ── 4. XFCE autostart entry ──
|
||||||
|
mkdir -p /etc/skel/.config/autostart
|
||||||
|
cat > /etc/skel/.config/autostart/alfred-welcome.desktop << 'DESK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Alfred Welcome
|
||||||
|
Comment=Alfred greets you on first login
|
||||||
|
Exec=/usr/local/bin/alfred-welcome.sh
|
||||||
|
Hidden=false
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
X-GNOME-Autostart-Delay=3
|
||||||
|
DESK
|
||||||
|
|
||||||
|
# ── 5. Alfred TTS CLI wrapper ──
|
||||||
|
cat > /usr/local/bin/alfred-say << 'SAY'
|
||||||
|
#!/bin/bash
|
||||||
|
# Alfred TTS — speak any text
|
||||||
|
# Usage: alfred-say "Hello, Commander"
|
||||||
|
|
||||||
|
TEXT="${*:-Hello, I am Alfred.}"
|
||||||
|
VOICE_PYTHON="python3"
|
||||||
|
[[ -x /usr/local/bin/alfred-voice-python ]] && VOICE_PYTHON="/usr/local/bin/alfred-voice-python"
|
||||||
|
|
||||||
|
$VOICE_PYTHON -c "
|
||||||
|
try:
|
||||||
|
from kokoro import KPipeline
|
||||||
|
pipe = KPipeline(lang_code='a')
|
||||||
|
generator = pipe('''$TEXT''', voice='af_heart', speed=1.0)
|
||||||
|
import soundfile as sf
|
||||||
|
for i, (gs, ps, audio) in enumerate(generator):
|
||||||
|
sf.write('/tmp/alfred-tts.wav', audio, 24000)
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
import subprocess
|
||||||
|
subprocess.run(['espeak-ng', '-w', '/tmp/alfred-tts.wav', '''$TEXT'''])
|
||||||
|
" 2>/dev/null
|
||||||
|
|
||||||
|
if [[ -f /tmp/alfred-tts.wav ]]; then
|
||||||
|
aplay /tmp/alfred-tts.wav 2>/dev/null || paplay /tmp/alfred-tts.wav 2>/dev/null
|
||||||
|
rm -f /tmp/alfred-tts.wav
|
||||||
|
fi
|
||||||
|
SAY
|
||||||
|
chmod +x /usr/local/bin/alfred-say
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b4] Voice subsystem installed."
|
||||||
131
config/hooks/live/0500-alfred-search.hook.chroot
Normal file
131
config/hooks/live/0500-alfred-search.hook.chroot
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0-b5 — Meilisearch Local Search Engine
|
||||||
|
#
|
||||||
|
# Installs Meilisearch for offline local search.
|
||||||
|
# BUILD: v2.0-b5 (Search)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b5] Installing Meilisearch..."
|
||||||
|
|
||||||
|
# ── 1. Download Meilisearch binary ──
|
||||||
|
MEILI_VER="v1.13.3"
|
||||||
|
MEILI_URL="https://github.com/meilisearch/meilisearch/releases/download/${MEILI_VER}/meilisearch-linux-amd64"
|
||||||
|
wget -q "$MEILI_URL" -O /usr/local/bin/meilisearch || {
|
||||||
|
echo "[WARN] Meilisearch download failed, trying latest..."
|
||||||
|
curl -L https://install.meilisearch.com | sh
|
||||||
|
mv meilisearch /usr/local/bin/meilisearch
|
||||||
|
}
|
||||||
|
chmod +x /usr/local/bin/meilisearch
|
||||||
|
|
||||||
|
# ── 2. Create meilisearch user ──
|
||||||
|
useradd -r -s /bin/false -d /var/lib/meilisearch meilisearch 2>/dev/null || true
|
||||||
|
mkdir -p /var/lib/meilisearch
|
||||||
|
chown meilisearch:meilisearch /var/lib/meilisearch
|
||||||
|
|
||||||
|
# ── 3. Systemd service ──
|
||||||
|
cat > /etc/systemd/system/meilisearch.service << 'SVC'
|
||||||
|
[Unit]
|
||||||
|
Description=Meilisearch Local Search Engine
|
||||||
|
Documentation=https://docs.meilisearch.com
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/meilisearch --db-path /var/lib/meilisearch --http-addr 127.0.0.1:7700 --no-analytics
|
||||||
|
User=meilisearch
|
||||||
|
Group=meilisearch
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
LimitNOFILE=65536
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SVC
|
||||||
|
systemctl enable meilisearch 2>/dev/null || true
|
||||||
|
|
||||||
|
# ── 4. Alfred Search CLI ──
|
||||||
|
cat > /usr/local/bin/alfred-search << 'SEARCH'
|
||||||
|
#!/bin/bash
|
||||||
|
# Alfred Search — local search powered by Meilisearch
|
||||||
|
# Usage: alfred-search "query"
|
||||||
|
|
||||||
|
QUERY="${*:-}"
|
||||||
|
if [[ -z "$QUERY" ]]; then
|
||||||
|
echo "Usage: alfred-search <query>"
|
||||||
|
echo "Search local documentation and files."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Meilisearch is running
|
||||||
|
if ! curl -s http://localhost:7700/health | grep -q available; then
|
||||||
|
echo "Meilisearch is not running. Start with: sudo systemctl start meilisearch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Search
|
||||||
|
RESULT=$(curl -s "http://localhost:7700/multi-search" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"queries\": [{\"indexUid\": \"docs\", \"q\": \"$QUERY\", \"limit\": 5}]}" 2>/dev/null)
|
||||||
|
|
||||||
|
if echo "$RESULT" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
data = json.load(sys.stdin)
|
||||||
|
results = data.get('results', [{}])[0].get('hits', [])
|
||||||
|
if not results:
|
||||||
|
print('No results found.')
|
||||||
|
else:
|
||||||
|
for r in results:
|
||||||
|
title = r.get('title', r.get('path', 'Untitled'))
|
||||||
|
snippet = r.get('content', '')[:200]
|
||||||
|
print(f' → {title}')
|
||||||
|
print(f' {snippet}')
|
||||||
|
print()
|
||||||
|
" 2>/dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "Search returned no parseable results."
|
||||||
|
fi
|
||||||
|
SEARCH
|
||||||
|
chmod +x /usr/local/bin/alfred-search
|
||||||
|
|
||||||
|
# ── 5. First-boot indexer script ──
|
||||||
|
cat > /usr/local/bin/alfred-index-docs << 'INDEX'
|
||||||
|
#!/bin/bash
|
||||||
|
# Index local documentation into Meilisearch
|
||||||
|
echo "Indexing local documentation..."
|
||||||
|
|
||||||
|
# Wait for Meilisearch
|
||||||
|
for i in {1..30}; do
|
||||||
|
curl -s http://localhost:7700/health | grep -q available && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Index man pages
|
||||||
|
DOCS='[]'
|
||||||
|
ID=0
|
||||||
|
for f in /usr/share/doc/*/README* /usr/share/doc/*/changelog*; do
|
||||||
|
[[ -f "$f" ]] || continue
|
||||||
|
CONTENT=$(head -c 5000 "$f" 2>/dev/null | tr -d '\0' | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))" 2>/dev/null)
|
||||||
|
[[ -z "$CONTENT" ]] && continue
|
||||||
|
DOCS=$(echo "$DOCS" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
docs = json.load(sys.stdin)
|
||||||
|
docs.append({'id': $ID, 'path': '$f', 'title': '$(basename "$(dirname "$f")")', 'content': $CONTENT})
|
||||||
|
print(json.dumps(docs))
|
||||||
|
" 2>/dev/null)
|
||||||
|
((ID++))
|
||||||
|
[[ $ID -ge 500 ]] && break
|
||||||
|
done
|
||||||
|
|
||||||
|
# Push to Meilisearch
|
||||||
|
echo "$DOCS" | curl -s -X POST "http://localhost:7700/indexes/docs/documents" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @- > /dev/null 2>&1
|
||||||
|
|
||||||
|
echo "Indexed $ID documents."
|
||||||
|
INDEX
|
||||||
|
chmod +x /usr/local/bin/alfred-index-docs
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b5] Meilisearch installed and configured."
|
||||||
344
config/hooks/live/0600-alfred-installer.hook.chroot
Normal file
344
config/hooks/live/0600-alfred-installer.hook.chroot
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# Alfred Linux v2.0-b6 — Calamares Graphical Installer
|
||||||
|
#
|
||||||
|
# Installs and brands Calamares for disk installation.
|
||||||
|
# BUILD: v2.0-b6 (Installer)
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "[Alfred Linux v2.0-b6] Installing Calamares installer..."
|
||||||
|
|
||||||
|
# ── 1. Install Calamares and dependencies ──
|
||||||
|
apt-get install -y calamares calamares-settings-debian 2>/dev/null || {
|
||||||
|
echo "[WARN] Calamares not in repos, trying manual install..."
|
||||||
|
# Calamares may need additional repos on Bookworm
|
||||||
|
apt-get install -y \
|
||||||
|
calamares \
|
||||||
|
qml-module-qtquick2 \
|
||||||
|
qml-module-qtquick-controls \
|
||||||
|
qml-module-qtquick-controls2 \
|
||||||
|
qml-module-qtquick-layouts \
|
||||||
|
qml-module-qtquick-window2 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 2. Alfred branding for Calamares ──
|
||||||
|
BRAND_DIR="/etc/calamares/branding/alfred"
|
||||||
|
mkdir -p "$BRAND_DIR"
|
||||||
|
|
||||||
|
cat > "$BRAND_DIR/branding.desc" << 'BRAND'
|
||||||
|
---
|
||||||
|
componentName: alfred
|
||||||
|
|
||||||
|
strings:
|
||||||
|
productName: "Alfred Linux"
|
||||||
|
shortProductName: "Alfred"
|
||||||
|
version: 4.0
|
||||||
|
shortVersion: 4.0
|
||||||
|
versionedName: "Alfred Linux 4.0"
|
||||||
|
shortVersionedName: "Alfred 4.0"
|
||||||
|
bootloaderEntryName: "Alfred Linux"
|
||||||
|
productUrl: https://alfredlinux.com
|
||||||
|
supportUrl: https://gositeme.com/support.php
|
||||||
|
knownIssuesUrl: https://alfredlinux.com/issues
|
||||||
|
releaseNotesUrl: https://alfredlinux.com/release-notes
|
||||||
|
|
||||||
|
images:
|
||||||
|
productLogo: "alfred-logo.png"
|
||||||
|
productIcon: "alfred-icon.png"
|
||||||
|
productWelcome: "alfred-welcome.png"
|
||||||
|
|
||||||
|
slideshow: "show.qml"
|
||||||
|
|
||||||
|
style:
|
||||||
|
sidebarBackground: "#0a0a14"
|
||||||
|
sidebarText: "#e8e8f0"
|
||||||
|
sidebarTextSelect: "#00D4FF"
|
||||||
|
sidebarTextHighlight: "#00D4FF"
|
||||||
|
BRAND
|
||||||
|
|
||||||
|
# Generate branding images with ImageMagick
|
||||||
|
if command -v convert &>/dev/null; then
|
||||||
|
# Product logo (128x128)
|
||||||
|
convert -size 128x128 xc:'#00D4FF' \
|
||||||
|
-fill '#0a0a14' -font 'DejaVu-Sans-Bold' -pointsize 80 \
|
||||||
|
-gravity center -annotate +0+0 'A' \
|
||||||
|
"$BRAND_DIR/alfred-logo.png" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Product icon (48x48)
|
||||||
|
convert -size 48x48 xc:'#00D4FF' \
|
||||||
|
-fill '#0a0a14' -font 'DejaVu-Sans-Bold' -pointsize 32 \
|
||||||
|
-gravity center -annotate +0+0 'A' \
|
||||||
|
"$BRAND_DIR/alfred-icon.png" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Welcome banner (800x300)
|
||||||
|
convert -size 800x300 \
|
||||||
|
-define gradient:angle=135 \
|
||||||
|
gradient:'#0a0a14-#1a1a2e' \
|
||||||
|
-fill '#00D4FF' -font 'DejaVu-Sans-Bold' -pointsize 48 \
|
||||||
|
-gravity center -annotate +0-30 'Alfred Linux' \
|
||||||
|
-fill '#8a8a9a' -font 'DejaVu-Sans' -pointsize 20 \
|
||||||
|
-annotate +0+30 'Sovereign Computing — Install to Disk' \
|
||||||
|
"$BRAND_DIR/alfred-welcome.png" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# QML slideshow
|
||||||
|
cat > "$BRAND_DIR/show.qml" << 'QML'
|
||||||
|
import QtQuick 2.0;
|
||||||
|
import calamares.slideshow 1.0;
|
||||||
|
|
||||||
|
Presentation {
|
||||||
|
id: presentation
|
||||||
|
|
||||||
|
Slide {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#0a0a14"
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 20
|
||||||
|
Text {
|
||||||
|
text: "Welcome to Alfred Linux"
|
||||||
|
color: "#00D4FF"
|
||||||
|
font.pixelSize: 32
|
||||||
|
font.bold: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "The Sovereign Operating System"
|
||||||
|
color: "#8a8a9a"
|
||||||
|
font.pixelSize: 18
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "No telemetry. No tracking. Yours."
|
||||||
|
color: "#e8e8f0"
|
||||||
|
font.pixelSize: 14
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slide {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#0a0a14"
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 20
|
||||||
|
Text {
|
||||||
|
text: "Alfred Browser"
|
||||||
|
color: "#00D4FF"
|
||||||
|
font.pixelSize: 28
|
||||||
|
font.bold: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Post-quantum encrypted browsing\nAES-256-GCM + Kyber-1024\nZero tracking. Zero telemetry."
|
||||||
|
color: "#e8e8f0"
|
||||||
|
font.pixelSize: 16
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slide {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#0a0a14"
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 20
|
||||||
|
Text {
|
||||||
|
text: "Alfred IDE"
|
||||||
|
color: "#00D4FF"
|
||||||
|
font.pixelSize: 28
|
||||||
|
font.bold: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Full development environment\nAI-powered coding assistant\nBuilt for sovereign developers"
|
||||||
|
color: "#e8e8f0"
|
||||||
|
font.pixelSize: 16
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Slide {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#0a0a14"
|
||||||
|
Column {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 20
|
||||||
|
Text {
|
||||||
|
text: "Your Computing. Your Rules."
|
||||||
|
color: "#00D4FF"
|
||||||
|
font.pixelSize: 28
|
||||||
|
font.bold: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Alfred Linux is built by GoSiteMe\nfor people who believe their computer\nshould work for them, not against them."
|
||||||
|
color: "#e8e8f0"
|
||||||
|
font.pixelSize: 16
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QML
|
||||||
|
|
||||||
|
# ── 3. Calamares settings ──
|
||||||
|
mkdir -p /etc/calamares
|
||||||
|
cat > /etc/calamares/settings.conf << 'SETTINGS'
|
||||||
|
modules-search: [ local, /usr/lib/calamares/modules ]
|
||||||
|
|
||||||
|
sequence:
|
||||||
|
- show:
|
||||||
|
- welcome
|
||||||
|
- locale
|
||||||
|
- keyboard
|
||||||
|
- partition
|
||||||
|
- users
|
||||||
|
- summary
|
||||||
|
- exec:
|
||||||
|
- partition
|
||||||
|
- mount
|
||||||
|
- unpackfs
|
||||||
|
- machineid
|
||||||
|
- fstab
|
||||||
|
- locale
|
||||||
|
- keyboard
|
||||||
|
- localecfg
|
||||||
|
- luksbootkeyfile
|
||||||
|
- users
|
||||||
|
- displaymanager
|
||||||
|
- networkcfg
|
||||||
|
- hwclock
|
||||||
|
- services-systemd
|
||||||
|
- bootloader
|
||||||
|
- umount
|
||||||
|
- show:
|
||||||
|
- finished
|
||||||
|
|
||||||
|
branding: alfred
|
||||||
|
SETTINGS
|
||||||
|
|
||||||
|
# ── 4. Application menu entry (always visible in System menu) ──
|
||||||
|
cat > /usr/share/applications/alfred-install.desktop << 'APPDESK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Install Alfred Linux
|
||||||
|
GenericName=System Installer
|
||||||
|
Comment=Install Alfred Linux to your hard drive
|
||||||
|
Exec=pkexec calamares
|
||||||
|
Icon=calamares
|
||||||
|
Type=Application
|
||||||
|
Categories=System;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=true
|
||||||
|
Keywords=install;installer;calamares;disk;
|
||||||
|
APPDESK
|
||||||
|
|
||||||
|
# ── 5. Desktop shortcut for installer ──
|
||||||
|
mkdir -p /etc/skel/Desktop
|
||||||
|
cat > /etc/skel/Desktop/install-alfred-linux.desktop << 'DESK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Install Alfred Linux
|
||||||
|
Comment=Install Alfred Linux to your hard drive
|
||||||
|
Exec=pkexec calamares
|
||||||
|
Icon=calamares
|
||||||
|
Type=Application
|
||||||
|
Categories=System;
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=true
|
||||||
|
DESK
|
||||||
|
chmod +x /etc/skel/Desktop/install-alfred-linux.desktop
|
||||||
|
|
||||||
|
# Mark desktop file as trusted for XFCE (prevents "untrusted launcher" dialog)
|
||||||
|
# XFCE uses a checksum stored in gio metadata to trust desktop files
|
||||||
|
# We create a script that runs once at login to trust all skel desktop files
|
||||||
|
cat > /etc/skel/.config/autostart/trust-desktop-files.desktop << 'TRUST_AUTO'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Trust Desktop Launchers
|
||||||
|
Exec=/usr/local/bin/alfred-trust-desktop
|
||||||
|
Hidden=false
|
||||||
|
NoDisplay=true
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
TRUST_AUTO
|
||||||
|
mkdir -p /etc/skel/.config/autostart
|
||||||
|
|
||||||
|
cat > /usr/local/bin/alfred-trust-desktop << 'TRUSTSCRIPT'
|
||||||
|
#!/bin/bash
|
||||||
|
# Trust all .desktop files on the Desktop for XFCE
|
||||||
|
# This runs once at first login, then disables itself
|
||||||
|
DESKTOP_DIR="$HOME/Desktop"
|
||||||
|
if [[ -d "$DESKTOP_DIR" ]]; then
|
||||||
|
for f in "$DESKTOP_DIR"/*.desktop; do
|
||||||
|
[[ -f "$f" ]] || continue
|
||||||
|
# XFCE trusts launchers by matching a hash of the file
|
||||||
|
HASH=$(sha256sum "$f" | cut -d' ' -f1)
|
||||||
|
gio set "$f" "metadata::xfce-exe-checksum" "$HASH" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
# Disable self after first run
|
||||||
|
rm -f "$HOME/.config/autostart/trust-desktop-files.desktop" 2>/dev/null
|
||||||
|
TRUSTSCRIPT
|
||||||
|
chmod +x /usr/local/bin/alfred-trust-desktop
|
||||||
|
|
||||||
|
# ── 6. "Install or Try" dialog on live boot ──
|
||||||
|
cat > /usr/local/bin/alfred-live-welcome << 'LIVEWELCOME'
|
||||||
|
#!/bin/bash
|
||||||
|
# Show install prompt on live boot (only if not installed)
|
||||||
|
if [[ -f /run/live/medium/.disk/info ]] || [[ -d /run/live ]]; then
|
||||||
|
# We're in a live session
|
||||||
|
zenity --question \
|
||||||
|
--title="Welcome to Alfred Linux" \
|
||||||
|
--text="Welcome to Alfred Linux!\n\nWould you like to install Alfred Linux to your hard drive, or continue trying it live?" \
|
||||||
|
--ok-label="Install to Disk" \
|
||||||
|
--cancel-label="Try Live" \
|
||||||
|
--width=400 --height=180 \
|
||||||
|
--window-icon=calamares 2>/dev/null
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
pkexec calamares &
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
LIVEWELCOME
|
||||||
|
chmod +x /usr/local/bin/alfred-live-welcome
|
||||||
|
|
||||||
|
# Autostart the welcome dialog in live sessions
|
||||||
|
cat > /etc/skel/.config/autostart/alfred-live-welcome.desktop << 'LIVEWELC_AUTO'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Alfred Linux Welcome
|
||||||
|
Comment=Install or Try Alfred Linux
|
||||||
|
Exec=/usr/local/bin/alfred-live-welcome
|
||||||
|
Hidden=false
|
||||||
|
NoDisplay=true
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
LIVEWELC_AUTO
|
||||||
|
|
||||||
|
# ── 7. Ensure zenity is available for the dialog ──
|
||||||
|
apt-get install -y --no-install-recommends zenity 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "[Alfred Linux v4.0] Calamares installer branded, configured, and install prompt enabled."
|
||||||
|
|
||||||
|
# ── 8. Fix Debian-branded desktop files left by calamares-settings-debian ──
|
||||||
|
if [[ -f /usr/share/applications/install-debian.desktop ]]; then
|
||||||
|
sed -i 's/Name=Install Debian/Name=Install Alfred Linux/' /usr/share/applications/install-debian.desktop
|
||||||
|
sed -i 's/Comment=Calamares.*$/Comment=Install Alfred Linux to your hard drive/' /usr/share/applications/install-debian.desktop
|
||||||
|
fi
|
||||||
|
if [[ -f /usr/share/applications/calamares.desktop ]]; then
|
||||||
|
sed -i 's/Name=Install Debian/Name=Install Alfred Linux/' /usr/share/applications/calamares.desktop
|
||||||
|
sed -i 's/Name=Install System/Name=Install Alfred Linux/' /usr/share/applications/calamares.desktop
|
||||||
|
fi
|
||||||
141
scripts/build.sh
Normal file
141
scripts/build.sh
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Alfred Linux v2.0 — ISO Build Script
|
||||||
|
# Build: b1 (Branding)
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
BUILD_DIR="$PROJECT_DIR/build"
|
||||||
|
OUTPUT_DIR="$PROJECT_DIR/iso-output"
|
||||||
|
DATE=$(date +%Y%m%d)
|
||||||
|
VERSION="2.0-b1"
|
||||||
|
ISO_NAME="alfred-linux-${VERSION}-amd64-${DATE}.iso"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " ╔═══════════════════════════════════════════════╗"
|
||||||
|
echo " ║ Alfred Linux — ISO Build System v2.0 ║"
|
||||||
|
echo " ║ Building: ${ISO_NAME} ║"
|
||||||
|
echo " ╚═══════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "ERROR: Must run as root (sudo)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for cmd in lb debootstrap mksquashfs xorriso; do
|
||||||
|
if ! command -v "$cmd" &>/dev/null; then
|
||||||
|
echo "ERROR: '$cmd' not found. Install: apt-get install live-build debootstrap squashfs-tools xorriso"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[BUILD] Setting up build directory..."
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
cd "$BUILD_DIR"
|
||||||
|
|
||||||
|
if [[ -f .build/config ]]; then
|
||||||
|
echo "[BUILD] Cleaning previous build..."
|
||||||
|
lb clean --purge 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[BUILD] Configuring live-build for Debian Bookworm..."
|
||||||
|
lb config \
|
||||||
|
--mode debian \
|
||||||
|
--distribution bookworm \
|
||||||
|
--architectures amd64 \
|
||||||
|
--binary-images iso-hybrid \
|
||||||
|
--bootloader syslinux \
|
||||||
|
--apt-indices false \
|
||||||
|
--memtest none \
|
||||||
|
--firmware-chroot false \
|
||||||
|
--linux-packages "linux-image" \
|
||||||
|
--linux-flavours "amd64" \
|
||||||
|
--parent-mirror-bootstrap "http://deb.debian.org/debian" \
|
||||||
|
--parent-mirror-chroot "http://deb.debian.org/debian" \
|
||||||
|
--parent-mirror-chroot-security "http://deb.debian.org/debian-security" \
|
||||||
|
--parent-mirror-binary "http://deb.debian.org/debian" \
|
||||||
|
--parent-mirror-binary-security "http://deb.debian.org/debian-security" \
|
||||||
|
--mirror-bootstrap "http://deb.debian.org/debian" \
|
||||||
|
--mirror-chroot "http://deb.debian.org/debian" \
|
||||||
|
--mirror-chroot-security "http://deb.debian.org/debian-security" \
|
||||||
|
--mirror-binary "http://deb.debian.org/debian" \
|
||||||
|
--mirror-binary-security "http://deb.debian.org/debian-security" \
|
||||||
|
--iso-application "Alfred Linux" \
|
||||||
|
--iso-publisher "GoSiteMe — alfredlinux.com" \
|
||||||
|
--iso-volume "Alfred Linux 2.0"
|
||||||
|
|
||||||
|
# Copy package lists
|
||||||
|
echo "[BUILD] Installing package lists..."
|
||||||
|
cp "$PROJECT_DIR/config/package-lists/"*.list.chroot config/package-lists/ 2>/dev/null || true
|
||||||
|
|
||||||
|
# Copy chroot hooks
|
||||||
|
echo "[BUILD] Installing build hooks..."
|
||||||
|
mkdir -p config/hooks/live
|
||||||
|
cp "$PROJECT_DIR/config/hooks/live/"*.hook.chroot config/hooks/live/ 2>/dev/null || true
|
||||||
|
chmod +x config/hooks/live/*.hook.chroot 2>/dev/null || true
|
||||||
|
|
||||||
|
# Security repo fix hook
|
||||||
|
cat > config/hooks/live/0010-fix-security-repo.hook.chroot << 'HOOKEOF'
|
||||||
|
#!/bin/bash
|
||||||
|
echo "deb http://deb.debian.org/debian-security bookworm-security main" > /etc/apt/sources.list.d/security.list
|
||||||
|
echo "deb http://deb.debian.org/debian bookworm-updates main" > /etc/apt/sources.list.d/updates.list
|
||||||
|
apt-get update -qq
|
||||||
|
HOOKEOF
|
||||||
|
chmod +x config/hooks/live/0010-fix-security-repo.hook.chroot
|
||||||
|
|
||||||
|
# Fix bootloader
|
||||||
|
echo "[BUILD] Fixing bootloader config (isolinux)..."
|
||||||
|
mkdir -p config/bootloaders/isolinux
|
||||||
|
for f in install.cfg isolinux.cfg live.cfg.in menu.cfg splash.svg.in stdmenu.cfg; do
|
||||||
|
if [[ -f /usr/share/live/build/bootloaders/isolinux/$f ]]; then
|
||||||
|
cp /usr/share/live/build/bootloaders/isolinux/$f config/bootloaders/isolinux/
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
cp /usr/lib/ISOLINUX/isolinux.bin config/bootloaders/isolinux/isolinux.bin
|
||||||
|
cp /usr/lib/syslinux/modules/bios/vesamenu.c32 config/bootloaders/isolinux/vesamenu.c32
|
||||||
|
for extra in ldlinux.c32 libutil.c32 libcom32.c32; do
|
||||||
|
[[ -f /usr/lib/syslinux/modules/bios/$extra ]] && cp /usr/lib/syslinux/modules/bios/$extra config/bootloaders/isolinux/
|
||||||
|
done
|
||||||
|
echo "[BUILD] Bootloader fix applied: $(ls config/bootloaders/isolinux/ | wc -l) files"
|
||||||
|
|
||||||
|
# Copy skeleton files
|
||||||
|
echo "[BUILD] Installing skeleton files..."
|
||||||
|
if [[ -d "$PROJECT_DIR/config/includes.chroot" ]]; then
|
||||||
|
mkdir -p config/includes.chroot
|
||||||
|
cp -r "$PROJECT_DIR/config/includes.chroot/"* config/includes.chroot/ 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build
|
||||||
|
echo "[BUILD] Starting ISO build... (this takes 20-40 minutes)"
|
||||||
|
echo "[BUILD] Build log: $BUILD_DIR/build.log"
|
||||||
|
lb build 2>&1 | tee "$BUILD_DIR/build.log"
|
||||||
|
BUILD_RC=${PIPESTATUS[0]}
|
||||||
|
echo "[BUILD] lb build exited with code: $BUILD_RC"
|
||||||
|
if [ $BUILD_RC -ne 0 ]; then
|
||||||
|
echo "[BUILD] WARNING: lb build returned non-zero ($BUILD_RC) — checking if ISO was still created..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move output
|
||||||
|
ISO_FILE=$(find . -maxdepth 1 -name "*.iso" -o -name "*.hybrid.iso" | head -1)
|
||||||
|
if [[ -n "$ISO_FILE" ]]; then
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
mv "$ISO_FILE" "$OUTPUT_DIR/$ISO_NAME"
|
||||||
|
cd "$OUTPUT_DIR"
|
||||||
|
sha256sum "$ISO_NAME" > "${ISO_NAME}.sha256"
|
||||||
|
SIZE=$(du -h "$ISO_NAME" | cut -f1)
|
||||||
|
echo ""
|
||||||
|
echo " ╔═══════════════════════════════════════════════╗"
|
||||||
|
echo " ║ BUILD COMPLETE ║"
|
||||||
|
echo " ║ ISO: $ISO_NAME"
|
||||||
|
echo " ║ Size: $SIZE"
|
||||||
|
echo " ║ SHA256: $(cat "${ISO_NAME}.sha256" | cut -d' ' -f1 | head -c 16)..."
|
||||||
|
echo " ╚═══════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo " ERROR: ISO build failed. Check build.log for details."
|
||||||
|
tail -30 "$BUILD_DIR/build.log"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Loading…
Reference in New Issue
Block a user