Skip to content

Onaylı otomatik güncelleme ve USB'den güncelleme / Approval-based auto-update and USB updates (#2) - #14

Open
Proxy34 wants to merge 13 commits into
schematrix:mainfrom
Proxy34:otomatik-guncelleme
Open

Proxy34 wants to merge 13 commits into
schematrix:mainfrom
Proxy34:otomatik-guncelleme

Conversation

@Proxy34

@Proxy34 Proxy34 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Closes #2

Onaylı otomatik güncelleme ve internetsiz USB'den güncelleme. Issue #2'de önerildiği gibi #3 ve #5'in üstüne kurulu; o ikisi birleşince bu PR'da yalnızca kendi commit'leri kalır.

  • Kendiliğinden hiçbir şey indirmez. Pi internete bağlanınca (NetworkManager kancası, en fazla 6 saatte bir; sürekli bağlı kutularda ayrıca günde bir) yeni sürümlere bakar. Ana sayfada boyutlarıyla bir liste ve "Seçilenleri güncelle" butonu çıkar. Pi çoğu zaman telefondan internet paylaşımıyla bağlı ve yalnızca İngilizce Vikipedi 120 GB; kararı kullanıcı verir.
  • Diske sığmayan içerik seçilemez, eski sürüm çalışmaya devam eder. Varsayılan seçim toplamda diske sığanlarla sınırlı. Kutuda hiç olmayan içerikler (yeni kurulumda hepsi) listede kapalı durur ve seçili gelmez. Kotalı bağlantıda ana sayfa mobil veri uyarısı verir.
  • İndirme Fix retired ZIM names, add Turkish content, catalog-based versions + SHA-256 / Ölü ZIM adları, Türkçe içerik, katalog tabanlı sürüm + SHA-256 #3'ün download-content.sh'ı (SHA-256) ve Offline vector map without the admin-console download (works in Turkey) / Çevrimdışı vektör harita: yönetim paneli indirmesi gerekmez (Türkiye'de çalışır) #5'in download-map.sh --update'i ile yapılır. İlerleme ana sayfada çubukla görünür. Harita sürüm listesi (builds.json) alınamazsa son günlerin harita dosyası doğrudan bulunur.
  • USB'den, internetsiz: USB disk takılınca salt okunur bağlanır; kutuda olmayan ya da daha yeni .zim dosyaları aynı listede "(USB'den)" etiketiyle çıkar. Kopya, ZIM dosyasının içindeki MD5 özetiyle doğrulanır; bozuk kopya kurulmaz. /library SSD'si USB ile bağlı olsa bile içerik diski sayılmaz.
  • Yönetici şifresi: buton yalnızca iiab-admin şifresiyle (kurulumda belirlenen, /admin girişindeki şifre) çalışır; ayrı bir şifre yok. Servis root olmadan çalışır: başlarken root bir adım yalnızca iiab-admin'in özetini /run/has-update/admin'e koyar, şifre değişince kendiliğinden yenilenir. Yanlış şifre 10 dakikada 5 denemeyle sınırlı. Liste herkese görünür.
  • Güvenlik: buton servisi yetkisiz bir kullanıcıyla (DynamicUser) çalışır, yalnızca listedeki içerikleri kabul eder ve yalnızca JSON alır; asıl indirmeyi root olarak bir systemd path birimi başlatır. Aynı anda tek güncelleme çalışır.

Test: Debian 13 + Internet-in-a-Box sanal makinesinde: gerçek Kiwix kataloğundan kontrol, nginx üzerinden buton, gerçek indirme ve SHA-256, internet gelince otomatik kontrol, taklit USB bellekle (dummy_hcd + g_mass_storage) sağlam/bozuk/eski dosya senaryoları, çıkarma ve yeniden başlatma, iiab-admin şifresi (boş/yanlış/doğru, deneme sınırı, şifre değişimi, yeniden başlatma). Gerçek bir Pi 5'te denenmedi.


