diff --git a/README.md b/README.md index af483a4..c6d003b 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,8 @@ Two interfaces, both on the same binding and port. WebDAV is the same server und Neither is masked. The addresses published for `ui` are what init writes into `trusted_domains`, so an address Nextcloud does not know about is rejected by Nextcloud itself, not by StartOS. +**Legacy binding retirement:** updates retire container-port 443 and 8080 bindings left on `main` by the StartOS 0.3.5 package, leaving port 80, its assigned external ports, and the host's domains intact. If either legacy binding existed, `reattachUiOnions` in `store.json` stays pending until Tor is installed at `0.4.9.13:1` or newer. Init reattaches unused `nextcloud/main/*` onions to the Web UI on 80 without SSL, retaining their hostnames; addresses already served by a `main` binding are skipped. It clears the flag after every attachment succeeds, or preserves it for a later init after failure. Tor is optional: its absence defers reattachment without failing the Nextcloud update. + **Apache's connection timeouts are raised above every hop in front of it** — `KeepAliveTimeout 75` and `RequestReadTimeout header=90`, via `startos-proxy-keepalive.conf` baked into the image. The StartOS reverse proxy pins each client connection to a single backend connection (it never re-dials) and holds idle client connections for up to 60 seconds, and sync clients poll every 30; Debian's stock timeouts (5 s keep-alive, 20–40 s request-read) closed the backend leg first, which desktop clients experienced as periodic "Network error" disconnect/reconnect flaps, with paired `" -" 408 0` entries from the bridge gateway (`10.0.3.1`) in the service log at each flap. Details in the start-os issue: . If those symptoms return, first check the snippet is still enabled: `start-cli package attach nextcloud -n nextcloud-sub -- ls /etc/apache2/conf-enabled/`. **The request scheme is per-request, derived from the proxy's `X-Forwarded-Proto`.** TLS terminates at the StartOS reverse proxy, which strips any client-supplied `X-Forwarded-Proto`/`X-Forwarded-For` on TLS bindings and injects its own; Apache always sees plain http. Nextcloud honors the header because the proxy connects from the container bridge, which `trusted_proxies` (`10.0.3.0/24`) covers, so PHP-generated URLs come out `https` on TLS addresses and `http` on plain ones (an onion binding) — which is why `overwriteprotocol` is deliberately kept unset. The image's `mod_remoteip` is disabled (`APACHE_DISABLE_REWRITE_IP=1`) so `REMOTE_ADDR` always is the proxy's IP and that trust can never break. The one place PHP can't help is Apache's own `.htaccess` redirects — `/.well-known/carddav`, `/.well-known/caldav`, and the WebDAV-client redirect on `/` — which absolutize from Apache's scheme; `startos-dav-redirects.conf`, baked into the image, issues those with the forwarded scheme instead, and Nextcloud has no PHP fallback for them (its well-known controller serves only `webfinger`/`nodeinfo`). Details: . To diagnose, `curl -sk -o /dev/null -w '%{http_code} %{redirect_url}' https://
/.well-known/carddav` must redirect to an `https://` URL; an `http://` target means the conf is missing or the header chain is broken. diff --git a/instructions.md b/instructions.md index eb2bcd0..834af69 100644 --- a/instructions.md +++ b/instructions.md @@ -27,6 +27,10 @@ Nextcloud auto-generates an admin password on first install and posts a critical Open the **Web UI** interface to reach Nextcloud's web interface. From there you install apps from the Nextcloud App Store, manage users and groups, and use Files, Calendar, Contacts, Photos, Talk, and anything else you install. +### Keeping an existing .onion address after an update + +If your server carried Nextcloud over from StartOS 0.3.5, updating frees its old network bindings and reattaches an unused .onion address to the Web UI while keeping its hostname. Install or update Tor to `0.4.9.13:1` or newer to complete that reattachment; Nextcloud can update without Tor and waits for it to become available. Use the updated Web UI or WebDAV interface address when reconnecting clients: the reattached onion uses plain HTTP, which Tor encrypts in transit. + ### WebDAV Point a Nextcloud desktop or mobile client (or any WebDAV client) at the **WebDAV** interface address to sync files. Use the username and password of the Nextcloud account you want to sync, not the admin account if it's a personal device. diff --git a/package-lock.json b/package-lock.json index 712414b..bfddb80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,9 +6,10 @@ "": { "name": "nextcloud-startos", "dependencies": { - "@start9labs/start-sdk": "3.0.3", + "@start9labs/start-sdk": "3.0.4", "filebrowser-startos": "github:Start9Labs/filebrowser-startos#next", - "nextexplorer-startos": "github:Start9Labs/nextexplorer-startos#next" + "nextexplorer-startos": "github:Start9Labs/nextexplorer-startos#next", + "tor-startos": "github:Start9Labs/tor-startos#next" } }, "node_modules/@eslint-community/eslint-utils": { @@ -252,9 +253,9 @@ "license": "MIT" }, "node_modules/@start9labs/start-sdk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@start9labs/start-sdk/-/start-sdk-3.0.3.tgz", - "integrity": "sha512-vnysNRhlEeUIlPyYq+505CSDbCIpODtydK07YXNVAdNiMC8sLclKpqNVVdwQ/a3fhy+yCsgYmKhHzPGAkBdeJA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@start9labs/start-sdk/-/start-sdk-3.0.4.tgz", + "integrity": "sha512-G02R4TlaLmTSisMpPnSAHB9KOSqJydjsKOeijwMkHp87ek6eNxg/FissID+AsheXmDcZSiyieos45lxud4kihA==", "bundleDependencies": [ "@start9labs/start-core" ], @@ -1623,6 +1624,12 @@ "node": ">=4" } }, + "node_modules/rfc4648": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.4.tgz", + "integrity": "sha512-rRg/6Lb+IGfJqO05HZkN50UtY7K/JhxJag1kP23+zyMfrvoB0B7RWv06MbOzoc79RgCdNTiUaNsTT1AJZ7Z+cg==", + "license": "MIT" + }, "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", @@ -1711,6 +1718,14 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tor-startos": { + "resolved": "git+ssh://git@github.com/Start9Labs/tor-startos.git#84bab8e43edfc3917d6e73e08557efe23fca3015", + "dependencies": { + "@noble/curves": "*", + "@start9labs/start-sdk": "3.0.3", + "rfc4648": "^1.5.4" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", diff --git a/package.json b/package.json index e227390..f5ada9d 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,10 @@ "regen-parser": "npx -y peggy@5.1.0 --format commonjs -o startos/fileModels/php-parser.js startos/fileModels/php.pegjs && prettier --write startos/fileModels/php-parser.js" }, "dependencies": { - "@start9labs/start-sdk": "3.0.3", + "@start9labs/start-sdk": "3.0.4", "filebrowser-startos": "github:Start9Labs/filebrowser-startos#next", - "nextexplorer-startos": "github:Start9Labs/nextexplorer-startos#next" + "nextexplorer-startos": "github:Start9Labs/nextexplorer-startos#next", + "tor-startos": "github:Start9Labs/tor-startos#next" }, "overrides": { "@start9labs/start-sdk": "$@start9labs/start-sdk" diff --git a/startos/fileModels/store.json.ts b/startos/fileModels/store.json.ts index 92185a3..fe0239e 100644 --- a/startos/fileModels/store.json.ts +++ b/startos/fileModels/store.json.ts @@ -69,6 +69,8 @@ const shape = z.looseObject({ // applied, and the record of what to clear on the next change. Same // desired-vs-actual split, and the same non-reactive read, as the two above. officeConfigured: z.string().catch('').default(''), + // Set when a migration retires a 0.3.5 binding; cleared once reattachUiOnions succeeds. + reattachUiOnions: z.boolean().catch(false).default(false), }) export type Store = z.infer diff --git a/startos/init/index.ts b/startos/init/index.ts index 3c28fef..b55a3e5 100644 --- a/startos/init/index.ts +++ b/startos/init/index.ts @@ -5,6 +5,7 @@ import { setInterfaces } from '../interfaces' import { sdk } from '../sdk' import { versionGraph } from '../versions' import { bootstrapNextcloud, guardUpstreamUpgrade } from './bootstrapNextcloud' +import { reattachUiOnions } from './reattachUiOnions' import { seedFiles } from './seedFiles' export const init = sdk.setupInit( @@ -16,6 +17,7 @@ export const init = sdk.setupInit( actions, dependencies, bootstrapNextcloud, + reattachUiOnions, ) export const uninit = sdk.setupUninit(versionGraph) diff --git a/startos/init/reattachUiOnions.ts b/startos/init/reattachUiOnions.ts new file mode 100644 index 0000000..19ccc5c --- /dev/null +++ b/startos/init/reattachUiOnions.ts @@ -0,0 +1,18 @@ +import { setupOnionReattachment } from 'tor-startos/startos/utils/reattach' +import { storeJson } from '../fileModels/store.json' +import { manifest } from '../manifest' +import { sdk } from '../sdk' +import { uiPort } from '../utils' + +export const reattachUiOnions = setupOnionReattachment(sdk, { + packageId: manifest.id, + hostId: 'main', + to: { interfaceId: 'ui', internalPort: uiPort, ssl: false }, + pending: storeJson.read((s) => s.reattachUiOnions), + clear: (effects) => + storeJson.merge( + effects, + { reattachUiOnions: false }, + { allowWriteAfterConst: true }, + ), +}) diff --git a/startos/versions/current.ts b/startos/versions/current.ts index 170e63c..559da83 100644 --- a/startos/versions/current.ts +++ b/startos/versions/current.ts @@ -1,31 +1,45 @@ import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk' +import { storeJson } from '../fileModels/store.json' +import { sdk } from '../sdk' export const current = VersionInfo.of({ - version: '35.0.1:1', + version: '35.0.1:2', releaseNotes: { en_US: `- Disable Maintenance Mode, Repair and Scan Files ask for confirmation before running. - The Office Suite, Delete Files in Trash and External Storage settings explain what each choice does. - Reset Admin Password offers only members of Nextcloud's admin group. -- The Delete Files in Trash choices are translated.`, +- The Delete Files in Trash choices are translated. +- Network ports left reserved by the StartOS 0.3.5 version of this package are freed. If that version had a Tor address, Nextcloud moves it to the Web UI, keeping the same .onion address, as soon as a version of Tor that allows it is installed.`, es_ES: `- Desactivar modo de mantenimiento, Reparar y Escanear archivos piden confirmación antes de ejecutarse. - Los ajustes Suite ofimática, Eliminar los archivos de la papelera y Almacenamiento externo explican qué hace cada opción. - Restablecer contraseña de administrador solo ofrece miembros del grupo admin de Nextcloud. -- Las opciones de Eliminar los archivos de la papelera están traducidas.`, +- Las opciones de Eliminar los archivos de la papelera están traducidas. +- Se liberan los puertos de red que la versión de este paquete para StartOS 0.3.5 dejó reservados. Si esa versión tenía una dirección Tor, Nextcloud la traslada a la interfaz web, conservando la misma dirección .onion, en cuanto se instala una versión de Tor que lo permita.`, de_DE: `- Wartungsmodus deaktivieren, Reparieren und Dateien scannen fragen vor der Ausführung nach einer Bestätigung. - Die Einstellungen Office-Suite, Dateien im Papierkorb löschen und Externer Speicher erklären, was jede Auswahl bewirkt. - Admin-Passwort zurücksetzen bietet nur Mitglieder der Nextcloud-Gruppe admin an. -- Die Auswahlmöglichkeiten von Dateien im Papierkorb löschen sind übersetzt.`, +- Die Auswahlmöglichkeiten von Dateien im Papierkorb löschen sind übersetzt. +- Netzwerkports, die die StartOS-0.3.5-Version dieses Pakets belegt gelassen hatte, werden freigegeben. Hatte diese Version eine Tor-Adresse, verlegt Nextcloud sie auf die Weboberfläche und behält dieselbe .onion-Adresse, sobald eine Tor-Version installiert ist, die das erlaubt.`, pl_PL: `- Wyłącz tryb konserwacji, Napraw i Skanuj pliki proszą o potwierdzenie przed uruchomieniem. - Ustawienia Pakiet biurowy, Usuwanie plików z kosza i Magazyn zewnętrzny wyjaśniają, co oznacza każdy wybór. - Resetuj hasło administratora oferuje tylko członków grupy admin w Nextcloud. -- Opcje ustawienia Usuwanie plików z kosza są przetłumaczone.`, +- Opcje ustawienia Usuwanie plików z kosza są przetłumaczone. +- Porty sieciowe, które wersja tego pakietu dla StartOS 0.3.5 pozostawiła zajęte, zostają zwolnione. Jeśli ta wersja miała adres Tor, Nextcloud przenosi go na interfejs webowy, zachowując ten sam adres .onion, gdy tylko zostanie zainstalowana wersja Tora, która na to pozwala.`, fr_FR: `- Désactiver le mode maintenance, Réparer et Scanner les fichiers demandent une confirmation avant de s'exécuter. - Les réglages Suite bureautique, Suppression des fichiers de la corbeille et Stockage externe expliquent l'effet de chaque choix. - Réinitialiser le mot de passe administrateur ne propose que les membres du groupe admin de Nextcloud. -- Les choix de Suppression des fichiers de la corbeille sont traduits.`, +- Les choix de Suppression des fichiers de la corbeille sont traduits. +- Les ports réseau que la version de ce paquet pour StartOS 0.3.5 avait laissés réservés sont libérés. Si cette version avait une adresse Tor, Nextcloud la déplace vers l'interface web, en conservant la même adresse .onion, dès qu'une version de Tor qui le permet est installée.`, }, migrations: { - up: async () => {}, + up: async ({ effects }) => { + // Tor keeps an .onion on a retired port as unused; reattachUiOnions moves it to 80. + const main = sdk.MultiHost.of(effects, 'main') + const retired = [await main.retirePort(8080), await main.retirePort(443)] + if (retired.some(Boolean)) { + await storeJson.merge(effects, { reattachUiOnions: true }) + } + }, down: IMPOSSIBLE, }, })