CzADSB-Mapa: Porovnání verzí

Z Poznámkový blok
Přejít na: navigace, hledání
(Autorizace)
(Lighttpd)
 
(Není zobrazeno 13 mezilehlých verzí od stejného uživatele.)
Řádka 14: Řádka 14:
 
=== Lighttpd ===
 
=== Lighttpd ===
 
  # prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
 
  # prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
  sudo apt install lighttpd
+
  sudo apt install -y lighttpd
 +
sudo apt install -y lighttpd-modules-lua lua-luaossl
 +
 
 
=== Nginx ===
 
=== Nginx ===
 
  # prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
 
  # prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
Řádka 67: Řádka 69:
  
 
=== Nastaveni Tar1090 ===
 
=== Nastaveni Tar1090 ===
 +
 +
sudo sed -i "s/\/\/PlaneCountInTitle = false.*/PlaneCountInTitle = true;/g" /usr/local/share/tar1090/html/config.js
 +
sudo sed -i "/^\/\/shareBaseUrl = 'https:\/\/adsb\.lol\/'[^;]*/i shareBaseUrl = 'https://aircrafts.rxw.cz/'" /usr/local/share/tar1090/html/config.js
 +
sudo sed -i "s/\/\/ imageConfigLink = .*/imageConfigLink = 'https:\/\/user.czadsb.cz';/g" /usr/local/share/tar1090/html/config.js
 +
sudo sed -i "s/\/\/ imageConfigText = .*/imageConfigText = 'CzADSB';/g" /usr/local/share/tar1090/html/config.js
 +
 
== Autorizace ==
 
== Autorizace ==
Za účelem přihlášení a přesměrování při neplatnem přihlášení vztvoříme skript:
+
Za účelem přihlášení a přesměrování při neplatném přihlášení použijeme LUA skript. Ten máme uložen v sekci LUA. Pro jeho vlastni aktivaci pak musíme upravit předpis pro tar1090 kde přidáme:
  sudo mcedit /usr/local/bin/lighttpd_auth.sh
+
 
 +
  sudo mcedit /etc/lighttpd/conf-available/88-tar1090.conf
 +
 
 +
server.modules += ( "mod_magnet" )
 +
 +
# --- Presmerovani a overeni Cookie a opravneneho pristupu
 +
$HTTP["url"] =~ "^/tar1090/.*\.(php|html)$|/$" {
 +
    magnet.attract-raw-url-to = ( "/etc/lighttpd/lua/sso_auth.lua" )
 +
}
 +
 
 +
== LUA ==
 +
Jde o velmi ořezaný skript jazyk uřečeny pro web servery ke zpracování, vyhodnocení nasměrovaní URL požadavků. Proto ani neumí pak zpracovat POST požadavky. U GET požadavku se musí pak dotaz parsovat jako celek. To ale nevadí pro zpracování cookie, IP adres a podobně. Přikládám pár užitečných pomocných skriptu.
 +
=== debug-log.lua ===
 +
 
 +
-- Funkce pro logovani
 +
local function debug_log(msg)
 +
    print("[SSO-DEBUG] " .. tostring(msg))
 +
end
 +
 +
-- Funkce pro ziskani hodnoty z GET (uri.query)
 +
local function get_get_param(param_name)
 +
    local query = lighty.env["uri.query"]
 +
    if not query then return nil end
 +
    -- Hleda v retezci vzor: param=hodnota
 +
    return query:match(param_name .. "=([^&]+)")
 +
end
 +
 +
-- Nacti promenne a hodnotu lighty.env
 +
debug_log("-------------------------------------------------")
 +
for k, v in pairs(lighty.env) do
 +
    debug_log("env    - [" .. k .. "]='" .. tostring(v) .. "'")
 +
end
 +
 +
-- Nacti promenne a hodnotu lighty.request
 +
for k, v in pairs(lighty.request) do
 +
    debug_log("request - [" .. k .. "]='" .. tostring(v) .. "'")
 +
end
 +
 +
-- Pouziti funkce ziskani hodnoty z GET:
 +
-- local page = get_get_param("page") -- vrati "login"
 +
 
 +