Approval-based automatic updates and updates from a USB drive without internet. Built on #3 and #5 as suggested in #2; once those are merged only this PR's own commits remain.

  • Never downloads on its own. When the Pi gets internet (NetworkManager hook, at most every 6 h, plus daily for boxes that stay online) it checks for newer versions; the homepage shows a list with sizes and a "Seçilenleri güncelle" button. The user decides, since the Pi is often on a phone hotspot and English Wikipedia alone is 120 GB.
  • Items that don't fit can't be selected and the old version keeps working; the default selection only includes what fits together. Content the box doesn't have yet (all of it on a fresh install) stays folded and unselected. Metered connections get a mobile data warning.
  • Downloads go through Fix retired ZIM names, add Turkish content, catalog-based versions + SHA-256 / Ölü ZIM adları, Türkçe içerik, katalog tabanlı sürüm + SHA-256 #3's download-content.sh (SHA-256) and Offline vector map without the admin-console download (works in Turkey) / Çevrimdışı vektör harita: yönetim paneli indirmesi gerekmez (Türkiye'de çalışır) #5's download-map.sh --update, with a progress bar on the homepage. If the map build list (builds.json) can't be fetched, recent daily map files are probed directly.
  • From USB, offline: a plugged-in drive is mounted read-only; missing or newer .zim files show up in the same list marked "(USB'den)". Each copy is verified against the MD5 stored inside the ZIM file. The /library SSD is never treated as a content drive, even over USB.
  • Admin password: the button only works with the iiab-admin password (set at install, also used for /admin); no second password. The service stays unprivileged: a root start step copies only iiab-admin's hash to /run/has-update/admin, refreshed automatically when the password changes. 5 wrong tries per 10 minutes. The list stays visible to everyone.
  • Security: the button service runs unprivileged (DynamicUser), accepts only listed items and only JSON; the download itself is started as root by a systemd path unit. One update at a time.

Tested in a Debian 13 + IIAB VM, including an emulated USB stick (dummy_hcd + g_mass_storage) with good, corrupt and older files, unplugging, reboots and the iiab-admin password (empty/wrong/right, rate limit, password change, reboot). Not tested on a real Pi 5.

Firewall (Proxy34)

turer73 and others added 6 commits November 1, 2026 20:19
…e map download needed

IIAB'ın harita indirmesi (contabostorage) Türkiye'de engelli; README bunun için WARP öneriyor.
scripts/download-map.sh Protomaps planet build'inden bölge kesiti (PMTiles) alır, küçük bir
MapLibre sayfasını /library/www/html/harita/ altına kurar; nginx dosyaları olduğu gibi sunar
(Range desteği hazır), ek ayar yok. Türkiye kesiti ~1,7 GB, z15, Türkçe etiketli.

The IIAB map download (contabostorage) is blocked in Turkey and the README suggests WARP for it.
scripts/download-map.sh cuts a region (PMTiles) from the Protomaps planet build and installs a
small MapLibre page under /library/www/html/harita/; nginx serves the files as-is (Range works
out of the box), no extra config. Turkey extract ~1.7 GB, zoom 15, Turkish labels.
…hematrix#2)

When the Pi gets internet it checks the Kiwix catalog and the Protomaps
build for newer versions; it never downloads on its own. The homepage
lists the updates with sizes, warns on metered (phone hotspot)
connections, disables items that do not fit on the disk, and anyone on
the network can start the download with one button.

- scripts/auto-update.sh: --check (rate-limited) and --apply
- download-content.sh: CHECK_ONLY mode, reused for the check
- update/: unprivileged button endpoint, systemd units, NetworkManager
  hook, nginx config; scripts/install-auto-update.sh installs them
- Builds on schematrix#3 and schematrix#5.
… seç

Varsayılan seçim boş alan ve payla sınırlı; seçim sığmazsa buton kapanır. Yüklü olmayan içerik için 'eski sürüm' uyarısı gösterilmez.
…leme

USB disk takılınca salt okunur bağlanır; kutuda olmayan ya da daha yeni ZIM'ler ana sayfadaki güncelleme listesine '(USB'den)' etiketiyle eklenir. Kopya, ZIM içindeki MD5 ile doğrulanır. fstab'daki ya da zaten bağlı diskler (USB'li SSD) atlanır; liste /run altında tutulur. install-auto-update.sh artık API'yi yeniden başlatıyor.
@schematrix

