Build nginx video-on-demand server on centos (nginx+vod+lua http sends authentication message)

Demand background:

    I wanted to build a video-on-demand server, and finally chose the nginx+vod solution, using lua scripts to write streaming authentication, but during the environment construction process, I found that the environment of nginx++vod+lua is not easy to build, it is nginx+ The lua environment is cumbersome to build manually, but it is still possible. There is another solution that can use openresty (nginx+lua) + vod, because openresty has already included the nginx and lua environment for you, but it is not yet Contains the on-demand module vod, just add-module vod yourself

Note that the on-demand lua authentication introduced in this article only does the authentication of the m3u8 file, not the authentication of the ts file, and simply judges whether there is token authentication. As for the design of the token, you need to configure it yourself.

This article mainly introduces the construction of the environment, the analysis of the authentication process, focusing on the process, and finally the installation script and the entire configuration file of nginx.conf will be attached to the article

Option 1 nginx+vod+lua

Configure server DNS:

echo "nameserver 114.114.114.114" >> /etc/resolv.conf

Install web tools

yum install wget ntpdate git -y 

Install compilation tools and dependent libraries

yum install -y gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel -y

Synchronize server time

ntpdate ntp.aliyun.com 
timedatectl set-timezone Asia/Shanghai

Create the installation directory of the on-demand server

I installed it in the /usr/cloudland/nginx directory

mkdir -p /usr/cloudland/nginx
export NGINX_INSTALL_PATH=/usr/cloudland/nginx

Download configuration install lua interpreter LuaJIT

wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar xzvf LuaJIT-2.0.4.tar.gz 
cd LuaJIT-2.0.4
make install PREFIX=$NGINX_INSTALL_PATH/luajit 
export LUAJIT_LIB=$NGINX_INSTALL_PATH/luajit/lib
export LUAJIT_INC=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0
cd -

Note the above two export commands to configure the environment variables of the lua interpreter

Download nginx NDK (ngx_devel_kit) extension module

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
tar -xzvf v0.3.0.tar.gz

Download lua-nginx-module

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
tar -xzvf v0.10.9rc7.tar.gz

Download and install the lua-resty-http module (lua library, some libraries that implement http functions)

wget https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.16.1.tar.gz
tar -zxvf v0.16.1.tar.gz
cp -r lua-resty-http-0.16.1/lib/resty/ $NGINX_INSTALL_PATH/luajit/lib/lua/5.1/
cp -r lua-resty-http-0.16.1/lib/resty/ $NGINX_INSTALL_PATH/luajit/share/lua/5.1/

Note that NGINX_INSTALL_PATH can be replaced with your own nginx installation path. The above two cp commands are to solve the problem that resty-http cannot find

Download and install the lua-cjson module (lua library, providing json-related functions for lua)

wget https://github.com/openresty/lua-cjson/archive/refs/tags/2.1.0.9.tar.gz
tar -zxvf 2.1.0.9.tar.gz
cd lua-cjson-2.1.0.9
make LUA_VERSION=5.1 PREFIX=$NGINX_INSTALL_PATH/luajit/ LUA_INCLUDE_DIR=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0/
make LUA_VERSION=5.1 PREFIX=$NGINX_INSTALL_PATH/luajit/ LUA_INCLUDE_DIR=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0/ install
cd -

Pay attention to the make parameters above, the specified installation path and header files, to solve the problem that lua-cjson related libraries cannot be found

Download the nginx-vod module

This module is to realize the on-demand function for nginx

wget https://github.com/kaltura/nginx-vod-module/archive/refs/tags/1.28.tar.gz
tar -zxvf 1.28.tar.gz

Download configuration and install nginx

wget https://nginx.org/download/nginx-1.20.1.tar.gz
tar -xzvf nginx-1.20.1.tar.gz
cd nginx-1.20.1
./configure --prefix=/usr/cloudland/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --with-pcre --add-module=../lua-nginx-module-0.10.9rc7 --add-module=../ngx_devel_kit-0.3.0 --add-module=../nginx-vod-module-1.28/
make
make install

Load the luajia related library

echo "$NGINX_INSTALL_PATH/luajit/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig

Modify the nginx configuration file nginx.conf

There are two modifications

Amendment 1:

init_by_lua_block {
        cjson = require "cjson";
        http = require "resty.http";
    }

