Category: Nginx

  • Enable SSL for icecast steam using nginx

    On ubuntu server running icecast, when i try enable SSL as per CentovaCast Enable SSL on icecast, i get following error

    connection/get_ssl_certificate No SSL capability
    

    I don’t compile my own icecast installation as it use Ubunu version of icecast, that get updated using apt.

    Instead of getting icecast serve steam using SSL, i installed Nginx, and proxy traffic from SSL port to icecast.

    Install nginx with

    apt install nginx
    

    remove default server entry

    rm -f /etc/nginx/sites-enabled/default
    

    Create file

    vi /etc/nginx/sites-enabled/stream.comf
    

    Add

    server {
        listen       9000 ssl;
        server_name  icecast.serverok.in;
        root         /var/www/html;
        ssl_certificate /etc/letsencrypt/live/icecast.serverok.in/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/icecast.serverok.in/privkey.pem;
    
        client_max_body_size 100M;
        proxy_read_timeout 600s;
        proxy_buffer_size   128k;
        proxy_buffers   4 256k;
        proxy_busy_buffers_size   256k;
    
        location / {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8000;
        }
    }
    

    In above configuration

        ssl_certificate /etc/letsencrypt/live/icecast.serverok.in/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/icecast.serverok.in/privkey.pem;
    

    is the SSL i already have on server. Replace it with path to SSL certifciate on your server. If you don’t have an SSL, you need to purcahse one or get a free SSL using LetsEncrypt.

    Restart Nginx

    systemctl restart nginx
    

    Now stream on port 8000 will work using HTTPS on port 9000.

    Modify ports as required.

    If you use Free LetsEncrypt SSL, you may need to add a cronjob to auto reastart nginx when SSL get updated.

    crontab -e
    

    Add

    @weekly systemctl restart nginx
    

    See Icecast, Nginx

  • Nginx Hotlink Protection

    To block hotlink protection or bandwidth stealing, you can add the following to the server configuration of your website.

    valid_referers yourdomain.tld www.yourdomain.tld;
    
    if ($invalid_referer) {
        return 403;
    }

    If you need to allow hotlinks from a specific domain, you can edit the valid_referers line and add the URL. For allowing access without any referral, you can use “none” instead of the domain name. For example

    valid_referers none yourdomain.tld www.yourdomain.tld;

    If you only want to limit access to images and videos, you can put the above code in a location block like

    location ~* \.(mp4|gif|png|jpg|jpeg|css|ico)$ {
        valid_referers  yourdomain.tld www.yourdomain.tld;
        if ($invalid_referer) {
           return 403;
        }
    }

    Example

    https://gist.github.com/serverok/e7e8e275a7ec3b69e19252edfed483e2

    See Nginx

  • Nginx Proxy Manager Certificate Key is not valid

    Nginx Proxy Manager Certificate Key is not valid

    When adding custom SSL on Nginx Proxy Manager, i get following error.

    Upload failed: Certificate Key is not valid (Command failed: openssl ec -in /tmp/15dbf072-4022-aee94-0f88e4fb8d86/tmp -check -noout 2>&1 )

    Nginx Proxy Manager Custom SSL upload error

    I tried upgrading Nginx Proxy Manager to the latest version with the following commands

    cd ~/nginx-proxy-manager/
    docker compose down
    docker compose pull
    docker compose up -d

    Even after the upgrade, this error persists.

    I checked logs for the docker container, but there were no errors.

    docker logs -f nginx-proxy-manager_app_1
    

    To fix this error, I edited the SSL key file.

    Find

    -----BEGIN PRIVATE KEY-----

    Replace with

    -----BEGIN RSA PRIVATE KEY-----

    Find

    -----END PRIVATE KEY-----

    Replace with

    -----END RSA PRIVATE KEY-----

    Now close the SSL upload dialogue and start over the custom SSL upload process. It will work.

    See Nginx Proxy Manager

  • EasyEngine Could not create user

    When creating a wordpress web site on EasyEngine, i get following error

    root@ee:~# ee site create smartandsolar.serverok.in --wp
    Starting site creation.
    Warning: Could not create user smartandsolar.serverok.in-8LHl6l. Please check logs.
    Warning: Initiating clean-up.
    Success: Site smartandsolar.serverok.in deleted.
    Report bugs here: https://github.com/EasyEngine/site-type-wp
    root@ee:~# 
    

    This is because EasyEngine try to create a WordPress admin user, that failed to create due to length. To fix the error, you can specify a shorter wordpress admin user name with option –admin-user=admin

    ee site create smartandsolar.serverok.in --wp --admin-user=admin
    

    easyengine wordpress error

    See EasyEngine

  • How to block .git directory in nginx

    When using git version control to deploy application, many forget to secure .git folder. This allows anyone to clone your git repository. If you have any credentials commited to your git version control, then hacker will be able to gain access.

    To avoid this, it is better plan the git repo in a way you have .git folder outside of your document root. If this is not possible, you need to block access to .git folder using nginx configuration.

    To block access to .git folder, add following to your nginx server entry.

    location ~ /\.git {
      deny all;
    }
    

    Now restart nginx

    systemctl restart nginx
    

    See Nginx, git

  • Enable Nginx Status Page

    Nginx status is provided by http_stub_status module. To verify if your Nginx is installed with this module, run

    nginx -V 2>&1 | grep -o with-http_stub_status_module
    

    If the result shows “with-http_stub_status_module”, you have the module installed.

    nginx status module

    To enbale stats edit nginx configuration file for your web site, add following code

    location /nginx_status {
        stub_status;
    }
    

    To linmit access to this page, you can use allow

    location /nginx_status {
     	stub_status;
     	allow 127.0.0.1;
     	allow YOUR_IP_HERE;
     	deny all;
    }
    

    Replace YOUR_IP_HERE with your actial IP address.

    Restart nginx with

    systemctl restart nginx
    

    Now you should be able to see nginx server stats at url

    https//yourdomain.com/nginx_status

    nginx status

    See Nginx

  • Nginx upstream sent too big header

    Nginx upstream sent too big header

    When I log in to a PrestaShop website, I get an error on a Plesk server.

    502 Bad Gateway
    

    On checking error login for the site in folder /var/www/vhosts/domain.com/logs/proxy_error_log, I found the following error message

    proxy_error_log:2020/11/25 19:41:41 [error] 1809#0: *39664 upstream sent too big header while reading response header from upstream, client: 59.92.71.53, server: tulivesi.com, request: “POST /en/login?back=my-account HTTP/2.0”, upstream: “https://shop.serverok.in:7081/en/login?back=my-account”, host: “shop.serverok.in”, referrer: “https://shop.serverok.in/en/login?back=my-account”

    To fix, add the following to Nginx config.

    If Nginx works as a reverse proxy to another application server.

    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    

    If Nginx serve pages using FastCGI/fpm.

    fastcgi_buffers 16 16k; 
    fastcgi_buffer_size 32k;
    

    On Plesk Server

    On Plesk, go to the domain name, then click “Apache & nginx Settings”. On next page add the following code and click OK.

    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    

    Plesk Nginx

    See Nginx

  • Country Blocking with nginx GeoIP on Ubuntu/Debian

    On Ubuntu/Debian, install nginx geoip module with

    apt install geoip-database libgeoip1 libnginx-mod-http-geoip -y
    

    Now edit nginx.conf

    vi /etc/nginx/nginx.conf
    

    Find

    http {
    

    Add below

    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $my_country_blocker {
        default no;
        US yes;
        AU yes;
        CA yes;
    }
    

    nginx geoip

    You can add 2 letter country code and set ye/no as required.

    To implement GeoIP blocking for a web site, you need to edit server entry for the web site. In this cause, i will use the default web site.

    vi /etc/nginx/sites-enabled/default
    

    Find

    server {
    

    Add blow

    if ($my_country_blocker = no) {
        return 444;
    }
    

    nginx geoip server configuration

    This will block access to the web site from any country that is not listed in nginx.conf

    You need to restart nginx web server

    systemctl restart nginx
    

    If you need to redirect blocked users to another site, use

    if ($my_country_blocker = no) {
        rewrite ^ https://google.com break;
    }
    

    This will redirect the visitor to google if their country is not US, AU or CA.

    See Nginx

  • Nginx Commands

    Nginx Commands

    Start Nginx

    nginx
    

    Stop Nginx

    nginx -s stop
    

    Reload Nginx

    nginx -s reload
    

    Test Nginx configuration

    nginx -t
    

    See Nginx

  • Install Nginx from source

    Install Nginx from source

    Install Requirements

    CentOS/RHEL/Fedora

    yum install glib2-devel openssl-devel pcre-devel bzip2-devel gzip-devel
    

    Ubuntu/Debian

    apt-get install libpcre3-dev
    

    Create nginx user

    useradd -c "Nginx user" -s /bin/false -r -d /var/lib/nginx nginx
    

    Downoad and insta Nginx

    You can download latest version of Nginx source code from

    https://nginx.org/en/download.html

    To install version 1.19.2, run

    cd /usr/local/src
    wget https://nginx.org/download/nginx-1.19.2.tar.gz
    tar xvf nginx-1.19.2.tar.gz
    cd nginx-1.19.2
    ./configure --user=nginx --group=nginx --prefix=/usr/share --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/log/run/nginx.pid --lock-path=/var/log/lock/subsys/nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_mp4_module --with-http_secure_link_module --with-http_v2_module
    make
    make install
    

    Test Nginx

    To start nginx run

    /usr/sbin/nginx
    

    Configuration file is at

    /etc/nginx/nginx.conf
    

    See Nginx

  • Install Nginx Proxy Manager

    Install Nginx Proxy Manager

    Nginx Proxy Manager is Docker based GUI for managing Nginx reverse proxy. It support LetsEncrypt free SSL.

    https://nginxproxymanager.com
    Nginx Proxy Manager Certificate Key is not valid
    Install Custom SSL on Nginx Proxy Manager
    To install, create a folder

    mkdir nginx-proxy-manager
    cd nginx-proxy-manager
    

    Creaye docker-compose.yaml file

    vi docker-compose.yaml
    

    add following content

    version: "3"
    services:
      app:
        image: 'jc21/nginx-proxy-manager:latest'
        restart: always
        ports:
          # Public HTTP Port:
          - '80:80'
          # Public HTTPS Port:
          - '443:443'
          # Admin Web Port:
          - '81:81'
        environment:
          # These are the settings to access your db
          DB_MYSQL_HOST: "db"
          DB_MYSQL_PORT: 3306
          DB_MYSQL_USER: "npm"
          DB_MYSQL_PASSWORD: "npm"
          DB_MYSQL_NAME: "npm"
          # If you would rather use Sqlite uncomment this
          # and remove all DB_MYSQL_* lines above
          # DB_SQLITE_FILE: "/data/database.sqlite"
          # Uncomment this if IPv6 is not enabled on your host
          # DISABLE_IPV6: 'true'
        volumes:
          - ./data:/data
          - ./letsencrypt:/etc/letsencrypt
        depends_on:
          - db
      db:
        image: jc21/mariadb-aria:latest
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: 'npm'
          MYSQL_DATABASE: 'npm'
          MYSQL_USER: 'npm'
          MYSQL_PASSWORD: 'npm'
        volumes:
          - ./data/mysql:/var/lib/mysql
    

    If you need to use other ports, for example, to handle streams, you need to add additional ports

    Find

          # Admin Web Port:
          - '81:81'
    

    To add port 3389, add

          - '3389:3389'
    

    If you don’t have docker and docker-compose installed, install it with

    apt install docker.io docker-compose
    

    To start Nginx Proxy Manager, run

    docker-compose up -d
    

    You can access Nginx Proxy Manager GUI at

    http://your-server-ip:81/login
    

    Nginx Proxy Manager

    Default user name and passwords are

    Email:    [email protected]
    Password: changeme
    

    See Nginx

  • LetsEncrypt SSL On Nginx Password Protected site

    When you develop a web site, you will need it password protected so others won’t see or you don’t want google to index the web pages while you are working on it.

    To password protect a web site in nginx, see

    Nginx Password Protect a website

    If you password protect a web site and try to get LetsEncrypt SSL cerificate using webroot verification method, it will fail. We need to disable password protection for url domain/.well-known. To do this, find

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

    Add below

    location ^~ /.well-known/acme-challenge/ {
        auth_basic "off";
    }
    

    Now restart nginx

    systemctl restart nginx
    

    See Letsencrypt