Copy link
Copy Markdown
Owner

Onaysız hiçbir şey indirmemesi ve USB'den güncelleme çok iyi düşünülmüş, teşekkürler. Bu PR #3 ve #5'e bağlı, önce onları bitirmek istiyorum. Bir de güvenlik tarafında bir ricam var: şu an Wi-Fi'a bağlanan herkes güncellemeyi başlatabiliyor. Pi telefon hotspot'una bağlıysa biri büyük bir indirme başlatıp bütün mobil veriyi bitirebilir. Buton sadece admin girişiyle çalışabilir mi?

Not downloading anything without approval and the USB updates are really well thought out, thanks. This PR depends on #3 and #5, so I'd like to finish those first. One security request too: right now anyone on the Wi-Fi can start an update. If the Pi is on a phone hotspot, someone could kick off a big download and burn through all the mobile data. Could the button work only after an admin login?

…i şifresi ister

Kurulumda bir kez sorulur, tuzlu PBKDF2 özeti /etc/has-update/admin'e yazılır ve
servise LoadCredential ile verilir; --sifre ile değiştirilir. Yanlış şifre denemeleri sınırlı.
Asked once at install; a salted PBKDF2 hash is stored in /etc/has-update/admin and passed
to the service with LoadCredential; change it with --sifre. Wrong passwords are rate limited.
@Proxy34

Proxy34 commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Tamam, #3 ve #5'i bekliyorum. Bu arada butonu yönetici şifresine bağladım:

  • Şifre kurulumda bir kez sorulur, sudo ./scripts/install-auto-update.sh --sifre ile değiştirilir.
  • Şifrenin kendisi saklanmaz; /etc/has-update/admin içinde yalnızca tuzlu PBKDF2 özeti durur (root, 600) ve servise systemd LoadCredential ile verilir. Servis yine yetkisiz kullanıcıyla çalışır.
  • Ana sayfada butonun yanında şifre kutusu var. Yanlış şifre 10 dakikada 5 denemeyle sınırlı.
  • Güncelleme listesi herkese görünmeye devam ediyor, yalnızca başlatmak şifre istiyor.

IIAB'nin iiab-admin hesabını kullanmadım, çünkü sistem şifresini kontrol etmek için buton servisine root yetkisi gerekirdi. Bu yüzden ayrı bir şifre koydum; istersen değiştiririm.

Sanal makinede boş/yanlış/doğru şifre, deneme sınırı, şifre değiştirme ve tarayıcıdan gerçek indirme denendi.

Firewall (Proxy34)

@schematrix

Copy link
Copy Markdown
Owner

Şifre konusunu düşündüm. Root yetkisi konusundaki gerekçen çok mantıklı, butona root yetkisi vermek istemem. Ama kullanıcı açısından iki ayrı şifre kafa karıştırır, afet anında kimse hangi şifrenin nerede kullanıldığını hatırlamaz. O yüzden şu aşamada olabildiğince tek şifreyle ilerleyelim. Örneğin kurulum sırasında iiab-admin için girilen şifreyi güncelleme butonu için de kullanmak mümkün mü? Root yetkisi gerektirmeyen bir yolu varsa onu tercih ederim, yoksa önerine açığım.


I've thought about the password. Your reasoning about root access makes a lot of sense, I don't want to give the button root privileges either. But from a user's point of view, two separate passwords are confusing, and in a disaster nobody will remember which password goes where. So at this stage let's stick to a single password as much as possible. For example, would it be possible to use the password entered for iiab-admin during install for the update button as well? If there's a way to do it without root access I'd prefer that, otherwise I'm open to your suggestion.

…dmin şifresini kullanır

Ayrı şifre yerine kurulumda belirlenen iiab-admin şifresi. Servis yetkisiz kalır: başlarken
root bir adım yalnızca iiab-admin'in /etc/shadow özetini /run/has-update/admin'e koyar,
şifre değişince has-update-admin.path yeniler. yescrypt'i sistemin libcrypt'i doğrular.
One password instead of two. The service stays unprivileged: a root start step copies only
iiab-admin's hash from /etc/shadow, has-update-admin.path refreshes it on change.
@Proxy34

