{"id":83,"date":"2019-03-05T20:20:17","date_gmt":"2019-03-05T12:20:17","guid":{"rendered":"https:\/\/www.rich-hsu.com\/blog\/?p=83"},"modified":"2019-03-05T20:20:20","modified_gmt":"2019-03-05T12:20:20","slug":"note-nginx-wordpress-https","status":"publish","type":"post","link":"https:\/\/www.rich-hsu.com\/blog\/note-nginx-wordpress-https\/","title":{"rendered":"[Note] Nginx + WordPress + Https"},"content":{"rendered":"\n<p>Days ago, instead of using separate micro\/nano servers, I try to collect all my sites onto a stronger server.<\/p>\n\n\n\n<p>Several of my server were establish by wordpress with apache, therefore, I setup a Nginx server as reverse proxy and launch each site by customized LAMP docker image.<\/p>\n\n\n\n<p>Things go pretty well with some configuration process, but I found something wrong with certain condition. <\/p>\n\n\n\n<p>That is, when I try to access the wordpress site in sub folder (ex. <strong><a href=\"https:\/\/www.rich-hsu.com\/blog\">https:\/\/www.rich-hsu.com\/blog<\/a><\/strong>), the server will redirect the URL to a strange form: <strong><a href=\"http:\/\/www.rich-hsu.com:443\/blog\">http:\/\/www.rich-hsu.com:443\/blog<\/a><\/strong><\/p>\n\n\n\n<p>Although I can modify the URL with &#8220;https&#8221; and add the tailing slash (<strong><a href=\"https:\/\/www.rich-hsu.com\/blog\/\">https:\/\/www.rich-hsu.com\/blog\/<\/a><\/strong>), this issue did make me dizzy. And I believe it will cause some impacts on SEO.<\/p>\n\n\n\n<p>After hours of debugging, I got the root cause and solution.<\/p>\n\n\n\n<p>The root cause is I&#8217;ve add a line in my Nginx server config file<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-light-gray-color has-very-dark-gray-background-color\">proxy_set_header Host $host:<span style=\"color:red\"><strong>$server_port<\/strong><\/span>;<\/p>\n\n\n\n<p>You wonder what is this configuration doing. It helps to solve the &#8220;mixed content&#8221; issue of WordPress. <\/p>\n\n\n\n<p>Since we apply SSL on each site with Nginx as proxy, the internal communications ( proxy_pass ) are just using HTTP. Therefore, you will get the main content in HTTPS but other resources in HTTP. And the browser will blocked such behavior.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-attachment-id=\"86\" data-permalink=\"https:\/\/www.rich-hsu.com\/blog\/note-nginx-wordpress-https\/image\/\" data-orig-file=\"https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?fit=756%2C179&amp;ssl=1\" data-orig-size=\"756,179\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-medium-file=\"https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?fit=300%2C71&amp;ssl=1\" data-large-file=\"https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?fit=756%2C179&amp;ssl=1\" loading=\"lazy\" width=\"756\" height=\"179\" src=\"https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?resize=756%2C179&#038;ssl=1\" alt=\"\" class=\"wp-image-86\" srcset=\"https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?w=756&amp;ssl=1 756w, https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?resize=300%2C71&amp;ssl=1 300w, https:\/\/i1.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/image.png?resize=696%2C165&amp;ssl=1 696w\" sizes=\"(max-width: 756px) 100vw, 756px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>Therefore, we have to do something for WordPress to know it should use &#8220;https&#8221; for all the resource accessing in HTML output. And the direct way (I though it is the direct way before this event&#8230;) is to set the configuration. WordPress will show the HTTPS in resource links by recognize the port 443.<\/p>\n\n\n\n<p>And Boooooom! The bomb comes and I have no idea to avoid the &#8220;Mixed Content&#8221; issue and keep the redirection issue away.<\/p>\n\n\n\n<p>With some search, there is no good solution to solve this issue. (I think the the &#8220;good&#8221; solution should be modification in configuration or add some plug-in only). <strong style=\"color:red\">We have to modify the WordPress code<\/strong>!!<\/p>\n\n\n\n<p>So the total solution is<\/p>\n\n\n\n<ul><li><strong>Not to pass the port information to WordPress<\/strong><\/li><\/ul>\n\n\n\n<p>          Remove the &#8220;:$server_port&#8221; from the Nginx setting. However, you still have to pass the $host to WordPress to keep the resources host correct.<\/p>\n\n\n\n<ul><li><strong>Modify the code of WordPress<\/strong><\/li><li><\/li><\/ul>\n\n\n\n<p>          Since we did not pass the port (i.e. 443) to WordPress, we have to set the $_SERVER[&#8216;HTTP&#8217;] flag on manually. Therefore, as we know the all the request will based on HTTPS as we defined in Nginx, we&#8217;re using the header &#8220;HTTP_X_Forwarded_Protocol&#8221; to make this happened. ( I know, some documents or articles use &#8220;Proto&#8221; but I like to make it more clearly. )<\/p>\n\n\n\n<p>          So we have 2 steps to do.<\/p>\n\n\n\n<p>          In Nginx setting, we add another line to pass the &#8220;https&#8221; information by header.<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-light-gray-color has-very-dark-gray-background-color\">proxy_set_header X-Forwarded-Protocol &#8220;https&#8221;;<\/p>\n\n\n\n<p>          In WordPress, we need to add some logic as early as possible. (I did it by modify the first line of &#8220;wp-config.php&#8221;<\/p>\n\n\n\n<p class=\"has-text-color has-background has-very-light-gray-color has-very-dark-gray-background-color\">if ($_SERVER[&#8216;HTTP_X_FORWARDED_PROTOCOL&#8217;] === &#8216;https&#8217;) { $_SERVER[&#8216;HTTPS&#8217;] = &#8216;1&#8217;; }<\/p>\n\n\n\n<p>        As the WordPress has a function named &#8220;is_ssl()&#8221;, and we should modify the function to hit the root cause, I believe the modification in configuration will be a better solution in maintenance perspective &#8212; the &#8220;is_ssl()&#8221; function might be overwritten after something such as upgrade.<br><\/p>\n\n\n\n<p>As the result, all my sites work well without such confusing and annoying issue. : )<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Days ago, instead of using separate micro\/nano servers,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":89,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[34,16,35,36,29,15],"tags":[21,39,9,13,37,8,38,40],"post_series":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2019\/03\/https.jpg?fit=1920%2C768&ssl=1","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9Qbvu-1l","jetpack-related-posts":[{"id":37,"url":"https:\/\/www.rich-hsu.com\/blog\/resources-web-developer-check-list\/","url_meta":{"origin":83,"position":0},"title":"[ Resources ] Web developer check list","date":"2018-04-25","format":false,"excerpt":"[] SSL [] Robots [] Backup [] Data firewall [] GA \u2026","rel":"","context":"\u5728\u300cDevelop\u300d\u4e2d","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2018\/04\/checklist.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":55,"url":"https:\/\/www.rich-hsu.com\/blog\/note-pretty-json-in-vim\/","url_meta":{"origin":83,"position":1},"title":"[ Note ] Pretty JSON in VIM","date":"2018-07-05","format":false,"excerpt":"As using VIM to review JSON data, the format and s\u2026","rel":"","context":"\u5728\u300cDevelop\u300d\u4e2d","img":{"alt_text":"","src":"https:\/\/i2.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2018\/07\/json_1530761804.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":46,"url":"https:\/\/www.rich-hsu.com\/blog\/tools-online-base64-encode-and-decode\/","url_meta":{"origin":83,"position":2},"title":"[ Tools ] Online Base64 Encode and Decode","date":"2018-04-26","format":false,"excerpt":"Sometime we need to encode and decode base64 data.\u2026","rel":"","context":"\u5728\u300cDevelop\u300d\u4e2d","img":{"alt_text":"","src":"https:\/\/i2.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2018\/04\/encryption.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":31,"url":"https:\/\/www.rich-hsu.com\/blog\/resources-web-developer-toolkit\/","url_meta":{"origin":83,"position":3},"title":"[ Resources ] Web developer toolkit","date":"2018-04-23","format":false,"excerpt":"As web developer, some tools might need.... CC0 Im\u2026","rel":"","context":"\u5728\u300cDevelop\u300d\u4e2d","img":{"alt_text":"","src":"https:\/\/i2.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2018\/04\/toolbox.jpg?fit=1200%2C803&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":98,"url":"https:\/\/www.rich-hsu.com\/blog\/nfc-briefing-quick-notes\/","url_meta":{"origin":83,"position":4},"title":"NFC Briefing - Quick notes","date":"2021-05-04","format":false,"excerpt":"Main Stream Card Type Type Standard Storage Storag\u2026","rel":"","context":"\u5728\u300cNote\u300d\u4e2d","img":{"alt_text":"close up of hand holding text over black background","src":"https:\/\/i0.wp.com\/www.rich-hsu.com\/blog\/wp-content\/uploads\/2021\/05\/pexels-photo-326576.jpeg?fit=1200%2C701&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/posts\/83"}],"collection":[{"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/comments?post=83"}],"version-history":[{"count":3,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/posts\/83\/revisions"}],"predecessor-version":[{"id":88,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/posts\/83\/revisions\/88"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/media\/89"}],"wp:attachment":[{"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/media?parent=83"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/categories?post=83"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/tags?post=83"},{"taxonomy":"post_series","embeddable":true,"href":"https:\/\/www.rich-hsu.com\/blog\/wp-json\/wp\/v2\/post_series?post=83"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}