{"id":460,"date":"2016-02-28T14:47:19","date_gmt":"2016-02-28T06:47:19","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=460"},"modified":"2018-09-04T22:51:24","modified_gmt":"2018-09-04T14:51:24","slug":"preventing-image-hotlinking-with-nginx-with-some-style","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/preventing-image-hotlinking-with-nginx-with-some-style\/","title":{"rendered":"Preventing image hotlinking with Nginx, with some style"},"content":{"rendered":"<p>Image hotlinking is a situation when your image appears on other website(s) but that image was actually being served by your web server. Image hotlinking is bad; your image gets stolen from your website and your server resources is being spent to serve them. If you happen to be running Nginx as your web server, this post describes how you can use Nginx to prevent image hotlinking with a <a href=\"http:\/\/www.hongkiat.com\/blog\/smarter-way-to-prevent-image-hotlinking-with-htaccess\/\" title=\"Hongkiat.com on how to prevent image hotlinking on Apache HTTP Server\" target=\"_blank\">smarter way that was suggested by Hongkiat<\/a>.  <\/p>\n<h3>Hosting an alternative image that informs web vistor of image hotlinking on a free website<\/h3>\n<p>There are many websites that allows us to upload an image and not restrict image hotlinking. Find one of such websites and upload <a href=\"https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif\" title=\"Techcoil.com hotlinked message\" target=\"_blank\">an image with some wordings on hotlinking<\/a>. Remember the URL of your uploaded image about image hotlinking, for example, https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif.<\/p>\n<h3>Configuring Nginx to inspect HTTP requests made to all your images<\/h3>\n<p>To begin with inspecting HTTP requests for images, we first begin with the following location block:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation ~ .(gif|jpe?g|png)$ {\r\n    # Configurations to check for image hotlinking. \r\n}\r\n<\/pre>\n<p>This location block tells our Nginx to use regular expression to determine if a HTTP request is made to an image ending with one of the following four image extensions:<\/p>\n<ul>\n<li>gif<\/li>\n<li>jpeg<\/li>\n<li>jpg<\/li>\n<li>png<\/li>\n<\/ul>\n<p>Note that this block <strong>will not match<\/strong> HTTP requests directed at scripts that generate images on the fly. For example, if you have an image generation script at <code>\/generateImage.php<\/code>, you will need the following block to match requests made to the image generation script:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation \/generateImage.php {\r\n    # Configurations to check for image hotlinking\r\n}\r\n<\/pre>\n<h3>Getting Nginx to check whether a HTTP request made to an image is a hotlink request<\/h3>\n<p>Hotlink requests are referred by websites that do not belong to us. Preventing image hotlinking with Nginx will require us to check whether an image HTTP request contains a valid <a href=\"http:\/\/www.w3.org\/Protocols\/HTTP\/HTRQ_Headers.html#z14\" title=\"More about http referer\" target=\"_blank\">HTTP referer<\/a> value. <\/p>\n<p>To check whether a HTTP request is a hotlink request in Nginx, we can include the following configurations inside the location block:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    # Remember to substitute example.com with your domain.    \r\n    valid_referers none blocked example.com *.example.com;\r\n    if ($invalid_referer) {\r\n        # Remember to substitute https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif \r\n        # with your image URL.\r\n        return 301 https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif;\r\n    }\r\n<\/pre>\n<p>With this, we use the <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_referer_module.html\" title=\"More about http_referer module on Nginx documentation site\" target=\"_blank\"><code>valid_referers<\/code> module<\/a> to check whether the HTTP request contains a valid HTTP referer value.<\/p>\n<p>A HTTP request with a valid referer for our case will be either<\/p>\n<ul>\n<li>not present, which is indicated by none <\/li>\n<li>blocked, which is usually the case of the request coming from behind firewalls <\/li>\n<li>having our domain (example.com) as the referee<\/li>\n<li>having anything domain that ends with our domain (example.com)<\/li>\n<\/ul>\n<p>After Nginx execute the <code>valid_referers<\/code> module, it will set the result of the check $invalid_referer variable. If $invalid_referer is true, we redirect the request to the image that contains the hotlink message. We do that by returning a HTTP response code of 301 alongside the image URL that contains the hotlink message.<\/p>\n<h3>Putting the Nginx configurations together<\/h3>\n<p>Putting everything together, you will get the following Nginx configurations:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation ~ .(gif|jpe?g|png)$ {\r\n    # Configurations to check for image hotlinking. \r\n    \r\n    # Remember to substitute example.com with your domain.    \r\n    valid_referers none blocked example.com *.example.com;\r\n    if ($invalid_referer) {\r\n        # Remember to substitute https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif \r\n        # with your image URL.\r\n        return 301 https:\/\/sites.google.com\/site\/tcperpetual\/home\/hotlinked-message.gif;\r\n    }\r\n}\r\n<\/pre>\n<p>With this, we should succeed in preventing image hotlinking with Nginx.<\/p>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-7q\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-7q&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-7q&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F460&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>Image hotlinking is a situation when your image appears on other website(s) but that image was actually being served by your web server. Image hotlinking is bad; your image gets stolen from your website and your server resources is being spent to serve them. If you happen to be running Nginx as your web server, this post describes how you can use Nginx to prevent image hotlinking with a <a href=\"http:\/\/www.hongkiat.com\/blog\/smarter-way-to-prevent-image-hotlinking-with-htaccess\/\" title=\"Hongkiat.com on how to prevent image hotlinking on Apache HTTP Server\" target=\"_blank\">smarter way that was suggested by Hongkiat<\/a>.  <\/p>\n","protected":false},"author":1,"featured_media":1240,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[4],"tags":[225,195],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/Nginx-Logo.jpg","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-7q","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/460"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=460"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/460\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1240"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=460"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=460"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=460"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}