Proxy34 commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Haklısın, tek şifreye geçtim. Buton artık iiab-admin şifresini (kurulumda belirlenen, /admin girişinde kullanılan şifre) istiyor; ayrı şifre ve --sifre kalktı.

Root yetkisi gerekmiyor:

  • Buton servisi yine yetkisiz kullanıcıyla çalışıyor ve /etc/shadow'u okuyamıyor.
  • Servis başlarken systemd'nin root çalışan kısa bir adımı (admin-hash.sh) yalnızca iiab-admin'in şifre özetini servisin kendi klasörüne (/run/has-update/admin, 600) koyuyor. Servis başka hiçbir hesabın özetini görmüyor.
  • iiab-admin şifresi değişirse has-update-admin.path özeti kendiliğinden yeniliyor, yeni şifre hemen geçerli oluyor.
  • Şifre kontrolünü sistemin kendi libcrypt'i yapıyor (Debian 13 yescrypt kullanıyor).

Sanal makinede denendi: doğru/yanlış/boş şifre, deneme sınırı, chpasswd ile şifre değişimi (yeni şifre geçiyor, eskisi reddediliyor), yeniden başlatma ve doğru şifreyle gerçek indirme.

Firewall (Proxy34)

@volthdl

volthdl commented Nov 3, 2026

Copy link
Copy Markdown

Merhaba @Proxy34, eline sağlık. #2'de incelemeye söz vermiştim; son hâli (fdd057f) okudum ve şifre kontrolünü ayrıca denedim (donanımda çalıştırmadım).

Tek şifreye geçiş güzel olmuş. Buton servisinin yetkisiz kalması, root adımın yalnızca iiab-admin özetini kopyalaması ve kontrolün libcrypt'e bırakılması temiz bir çözüm. password_ok'u yescrypt ve sha512 özetleriyle denedim: doğru şifre geçiyor; yanlış, boş ve kilitli hesap (!, *, boş) reddediliyor; crypt çağrısının kilitle korunması da doğru. Root tarafın seçilen adları updates.json / usb.json'a göre yeniden doğrulaması da iyi.

İki öneri:

  1. Yanlış şifre sınırına genel bir üst sınır. iiab-admin IIAB'de sudo grubunda (iiab_admin_can_sudo: True) ve SSH açık; yani buton artık root yetkili bir hesabın şifresini deniyor. Mevcut sınır IP başına 10 dakikada 5; hotspot'taki biri IP adresini değiştirerek bunu aşabilir. IP başına sınırın yanına tüm cihazlar için toplam bir sınır (örneğin 10 dakikada 20 yanlış deneme) eklemek kolay ve çok şey kazandırır. Bunu aşan bir saldırganın en fazla birkaç dakikalığına butonu kilitleyebilmesi, şifreyi tahmin edebilmesinden çok daha az zararlı.
  2. USB'den gelen dosyanın kaynağı doğrulanmıyor. zim_ok ZIM'in kendi MD5 sağlamasını kontrol ediyor; bu bozulmayı yakalar ama değiştirilmiş bir dosyayı yakalamaz, çünkü sağlama yeniden hesaplanabilir. Adı daha yeni tarihli bir ZIM (ör. ..._2099-01.zim) mevcut sürümün yerine geçer ve eskisi silinir; tıp kitapları için bu önemli. Öneri: yalnızca content.conf'taki ön eklere izin vermek ve USB satırında "yalnızca güvendiğiniz kaynaktan gelen USB'yi onaylayın" uyarısı göstermek.

Birleştirme sırası: README ve ana sayfada #9 (mesh sohbet) ile çakışıyor; ikisi de yeni bölüm eklediği için çözmesi kolay. #14 önce birleşirse #9'u ben güncellerim.