=== debug-file.lua ===
  
  #!/bin/bash
+
  local ts = os.date("%Y%m%d-%H%M%S")
 +
local fname = "/tmp/magnet_env-" .. ts .. ".log"
 +
 +
local f = io.open(fname, "w")
 +
if f then
 
   
 
   
# 1. Načtení vstupu od Lighttpd (stdin)
+
  for k, v in pairs(lighty.env) do
# Lighttpd posílá jméno na prvním řádku a heslo (v našem případě token) na druhém
+
    f:write("env:    " .. k .. "=" .. tostring(v) .. "\n")
read -r USERNAME
+
  end
read -r TOKEN
 
 
   
 
   
# 2. Získání reálné IP adresy klienta
+
  forr k, v in pairs(lighty.request) do
# Protože je server za proxy, musíme zkontrolovat X-Forwarded-For.
+
    f:write("request: " .. k .. "=" .. tostring(v) .. "\n")
# Pokud existuje, vezmeme první IP v seznamu. Pokud ne, použijeme REMOTE_ADDR.
+
  end
if [ -n "$HTTP_X_FORWARDED_FOR" ]; then
 
    # Odstraníme případné mezery a vezmeme první záznam před první čárkou
 
    CLIENT_IP=$(echo "$HTTP_X_FORWARDED_FOR" | cut -d',' -f1 | tr -d ' ')
 
else
 
    CLIENT_IP="$REMOTE_ADDR"
 
fi
 
 
   
 
   
# 3. Odeslání dotazu na centrální portál metodou POST
+
  f:close()
# Používáme timeout 5 sekund, aby Lighttpd nezatuhl, pokud by portál neodpovídal.
+
  end
# Očekáváme, že PHP skript vrátí text "OK" pro úspěch.
 
  RESPONSE=$(curl -s --max-time 5 -X POST \
 
    -d "username=$USERNAME" \
 
    -d "token=$TOKEN" \
 
    -d "ip=$CLIENT_IP" \
 
    "https://user.czadsb.cz/service/autentizace.php")
 
 
   
 
   
  # 4. Vyhodnocení odpovědi
+
  return lighty.RESTART_REQUEST
if [ "$RESPONSE" == "OK" ]; then
 
    # Úspěšná autorizace - skript musí skončit s kódem 0
 
    exit 0
 
else
 
    # Neúspěšná autorizace - skript musí skončit s kódem 1 (nebo jiným než 0)
 
    # Volitelně můžete logovat chyby pro ladění:
 
    # echo "$(date) Auth failed for $USERNAME from $CLIENT_IP. Portal said: $RESPONSE" >> /var/log/lighttpd/auth_debug.log
 
    exit 1
 
fi
 
  
  sudo mcedit /var/www/html/redirect_login.html
+
=== sso_auth.lua ===
  
  <!DOCTYPE html>
+
  -- Konfigurace
  <html>
+
local secret = "vase_velmi_tajne_heslo_123456"
  <head>
+
local login_url = "https://user.czadsb.cz/index.php?page=login&return=mapy&mapa=tar"
     <meta charset="UTF-8">
+
local cookie_name = "czadsb_sso"
     <!-- Přesměrování na váš portál po 0 sekundách -->
+
     <meta http-equiv="refresh" content="0;url=https://user.czadsb.cz/login.php?error=unauthorized">
+
-- Lokalni IP (whitelist)
     <script type="text/javascript">
+
local trusted_ips = {
        window.location.href = "https://user.czadsb.cz/login.php?error=unauthorized"
+
    ["127.0.0.1"] = true,
    </script>
+
    ["::1"] = true,
  </head>
+
    ["10.129.99.145"] = true,
  <body>
+
}
     Požadováno přihlášení. Přesměrovávám na <a href="https://user.czadsb.cz/login.php">user.czadsb.cz</a>...
+
  </body>
+
-- Opustit statiku (bleskove)
  </html>
+
local uri = lighty.env["uri.path"] or ""
Následně upravíme konfiguraci pro lighttpd a tar1090:
+
if uri:match("%.%w%w%w?$") and not uri:match("%.php") and not uri:match("%.html") then
 +
    return 0
 +
