{"id":2337,"date":"2025-05-22T09:51:00","date_gmt":"2025-05-22T08:51:00","guid":{"rendered":"https:\/\/jalvo.eu\/ochrona-przed-hotlinkingiem-nginx-grafika-google\/"},"modified":"2025-05-22T09:51:00","modified_gmt":"2025-05-22T08:51:00","slug":"ochrona-przed-hotlinkingiem-nginx-grafika-google","status":"publish","type":"post","link":"https:\/\/jalvo.eu\/pl\/ochrona-przed-hotlinkingiem-nginx-grafika-google\/","title":{"rendered":"Ochrona przed hotlinkingiem w NGINX bez blokowania Grafiki Google"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Ochrona przed hotlinkingiem<\/strong> w NGINX przepuszcza \u017c\u0105dania obrazk\u00f3w tylko wtedy, gdy nag\u0142\u00f3wek Referer jest pusty, wskazuje na Twoje w\u0142asne domeny albo pochodzi z wyszukiwarki. Wszystko inne dyrektywa <em>valid_referers<\/em> odrzuca. Po co to? \u017beby inne strony nie osadza\u0142y Twoich plik\u00f3w i nie kaza\u0142y Twojemu serwerowi p\u0142aci\u0107 za ich dostarczanie (m\u00f3wi si\u0119 na to kradzie\u017c transferu obrazk\u00f3w). Prawdziwym zagro\u017ceniem nie s\u0105 jednak z\u0142odzieje. Jest nim zbyt surowa regu\u0142a, bo po cichu mo\u017ce ona sprawi\u0107, \u017ce Twoje zdj\u0119cia znikn\u0105 z Grafiki Google. Wszystko, co opisuj\u0119 poni\u017cej, dzia\u0142a na Twoim w\u0142asnym serwerze \u017ar\u00f3d\u0142owym NGINX.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Czym jest hotlinking obrazk\u00f3w i jak NGINX go wykrywa?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kto\u015b wstawia adres Twojego obrazka do w\u0142asnego znacznika &lt;img&gt;. Od tej chwili to Tw\u00f3j serwer dostarcza plik jego odwiedzaj\u0105cym. To w\u0142a\u015bnie hotlinking. Gdy przegl\u0105darka \u0142aduje tak\u0105 stron\u0119, zwykle wysy\u0142a nag\u0142\u00f3wek Referer z adresem strony, kt\u00f3ra osadza obrazek, a NGINX mo\u017ce por\u00f3wna\u0107 go z list\u0105 dozwolonych adres\u00f3w. Ten nag\u0142\u00f3wek to jednak tylko wskaz\u00f3wka. Nic wi\u0119cej. Przegl\u0105darki i proxy mog\u0105 go pomin\u0105\u0107 albo wyci\u0105\u0107, wi\u0119c nigdy nie jest prawdziwym uwierzytelnieniem. Zyskujesz koniec przypadkowego osadzania na innych stronach. A kto\u015b, kto celowo chce zdoby\u0107 Twoje pliki? Nadal je zdob\u0119dzie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak dzia\u0142a valid_referers w NGINX<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dyrektywa valid_referers ustawia zmienn\u0105 <code>$invalid_referer<\/code>. Potem blok <code>if<\/code> zwraca 403 (albo obrazek zast\u0119pczy) dla ka\u017cdego \u017c\u0105dania, kt\u00f3re nie pasuje. Przyk\u0142ad z <a href=\"https:\/\/nginx.org\/en\/docs\/http\/ngx_http_referer_module.html\" rel=\"nofollow noopener\" target=\"_blank\">dokumentacji modu\u0142u referer w NGINX<\/a> mie\u015bci wszystkie typy parametr\u00f3w w jednej linii:<\/p>\n\n\n\n<pre><code>valid_referers none blocked server_names *.example.com example.* www.example.org\/galleries\/ ~.google.;<\/code><\/pre>\n<ul>\n<li><strong>none<\/strong> obejmuje \u017c\u0105dania w og\u00f3le bez nag\u0142\u00f3wka Referer.<\/li>\n<li><strong>blocked<\/strong> obejmuje nag\u0142\u00f3wki, kt\u00f3re istniej\u0105, ale zosta\u0142y opr\u00f3\u017cnione przez proxy albo firewall.<\/li>\n<li><strong>server_names<\/strong> obejmuje to, co masz w dyrektywie <code>server_name<\/code>. Wpisz tam wersj\u0119 z www i bez www, a tak\u017ce ka\u017cd\u0105 subdomen\u0119 albo hosta CDN, kt\u00f3ry serwuje Twoje strony.<\/li>\n<li>Symbole wieloznaczne, takie jak <code>*.example.com<\/code>, i wyra\u017cenia regularne zaczynaj\u0105ce si\u0119 od <code>~<\/code> obs\u0142uguj\u0105 szersze wzorce, w tym domeny wyszukiwarek.<\/li>\n<\/ul>\n\n<h2>Bezpieczna konfiguracja ochrony przed hotlinkingiem krok po kroku<\/h2>\n<p class=\"wp-block-paragraph\">Bezpieczna oznacza tu trzy rzeczy: sprawdzasz tylko pliki graficzne, przepuszczasz puste i zaufane nag\u0142\u00f3wki Referer, a wszystkim pozosta\u0142ym zwracasz zwyk\u0142e 403. Kroki:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Utw\u00f3rz blok location, kt\u00f3ry pasuje tylko do rozszerze\u0144 obrazk\u00f3w.<\/li>\n<li>Dodaj <code>valid_referers none blocked server_names<\/code>, a potem swoje domeny i <code>~.google.<\/code>.<\/li>\n<li>Dodaj <code>if ($invalid_referer) { return 403; }<\/code>.<\/li>\n<li>Uruchom <code>nginx -t<\/code>, a potem prze\u0142aduj NGINX.<\/li>\n<li>Przetestuj curlem, wysy\u0142aj\u0105c r\u00f3\u017cne nag\u0142\u00f3wki Referer.<\/li>\n<\/ol>\n\n\n\n<pre><code>location ~* .(jpg|jpeg|png|gif|webp|avif|svg)$ {\n    valid_referers none blocked server_names\n                   example.com www.example.com\n                   ~.google.;\n    if ($invalid_referer) {\n        return 403;\n    }\n}<\/code><\/pre>\n<p class=\"wp-block-paragraph\">Twoje strony HTML nie s\u0105 obj\u0119te t\u0105 regu\u0142\u0105, bo dotyczy ona tylko plik\u00f3w graficznych. Czy zamiast 403 podstawi\u0107 z\u0142o\u015bliw\u0105 grafik\u0119 z napisem &#8222;kradziony obrazek&#8221;? Nie polecam. Zwyk\u0142e 403 \u0142atwiej utrzyma\u0107 i nikogo nie wprowadza w b\u0142\u0105d co do tego, czym naprawd\u0119 jest plik. Potem przetestuj cztery przypadki: brak nag\u0142\u00f3wka Referer, w\u0142asn\u0105 domen\u0119, domen\u0119 Google i obc\u0105 domen\u0119. Na przyk\u0142ad <code>curl -I -e https:\/\/other-site.test\/ https:\/\/example.com\/photo.jpg<\/code> powinno zwr\u00f3ci\u0107 403, a to samo \u017c\u0105danie bez <code>-e<\/code> powinno da\u0107 200.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dlaczego puste nag\u0142\u00f3wki Referer musz\u0105 by\u0107 dozwolone<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u015bli zablokujesz \u017c\u0105dania bez nag\u0142\u00f3wka Referer, odetniesz prawdziwych u\u017cytkownik\u00f3w i crawlery. Dlatego <code>none<\/code> i <code>blocked<\/code> nie s\u0105 opcjonalne. Kto nie wysy\u0142a nag\u0142\u00f3wka Referer? Ludzie wpisuj\u0105cy adres r\u0119cznie, osoby z restrykcyjnymi ustawieniami prywatno\u015bci, zak\u0142adki, czytniki kana\u0142\u00f3w, crawlery. Do tego Googlebot-Image pobiera pliki bez strony odsy\u0142aj\u0105cej, wi\u0119c regu\u0142a bez <code>none<\/code> ca\u0142kowicie go blokuje. Najcz\u0119stsze b\u0142\u0119dy:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pomini\u0119cie <code>none<\/code> albo <code>blocked<\/code>,<\/li>\n<li>zapomnienie o wersji domeny z www,<\/li>\n<li>sprawdzanie ca\u0142ej witryny zamiast samego bloku location dla obrazk\u00f3w,<\/li>\n<li>wyra\u017cenie regularne dla Google tak w\u0105skie, \u017ce nie \u0142apie domen krajowych.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Jak utrzyma\u0107 obrazki w Grafice Google<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Google musi m\u00f3c pobra\u0107 dok\u0142adnie ten plik, kt\u00f3ry widzi u\u017cytkownik. Dlatego \u017cadnego specjalnego wyj\u0105tku dla Googlebot-Image i \u017cadnej innej odpowiedzi. Serwowanie crawlerom czego\u015b innego ni\u017c ludziom to po prostu cloaking. Twoja regu\u0142a powinna traktowa\u0107 ka\u017cdego klienta tak samo i r\u00f3\u017cni\u0107 si\u0119 tylko nag\u0142\u00f3wkiem Referer. Zgodnie z <a href=\"https:\/\/developers.google.com\/search\/docs\/appearance\/google-images\" rel=\"nofollow noopener\" target=\"_blank\">wytycznymi Google dotycz\u0105cymi SEO obraz\u00f3w<\/a> Google znajduje obrazki w standardowym atrybucie <code>&lt;img src&gt;<\/code>, akceptuje mapy witryny dla obraz\u00f3w, obs\u0142uguje formaty takie jak WebP, SVG i AVIF i nie indeksuje obrazk\u00f3w t\u0142a z CSS. Chcesz ograniczy\u0107 wy\u015bwietlanie plik\u00f3w w pe\u0142nym rozmiarze? Oficjalna droga to rezygnacja z linkowania bezpo\u015bredniego w Grafice Google, a Google zapewnia, \u017ce nie traktuje tego jako cloakingu obraz\u00f3w.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sprawdzanie log\u00f3w po w\u0142\u0105czeniu ochrony przed hotlinkingiem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Regu\u0142a wdro\u017cona. Teraz przejrzyj w logach dost\u0119pu \u017c\u0105dania obrazk\u00f3w, kt\u00f3re dosta\u0142y 403, i upewnij si\u0119, \u017ce \u017cadne nie przysz\u0142o z Twojej strony ani od Google. Filtruj po statusie, <code>$http_referer<\/code>, user agencie i \u015bcie\u017cce obrazka. Pierwszy raz przekopujesz si\u0119 przez te dane? Nasz poradnik o tym, jak czyta\u0107 <a href=\"https:\/\/jalvo.eu\/pl\/logi-serwera-problemy-z-crawlowaniem\/\">\u017c\u0105dania obrazk\u00f3w w logach dost\u0119pu<\/a>, omawia poszczeg\u00f3lne pola. Je\u015bli obrazki zaczn\u0105 znika\u0107 z Grafiki Google, usu\u0144 na jaki\u015b czas wyra\u017cenie regularne i blok <code>if<\/code>, a potem por\u00f3wnaj logi sprzed i po zmianie, \u017ceby zobaczy\u0107, kt\u00f3ry Referer zosta\u0142 odrzucony.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Jak ochrona przed hotlinkingiem wsp\u00f3\u0142gra z cache i limitami dla bot\u00f3w<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sprawdzanie nag\u0142\u00f3wka Referer dzia\u0142a niezale\u017cnie od cache i ograniczania liczby \u017c\u0105da\u0144. Jednak kolejno\u015b\u0107 regu\u0142 w konfiguracji decyduje o tym, co faktycznie dostaje crawler. Je\u015bli przed serwerem \u017ar\u00f3d\u0142owym stoi cache, odpowied\u017a 403 wywo\u0142ana obcym nag\u0142\u00f3wkiem Referer nigdy nie mo\u017ce zosta\u0107 zapisana i potem serwowana wszystkim (to naprawd\u0119 boli). Przejrzyj swoje <a href=\"https:\/\/jalvo.eu\/pl\/cache-reverse-proxy-a-seo-bez-nieaktualnych-stron\/\">regu\u0142y cache dla crawler\u00f3w<\/a>, \u017ceby takie odpowiedzi by\u0142y trzymane osobno. A na agresywne scrapery limity \u017c\u0105da\u0144 zawsze dzia\u0142aj\u0105 lepiej ni\u017c ostrzejsze regu\u0142y dla nag\u0142\u00f3wka Referer. S\u0105 sposoby <a href=\"https:\/\/jalvo.eu\/pl\/rate-limiting-botow-bez-spowalniania-googlebota\/\">ograniczania bot\u00f3w bez szkody dla Googlebota<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oprzyj ochron\u0119 przed hotlinkingiem na <code>none<\/code>, <code>blocked<\/code>, <code>server_names<\/code> i domenach Google, a zablokujesz osadzanie Twoich obrazk\u00f3w na innych stronach, zachowuj\u0105c ich widoczno\u015b\u0107 w wynikach wyszukiwania.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list \">\n<div id=\"faq-question-1790771564520-0\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Czy ochrona przed hotlinkingiem usunie moje obrazki z Grafiki Google?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Nie, o ile dopuszczasz \u017c\u0105dania bez nag\u0142\u00f3wka Referer i domeny Google. Stosuj t\u0119 sam\u0105 regu\u0142\u0119 do ka\u017cdego odwiedzaj\u0105cego i crawlera, a Googlebot-Image b\u0119dzie pobiera\u0142 Twoje pliki tak jak wcze\u015bniej.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1790771564520-1\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Czy dopisa\u0107 Googlebot-Image do bia\u0142ej listy po user agencie?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Nie. Regu\u0142a dla nag\u0142\u00f3wka Referer wystarczy, bo crawler nie wysy\u0142a strony odsy\u0142aj\u0105cej, a <code>none<\/code> ju\u017c go przepuszcza. Osobne traktowanie crawler\u00f3w to proszenie si\u0119 o k\u0142opoty z cloakingiem.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1790771564520-2\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question \">Czy ochrona przed hotlinkingiem powstrzyma kogo\u015b przed pobraniem moich obrazk\u00f3w?<\/h3>\n<div class=\"rank-math-answer \">\n\n<p>Nie. Blokuje tylko osadzanie na innych stronach. Ka\u017cdy mo\u017ce podrobi\u0107 albo pomin\u0105\u0107 nag\u0142\u00f3wek Referer, wi\u0119c bezpo\u015brednie pobranie nadal dzia\u0142a.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Ochrona przed hotlinkingiem w NGINX przepuszcza \u017c\u0105dania obrazk\u00f3w tylko wtedy, gdy nag\u0142\u00f3wek Referer jest pusty, wskazuje na Twoje w\u0142asne domeny albo pochodzi z wyszukiwarki. Wszystko inne dyrektywa valid_referers odrzuca. Po co to? \u017beby inne strony nie osadza\u0142y Twoich plik\u00f3w i nie kaza\u0142y Twojemu serwerowi p\u0142aci\u0107 za ich dostarczanie (m\u00f3wi si\u0119 na to kradzie\u017c transferu obrazk\u00f3w). [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":2313,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[182],"tags":[304,406,247,407,28,416],"class_list":["post-2337","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-seo-pl","tag-bezpieczenstwo","tag-hotlinking-x","tag-nginx-x","tag-obrazy","tag-seo-pl","tag-serwer-www"],"acf":[],"_links":{"self":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts\/2337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/comments?post=2337"}],"version-history":[{"count":0,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/posts\/2337\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/media\/2313"}],"wp:attachment":[{"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/media?parent=2337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/categories?post=2337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jalvo.eu\/pl\/wp-json\/wp\/v2\/tags?post=2337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}