# swinstall.sh – Dokumentation

**SnowTV Player Typ 1 – Erstinstallation**
Version: 2.0 | Quelle: `https://172.105.95.252/`

---

## Voraussetzungen

### Preseed-Deployment (Normalfall)

Keine manuellen Voraussetzungen. Der Preseed erledigt alles automatisch:
- User `snowtv` mit `NOPASSWD: ALL` in `/etc/sudoers.d/snowtv`
- `firstboot.sh` lädt `swinstall.sh` herunter und führt es aus
- `swinstall.sh` schränkt sudoers am Ende auf shutdown/reboot/nmcli ein

→ Siehe `preseed.md` für den vollständigen Ablauf.

### Manuelle Installation (ohne Preseed)

Diese Schritte müssen auf einem frischen Debian **vor** dem Skriptaufruf erledigt werden:

**1. sudo installieren**
```bash
su
apt install sudo
adduser snowtv sudo
exit
```
Danach Rechner **neu starten** (Abmelden reicht nicht).

**2. Falls sudo/reboot/shutdown nicht gefunden wird**
```bash
sudo vim ~/.bashrc
# Zeile einfügen:
export PATH="$PATH:/usr/sbin/"
```
Alternativ direkt aufrufen: `/sbin/reboot`, `/sbin/shutdown`

**3. vim installieren**
```bash
su
apt install vim
exit
```

**4. Shutdown/Reboot ohne Passwort (temporär, für Skriptlauf)**
```bash
sudo visudo
# Am Ende einfügen:
snowtv ALL=(ALL) NOPASSWD: ALL
```
`swinstall.sh` ersetzt diese Regel am Ende automatisch durch die eingeschränkte Version.

**5. swinstall.sh herunterladen**
```bash
wget --no-check-certificate https://172.105.95.252/swinstall.sh
chmod +x swinstall.sh
```

**6. Timeshift-Snapshot erstellen (VOR dem Skriptaufruf, empfohlen)**
```bash
sudo apt install timeshift
sudo timeshift --create --comments "vor swinstall v2.0"
# Snapshot-Liste prüfen:
sudo timeshift --list
```
Bei Bedarf restore: `sudo timeshift --restore`

---

## Was das Skript macht

### 1. System aktualisieren
`apt update` + `apt upgrade`

### 2. Software installieren
Alle benötigten Pakete in einem Durchgang:

| Kategorie | Pakete |
|---|---|
| Desktop / X | `openbox`, `xorg`, `tint2`, `feh`, `lxpanel`, `lxappearance`, `pcmanfm`, `gmrun`, `gnome-terminal`, `xbacklight`, `xdotool` |
| Browser | `firefox-esr`, `chromium` |
| Editoren | `vim`, `vim-gtk3` |
| Audio | `pulseaudio`, `pavucontrol`, `paprefs`, `alsa-utils`, `libasound2-plugins` |
| Netzwerk | `network-manager`, `network-manager-gnome`, `autossh`, `openvpn`, `network-manager-openvpn`, `network-manager-openvpn-gnome`, `modemmanager`, `libqmi-utils`, `libmbim-utils`, `avahi-daemon` |
| Remote | `x11vnc` |
| Multimedia | `libavcodec-extra`, `mplayer`, `yt-dlp`, `imagemagick` |
| System-Tools | `htop`, `silversearcher-ag`, `tmux`, `fastfetch`, `figlet`, `curl`, `bc`, `zip`, `dnsutils`, `net-tools`, `lftp`, `netcat-openbsd`, `mtr`, `less`, `jq`, `scrot`, `usbutils` |
| Hardware | `firmware-realtek`, `firmware-iwlwifi`, `intel-gpu-tools`, `intel-microcode`, `lshw`, `cec-utils`, `chafa` |
| Statistik | `vnstat` |

### 3. OpenVPN 3
`openvpn3` ist nicht in den Standard-Debian-Repos enthalten. Das Skript fügt das offizielle OpenVPN-Repository hinzu und installiert `openvpn3` daraus.

### 4. CEC-Client
User `snowtv` wird der Gruppe `dialout` hinzugefügt (HDMI-Steuerung via `/dev/ttyACM0`).

### 5. Bash-Aliases für Reboot/Shutdown
Aliases in `~/.bash_aliases` (kein sudo-Prompt im Terminal):
```bash
alias reboot='sudo /sbin/reboot'
alias shutdown='sudo /sbin/shutdown'
```

### 6. SSH – Härtung + Keys
- `openssh-server` installieren
- `~/.ssh/` anlegen (`700`), `authorized_keys` anlegen (`600`)
- SSH Private/Public Key für Reverse-SSH-Tunnel aus `cfg_files` deployen:
  - `id_ed25519` → `~/.ssh/id_ed25519` (`600`) – wird von `sshcon.sh` / `autossh` verwendet
  - `id_ed25519.pub` → `~/.ssh/id_ed25519.pub` (`644`)
- `sshd_config` wird vollständig gehärtet:

