Initial commit — GuacPanel v1.0

All-in-one installer za Apache Guacamole s Nginx reverse proxy,
fail2ban, SSL (Let's Encrypt / Self-signed), GeoIP blokiranjem
i Flask web GUI za upravljanje.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
njomac
2026-04-26 11:21:44 +02:00
commit 50c125e0db
17 changed files with 5249 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
{% extends 'base.html' %}
{% block title %}Postavke Guacamole Manager{% endblock %}
{% block content %}
<h4 class="mb-4"><i class="bi bi-gear me-2"></i>Postavke</h4>
<div class="row g-4">
<div class="col-md-5">
<div class="card">
<div class="card-header fw-semibold">
<i class="bi bi-key me-1"></i> Promjena lozinke GUI-ja
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label small text-muted">Korisničko ime</label>
<input type="text" class="form-control" value="{{ username }}" readonly
style="background:#0d1117; opacity:.7">
</div>
<div class="mb-3">
<label class="form-label small text-muted">Trenutna lozinka</label>
<input id="cur-pw" type="password" class="form-control" placeholder="••••••••">
</div>
<div class="mb-3">
<label class="form-label small text-muted">Nova lozinka</label>
<input id="new-pw" type="password" class="form-control" placeholder="Min. 8 znakova">
</div>
<div class="mb-3">
<label class="form-label small text-muted">Potvrdi novu lozinku</label>
<input id="new-pw2" type="password" class="form-control" placeholder="••••••••">
</div>
<button class="btn btn-primary w-100" onclick="changePassword()">
<i class="bi bi-floppy"></i> Spremi lozinku
</button>
</div>
</div>
</div>
<div class="col-md-7">
<div class="card">
<div class="card-header fw-semibold">
<i class="bi bi-info-circle me-1"></i> Informacije
</div>
<div class="card-body">
<dl class="row">
<dt class="col-5 text-muted small">Instalacijski dir</dt>
<dd class="col-7 font-monospace small">/opt/guacamole</dd>
<dt class="col-5 text-muted small">Nginx konfig</dt>
<dd class="col-7 font-monospace small">/etc/nginx/.../guacamole</dd>
<dt class="col-5 text-muted small">Basic Auth file</dt>
<dd class="col-7 font-monospace small">/etc/nginx/.guac_htpasswd</dd>
<dt class="col-5 text-muted small">GeoIP konfig</dt>
<dd class="col-7 font-monospace small">/etc/nginx/conf.d/guacamole-geoip.conf</dd>
<dt class="col-5 text-muted small">fail2ban jail</dt>
<dd class="col-7 font-monospace small">/etc/fail2ban/jail.d/guacamole.conf</dd>
</dl>
</div>
</div>
<div class="card mt-3">
<div class="card-header fw-semibold">
<i class="bi bi-terminal me-1"></i> Brze naredbe (u terminalu)
</div>
<div class="card-body">
<pre class="small mb-0" style="background:#0d1117; border:1px solid #30363d; padding:.75rem; border-radius:6px; color:#8b949e"># Logovi Guacamolua
docker logs -f guacamole
# Restart svih kontejnera
cd /opt/guacamole && docker compose restart
# fail2ban status
fail2ban-client status
# Backup konfiguracije
sudo bash /path/to/manage.sh</pre>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
async function changePassword() {
const cur = document.getElementById('cur-pw').value;
const np = document.getElementById('new-pw').value;
const np2 = document.getElementById('new-pw2').value;
if (np !== np2) return showToast('Lozinke se ne podudaraju', false);
if (np.length < 8) return showToast('Lozinka mora imati najmanje 8 znakova', false);
const r = await api('/api/settings/password', {current: cur, new_password: np});
showToast(r.msg, r.ok);
if (r.ok) {
['cur-pw','new-pw','new-pw2'].forEach(id =>
document.getElementById(id).value = '');
}
}
</script>
{% endblock %}