From 9b04c158a5e4d306bf2fee9d948482bf75741f4a Mon Sep 17 00:00:00 2001 From: njomac Date: Wed, 29 Jul 2026 17:44:05 +0200 Subject: [PATCH] feat: hrvatski raspored tipkovnice za RDP (hr-hr-qwertz) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Guacamole isporucuje 22 rasporeda, hrvatskog nema. Rasporedi se kompajliraju u libguac-client-rdp, pa se ne mogu dodati naknadno — guacd se mora ponovno prevesti. guacd-hr/hr_hr_qwertz.keymap Izveden iz X11 "hr" rasporeda na stvarnom sustavu (hr -> rs(latin): rs(common) za brojcani red, rs(latalpha) za s/d/c/c/z s dijakriticima, rs(latlevel3) za AltGr), ne po sjecanju. Strukturno prati cs-cz-qwertz jer njegov caps model dira samo slova, dok de_de_qwertz izvrce i brojcani red. guacd-hr/build.sh Preuzme sluzbeni izvor tražene verzije, ubaci keymap u keymaps/ i u popis rdp_keymaps, pa gradi koristeci Dockerfile koji dolazi uz taj izvor. Namjerno se ne prepisuje upstream receptura, da nadogradnja bude "./build.sh 1.7.0" umjesto odrzavanja vlastitog builda. Ovisnosti su zakljucane jer ih upstream gradi iz gita i bira najnoviji tag, pa gradnja pukne sama od sebe: libwebsockets v5 trazi GnuTLS kojeg build okruzenje 1.6.0 nema, a FreeRDP 2.x je odmakao na razvojne tagove koje configure odbija. Zakljucani su na v4.x i 2.11.7 — ono sto nosi sluzbeni guacd:1.6.0 — i pregazivi su preko env varijabli. install.sh Novo pitanje pri instalaciji; ako se prihvati, gradi image i compose koristi njega umjesto sluzbenog guacd-a. Postojeci image se ne gradi ponovno. Provjereno cistom instalacijom na Ubuntu 24.04: gradnja prolazi u sklopu installera, image sadrzi hr-hr-qwertz uz svih 22 standardnih, FreeRDP je 2.11.7 kao u sluzbenom, i svih 9 GUI stranica vraca 200. Co-Authored-By: Claude Opus 5 --- README.md | 2 + UPUTE.txt | 22 ++++++++- guacd-hr/build.sh | 81 +++++++++++++++++++++++++++++++ guacd-hr/hr_hr_qwertz.keymap | 92 ++++++++++++++++++++++++++++++++++++ install.sh | 25 +++++++++- 5 files changed, 220 insertions(+), 2 deletions(-) create mode 100755 guacd-hr/build.sh create mode 100644 guacd-hr/hr_hr_qwertz.keymap diff --git a/README.md b/README.md index fa7e7e2..c17663a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ web-based RDP/VNC/SSH pristup udaljenim računalima. - **Nginx** — reverse proxy s Basic Auth zaštitom - **fail2ban** — automatsko blokiranje brute-force napada - **TOTP 2FA** — dvofaktorska autentikacija +- **Hrvatski raspored** — `hr-hr-qwertz` za RDP (po izboru, gradi vlastiti guacd) - **Web GUI** — web sučelje za upravljanje svim postavkama ## Podržani OS @@ -49,6 +50,7 @@ Skripta pita za sve potrebne podatke i automatski instalira sve komponente. | `install.sh` | Glavni installer — sve u jednoj skripti | | `manage.sh` | CLI upravljanje nakon instalacije | | `webgui/` | Flask web GUI aplikacija | +| `guacd-hr/` | Hrvatski raspored tipkovnice + skripta za gradnju guacd-a | | `UPUTE.txt` | Detaljne upute i dokumentacija | ## Web GUI stranice diff --git a/UPUTE.txt b/UPUTE.txt index 164da2f..a9d11eb 100644 --- a/UPUTE.txt +++ b/UPUTE.txt @@ -119,7 +119,27 @@ Skripta postavlja sljedeća pitanja redom: odjednom, rate limit postaje jedan zajednicki budzet za sve, a GeoIP filtrira po adresi proxyja i ne radi nista. - 7. WEB GUI + 7. HRVATSKI RASPORED TIPKOVNICE + y = da, n = ne + Guacamole ne isporucuje hrvatski raspored — postoji 22 rasporeda, + hrvatskog nema. Rasporedi su kompajlirani u libguac-client-rdp, + pa se ne mogu dodati naknadno; guacd se mora ponovno prevesti. + + Odgovorite li DA, install.sh pokrece guacd-hr/build.sh koji + preuzme sluzbeni izvor, ubaci hr_hr_qwertz.keymap i sagradi + image guacd:-hr. Traje 15-30 min (gradi se i FreeRDP). + + Nakon toga na svakoj RDP konekciji treba postaviti: + server-layout = hr-hr-qwertz + a ciljno racunalo mora imati hrvatski raspored. + + Napomena: time prelazite na vlastiti guacd image, pa nadogradnja + Guacamolea trazi ponovnu gradnju: + ./guacd-hr/build.sh 1.7.0 + + Za VNC konekcije ovo nije potrebno — VNC prenosi znak izravno. + + 8. WEB GUI y = da, n = ne Instalira Flask web aplikaciju za upravljanje svim postavkama. Ako da: diff --git a/guacd-hr/build.sh b/guacd-hr/build.sh new file mode 100755 index 0000000..2c358f6 --- /dev/null +++ b/guacd-hr/build.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# +# Gradi guacd image s dodanim hrvatskim rasporedom tipkovnice. +# +# Rasporedi se kompajliraju u libguac-client-rdp, pa se ne mogu dodati +# naknadno — guacd se mora ponovno prevesti. Skripta namjerno koristi +# Dockerfile koji dolazi uz sluzbeni izvor tražene verzije umjesto da +# recepturu prepisuje, da nadogradnja na novi Guacamole ne trazi +# odrzavanje ovdje. +# +# ./build.sh [verzija] npr. ./build.sh 1.7.0 +# +set -euo pipefail + +GUAC_VERSION="${1:-1.6.0}" +IMAGE="guacd:${GUAC_VERSION}-hr" +KEYMAP="hr_hr_qwertz.keymap" +SRC_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" + +[[ -f "${SRC_DIR}/${KEYMAP}" ]] || { echo "Nedostaje ${KEYMAP}" >&2; exit 1; } +command -v docker >/dev/null || { echo "Docker nije pronaden" >&2; exit 1; } + +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT + +echo "==> Preuzimanje izvora guacamole-server ${GUAC_VERSION}" +TARBALL="guacamole-server-${GUAC_VERSION}.tar.gz" +for base in "https://downloads.apache.org/guacamole" \ + "https://archive.apache.org/dist/guacamole"; do + if curl -fsSL -o "${WORK}/${TARBALL}" \ + "${base}/${GUAC_VERSION}/source/${TARBALL}"; then + break + fi +done +[[ -s "${WORK}/${TARBALL}" ]] || { echo "Izvor ${GUAC_VERSION} nije pronaden" >&2; exit 1; } + +tar -xzf "${WORK}/${TARBALL}" -C "$WORK" +BUILD_CTX="${WORK}/guacamole-server-${GUAC_VERSION}" +[[ -f "${BUILD_CTX}/Dockerfile" ]] || { echo "Izvor nema Dockerfile" >&2; exit 1; } + +echo "==> Ugradnja ${KEYMAP}" +cp "${SRC_DIR}/${KEYMAP}" "${BUILD_CTX}/src/protocols/rdp/keymaps/" + +# Keymap mora biti naveden u rdp_keymaps, inace ga generate.pl preskoci. +MAKEFILE="${BUILD_CTX}/src/protocols/rdp/Makefile.am" +grep -q "$KEYMAP" "$MAKEFILE" || \ + sed -i "s|\(\$(srcdir)/keymaps/en_us_qwerty.keymap[[:space:]]*\\\\\)|\1\n \$(srcdir)/keymaps/${KEYMAP} \\\\|" "$MAKEFILE" +grep -q "$KEYMAP" "$MAKEFILE" || { echo "Ubacivanje u Makefile.am nije uspjelo" >&2; exit 1; } + +echo "==> Gradnja ${IMAGE} (dugotrajno, gradi se i FreeRDP)" +# Upstream Dockerfile ovisnosti gradi iz gita i bira NAJNOVIJI tag koji +# odgovara regexu. Kako te biblioteke izlaze, gradnja pukne sama od sebe +# iako se nista nije promijenilo kod nas: +# - libwebsockets v5 trazi GnuTLS kojeg build okruzenje 1.6.0 nema +# - FreeRDP 2.x je odmakao na razvojne tagove koje configure odbija +# Zato su zakljucani na ono sto nosi sluzbeni guacd:1.6.0 image. +# Za drugu verziju Guacamolea po potrebi pregazi preko env varijabli. +docker build \ + --build-arg BUILD_JOBS="$(nproc)" \ + --build-arg WITH_LIBWEBSOCKETS="${WITH_LIBWEBSOCKETS:-v4(\\.\\d+)+}" \ + --build-arg WITH_FREERDP="${WITH_FREERDP:-2\\.11\\.7}" \ + -t "$IMAGE" "$BUILD_CTX" + +echo "==> Provjera da je raspored u imageu" +if docker run --rm --entrypoint sh "$IMAGE" -c \ + 'strings /opt/guacamole/lib/libguac-client-rdp.so.0.0.0 | grep -qx hr-hr-qwertz'; then + echo "OK — ${IMAGE} sadrzi hr-hr-qwertz" +else + echo "GRESKA: raspored nije zavrsio u imageu" >&2 + exit 1 +fi + +cat <YXCVBNM;:_" + +map +caps -altgr -shift 0x29 0x02..0x0D ~ "`1234567890'+" +map +caps -altgr -shift 0x10..0x1B ~ "QWERTZUIOPŠĐ" +map +caps -altgr -shift 0x1E..0x28 0x2B ~ "ASDFGHJKLČĆŽ" +map +caps -altgr -shift 0x56 0x2C..0x35 ~ "yxcvbnm;:_" + +# +# Keys requiring AltGr +# + +map +altgr -shift 0x04 ~ "^" +map +altgr -shift 0x06 ~ "°" + +map +altgr -shift 0x10 ~ "\" +map +altgr -shift 0x11 ~ "|" +map +altgr -shift 0x12 ~ "€" +map +altgr -shift 0x1A ~ "÷" +map +altgr -shift 0x1B ~ "×" + +map +altgr -shift 0x21 ~ "[" +map +altgr -shift 0x22 ~ "]" +map +altgr -shift 0x25 ~ "ł" +map +altgr -shift 0x28 ~ "ß" +map +altgr -shift 0x2B ~ "¤" + +map +altgr -shift 0x2E ~ "¢" +map +altgr -shift 0x2F ~ "@" +map +altgr -shift 0x30 ~ "{" +map +altgr -shift 0x31 ~ "}" +map +altgr -shift 0x32 ~ "§" + +# +# Dead keys +# + +map +altgr -shift 0x03 ~ 0xFE5A # Dead caron +map +altgr -shift 0x05 ~ 0xFE55 # Dead breve +map +altgr -shift 0x07 ~ 0xFE5C # Dead ogonek +map +altgr -shift 0x09 ~ 0xFE56 # Dead abovedot +map +altgr -shift 0x0A ~ 0xFE51 # Dead acute +map +altgr -shift 0x0B ~ 0xFE59 # Dead doubleacute +map +altgr -shift 0x0C ~ 0xFE57 # Dead diaeresis +map +altgr -shift 0x0D ~ 0xFE5B # Dead cedilla diff --git a/install.sh b/install.sh index 6bce051..ef104d7 100755 --- a/install.sh +++ b/install.sh @@ -140,6 +140,15 @@ if [[ "$DO_PROXY" =~ ^[Yy]$ ]]; then done fi +echo "" +echo -e "${CYAN}Hrvatski raspored tipkovnice${NC} za RDP konekcije?" +echo " Guacamole ne isporucuje hrvatski raspored, pa se guacd mora" +echo " ponovno prevesti. Gradnja traje 15-30 min i stvara vlastiti image." +read -rp "Ugraditi hrvatski raspored? [y/N]: " DO_HRKEYMAP +DO_HRKEYMAP="${DO_HRKEYMAP:-n}" +GUACD_IMAGE="guacamole/guacd:${GUAC_VERSION}" +[[ "$DO_HRKEYMAP" =~ ^[Yy]$ ]] && GUACD_IMAGE="guacd:${GUAC_VERSION}-hr" + echo "" read -rp "$(echo -e "${CYAN}Web GUI${NC} — instalirati web sučelje za upravljanje? [y/N]: ")" DO_WEBGUI DO_WEBGUI="${DO_WEBGUI:-n}" @@ -280,12 +289,26 @@ SECRET_KEY=${SECRET_KEY} EOF chmod 600 "${INSTALL_DIR}/.env" +if [[ "$DO_HRKEYMAP" =~ ^[Yy]$ ]]; then + section "Hrvatski raspored tipkovnice" + if docker image inspect "$GUACD_IMAGE" >/dev/null 2>&1; then + info "Image ${GUACD_IMAGE} vec postoji, preskacem gradnju" + else + [[ -x "${SRC_DIR}/guacd-hr/build.sh" ]] \ + || error "Nedostaje ${SRC_DIR}/guacd-hr/build.sh" + info "Gradnja ${GUACD_IMAGE} — potrajat ce" + "${SRC_DIR}/guacd-hr/build.sh" "$GUAC_VERSION" \ + || error "Gradnja guacd-a s hrvatskim rasporedom nije uspjela" + fi + info "Na konekcijama postavite server-layout = hr-hr-qwertz" +fi + section "docker-compose.yml" cat > "${INSTALL_DIR}/docker-compose.yml" << EOF version: '3.8' services: guacd: - image: guacamole/guacd:${GUAC_VERSION} + image: ${GUACD_IMAGE} container_name: guacd restart: unless-stopped volumes: