Category: nginx

Install *Synology* NAS managed *Let’s Encrypt Certificate* in *NGINX*

Install Synology NAS managed Let's Encrypt Certificate in NGINX

Certificate Management

Synology NAS can be used for certificate management, and Let's Encrypt certificate can be exported as ZIP file used for NGINX HTTPS configuration.

  1. Go to Control Panel -> Security -> Certificate
  2. Select certificate to be exported
  3. Select Export Certificate from right click menu
  4. Save exported file

For existing certificates, can use right click -> renew option to renew.

Note: All domain in the certificates, must be resolved to current Synology NAS at port 80 and port 443, otherwise, certificate generation will be failed.

In downloaded ZIP file, following files can be found.

  • certs.pem
  • chain.pem
  • privkey.pem

NGINX configuration

  1. Concatenate cert.pem and chain.pem to cert-with-chain.pem (or fullchain.pem) file

  2. Copy cert-with-chain.pem and privkey.pem into NGNIX conf.d folder

  3. Verify NGINX configuration as below

ssl_certificate     conf.d/cert-with-chain.pem;
ssl_certificate_key conf.d/privkey.pem;
  1. Restart NGINX

Verification

Browser

The date of issue for new certificate should be displayed in certificate information window.

Command line

Following command can be used for verification

openssl s_client -connect <domain_name>:<port>

If got following error, concatenate chain.pem into cert.pem, because the full chain is required.

verify error:num=20:unable to get local issuer certificate
verify error:num=21:unable to verify the first certificate

References

How to install Let's Encrypt on Nginx

Split NGINX configuration file

Split NGINX configuration file