| Parameter | Wert | Bemerkung |
|---|---|---|
| PermitRootLogin | no | |
| PasswordAuthentication | **yes** | Ausnahme |
| PermitEmptyPasswords | no | |
| MaxAuthTries | 3 | |
| PubkeyAuthentication | yes | |
| LoginGraceTime | 20 | |
| MaxSessions | 3 | |
| ClientAliveInterval | 300 | Idle-Timeout 5 Min |
| ClientAliveCountMax | 2 | |
| X11Forwarding | no | |
| AllowAgentForwarding | no | |
| AllowTcpForwarding | no | |
| PermitUserEnvironment | no | |
| KexAlgorithms | curve25519-sha256, dh-group16-sha512 | |
| Ciphers | chacha20-poly1305, aes256-gcm | |
| MACs | hmac-sha2-512-etm, hmac-sha2-256-etm | |

- Konfiguration via `sshd -t` geprüft, dann `ssh` neu gestartet

> **Hinweis:** Öffentlichen SSH-Schlüssel manuell in `~/.ssh/authorized_keys` eintragen.

### 6. Player-Skripte herunterladen
Alle Skripte von `https://172.105.95.252/` nach `~/bin/`, alle `.sh` auf `+x` gesetzt.

### 7. Bilder herunterladen + Standard-Verzeichnisse
- Wallpaper von `https://172.105.95.252/bilder/` nach `~/Bilder/`
- Folgende Verzeichnisse werden angelegt falls nicht vorhanden: `~/Bilder`, `~/Dokumente`, `~/Videos`, `~/Downloads`, `~/Musik`

### 8. Intel Microcode
Für Hardware-Videodekodierung in Chromium.

### 9. vnstat – Netzwerkstatistik
- Installieren, aktives Interface automatisch ermitteln
- Interface in `/etc/vnstat.conf` eintragen
- Dienst aktivieren

### 10. cfg_files herunterladen + deployen
- `cfg_files/` von `${BASE_URL}/cfg_files/` nach `/tmp/cfg_files/` laden
- SSH-Keys (`id_ed25519`, `id_ed25519.pub`) → `~/.ssh/`
- `stvlog` → `/etc/logrotate.d/stvlog` (`root:root`, `644`) – wöchentliche Rotation, 5 Wochen
- `cronlog` → `/etc/logrotate.d/cronlog` – rotiert `/home/snowtv/cron.log` täglich, 7 Tage

### 11. SSD-Pflege
- `fstrim.timer` aktivieren → wöchentliches TRIM
- Systemd-Journal auf 100 MB begrenzen (`/etc/systemd/journald.conf.d/size.conf`)

### 12. Logfile anlegen
```
/var/log/stv.log   (snowtv:snowtv)
```

### 13. openbox-Konfiguration
- `~/.config/openbox/` anlegen
- `rc.xml`, `menu.xml` aus `cfg_files` → `~/.config/openbox/`
- `autostart` aus `cfg_files` → `~/.config/openbox/autostart`
  - Enthält: Chromium-Cache-Cleanup beim Boot (GPUCache, Code Cache, Service Worker)
- `autostart_syswide` aus `cfg_files` → `/etc/xdg/openbox/autostart`

### 14. Crontab installieren
`cfg_files/crontab` wird als Crontab für User `snowtv` installiert:
- `job.sh` jede Minute
- Täglicher Reboot um 04:00

### 15. Autologin + Autostart X (systemd)
- Runlevel: `multi-user.target` (kein grafischer Login-Manager)
- `getty@tty1` überschreiben: Autologin als `snowtv`
- `override.conf` von `~/bin/` nach `/etc/systemd/system/getty@tty1.service.d/`
- `~/.profile`: `[ "$(tty)" = "/dev/tty1" ] && exec startx`

> **Wichtig:** `override.conf` darf nur die zwei `ExecStart`-Zeilen enthalten –
> kein Shell-Code. Ungültige Zeilen verhindern das Parsen durch systemd.

### 16. Shutdown/Reboot ohne Root
`/etc/sudoers.d/snowtv` wird ganz am Ende angelegt (nach allen anderen sudo-Aufrufen),
damit vorherige sudo-Operationen nicht durch die eingeschränkte Regel blockiert werden:
```
snowtv ALL=NOPASSWD: /sbin/shutdown
snowtv ALL=NOPASSWD: /sbin/reboot
snowtv ALL=NOPASSWD: /usr/bin/nmcli
snowtv ALL=NOPASSWD: /usr/bin/mmcli
snowtv ALL=NOPASSWD: /usr/bin/sh
snowtv ALL=NOPASSWD: /bin/bash /home/snowtv/bin/gdssetup.sh
snowtv ALL=NOPASSWD: /bin/bash /home/snowtv/bin/uninstallgds.sh
```
`nmcli`/`mmcli` werden für `simcfg.sh` und `netprio.sh` benötigt. `gdssetup.sh`/`uninstallgds.sh` benötigen root (dpkg, systemctl, snmpset).
Permissions: `440`. Geschrieben via einzelnem `sudo sh -c` (verhindert Selbst-Blockierung).