Add location:

Modification 2:

 location /vod {

                rewrite_by_lua_block {
                                -- local cjson = require "cjson"
                                -- local http = require "resty.http"
                                local httpc = http.new()
                                local ngx = ngx
                                local headers = ngx.req.get_headers()
                                local extension = ngx.var.request_uri:match(".+%.(%w+)$")

                                local token = headers["token"]
                                local request_method = ngx.var.request_method
                                local args = nil
                                if "GET" == request_method then
                                        args = ngx.req.get_uri_args()
                                elseif "POST" == request_method then
                                        ngx.req.read_body()
                                        args = ngx.req.get_post_args()
                                end

                                if extension == 'm3u8' then
                                        token = args["token"];
                                        if not token then
                                                ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                                ngx.status = ngx.HTTP_FORBIDDEN
                                                ngx.say("Nil token,Not Privileged To Play")
                                                -- ngx.say(ngx.var.request_uri);
                                                -- ngx.say(extension);
                                                ngx.exit(200)
                                        end
                                        -- 要实现token鉴权的服务,header和参数已经实现,根据实际需要选择
                                        -- 可以将URL发送给一个golang服务,用golang服务来做具体鉴权
                                        local url = "http://172.20.0.95:11985/api/rest/v1/vod/check";

                                        local res, err = httpc:request_uri(url, {method="GET", headers={["token"]=token}})

                                        if not res then
                                                ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                                ngx.say(cjson.encode({message = "Error getting response",status = ngx.HTTP_INTERNAL_SERVER_ERROR }));
                                                ngx.exit(200)
                                        end
                                        if res.body == '0' then
                                                ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                                ngx.say("Valid token,Not Privileged To Play.");
                                                ngx.exit(200)
                                        end
                                end
                }

                vod hls; # 协议使用hls模式
                vod_mode local; # 访问模式指定为local模式

                vod_align_segments_to_key_frames on; # 每个切片以关键帧开头
                vod_manifest_segment_durations_mode accurate; # 精确显示每个切片的长度
                root /media;

                #alias /media; # 视频文件路径
                #proxy_pass http://172.0.0.74:80/lua;
        }

Add location:

Configuration of the entire nginx.conf file