EN: Reviewed fdd057f and tested the password check (not run on hardware). Switching to the single iiab-admin password is clean: the service stays unprivileged, a root step copies only iiab-admin's hash, and libcrypt verifies it. With yescrypt and sha512 hashes the right password passes and wrong, empty and locked (!, *, empty) hashes fail; the lock around crypt is right too. Two suggestions: (1) iiab-admin is in sudo (iiab_admin_can_sudo: True) and SSH is on, so the button now guesses a root-capable account's password; the 5-per-10-min limit is per IP and can be bypassed by changing IP on the hotspot, so add a global cap (e.g. 20 wrong tries per 10 min across all clients). (2) USB imports only check the ZIM's own MD5, which catches corruption but not tampering; restrict to content.conf prefixes and warn to approve only trusted drives. README/homepage conflicts with #9 are simple; I'll update #9 if #14 lands first.

… yanlış şifre sınırı; USB'den yalnızca content.conf içerikleri
@Proxy34

Proxy34 commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

@volthdl incelemen ve testlerin için teşekkürler, iki öneriyi de ekledim (3009020).

  1. Yanlış şifre sınırına tüm cihazlar için toplam bir sınır ekledim: 10 dakikada cihaz başına 5, toplamda 20 yanlış deneme. Sanal makinede 20 farklı IP'den denedim; 20 yanlıştan sonra yeni bir IP de bekletiliyor, tek cihaz sınırı da eskisi gibi çalışıyor. Dediğin gibi, biri bilerek yanlış şifre denerse butonu en fazla 10 dakika kilitleyebiliyor, şifreyi tahmin edemiyor.
  2. USB'den artık yalnızca content.conf'taki içerikler alınıyor. Listede olmayan bir ZIM USB'de dursa da güncelleme listesine çıkmıyor, istekle gönderilse de reddediliyor. USB'den gelen içerik varsa şifre kutusunun üstünde "yalnızca güvendiğiniz bir kaynaktan geldiyse seçin" uyarısı çıkıyor. README'ye de MD5 özetinin dosyayı kimin hazırladığını kanıtlamadığını ekledim.

Bunları sanal makinede sahte bir USB klasörüyle denedim: listedeki ZIM kopyalanıp kuruldu, listede olmayan çıkmadı.

#9 için de teşekkürler, #14 önce birleşirse çakışmayı senin çözmen çok iyi olur.

Firewall (Proxy34)

@volthdl

volthdl commented Nov 3, 2026

Copy link
Copy Markdown

Teşekkürler @Proxy34, 3009020'ı kontrol ettim: toplam sınır mantığı doğru, USB filtresini de örnek dosya adlarıyla denedim. Listedeki içerikler kabul ediliyor; listeden çıkarılmış, yorum satırında duran ya da hiç listede olmayanlar reddediliyor. Değiştirilmiş bir kopyanın çevrimdışı ayırt edilememesi için arayüzdeki uyarı ve README notu da yerinde. Benim tarafımdan başka bir şey yok. #14 önce birleşirse #9'u güncellerim.

EN: Checked 3009020: the global cap logic is right, and the USB filter accepts listed items and rejects retired, commented-out and unlisted ones in my test. The UI warning and README note cover what can't be verified offline. Nothing more from me; I'll update #9 if #14 lands first.

@ramazansancar

Copy link
Copy Markdown

@Proxy34 Conflict var müsait olduğunda çözebilir misin?

# Conflicts:
#	README.md
#	install.sh
#	www/home/index.html
…fre kutusu: telefonda tam genişlik, yakınlaştırma yok
@Proxy34

Proxy34 commented Nov 7, 2026

Copy link
Copy Markdown
Contributor Author

@ramazansancar güncel main'i birleştirip çakışmaları çözdüm. Telefonda şifre kutusuna dokununca iPhone'un sayfayı yakınlaştırmaması için kutuyu telefonda tam genişlik ve 16 px yaptım. Sanal makinede kurup kontrol ettim: disk uyarısı ve güncelleme listesi ana sayfada birlikte çalışıyor. #14 hâlâ #5'in birleşmesini bekliyor.

Firewall (Proxy34)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] About the automatic update system (wiki, maps etc.)

5 participants