end
 +
 +
-- Zjisteni IP adresy a opustit pokud je v whitelist IP (bleskove)
 +
  local final_ip = lighty.request["X-Forwarded-For"] or lighty.env["request.remote-ip"] or lighty.env["remote_addr"]
 +
  if final_ip then
 +
     final_ip = final_ip:match("([^, ]+)")
 +
    if trusted_ips[final_ip] then return 0 end
 +
end
 +
 +
-- Funkce pro logovani
 +
local function debug_log(msg)
 +
    print("[SSO-DEBUG] " .. tostring(msg))
 +
end
 +
 +
-- Funkce pro Base64 dekodovani
 +
local function base64_decode(data)
 +
    local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
 +
    data = string.gsub(data, '[^'..b..'=]', '')
 +
     return (data:gsub('.', function(x)
 +
        if (x == '=') then return '' end
 +
        local r,f='',(b:find(x)-1)
 +
        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
 +
        return r;
 +
    end):gsub('%d%d%d%d%d%d%d%d', function(x)
 +
        local r=0
 +
        for i=1,8 do r=r+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
 +
        return string.char(r)
 +
     end))
 +
end
 +
 +
-- Funkce pro URL dekodovani
 +
local function url_decode(str)
 +
    str = string.gsub(str, "+", " ")
 +
    str = string.gsub(str, "%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
 +
    return str
 +
end
 +
 +
-- Nacteni HMAC knihovny (lua-ossl)
 +
local status_hmac, openssl_hmac = pcall(require, "openssl.hmac")
 +
if not status_hmac then
 +
    debug_log("CHYBA: Knihovna openssl.hmac nenalezena!")
 +
    return 500
 +
end
 +
 +
-- Nacteni a zpracovani Cookie
 +
local cookie_header = lighty.request["Cookie"] or lighty.request["cookie"]
 +
 +
if cookie_header then
 +
    local sso_cookie_raw = cookie_header:match(cookie_name .. "=([^;]+)")
 +
 +
     if sso_cookie_raw then
 +
        local sso_cookie = url_decode(sso_cookie_raw)
 +
        local status_b64, decoded = pcall(base64_decode, sso_cookie)
 +
 +
        if status_b64 and decoded then
 +
            local sep_pos = decoded:find("||")
 +
            if sep_pos then
 +
                local payload = decoded:sub(1, sep_pos - 1)
 +
                local signature_raw = decoded:sub(sep_pos + 2)
 +
 +
                -- RESENI: SHA256 HEX ma vzdy 64 znaku. Orizneme pripadne nuly z dekoderu.
 +
                local signature = signature_raw:sub(1, 64)
 +
 +
                -- HMAC SHA256 vypocet
 +
                local h = openssl_hmac.new(secret, "SHA256")
 +
                h:update(payload)
 +
                local bin_sig = h:final()
 +
 +
                local hex_sig = ""
 +
                for i = 1, #bin_sig do
 +
                    hex_sig = hex_sig .. string.format("%02x", string.byte(bin_sig, i))
 +
                end
 +
 +
                if hex_sig == signature then
 +
                    -- Rozdeleni payloadu (user_id|username|time)
 +
                    local parts = {}
 +
                    for part in (payload .. "|"):gmatch("([^|]*)|") do
 +
                        table.insert(parts, part)
 +
                    end
 +
   
 +
                    local u_time = tonumber(parts[3])
 +
                    if u_time then
 +
                        local diff = os.time() - u_time
 +
                        if diff >= 0 and diff < 7200 then
 +
  --                            debug_log("Autentizace OK pro: " .. tostring(parts[2]))
 +
                            return 0
 +
                        else
 +
                            debug_log("Cookie vyprsela, rozdil: " .. diff)
 +
                        end
 +
                    end
 +
                else
 +
                    debug_log("Podpis nesouhlasi! (" .. final_ip .. ")")
 +
                    debug_log("Vypocteno:          " .. hex_sig)
 +
                    debug_log("Prijato (upraveno): " .. signature)
 +
                    debug_log("Prijato (raw):      " .. signature_raw)
 +
                end
 +
            end
 +
        end
 +
     end
 +
end
 +
 +
-- Pridani hlavicek proti cachovani pro jistotu
 +
lighty.header["Cache-Control"] = "no-cache, no-store, must-revalidate"
 +
lighty.header["Connection"] = "close"
 +
lighty.header["Pragma"] = "no-cache"
 +
lighty.header["Expires"] = "0"
 +
 +
-- Pokud nic neproslo, presmerujeme
 +
debug_log("Pristup odmitnut, presmerovani (" .. final_ip .. " | " .. uri .. ").")
 +
  lighty.header["Location"] = login_url
 +
  return 302

Aktuální verze z 19. 2. 2026, 18:00

Uvod

Predpokladany postup instalace

  • Pripravit si distribuci
  • Zkompilovat ReADSB (nepotrebujeme zadne sdr ovladace)
  • Nastavit ReADSB
  • Nainstalovat Tar1090
  • Zkonfigurovat Tar1090

Distribuce

Nebojime se niceho, takze jdeme do nejnovejsiho operacniho systemu, at mame na dlouho klid. Priparvime si komplet distribuci vcetne aktualizaci a ovladaci pro virtual ( Linux & Aplikace ).

WebServer

Pro provoz potrebujeme jeden ze dvou nize uvedenych web serveru. Volba je v podstate na vas, ale Tar1090 ma primo integrovanou podporu pro Lighttpd.

Lighttpd

# prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
sudo apt install -y lighttpd
sudo apt install -y lighttpd-modules-lua lua-luaossl

Nginx

# prvne nainstalujeme WebServer. Doporu4uje se nginx, nebo lighttpd
sudo apt install nginx

ReADSB

Kompilace

sudo apt update && sudo apt upgrade -y
sudo apt install --no-install-recommends --no-install-suggests -y \
   git build-essential debhelper libusb-1.0-0-dev pkg-config fakeroot libncurses-dev zlib1g-dev libzstd-dev librtlsdr-dev help2man

git clone --depth 20 https://github.com/wiedehopf/readsb.git
cd readsb

rm -f ../readsb_*.deb
export DEB_BUILD_OPTIONS=noddebs
dpkg-buildpackage -b -ui -uc -us

Pokud již máme potřebný balíček, tak jej nainstalujeme:

cd
rm -f /tmp/readsb_*.deb
cp ./readsb_*.deb /tmp/
sudo apt install /tmp/readsb_*.deb
rm -f /tmp/readsb_*.deb

Dale vytvorime pravidlo pro Lighttpd (pokud jsme jej instalovali

sudo wget -q https://rxw.cz/adsb/install/web/64-readsb.conf -O /etc/lighttpd/conf-available/64-readsb.conf
sudo ln -s ../conf-available/64-readsb.conf /etc/lighttpd/conf-enabled/64-readsb.conf
sudo wget -q https://rxw.cz/adsb/install/web/system.cgi -O /var/www/html/system.cgi
sudo systemctl reload lighttpd.service

Nastaveni ReADSB

sudo mcedit /etc/default/readsb
# readsb configuration
# This is sourced by /etc/systemd/system/default.target.wants/readsb.service as
# daemon startup configuration.

RECEIVER_OPTIONS="--net --net-only --net-ingest --net-connector 10.0.0.74,30005,beast_in,silent_fail --net-connector 10.129.99.147,30005,beast_in,silent_fail --net-connector 10.0.0.73,30005,beast_in,silent_fail"
DECODER_OPTIONS="--write-json-every 1 --net-beast-reduce-interval 0.5 --net-heartbeat 60 --net-ro-size 1280 --net-ro-interval=0.05 --net-ro-interval-beast-reduce=0.12"
NET_OPTIONS="--net-ro-port 0 --net-sbs-port 0 --net-bi-port 0 --net-bo-port 0 --net-ri-port 0 --net-api-port unix:/run/readsb/api.sock --api-shutdown-delay 10 --tar1090-use-api"
JSON_OPTIONS="--write-receiver-id-json --write-json-every 1 --json-location-accuracy 2 --range-outline-hours 24"
sudo systemctl restart readsb.service

Tar1090

POZOR: Pokud neni funkcni ReADSB, tak nam nebude fungovat ani Tar. Ve skriptu si zjistuje kde ma data letadel a pokud je nema, tak se nespusti.

Instalace

# Nainstalujeme vlastni Tar1090
sudo bash -c "$(wget -nv -O - https://github.com/wiedehopf/tar1090/raw/master/install.sh)"
sudo wget -O /usr/local/share/tar1090/aircraft.csv.gz https://github.com/wiedehopf/tar1090-db/raw/csv/aircraft.csv.gz

Nastaveni Tar1090

sudo sed -i "s/\/\/PlaneCountInTitle = false.*/PlaneCountInTitle = true;/g" /usr/local/share/tar1090/html/config.js
sudo sed -i "/^\/\/shareBaseUrl = 'https:\/\/adsb\.lol\/'[^;]*/i shareBaseUrl = 'https://aircrafts.rxw.cz/'" /usr/local/share/tar1090/html/config.js
sudo sed -i "s/\/\/ imageConfigLink = .*/imageConfigLink = 'https:\/\/user.czadsb.cz';/g" /usr/local/share/tar1090/html/config.js
sudo sed -i "s/\/\/ imageConfigText = .*/imageConfigText = 'CzADSB';/g" /usr/local/share/tar1090/html/config.js

Autorizace

Za účelem přihlášení a přesměrování při neplatném přihlášení použijeme LUA skript. Ten máme uložen v sekci LUA. Pro jeho vlastni aktivaci pak musíme upravit předpis pro tar1090 kde přidáme:

sudo mcedit /etc/lighttpd/conf-available/88-tar1090.conf
server.modules += ( "mod_magnet" )

# --- Presmerovani a overeni Cookie a opravneneho pristupu
$HTTP["url"] =~ "^/tar1090/.*\.(php|html)$|/$" {
    magnet.attract-raw-url-to = ( "/etc/lighttpd/lua/sso_auth.lua" )
}

LUA

Jde o velmi ořezaný skript jazyk uřečeny pro web servery ke zpracování, vyhodnocení nasměrovaní URL požadavků. Proto ani neumí pak zpracovat POST požadavky. U GET požadavku se musí pak dotaz parsovat jako celek. To ale nevadí pro zpracování cookie, IP adres a podobně. Přikládám pár užitečných pomocných skriptu.

debug-log.lua

-- Funkce pro logovani
local function debug_log(msg)
    print("[SSO-DEBUG] " .. tostring(msg))
end

-- Funkce pro ziskani hodnoty z GET (uri.query)
local function get_get_param(param_name)
    local query = lighty.env["uri.query"]
    if not query then return nil end
    -- Hleda v retezci vzor: param=hodnota
    return query:match(param_name .. "=([^&]+)")
end

-- Nacti promenne a hodnotu lighty.env
debug_log("-------------------------------------------------")
for k, v in pairs(lighty.env) do
    debug_log("env     - [" .. k .. "]='" .. tostring(v) .. "'")
end

-- Nacti promenne a hodnotu lighty.request
for k, v in pairs(lighty.request) do
    debug_log("request - [" .. k .. "]='" .. tostring(v) .. "'")
end

-- Pouziti funkce ziskani hodnoty z GET:
-- local page = get_get_param("page") -- vrati "login"

debug-file.lua

local ts = os.date("%Y%m%d-%H%M%S")
local fname = "/tmp/magnet_env-" .. ts .. ".log"

local f = io.open(fname, "w")
if f then

  for k, v in pairs(lighty.env) do
    f:write("env:     " .. k .. "=" .. tostring(v) .. "\n")
  end

  forr k, v in pairs(lighty.request) do
    f:write("request: " .. k .. "=" .. tostring(v) .. "\n")
  end

  f:close()
end

return lighty.RESTART_REQUEST

sso_auth.lua

-- Konfigurace
local secret = "vase_velmi_tajne_heslo_123456"
local login_url = "https://user.czadsb.cz/index.php?page=login&return=mapy&mapa=tar"
local cookie_name = "czadsb_sso"

-- Lokalni IP (whitelist)
local trusted_ips = {
    ["127.0.0.1"] = true,
    ["::1"] = true,
    ["10.129.99.145"] = true,
}

-- Opustit statiku (bleskove)
local uri = lighty.env["uri.path"] or ""
if uri:match("%.%w%w%w?$") and not uri:match("%.php") and not uri:match("%.html") then
    return 0
end

-- Zjisteni IP adresy a opustit pokud je v whitelist IP (bleskove)
local final_ip = lighty.request["X-Forwarded-For"] or lighty.env["request.remote-ip"] or lighty.env["remote_addr"]
if final_ip then
    final_ip = final_ip:match("([^, ]+)")
    if trusted_ips[final_ip] then return 0 end
end

-- Funkce pro logovani
local function debug_log(msg)
    print("[SSO-DEBUG] " .. tostring(msg))
end

-- Funkce pro Base64 dekodovani
local function base64_decode(data)
    local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    data = string.gsub(data, '[^'..b..'=]', )
    return (data:gsub('.', function(x)
        if (x == '=') then return  end
        local r,f=,(b:find(x)-1)
        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
        return r;
    end):gsub('%d%d%d%d%d%d%d%d', function(x)
        local r=0
        for i=1,8 do r=r+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
        return string.char(r)
    end))
end

-- Funkce pro URL dekodovani
local function url_decode(str)
    str = string.gsub(str, "+", " ")
    str = string.gsub(str, "%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
    return str
end

-- Nacteni HMAC knihovny (lua-ossl)
local status_hmac, openssl_hmac = pcall(require, "openssl.hmac")
if not status_hmac then
    debug_log("CHYBA: Knihovna openssl.hmac nenalezena!")
    return 500
end

-- Nacteni a zpracovani Cookie
local cookie_header = lighty.request["Cookie"] or lighty.request["cookie"]

if cookie_header then
    local sso_cookie_raw = cookie_header:match(cookie_name .. "=([^;]+)")

    if sso_cookie_raw then
        local sso_cookie = url_decode(sso_cookie_raw)
        local status_b64, decoded = pcall(base64_decode, sso_cookie)

        if status_b64 and decoded then
            local sep_pos = decoded:find("||")
            if sep_pos then
                local payload = decoded:sub(1, sep_pos - 1)
                local signature_raw = decoded:sub(sep_pos + 2)

                -- RESENI: SHA256 HEX ma vzdy 64 znaku. Orizneme pripadne nuly z dekoderu.
                local signature = signature_raw:sub(1, 64)

                -- HMAC SHA256 vypocet
                local h = openssl_hmac.new(secret, "SHA256")
                h:update(payload)
                local bin_sig = h:final()

                local hex_sig = ""
                for i = 1, #bin_sig do
                    hex_sig = hex_sig .. string.format("%02x", string.byte(bin_sig, i))
                end

                if hex_sig == signature then
                    -- Rozdeleni payloadu (user_id|username|time)
                    local parts = {}
                    for part in (payload .. "|"):gmatch("([^|]*)|") do
                        table.insert(parts, part)
                    end

                    local u_time = tonumber(parts[3])
                    if u_time then
                        local diff = os.time() - u_time
                        if diff >= 0 and diff < 7200 then
--                            debug_log("Autentizace OK pro: " .. tostring(parts[2]))
                            return 0
                        else
                            debug_log("Cookie vyprsela, rozdil: " .. diff)
                        end
                    end
                else
                    debug_log("Podpis nesouhlasi! (" .. final_ip .. ")")
                    debug_log("Vypocteno:          " .. hex_sig)
                    debug_log("Prijato (upraveno): " .. signature)
                    debug_log("Prijato (raw):      " .. signature_raw)
                end
            end
        end
    end
end

-- Pridani hlavicek proti cachovani pro jistotu
lighty.header["Cache-Control"] = "no-cache, no-store, must-revalidate"
lighty.header["Connection"] = "close"
lighty.header["Pragma"] = "no-cache"
lighty.header["Expires"] = "0"

-- Pokud nic neproslo, presmerujeme
debug_log("Pristup odmitnut, presmerovani (" .. final_ip .. " | " .. uri .. ").")
lighty.header["Location"] = login_url
return 302