Tag: nginx

  • Redirect site from www to non-www

    Redirect site from www to non-www

    It is better to make web site available with one URL. Many sites work with both wwww and non-www (naked domain) urls.

    Using www or non-www is personal choice. One advantage of using wwww for URL is when you have lot of sub domains. If you use non-www url, cookies set by the domain will be available to sub domains. This will increase bandwidth usage as cookie need to be sent with every request browser make to web server.

    Apache

    If you are using Apache web server, you can redirect wwww to non-www URL by adding the following code in the .htaccess file

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www.yourdomain.com [NC]
    RewriteRule ^(.*)$ https://yourdomain.com$1 [L,R=301]

    Redirect non-www to www

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^yourdomain.com [NC]
    RewriteRule ^(.*)$ https://www.yourdomain.com$1 [L,R=301]

    Nginx

    If you use Nginx, it is better to create a server entry for the www URL, and then set a redirect

    server {
        server_name www.yourdomain.com;
        return 301 $scheme://yourdomain.com$request_uri;
    }

    If you want to use the same server entry for www and non-www, add the following code to the nginx server entry for the website.

    Redirect www domain to non-www

    if ( $host != 'yourdomain.com' ) {
        return 301 https://yourdomain.com$request_uri;
    }

    If you use custom ports, use

    if ( $host != 'yourdomain.com' ) {
        return 301 https://yourdomain.com:$server_port$request_uri;
    }

    Redirect Naked Domain to www

    if ( $host != 'www.serverok.in' ) {
        return 301 https://serverok.in$request_uri;
    }

    Related Posts

    Redirect

    htaccess

  • Show Real IP Nginx Behind Reverse Proxy

    Show Real IP Nginx Behind Reverse Proxy

    When your Nginx web server is running behind a reverse proxy, you will see IP of the reverse proxy server as visitor IP in web servers access log.

    To fix this, edit nginx.conf file

    vi /etc/nginx/nginx.conf
    

    Find

    http {
    

    Inside http section, add

    set_real_ip_from IP_ADDRESS_OF_PROXY_SERVER_HERE;
    real_ip_header X-Forwarded-For;
    

    Example

    set_real_ip_from 192.168.122.1;
    real_ip_header X-Forwarded-For;
    

    Restart Nginx

    nginx -s reload
    
  • Install Nginx on CentOS 8

    Install Nginx on CentOS 8

    To install Nginx web server on CentOS 8, create repo

    vi /etc/yum.repos.d/nginx.repo
    

    Add

    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=0
    enabled=1
    

    Install nginx with dnf or yum

    dnf install nginx
    

    Open HTTP and HTTPS ports on firewall

    firewall-cmd --zone=public --permanent --add-service=http
    firewall-cmd --zone=public --permanent --add-service=https
    firewall-cmd --zone=public --permanent --add-service=ssh
    firewall-cmd --reload
    
  • Redirect HTTP to HTTPS when using Reverse Proxy

    When you are using Reverse Proxy like Nginx, Haproxy or Amazon ELB in front of web server and web server use HTTP to serve all traffic, you can use normal redirect code based HTTPS variable to do the redirect to HTTPS. You need to use X-Forwarded-Proto to do the redirect.

    For Apache, add following code to .htaccess to Apache Virtual Host entry.

    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} =http
    RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
    

    For Nginx, add following to server entry for the domain name

    if ($http_x_forwarded_proto = 'http'){
        return 301 https://$host$request_uri;
    }
    

    For IIS edit web.config, add following to section.

    
        
            
                
                
                    
                
                
            
        
    
    
  • Nginx Location Directive

    Nginx Location Directive is used to route request to correct files.

    Match

    Exact match is used to match an exact URL.

    server {
        listen 80 default_server;
        root /var/www/html;
        index index.html;
        server_name _;
    
        location /ok/ {
            root /home/;
        }
    }
    

    When location is used with no modifiers, then beginning of the URL is matched. In this case, any url http://domain/ok/FILE_NAME will be served from /home/ok/FILE_NAME

    Exact Match (=)

    Exact match is used to match an exact URL.

    server {
        listen 80 default_server;
        root /var/www/html;
        index index.html;
        server_name _;
    
        location = /ok/index.html {
            root /home/;
        }
    }
    

    In this example http://domain/ok/index.html get served from /home/ok/index.html. Only this specific file will be matched.

    Cause Insensitive Regular Expression Match (~*)

    server {
        listen 80 default_server;
        root /var/www/html;
        index index.html;
        server_name _;
    
        location /ok/ {
            root /home/;
        }
    }
    

    Above code routes URL http://domain/ok/ to /home/ok/index.html. But won’t match http://domain/OK/.

    If you need both /ok and /OK work, you need to use

        location ~* /ok/ {
            root /home/;
        }
    

    With this config, http://domain/OK/FILE will be served from /home/OK/FILE.

    See Nginx

  • Nginx Password Protect a website

    Nginx Password Protect a website

    nginx password protect

    To password protect a website, you need to install htpasswd utility. On Ubuntu/Debian, you can install it with the command

    apt install apache2-utils -y

    Now create a password file with the command

    htpasswd -c /etc/nginx/.htpasswd  USER_NAME_HERE

    It will ask for a password.

    Edit the configuration file for your website and add the following in the server entry for the website.

    auth_basic "Members Only";
    auth_basic_user_file /etc/nginx/.htpasswd;

    Restart Nginx.

    systemctl restart nginx

    Now on visiting the website, you will be asked to enter your username and password.

    If you need to allow SSL renewals, then see SSL Renewal On Nginx Password Protected site

    See Nginx

  • Nginx vs Apache

    I recently added nginx as front end for apache. Now nginx serve static content, PHP requests are peroxided to Apache.

    Nginx frontend, Apache backend

    [root@server12 ~]# ab -n 1000 -c 100 http://netfree.netfreehost.com/
    This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright 2006 The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking netfree.netfreehost.com (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Finished 1000 requests
    
    
    Server Software:        nginx/1.1.0
    Server Hostname:        netfree.netfreehost.com
    Server Port:            80
    
    Document Path:          /
    Document Length:        16844 bytes
    
    Concurrency Level:      100
    Time taken for tests:   5.463353 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      17357000 bytes
    HTML transferred:       16844000 bytes
    Requests per second:    183.04 [#/sec] (mean)
    Time per request:       546.335 [ms] (mean)
    Time per request:       5.463 [ms] (mean, across all concurrent requests)
    Transfer rate:          3102.49 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   0.8      0       5
    Processing:    44  518  93.9    534     719
    Waiting:       44  517  94.0    533     718
    Total:         47  518  93.2    534     719
    
    Percentage of the requests served within a certain time (ms)
      50%    534
      66%    553
      75%    566
      80%    574
      90%    592
      95%    606
      98%    642
      99%    665
     100%    719 (longest request)
    [root@server12 ~]#
    

    Apache Only

    [root@server12 ~]# ab -n 1000 -c 100 http://netfree.netfreehost.com:81/
    This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright 2006 The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking netfree.netfreehost.com (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Finished 1000 requests
    
    
    Server Software:        Apache/2.2.3
    Server Hostname:        netfree.netfreehost.com
    Server Port:            81
    
    Document Path:          /
    Document Length:        16844 bytes
    
    Concurrency Level:      100
    Time taken for tests:   7.102347 seconds
    Complete requests:      1000
    Failed requests:        1
       (Connect: 0, Length: 1, Exceptions: 0)
    Write errors:           0
    Total transferred:      17351384 bytes
    HTML transferred:       16827683 bytes
    Requests per second:    140.80 [#/sec] (mean)
    Time per request:       710.235 [ms] (mean)
    Time per request:       7.102 [ms] (mean, across all concurrent requests)
    Transfer rate:          2385.69 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        0    0   1.1      0       6
    Processing:    34  676 174.9    669    1261
    Waiting:       32  675 175.0    668    1260
    Total:         34  676 174.4    669    1261
    
    Percentage of the requests served within a certain time (ms)
      50%    669
      66%    696
      75%    732
      80%    754
      90%    893
      95%    974
      98%   1081
      99%   1128
     100%   1261 (longest request)
    [root@server12 ~]#
    

    See Apache, Nginx

  • Configure Nginx to listen on single IP Address

    By default Nginx listens on all IP address on a server. To make nginx listen on specific IP address, edit nginx configuration file

    vi /etc/nginx/nginx.conf
    

    And VirtualHost/server files for each domain located in folders

    /etc/nginx/conf.d => on CentOS/RHEL
    /etc/nginx/sites-available => on Debian/Ubuntu
    

    Find

    listen 80
    

    Replace with

    listen IP_ADDR_HERE:80
    

    IP_ADDR_HERE = your server IP address on which you need nginx listen on.

    See Nginx

  • Running Python Application with gunicorn and nginx

    Create a service file for gunicorn

    root@django:~# cat /etc/systemd/system/gunicorn2.service
    [Unit]
    Description=gunicorn2 daemon
    Requires=gunicorn2.socket
    After=network.target
    
    [Service]
    User=ubuntu
    Group=www-data
    WorkingDirectory=/home/ubuntu/myapp/wagtail2
    ExecStart=/home/ubuntu/myapp/venv/bin/gunicorn \
              --access-logfile - \
              --workers 3 \
              --bind unix:/run/gunicorn2.sock \
              wagtailblog4.wsgi:application
    
    [Install]
    WantedBy=multi-user.target
    root@django:~# 
    

    Here

    /home/ubuntu/myapp/wagtail2 = path to the folder where web application is.

    /home/ubuntu/myapp/venv/bin/gunicorn = is where gunicorn installed inside virtualenv.

    Change these path as required.

    Restart gunicorn with

    systemctl restart gunicorn2
    

    use following nginx config

    root@django:~# cat /etc/nginx/sites-enabled/django.conf
    server {
        server_name domain.extn;
    
        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/ubuntu/myapp/wagtail2;
        }
        
        location /media/ {
            root /home/ubuntu/myapp/wagtail2;    
        }
    
        location / {
            include proxy_params;
            proxy_pass http://unix:/run/gunicorn2.sock;
        }
    
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/domain.extn/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/domain.extn/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
    
    }
    server {
        if ($host = www.domain.extn) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        if ($host = domain.extn) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        listen 80;
        server_name domain.extn www.domain.extn;
        return 404; # managed by Certbot
    }
    root@django:~# 
    

    Restart nginx

    systemctl restart nginx
    
  • Nginx Config for Laravel Application in sub folder

    Nginx Config for Laravel Application in sub folder

    To run Laravel Application on a subfolder of a website, use the following configuration. If you run the Laravel application as the main site, see Nginx Config for Laravel Application

    # subFolderApp1
    
    location /subFolderApp1 {  
        alias /home/yorudomain.com/html/subFolderApp1/public;  
        try_files $uri $uri/ @subFolderApp1;
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_pass unix:/run/php/php7.2-fpm-torrentp.sock;
        }
    }  
    
    location @subFolderApp1 {
        rewrite /subFolderApp1/(.*)$ /subFolderApp1/index.php?/$1 last;
    }
    
    # end subFolderApp1

    Here you place the Laravel application in a subdirectory “subFolderApp1”.

    Example

    server {
        server_name serverok.in www.serverok.in;
        root /home/serverok.in/html/;
        index index.php index.html index.htm;
        client_max_body_size 1000M;
        proxy_read_timeout 600s;
        fastcgi_read_timeout 600s;
        fastcgi_send_timeout 600s;
    
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
    
    
        # service
    
        location /service {  
            alias /home/serverok.in/html/service/public;  
            try_files $uri $uri/ @nested1;
            location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_pass unix:/run/php/php7.2-fpm-torrentp.sock;
            }
        }  
    
        location @nested1 {
            rewrite /service/(.*)$ /service/index.php?/$1 last;
        }
    
        # end service
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_intercept_errors on;
            fastcgi_buffers 16 16k;
            fastcgi_buffer_size 32k;
            fastcgi_pass unix:/run/php/php7.2-fpm-torrentp.sock;
        }
    
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/serverok.in/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/serverok.in/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    }
    
    server {
        if ($host = www.serverok.in) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        if ($host = serverok.in) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        listen 80;
        server_name serverok.in www.serverok.in;
        return 404; # managed by Certbot
    }

    Back to Nginx

  • Nginx Config for Laravel Application

    Here is Nginx configuration for a laravel application

    server {
        listen 80;
        server_name www.domain.com;
        access_log  /var/log/nginx/domain.com.log;
        root /home/domain.com/html/public;
        index index.html index.php;
        access_log /var/log/nginx/domain.com.log;
        error_log /var/log/nginx/domain.com-error.log;
        client_max_body_size 1000M;
        proxy_read_timeout 600s;
        fastcgi_read_timeout 600s;
        fastcgi_send_timeout 600s;
    
        location / {
            try_files $uri $uri/ /index.php$is_args$args;
        }
    
        location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
           try_files $uri =404;
           access_log off;
           expires max;
        }
    
        location = /robots.txt      { access_log off; log_not_found off; }
        location = /favicon.ico    { access_log off; log_not_found off; }  
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_intercept_errors on;
            fastcgi_buffers 16 16k;
            fastcgi_buffer_size 32k;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        }
    }
    
    server {
        listen 80;
        server_name  domain.com;
        return       301 http://www.domain.com$request_uri;
    }
    

    Nginx Config for Laravel Application in sub folder

  • Nginx Rails Origin header didn’t match request.base_url

    Nginx Rails Origin header didn’t match request.base_url

    After installing SSL on Nginx server, rails application login page stopped working.

    On log file (log/production.log), found following error

    HTTP Origin header (https://domain.com) didn't match request.base_url (http://domain.com)

    The Nginx config used was

    upstream app {
       server unix:/var/www/public/shared/sockets/unicorn.sock fail_timeout=0;
    }
    
    server {
       listen 443 ssl;
       root /var/www/public;
       ssl_certificate /etc/ssl/ssl.crt;
       ssl_certificate_key /etc/ssl/ssl.key;
       server_name domain.com;
       try_files $uri/index.html $uri @app;
       location @app {
           proxy_pass http://app;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_redirect off;
       }
       error_page 500 502 503 504 /500.html;
       client_max_body_size 4G;
       keepalive_timeout 10;
    }
    

    The problem is solved by adding following to nginx config.

    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  X-Forwarded-Ssl on;
    proxy_set_header  X-Forwarded-Port $server_port;
    proxy_set_header  X-Forwarded-Host $host;
    

    The new config is

    server {
       listen 443 ssl;
       root /var/www/public;
       ssl_certificate /etc/ssl/ssl.crt;
       ssl_certificate_key /etc/ssl/ssl.key;
       server_name domain.com;
       try_files $uri/index.html $uri @app;
       location @app {
           proxy_pass http://app;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_set_header  X-Forwarded-Proto $scheme;
           proxy_set_header  X-Forwarded-Ssl on;
           proxy_set_header  X-Forwarded-Port $server_port;
           proxy_set_header  X-Forwarded-Host $host;
           proxy_redirect off;
       }
       error_page 500 502 503 504 /500.html;
       client_max_body_size 4G;
       keepalive_timeout 10;
    }
    

    See Nginx