Nejste přihlášeni
Proxy jsem na CNAME pro ověření ACME vypnul.
Vytvořeno. Mám to nechat za proxy nebo vypnout proxy?
Ok, díky za rady.
Ok, díky za rady. Zkusím se mrknout, co mohu udělat. Možná využiju druhou schránku, kterou jsem si teď vytvořil. Potřebuju, aby kontaktní formulář odeslal email s hlavičkou "From" odpovídající tomu, co zadá uživatel do formuláře (tedy Jméno <email>). Email musí být SPF compliant. Pokud to nepůjde, tak holt bude ve "From" hlavičce email schránky, a v hlavičce "Reply-To" vlastní email odesílatele.
Lze to nějak udělat, aniž bych musel proxy vypínat natrvalo?
Zde mám nastavení v Cloudflare:
Nelze vygenerovat SSL certifikát Let's Encrypt pro mou doménu czghost.cz, jelikož systém detekuje jinou IP adresu serveru. To bude patrně IP adresa Cloudflaru, jelikož web je schován za proxy. Lze to nějak nastavit, aby to bralo proxy od Cloudflare, nebo musím proxy vypnout?

Google Analytics vám pomohou.
Tak já si dělám webové stránky pomocí vlastního kódu, na blogu ve WP kontaktní formulář nebude. Rád bych viděl, když tam někdo zadá údaje, předmět a text zprávy, abych v seznamu viděl:
Jméno
Předmět
Úvod zprávy
(viz tento obrázek)
A po rozkliknutí pak v okně emailu vedle jména a příjmení také adresu odesílatele (emailová adresa).
Takže pokud někdo zadá následující údaje:
Jméno: Prokop Buben
email: prokop.buben@seznam.cz
Předmět: Něco se mi nelíbí
tak bych rád viděl hned v seznamu emailů, že email přišel od někoho jménem Prokop Buben, s předmětem "Něco se mi nelíbí", a po rozkliknutí bych rád viděl jeho emailovou adresu "prokop.buben@seznam.cz". Jde to udělat tak, aby to odpovídalo mé představě a zároveň to splňovalo podmínky pro SPF compliance, a aby to fungovalo? Nově by měly emaily chodit na mou veřejnou schránku na Endoře, a svůj Gmail chci uchovat více v soukromí. To je jeden z hlavních důvodů, proč jsem si pořizoval doménu druhého řádu. Email má být odesílaný pomocí PHP skriptu Ajaxem, chráněný pomocí Cloudflare Turnstile.
Zde je PHP kód, který mám zatím napsaný:
<?php
// Supress error displaying (error reports are in HTML format, which messes up JSON formatting)
$void = ini_set('display_errors', 0);
$void = ini_set('display_startup_errors', 0);
// Check success and error displaying status
if ($void === false && (ini_get('display_errors') === '1' || ini_get('display_startup_errors') === '1')) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => 'Internal Server Error',
'message' => 'Failed to supress error displaying.',
'code' => 500
]);
error_log('Failed to supress error displaying.');
exit;
}
// Start session => Should make session variables accessible
session_start();
// Set content type to JSON
header('Content-Type: application/json');
// Determine language
$lang = isset($_POST['lang']) ? preg_replace('/[^a-zA-Z0-9\-]/', '', $_POST['lang']) : 'en-US';
if (!in_array($lang, ['en-US', 'cs-CZ'])) {
$lang = 'en-US';
}
// Include ajax response templates
$ajax_templates = json_decode(file_get_contents(__DIR__ . "/../.incl/translations/$lang/ajax/responses.json"));
// Get session token and given token
$session_token = isset($_SESSION['token']) ? $_SESSION['token'] : null;
$given_token = isset($_POST['token']) ? $_POST['token'] : null;
// Check that referer is local server
if (!isset($_SERVER['HTTP_REFERER']) || (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != $_SERVER['SERVER_NAME'])) {
http_response_code(403);
echo json_encode([
'success' => false,
'error' => $ajax_templates->invalid_referer->heading ?? 'Invalid referer',
'message' => $ajax_templates->invalid_referer->message ?? 'Direct access not permitted.',
'code' => 403
]);
error_log('Invalid referer: ' . ($_SERVER['HTTP_REFERER'] ?? '(none)'));
exit;
}
// Check that this is a valid POST request
if ($_SERVER['REQUEST_METHOD'] != 'POST' || empty($_POST)) {
http_response_code(400);
echo json_encode([
'success' => false,
'error' => $ajax_templates->invalid_request->heading ?? 'Invalid request',
'message' => $ajax_templates->invalid_request->message ?? 'This endpoint expects a POST request with valid parameters.',
'code' => 400
]);
error_log('Invalid request method: ' . ($_SERVER['REQUEST_METHOD'] ?? '(none)'));
exit;
}
// Check session token
if (is_null($session_token) || is_null($given_token) || $session_token !== $given_token) {
http_response_code(401);
echo json_encode([
'success' => false,
'error' => $ajax_templates->invalid_session_token->heading ?? 'Invalid session token',
'message' => $ajax_templates->invalid_session_token->message
?? 'Session token is invalid. Please reload the page and try again.',
'code' => 401
]);
error_log('Invalid session token.\n Given: ' . ($given_token ?? '(none)')
. '\n Expected: ' . ($session_token ?? '(session token not initiated)'));
exit;
}
// Include Cloudflare Turnstile validation
require_once(__DIR__ . '/../.incl/functions/cf_validate.php');
// Prepare email data
//----------------------------------------------------------------
// Host information
$host = $_SERVER['HTTP_HOST'];
// Contact info
$to = 'kontakt@czghost.cz'; // Recipient email address
$sender = 'REDACTED_FOR_PRIVACY'; // Sender/return path address to avoid SPF errors
// Email details
$email = isset($_POST['from']) ? filter_var($_POST['from'], FILTER_SANITIZE_EMAIL) : null;
$name = isset($_POST['name']) ? (trim($_POST['name']) ?? 'Anonymous') : 'Anonymous';
$subject = isset($_POST['subject']) ? trim($_POST['subject']) : null;
$message = isset($_POST['message']) ? (trim($_POST['message']) ?? 'Message not provided') : 'Message not provided';
// Email headers
$headers = [
"From" => "\"$name\" <$email>", // Sender's name and email address
"Reply-To" => $email, // Reply-To email address
'Sender' => $sender, // Technical sender address to avoid SPF errors
'Return-Path' => $sender, // Return-Path address to avoid SPF errors
'MIME-Version' => '1.0', // MIME protocol version
'Content-Type' => 'text/plain; charset=UTF-8', // MIME Content-Type header
'X-Mailer' => "Contact form at $host" // Mailer application
];
// Prepare MIME headers and set up valid format
$mime_headers = [];
foreach ($headers as $key => $value) {
$mime_headers[] = "$key: $value";
}
$mail_headers = join("\n", $mime_headers);
// Validate form fields
//----------------------------------------------------------------
// Check for empty email field
if (is_null($email) || empty($email)) {
http_response_code(400);
echo json_encode([
'success' => false,
'error' => $ajax_templates->email_is_required->heading ?? 'Email is required',
'message' => $ajax_templates->email_is_required->message ?? 'Please provide your email address.',
'code' => 400
]);
error_log('Missing sender email address');
exit;
}
// Check for valid email format
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(400);
echo json_encode([
'success' => false,
'error' => $ajax_templates->invalid_email_address->heading ?? 'Invalid email address',
'message' => $ajax_templates->invalid_email_address->message ?? 'Please provide a valid email address.',
'code' => 400
]);
error_log('Invalid sender email address: ' . $email);
exit;
}
// Validate other fields as needed
if (is_null($subject) || empty($subject)) {
http_response_code(400);
echo json_encode([
'success' => false,
'error' => $ajax_templates->subject_is_required->heading ?? 'Subject is required',
'message' => $ajax_templates->subject_is_required->message ?? 'Please provide a subject for your message.',
'code' => 400
]);
error_log('Missing subject in contact form');
exit;
}
// Send email
if (mail($to, $subject, "New message from $name sent via contact form at $host:\n\n$message", $mail_headers, '-f' . $sender)) {
// Email successfully sent
http_response_code(200);
echo json_encode([
'success' => true,
'title' => $ajax_templates->email_sent_successfully->heading ?? 'Email sent successfully',
'message' => $ajax_templates->email_sent_successfully->message ?? 'Your message has been sent successfully.',
'code' => 200
]);
} else {
// Email failed to send
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $ajax_templates->failed_to_send_email->heading ?? "Failed to send email",
'message' => str_replace('${host}', $host, $ajax_templates->failed_to_send_email->message) ?? "Failed to send email, please try again later. If the problem persists, contact me at <a href=\"mailto:contact@$host\">contact@$host</a>.",
'code' => 500
]);
error_log('Failed to send email: ' . print_r(error_get_last(), true));
}
// Clear session data and destroy session
session_unset();
session_destroy();
exit;
?>Ochota zřejmě nulová. Zeptám se tedy jinde. Děkuji.
Reklamní patička překrývá v mém starém webu skutečnou patičku stránky, protože je nastavená jako fixní v okně prohlížeče, a je tedy vyjmuta z kontextu stránky. Patička stránky tak není vidět. Abych si obsah patičky mohl přečíst, reklamu jsem si musel pomocí developer tools v prohlížeči lokálně skrýt.