#user  nobody;
worker_processes  1;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    init_by_lua_block {
        cjson = require "cjson";
        http = require "resty.http";
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
        
        location /lua {
                default_type 'text/plain';
                content_by_lua 'ngx.say("hello, lua for vod")';
    }


        location /vod {

                rewrite_by_lua_block {
                                -- local cjson = require "cjson"
                                -- local http = require "resty.http"
                                local httpc = http.new()
                                local ngx = ngx
                                local headers = ngx.req.get_headers()
                local extension = ngx.var.request_uri:match(".+%.(%w+)$")
                
                                local token = headers["token"]
                                local request_method = ngx.var.request_method
                                local args = nil
                                if "GET" == request_method then
                                        args = ngx.req.get_uri_args()
                                elseif "POST" == request_method then
                                        ngx.req.read_body()
                                        args = ngx.req.get_post_args()
                                end

                if extension == 'm3u8' then
                                    token = args["token"];
                                    if not token then
                                            ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                            ngx.status = ngx.HTTP_FORBIDDEN
                                            ngx.say("Nil token,Not Privileged To Play")
                                            -- ngx.say(ngx.var.request_uri);
                                            -- ngx.say(extension);
                                            ngx.exit(200)
                                    end
                                    -- 要实现token鉴权的服务,header和参数已经实现,根据实际需要选择
                    -- 可以将URL发送给一个golang服务,用golang服务来做具体鉴权
                                    local url = "http://172.20.0.95:11985/api/rest/v1/vod/check";

                                    local res, err = httpc:request_uri(url, {method="GET", headers={["token"]=token}})

                                    if not res then 
                                            ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                            ngx.say(cjson.encode({message = "Error getting response",status = ngx.HTTP_INTERNAL_SERVER_ERROR }));
                                            ngx.exit(200)
                                    end
                                    if res.body == '0' then
                                            ngx.header['Content-Type'] = 'text/plain; charset=utf-8';
                                            ngx.say("Valid token,Not Privileged To Play.");
                                            ngx.exit(200)
                                    end
                                end
                }

                vod hls; # 协议使用hls模式
                vod_mode local; # 访问模式指定为local模式

                vod_align_segments_to_key_frames on; # 每个切片以关键帧开头
                vod_manifest_segment_durations_mode accurate; # 精确显示每个切片的长度
        root /media;

                #alias /media; # 视频文件路径
                #proxy_pass http://172.0.0.74:80/lua;
        }


        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

Modify the above nginx.conf to /usr/cloudland/nginx.conf

start nginx

cd /usr/cloudland/nginx/
./sbin/nginx -p $PWD -c conf/nginx.conf

Result verification:

Turn off the firewall last before authenticating

Turn off the firewall:

systemctl stop firewalld

Just copy a video to the /media/vod directory

Open http://172.24.0.74/vod/720p-test.mp4/index.m3u8 with a browser

The above result without token

Use a browser to open the URL with token http://172.24.0.74/vod/720p-test.mp4/index.m3u8

Discovery will allow downloading the index.m3u8 file

Use VLC to open the URL with token and find that the video can be played

The script to build the whole environment:

#!/bin/sh
NGINX_INSTALL_PATH=/usr/cloudland/nginx
echo "nameserver 114.114.114.114" >> /etc/resolv.conf

yum install wget ntpdate git -y

yum install -y gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel -y


ntpdate ntp.aliyun.com

timedatectl set-timezone Asia/Shanghai


# LuaJIT
if [ ! -f LuaJIT-2.0.4.tar.gz ]; then
    wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz
fi
tar xzvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make install PREFIX=$NGINX_INSTALL_PATH/luajit
export LUAJIT_LIB=$NGINX_INSTALL_PATH/luajit/lib
export LUAJIT_INC=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0
cd -

#ngx_devel_kit
if [ ! -f v0.3.0.tar.gz ]; then
    wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
fi
tar -xzvf v0.3.0.tar.gz

#lua-nginx-module
if [ ! -f v0.10.9rc7.tar.gz ]; then
    wget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz
fi
tar -xzvf v0.10.9rc7.tar.gz


#lua-resty-http
if [ ! -f v0.16.1.tar.gz ]; then
    wget https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.16.1.tar.gz
fi
tar -zxvf v0.16.1.tar.gz 
cp -r lua-resty-http-0.16.1/lib/resty/ $NGINX_INSTALL_PATH/luajit/lib/lua/5.1/
cp -r lua-resty-http-0.16.1/lib/resty/ $NGINX_INSTALL_PATH/luajit/share/lua/5.1/ 

#lua-cjson
if [ ! -f 2.1.0.9.tar.gz ]; then
    wget https://github.com/openresty/lua-cjson/archive/refs/tags/2.1.0.9.tar.gz
fi
tar -zxvf 2.1.0.9.tar.gz
cd lua-cjson-2.1.0.9
make LUA_VERSION=5.1 PREFIX=$NGINX_INSTALL_PATH/luajit/ LUA_INCLUDE_DIR=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0/
make LUA_VERSION=5.1 PREFIX=$NGINX_INSTALL_PATH/luajit/ LUA_INCLUDE_DIR=$NGINX_INSTALL_PATH/luajit/include/luajit-2.0/ install
cd -

# vod module
if [ ! -f 1.28.tar.gz ]; then
    wget https://github.com/kaltura/nginx-vod-module/archive/refs/tags/1.28.tar.gz
fi
tar -zxvf 1.28.tar.gz


# nginx
if [ ! -f nginx-1.20.1.tar.gz ]; then
    wget https://nginx.org/download/nginx-1.20.1.tar.gz
fi
tar -xzvf nginx-1.20.1.tar.gz
cd nginx-1.20.1
 ./configure --prefix=$NGINX_INSTALL_PATH --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --with-pcre --add-module=../lua-nginx-module-0.10.9rc7 --add-module=../ngx_devel_kit-0.3.0 --add-module=../nginx-vod-module-1.28/
make
make install
cd -

echo "$NGINX_INSTALL_PATH/luajit/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig

\cp ./nginx.conf $NGINX_INSTALL_PATH/conf

cd $NGINX_INSTALL_PATH

$NGINX_INSTALL_PATH/sbin/nginx -p $NGINX_INSTALL_PATH -c $NGINX_INSTALL_PATH/conf/nginx.conf 

Guess you like

Origin blog.csdn.net/u011285281/article/details/129008487