To split NGINX configuration file into multiple conf.d/*.conf files.

This is defined in /etc/nginx/nginx.conf file as below

http {
    ...
    include /etc/nginx/conf.d/*.conf;
}

Pros

Avoid large configuration file and manage easiler.

NGINX will read all files in conf.d directory, which has extension name as .conf and use them all as final configuration.

Cons

Only definitions in http { ... } directive can be defined in conf.d/*.conf.

Which file to be loaded first is unclear.

One server definition should not be defined in mulitipe files.

Replace Contents in NGINX

Replace Contents in NGINX

The content of a webpage contains URL or other information need to be replaced, especially when domain name changed in URL.

sub_filter

Use sub_filter module in NGINX to replace content.

For example,

server {
    ```
    location / {
        sub_filter 'www.example.com' 'www.xx.example.com';
        sub_filter_once on;

        proxy_pass  http://www.example.com;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
   }
}

Note: Place sub_filter at beginning of the location session

If required, also need to change host to allow server decide which page requested if it is also a NGINX server and displays page depending on the host as well.

proxy_set_header        Host            www.example.com;

References

Module ngx_http_sub_module
http_sub_module / sub_filter of nginx and reverse proxy not working

Configure different target based on incoming domain in NGINX

Configure different target based on incoming domain in NGINX

NGINX can divert incoming request to different server based on domain name given in browser.

Usage

If there are a few application, such as 192.168.1.1 for faq.example.com, 192.168.1.2 for www.example.com, etc.

Configuration

Following configuration can be used for diverting request for faq requests.

server {
    server_name  faq.example.com;

    # SSL configuration
    listen 443 ssl;

    ssl_certificate     conf.d/www.example.com.crt;
    ssl_certificate_key conf.d/www.example.com.key;

    location / {
        proxy_pass  'https://192.168.1.1:443';
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_read_timeout    90;
        proxy_connect_timeout 90;
        proxy_redirect        off;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port 443;
        proxy_set_header Proxy "";
    }

    client_max_body_size 64M;
}

server {
    listen       80;
    server_name  faq.example.com;

    return 301 https://$host$request_uri;
}

Application Stopped due to upstream unreachable

Application Stopped due to upstream unreachable

During Chef Server troubleshooting time, found chef is unreachable from localhost

Description

  • Nginx was shown as started in chef-server-ctl status command, pid could be found
  • TCP port 443 was inaccessable from localhost.
  • Reboot server, but still the same issue
  • Used ps -ef | grep nginx, found nginx is running without indication of master
  • Run nginx command line which found in ps
  • Shows upstream server and port was not reachable, which is automate server

Result

  • Can not find IP address, then add IP and host into /etc/host file, result shows

    • NGINX running with master indicator
    • TCP port 443 was listening
  • Still can not reach upstream server

Consolution

The problem could be related to following issues caused application stopped due to no IP can be found for upstream servers.

  • Routing issue
  • Firewall issue

Increase upload file size limit for WordPress and NGNIX

Increase upload file size limit for WordPress and NGNIX

There are various ways to do, but the workable way is, updating .htaccess in WordPress and NGNIX configuration file.

Issue

First, tried the way by changing function.php in theme, but no luck. Then updated .htaccess file, it worked.

Then the client gets the error “Request Entity Too Large” (413). This error reported by NGINX.

WordPress

Add following lines in .htaccess file in html directory

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300

Then the upload page in WordPress should be shown as below

Maximum upload file size: 64 MB.

Alternative

These options are PHP options, which can be applied to php.ini as well as below

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300

NGINX

Add the following line to http, server or location context in nginx.conf or conf.d/default.conf

client_max_body_size 64M;

Then reload NGINX configure.

# /usr/local/nginx/sbin/nginx -s reload

This will fix the client error “Request Entity Too Large” (413).

Increase client_max_body_size in NGINX for docker registry

Increase client_max_body_size in NGINX for docker registry

Error "413 Request Entity Too Large" occurred when push image to docker registry.

To fix this issue, add client_max_body_size in NGINX configuration file for docker registry as below, then restart NGINX.

server {
    listen 443;
    server_name hub.bx.net docker.bx.net registry.bx.net dockerhub.bx.net;

    location /v2/ {
        proxy_pass https://registry.my_bridge/v2/;
        proxy_set_header  Authorization $http_authorization;
        proxy_pass_header Authorization;
    }

    client_max_body_size 100M;
}

WordPress URLs point actual server behind NGINX

WordPress URLs point actual server behind NGINX

NGINX did not translate URL correctly

When accessing server via NGINX, it didn't translate URLs in page to the URL accessing.

For example, the URL is https://example.com/sample.html, the server behind is https://192.168.1.11/sample.html, the NGINX is still leaving it without translating.

I have done following, but not useful

  1. Updated both options siteurl and home in database
update wp_options set option_value='http://newhost:8080' where option_name='siteurl';
update wp_options set option_value='http://newhost:8080' where option_name='home';
  1. Added host and port in wp_config.php
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
      $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
      $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_PORT'];
}

Someone suggested following lines as well, but I didn't do it.

define('WP_HOME','https://test.com/blog/');
define('WP_SITEURL','https://test.com/blog/');
  1. Updated NGINX configuration.
proxy_pass http://newhost

Solution

Modify NGINX configuration

Configure https

server {
    server_name  blog.bianxi.com;

    # SSL configuration
    listen 443 ssl;

    ssl_certificate     conf.d/www.bianxi.com.crt;
    ssl_certificate_key conf.d/www.bianxi.com.key;

    location / {
        proxy_pass      'http://192.168.1.14:8080';
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_read_timeout    90;
        proxy_connect_timeout 90;
        proxy_redirect        off;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port 443;
        proxy_set_header Proxy "";
    }
}

Configure http redirect

server {
    listen       80;
    server_name  blog.bianxi.com;

    return 301 https://$host$request_uri;
}

Config wp-config.php

Add following lines in wp-config.php

//$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/blog/wp-admin/",  $_SERVER['REQUEST_URI']);

if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'){

    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;

    define('WP_HOME','https://blog.bianxi.com/');
    define('WP_SITEURL','https://blog.bianxi.com/');
}

If change URL is required

Change location in NGINX configuration file, and the URL replace were used if requires changing of URL as well in wp-config.php file.