Ne, že by mi na tom nějak záleželo, mám doménu druhého řádu, kam chci umístit svůj nový web (je v aktivním vývoji), a tam mám hosting zaplacený čiže bez reklam. Ale někomu jinému to může vadit, a celkem to omezuje možnosti stylování stránek, protože musí stránky stylovat okolo toho.
Máte aktualizované DNS záznamy, aby směřovaly na Endoru? Buď nameservery nasměrované na Endoru s DNS na Endoře, nebo DNS záznamy (třeba na Cloudflare) směřované na server, kde máte nový web? Tyto změny obvykle trvají maximálně 24 hodin.
Dobrá, poradíte mi tedy, jak mám nastavit kontaktní formulář, aby email v pořádku dorazil, prošel SPF a DKIM kontrolou a abych jako odesílatele viděl toho, kdo to poslal?
Jde mi o to, abych viděl hned v seznamu emailů odesílatele (jméno), předmět zprávy, a případně začátek této zprávy.
A v zobrazeném emailu, aby byla vidět emailová adresa odesílatele:
Email samozřejmě musí projít SPF i DKIM kontrolou, a musí být odeslán přes kontaktní formulář.
Co vyplňuje odesílatel na kontaktním formuláři je jméno, email, předmět a zpráva. Samozřejmostí je ochrana proti spamu captchou (Cloudflare Turnstile), a mám implementovanou i svou vlastní ochranu proti zneužití API endpointu (neboť nový kontaktní formulář bude využívat AJAX).
Doporučuju si přečíst tuto stránku (a všechny stránky pod ní přidružené, včetně FAQ):
https://migrace.endora.cz/
Ale jednu věc jsem objevil při testování emailu ze svého kontaktního emailu na mé doméně, a sice, že DKIM zřejmě není správně nastaven. SPF projde, ale DKIM nikoliv. Nevím, jestli je to Outlookem (MS Office), protože mail tester mi neukázal žádný klíč, ani neříkal, že by byl klíč neplatný, prostě jako by neexistoval. Klíč tam přitom je.
To nevím, jak bych dokázal udělat. Jedná se o email odesílaný jménem toho, kdo vyplňuje kontaktní formulář, z technických důvodů se používá Sender hlavička, která se nastavuje na moji Gmail adresu, a kontaktní formulář stále odesílá email na moji Gmail adresu (nebo se o to alespoň snaží). Sender hlavička se používá právě kvůli SPF. Ale nevím co se stalo, jestli došlo někdy ke změně buď v Googlu nebo u vás, protože aniž bych dělal jakékoliv změny v kontaktním formuláři, přestalo to fungovat. Formulář sice oznámí, že se email odeslal, ale email nedorazí. Takže SMTP server, ke kterému se funkce mail() připojuje, musel email odeslat a oznámit úspěšný pokus. Někde po cestě musela nastat chyba. Zřejmě je na vině Gmail, který nejspíš zavrhuje emaily, které jsou označené Sender hlavičkou s jinou emailovou adresou než tou, která je v hlavičce From. Google používá celou řadu obranných mechanismů na detekci spamu, a ty spamy, které se objeví ve spamové složce, jsou možná ani ne 1 % z celkového množství spamu, který se pokouší o spojení. Zdá se, že Google emaily odesílané mým kontaktním formulářem automaticky zavrhuje jako zjevný pokus o spam, díky té Sender hlavičce.
No nic, pokud na straně Endory není žádná chyba, pak to řešit nebudu. Stejně dělám nové webové stránky, které budou používat nový kontaktní formulář již s kontaktem na můj veřejný email, a celé webovky budou na nové adrese. Starou doménu třetího řádu ještě nechám běžet a udělám z toho přesměrování na subdoménu na mé nové doméně druhého řádu, kde bude kopie starého webu (kde ovšem znefunkčním starý kontaktní formulář a hodím do něj odkaz na ten nový).
Z ničeho nic mi přestal fungovat na mých free stránkách kontaktní formulář. Po odeslání emailu se sice zobrazí, že došlo k odeslání emailu, ale do schránky mi nic nedorazí. Logy si nedokážu momentálně zobrazit (respektive teď nevím jak na to).
Kontaktní formulář mám k dispozici zde: http://czghost.4fan.cz/cz/contact
Je funkce mail() zakázána? Jak si mám udělat na stránkách kontaktní formulář?
Problém stále přetrvává. Email odeslán.
V phpinfo() jsem se verzi Apache nedozvěděl. V kolonce $_SERVER['SERVER_SOFTWARE'] bylo pouze "Apache", bez verze. Nikde jinde verze Apache zmíněna nebyla, pouze verze PHP. A migrace na Webglobe je již hotová nebo se ještě bude uskutečňovat?
Chtěl jsem se podívat na jaké verzi Apache běží Endora, neboť od verze 2.3 je změněná syntaxe allow/deny v .htaccess, a já mám u sebe na localhostu Apache 2.4, což znamená, že pokud je na Endoře starší verze, nepůjdou mi nové direktivy. Nicméně zatímco u mě na localhostu PHP funkce get_apache_version() funguje, na Endoře to vrací error 500. Funkce je tedy zřejmě vypnutá. Existuje nějaký způsob, jak zjistit verzi Apache na serveru? Ve webové administraci bohužel nic vidět není.
Dále bych se rád zeptal, jak je na tom migrace na servery Webglobe. Dozvěděl jsem se, že se IP adresa sasanky změnila, pravděpodobně asi i ostatních. Souvisí to s tou migrací pod Webglobe? Děkuji.
Aha. Tak mě osobně to nevadí, já stejně své webové stránky migruju společně s kompletním redesignem a restrukturizací na novou adresu = pořídil jsem si doménu druhého řádu a k tomu Endora Plus webhosting. Těžko říct, kdy dojde k migraci Endory na Webglobe servery (pokud již k tomu nedošlo).
Zdravím. Označování zpráv (oznámení) v administraci za přečtené na několik minut zablokuje celou administraci. Chtěl jsem označit upozornění na překročené limity běžících PHP procesů za přečtené, poté byla administrace nedostupná. Ztratil jsem heslo k FTP, z nějakého důvodu se mi ztratil uložený trezor v Total Commanderu, nicméně vím, že v administraci si jej lze obnovit.
Chtělo by to tuto chybu opravit.
Zdravím.
Bylo by na místě okamžitě updatovat verzi glibc na nedávný hotfix, pokud jste tak ještě neučinili, která opravuje zranitelnost umožňující nepovolený přístup do paměti (čímž lze spustit nevyžádaný kód na cílovém stroji, v tomto případě na serverovém stroji hostující webové stránky).
Ponecháním zranitelné verze vystavujete nejen sebe, ale i všechny zákazníky potenciálnímu riziku zneužití této zranitelnosti.
Chyba, která se opraví sama od sebe, je ta nejhorší, co může existovat. ![]()
Stránka do chyby 500 nespadla, ale nefunguje to podle představ.
,
V path selectoru se má objevit "test". Vypadá to, že ChatGPT si trošku vymýšlí.
Zde je .htaccess soubor:
# No directory listing, no multi views
Options -Indexes
# Redirects and rewrites allowed
RewriteEngine on
# Redirect HTTP to HTTPS
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]
# Redirect direct requests for "index.php?lang=xyz" to "/xyz/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} lang=([a-z]{2,3})
RewriteRule ^(index\.php)?$ https://%{HTTP_HOST}/%1/? [R=301,L]
# Redirect direct requests for "root.php?lang=xyz" to "/xyz/root/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} lang=([a-z]{2,3})
RewriteRule ^(root\.php)$ https://%{HTTP_HOST}/%1/root/? [R=301,L]
# Redirect direct requests for "root.php?lang=xyz&path=<anything>" to "/xyz/root/<anything>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} lang=([a-z]{2,3})
RewriteCond %{QUERY_STRING} path=(.+)
RewriteRule ^(root\.php)$ https://%{HTTP_HOST}/%1/root/%{QUERY_STRING_UNESCAPED:path}? [R=301,L,NE]
# Redirect direct requests for "root.php?path=<anything>" to "/root/<anything>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} path=(.+)
RewriteRule ^(root\.php)$ https://%{HTTP_HOST}/root/%{QUERY_STRING_UNESCAPED:path}? [R=301,L,NE]
# Redirect direct requests for "index.php" to "/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ https://%{HTTP_HOST}/? [R=301,L]
# Redirect direct requests for "root.php" to "/root/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^root\.php$ https://%{HTTP_HOST}/root/? [R=301,L]
# Redirect "/xyz/root" to "/xyz/root/" (with the slash at the end)
RewriteRule ^([a-z]{2,3})/root$ ./root/? [R=301,L]
# Internally rewrite "/xyz/root/" to "/root.php?lang=xyz"
RewriteRule ^([a-z]{2,3})/root/$ ./root.php?lang=$1 [L]
# Encode forward slashes in query string
#RewriteCond %{QUERY_STRING} ^(.*&|\?)path=([^&]*)(.*)$
#RewriteRule ^ - [E=PATH_ENCODED:${urlencoder:$2}]
# Internally rewrite "/xyz/root/<anything>" to "/root.php?lang=xyz&path=<anything>"
#RewriteRule ^([a-z]{2,3})/root/(.+)$ ./root.php?lang=$1&path=%{ENV:PATH_ENCODED}
RewriteRule ^([a-z]{2,3})/root/(.+)$ ./root.php?lang=$1&path=${urlencoder:$2} [B,L]
# Internally rewrite "/xyz/" or "/xyz/index/" to "/index.php?lang=xyz"
RewriteRule ^([a-z]{2,3})(/(index/?)?)?$ ./index.php?lang=$1 [L]
# Internally rewrite "/index/" to "/index.php"
RewriteRule ^index/?$ ./index.php [L]
# Internally rewrite "/root/" to "/root.php"
RewriteRule ^root/$ ./root.php [L]
# Encode forward slashes in query string
#RewriteCond %{QUERY_STRING} ^(.*&|\?)path=([^&]*)(.*)$
#RewriteRule ^ - [E=PATH_ENCODED:${urlencoder:$2}]
# Internally rewrite "/root/<anything>" to "/root.php?path=<anything>"
#RewriteRule ^root/(.+)$ ./root.php?path=%{ENV:PATH_ENCODED} [B,L]
RewriteRule ^root/(.+)$ ./root.php?path=${urlencoder:$2} [B,L]Zde je soubor root.php:
<!DOCUMENT HTML>
<html>
<head>
<meta charset="utf-8" />
<title>Hello World</title>
</head>
<body>
<h1>Test: Hello World</h1>
<ol>
<li>Language selector: <?php echo $_GET['lang']; ?></li>
<li>Path selector: <?php echo $_GET['path']; ?></li>
</ol>
</body>
</html>Jen dodám, že czghost.test je moje lokální testovací doména, která není přístupná z jiného počítače.