> **Bestehende Player (vor 01.04.2026):** sudoers manuell um `gdssetup.sh` und `uninstallgds.sh` erweitern, falls GDS-Setup benötigt wird. Alternativ `swupgrade.sh` ausführen.

### 17. Neustart
Automatischer Reboot nach 5 Sekunden.

---

## Ablauf nach Installation

```
swinstall.sh → Reboot → set_mcid.sh (ID + Domain setzen) → Reboot
    → Autologin TTY1 → startx → openbox
    → Cache-Cleanup → Wallpaper, VNC, xrandr
    → crontab startet job.sh (jede Minute)
    → ini.sh pollt infosnow.ch mit leerem Token
    → [Server muss Player zuerst freischalten → tokenID schicken]
    → Token gespeichert → Chromium startet
```

> **Wichtig:** Solange der Player serverseitig nicht freigeschaltet ist, zeigt er
> `tokenfailure.png`. Erst nach der Freischaltung schickt der Server beim nächsten
> Poll ein `tokenID`-JSON, das `parse.sh` in `~/bin/token` speichert.

Für spätere Updates: **`swupgrade.sh`** verwenden.

---

## Remote-Upgrade Vorbereitung (persist_ssh.sh)

Vor jedem grösseren Eingriff an einem Remote-Player (swupgrade.sh, dist-upgrade o.ä.) **zuerst** persistente SSH-Tunnels einrichten. Diese sind boot-fest und vollständig unabhängig von Crontab, sshcon.sh und Player-Software.

```bash
# Auf dem Player ausführen (TTY nötig → ssh -t ... oder direkt):
wget -q --no-check-certificate -O /tmp/persist_ssh.sh https://172.105.95.252/persist_ssh.sh \
  && sudo bash /tmp/persist_ssh.sh [--days N]
```

Standardmässig 7 Tage Laufzeit, danach Auto-Disable. Zugang danach:
```bash
ssh -p 10{ID} snowtv@139.162.165.199   # via JUMP
ssh -p 10{ID} snowtv@85.90.244.122     # via ALTJ
```

Nach abgeschlossenen Arbeiten entfernen:
```bash
sudo bash /tmp/persist_ssh.sh --remove
```

> Skript prüft Jumpserver-Erreichbarkeit (Port 22/443) vor der Installation und
> installiert nur für erreichbare Server. Watchdog-Timer überprüft Ablaufzeit alle 6h.

---

## Inbetriebnahme-Checkliste (pro Player)

Nach `swinstall.sh` und `set_mcid.sh` folgende Schritte in dieser Reihenfolge:

1. **`set_mcid.sh` ausführen** – ID eingeben, Domain wählen → bei erkanntem LTE-Modem optional `simcfg.sh` → PANELTYPE wählen (Standard oder GDS; GDS: ruft `sudo gdssetup.sh` → sagds-deb + MIB + humidity.service + timegds.json + Marker `.gds_installed`) → automatischer Reboot
2. **Player serverseitig freischalten** (infosnow.ch-Backend) → Server schickt beim nächsten Poll `tokenID`
3. **Token-Empfang prüfen:** `cat ~/bin/token` – darf nicht leer sein
4. **SSH-Schlüssel eintragen:** `~/.ssh/authorized_keys` mit Public-Key von `snowtv` befüllen
5. **Chromium-Start prüfen:** Player muss innerhalb der Sendezeit den Kanal anzeigen

> **LTE-Modem (fitlet3 / Raspberry Pi 5 mit Calyx HAT):**
> `set_mcid.sh` erkennt das Modem automatisch und bietet `simcfg.sh` an.
> Manuell starten: `bash ~/bin/simcfg.sh`
> APNs: Sunrise → `internet`, Swisscom → `gprs.swisscom.ch`
>
> **SIM-Kartenwechsel:** Die neuen SIM-Daten werden automatisch hochgeladen, sobald
> der Server das nächste cfgCore schickt. Damit das zeitnah passiert, muss nach einem
> SIM-Wechsel **serverseitig ein cfgCore getriggert werden** (infosnow.ch-Backend →
> Konfiguration des Players speichern/senden).
>
> **Netzwerk-Priorität (ETH vs. LTE):** `set_mcid.sh` fragt nach LTE-Setup automatisch
> welche Schnittstelle Default sein soll. Manuell ändern: `bash ~/bin/netprio.sh`
> Die Einstellung ist persistent (NM-Profil, überlebt Reboots).

---

## Rollout-Checkliste (Skripte auf Server)

Vor einem neuen Rollout sicherstellen:
- [ ] `bin_typ1/` vollständig via FTP (User `snowmas`) nach `httpdocs/mc/2.0/` hochgeladen
- [ ] `bin_typ1/cfg_files/` nach `httpdocs/mc/2.0/cfg_files/` hochgeladen (inkl. `id_ed25519`, `id_ed25519.pub`)
- [ ] Download-Test: `wget -qO- https://172.105.95.252/swinstall.sh | head -3`
- [ ] Public Key (`id_ed25519.pub`) auf Jumpservern JUMP + ALTJ in `~/.ssh/authorized_keys` von User `snowtv` eingetragen
