Nginx nâng cao - cài đặt Nginx RTMP Module

Cài đặt NGINX với RTMP Modules

Nginx (phát âm là "èn gin ích") là một phần mềm mã nguồn mở dùng để phục vụ cho máy chủ web và có tính mở ộng cao. Nginx có thể được sử dụng làm máy chủ HTTP/HTTPS, reverse proxy, stmp proxy (mail), load balancing,....




Giới thiệu

Nginx là một trong những phần mềm được sử dụng rộng rãi nhất hiện nay. Nó được sử dụng bởi nhiều công ty nổi tiếng trên toàn cầu như Yandex, VK, Mail.ru, Dropbox, Netflix, WordPress.com, PastMail,....

Nginx là một mã nguồn mở có thể tích hợp được với các mô-đun khác nhau và do cộng đồng phát triển. Ngay cả trong bộ cài đặt của nginx nó cũng có một số modules được "tích hợp sẵn", chẳng hạn như GZIP hoặc SSL và bạn hoàn toàn có thể bật tắt được các modules này một cách dễ dàng.

Nginx có các mô-đun lõi (gốc) và các mô-đun của bên thứ ba (bên ngoài) do cộng đồng tạo ra. Hiện tại có hơn một trăm mô-đun của bên thứ ba mà chúng ta có thể sử dụng.

Nginx được viết bằng ngôn ngữ C, đây là một ngôn ngữ nhanh nhẹ và được hỗ trợ hầu như toàn bộ các máy tính nên việc cài đặt Nginx để thêm các modules hoặc bật tắt các modules không cần thiết khá là dễ dàng.

Trong hướng dẫn này mình sẽ biên dịch phiên bản mainline của Nginx (ở bản1.19.2 tại thời điểm viết bài này) trên hệ thống Ubuntu 18.04 LTS (bionic). Mình sẽ sẽ sủ dụng tất cả các mô-đun có sẽ trong phiên bản mã nguồn mở của Nginx và cài đặt thêm Nginx RTMP Module để có thể livestream hoặc phát video theo từng các chuck.

Lưu ý: Nên cài đặt cố định một phiển bản ví dụ là Nginx 1.19.2 tại bài viết này.

Lợi ích khi biển dịch và cài đặt từ source code thay vì cài đặt qua các CLI

Bạn có thể hỏi tại sao người ta lại biên dịch Nginx từ source code trong khi bạn có thể sử dụng các câu lệch đã chuẩn bị từ trước. Dưới đây là một số lý do tại sao bạn có thể muốn tự biên dịch phần mềm cụ thể:

  • Để kiểm soát các cấu hình tuỳ chỉnh.
  • Để cài đặt các modules do cộng đồng phát triển
  • Để kiểm soát phiên bản cài đặt mà bạn cài đặt. Các bàn cài đặt qua các câu lệnh thường sẽ được cập nhập phiên bản mới nhất. Ngay trong chính NGINX thì cũng sẽ sử dụng một số modules bên ngoài được tích hợp sẵn.
  • Để hiểu rõ hơn về cách thức hoạt động của phần mềm

Các loại module trong NGINX

Ở trong bài viết này mình muốn tuỳ chỉnh lại NGINX vì mình muốn cài đặt thêm một modules mới phục vụ cho công việc của mình. Nhưng về bản chất thì NGINX được phân biệt thành các modules dưới đây

Module gốc và module của bên thứ ba
Nginx có hai loại module mà bạn có thể sử dụng: module gốc (core) và module của bên thứ ba:
  • Các nhà phát triển Nginx sẽ xây dựng các module gốc.
  • Với các modules thứ 3 thì thường sẽ do cộng đồng xây dựng và bảo trì bạn có thể sử dụng chúng để mở rộng chức năng của Nginx. Có rất nhiều mô-đun hữu ích  nổi tiếng nhất trong số đó là PageSpeed, ModSecurity, RTMP, Lua, Javascript... Các bạn có thể xem các modules được phát triển bởi cộng đồng NGINX tại đây

Module tĩnh so với module động
Các module tĩnh tồn tại trong Nginx từ phiên bản đầu tiên. Các module động đã được giới thiệu với Nginx 1.9.11+ vào tháng 2 năm 2016. Với các module tĩnh, nó chỉ có thể thêm vào Nginx lúc biên dịch với file có tên là configure  - cài mà chúng ta sẽ tải bên dưới.

Module tĩnh sử dụng cú pháp --with-foo_bar_module hoặc --add-module=PATH.    

Để biên dịch module gốc (tiêu chuẩn) dưới dạng động, chúng ta thêm =dynamic, ví dụ --with-http_image_filter_module=dynamic.

Để biên dịch module của bên thứ ba dưới dạng động, chúng tôi sử dụng cú pháp --add-dynamic-module=/path/to/module, sau đó chúng ta tải chúng bằng cách sử dụng load_module trong ngữ cảnh chung của tệp nginx.conf.

Phần về module động mình sẽ viết ở một bài viết khác chi tiết hơn.

Các yêu cầu để build Nginx từ source code

So với một số phần mềm UNIX/ Linux khác, Nginx khá nhẹ và không có nhiều phụ thuộc vào thư viện tĩnh của máy tính. Để build Nginx thì chúng ta chỉ cần 3 thư viện sau: OpenSSL/LibreSSL/BoringSSL (một trong 3), Zlib và PCRE.

Những yêu cầu bắt buộc:
  • Trình biên dịch GNU (GCC)
  • Phiên bản thư viện OpenSSL giữa 1.0.2 - 1.1.1 hoặc thư viện LibreSSL hoặc thư viện BoringSSL
  • Phiên bản thư viện Zlib giữa 1.1.3 - 1.2.11
  • Phiên bản thư viện PCRE giữa 4.4 - 8.44
Yêu cầu tuỳ chọn:
  • Perl
  • LibGD
  • MaxMind GeoIP Legacy C Library
  • libxml2
  • libxslt

Bắt đầu custom NGINX nào!!!!

Cập nhập các phần mềm của hệ điều hành
sudo apt update && sudo apt upgrade -y
Cài đặt thêm một số package cần thiết.
sudo apt install -y software-properties-common ufw build-essential git
Tải xuống mã nguồn phiên bản 1.19.2 của Nginx và giải nén nó.
wget https://nginx.org/download/nginx-1.19.2.tar.gz && tar zxvf nginx-1.19.2.tar.gz
Tải xuống mã nguồn của các phần khác mà Nginx bắt buộc và giải nén nó.
# PCRE version 8.44
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz && tar xzvf pcre-8.44.tar.gz

# zlib version 1.2.11
wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz

# OpenSSL version 1.1.1g
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz && tar xzvf openssl-1.1.1g.tar.gz
Lưu ý: Phiên bản ổn định mới nhất của OpenSSL là dòng 1.1.1. Đâu là phiên bản hỗ trợ lâu dài (LTS), được hỗ trợ đến ngày 11 tháng 9 năm 2023. Tất cả các phiên khác (bao gồm 1.1.0, 1.0.2, 1.0.0, 0.9.8) không được hỗ trợ và không nên sử dụng. Đối với các phiên bản cũ thì được khuyến khích nâng lên 1.1.1.1 càng sớm càng tốt

Tải xuống module Nginx RTMP Module để có thể thêm vào
# Nginx RTMP Module
git clone https://github.com/arut/nginx-rtmp-module
Cài đặt các Nginx tuỳ chọn khác (Các tuỳ chọn này dùng để hướng tới làm sao giống với bản khi bạn cài CLI nhất có thể).  Nếu trong quá trình chạy lệch dưới mà bị lỗi version không trùng khớp hoặc là version đã tồn tại nhưng không thể cài thì các bạn nên dùng 1 package khác của ubuntu có tên là aptitude để cài đặt nhé
sudo apt install -y perl libperl-dev libgd3 libgd-dev libgeoip1 libgeoip-dev geoip-bin libxml2 libxml2-dev libxslt1.1 libxslt1-dev
Sau đó chúng ta đi vào thư mục của nginx vừa tải ở trên
cd ~/nginx-1.19.2
Cấu hình, biên dịch và cài đặt Nginx.
./configure --prefix=/etc/nginx \
            --sbin-path=/usr/sbin/nginx \
            --modules-path=/usr/lib/nginx/modules \
            --conf-path=/etc/nginx/nginx.conf \
            --error-log-path=/var/log/nginx/error.log \
            --pid-path=/var/run/nginx.pid \
            --lock-path=/var/run/nginx.lock \
            --user=nginx \
            --group=nginx \
            --build=Ubuntu \
            --builddir=nginx-1.19.2 \
            --with-select_module \
            --with-poll_module \
            --with-threads \
            --with-file-aio \
            --with-http_ssl_module \
            --with-http_v2_module \
            --with-http_realip_module \
            --with-http_addition_module \
            --with-http_xslt_module=dynamic \
            --with-http_image_filter_module=dynamic \
            --with-http_geoip_module=dynamic \
            --with-http_sub_module \
            --with-http_dav_module \
            --with-http_flv_module \
            --with-http_mp4_module \
            --with-http_gunzip_module \
            --with-http_gzip_static_module \
            --with-http_auth_request_module \
            --with-http_random_index_module \
            --with-http_secure_link_module \
            --with-http_degradation_module \
            --with-http_slice_module \
            --with-http_stub_status_module \
            --with-http_perl_module=dynamic \
            --with-perl_modules_path=/usr/share/perl/5.26.1 \
            --with-perl=/usr/bin/perl \
            --http-log-path=/var/log/nginx/access.log \
            --http-client-body-temp-path=/var/cache/nginx/client_temp \
            --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
            --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
            --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
            --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
            --with-mail=dynamic \
            --with-mail_ssl_module \
            --with-stream=dynamic \
            --with-stream_ssl_module \
            --with-stream_realip_module \
            --with-stream_geoip_module=dynamic \
            --with-stream_ssl_preread_module \
            --with-compat \
            --with-pcre=../pcre-8.44 \
            --with-pcre-jit \
            --with-zlib=../zlib-1.2.11 \
            --with-openssl=../openssl-1.1.1g \
            --with-openssl-opt=no-nextprotoneg \
            --add-module=../nginx-rtmp-module

make
sudo make install
Các bạn có thể để ý thấy --add-module=../nginx-rtmp-module là mình đang cài đặt thêm module RTMP cho nginx. Ở nginx chúng ta không cần đường dẫn tuyệt đối, vì mọi thứ sẽ được build sau khi chúng ta chạy lệnh make
Sau khi biên dịch, điều hướng đến thư mục home (~của bạn.
cd ~
Liên kết /usr/lib/nginx/modules vào thư mục /etc/nginx/modules. Bạn có thể liên kết với bất kỳ thư mục nào bạn muốn nhưng etc/nginx/modules là một nơi tiêu chuẩn cho các modules Nginx.
sudo ln -s /usr/lib/nginx/modules /etc/nginx/modules
Sau đó kiểm tra phiên bản Nginx, phiên bản trình biên dịch và cấu hình các thông số tập lệnh.
sudo nginx -V

# nginx version: nginx/1.19.2 (Ubuntu)
# built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
# built with OpenSSL 1.1.1g  31 Mar 2020
# TLS SNI support enabled
# configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules . . .
# . . .
# . . .
Tạo nhóm người dùng cho quá trình chạy Nginx, không nên chạy nginx với quyền root để tránh các lỗi security tiềm ẩn

sudo adduser --system --home /nonexistent --shell /bin/false --no-create-home --disabled-login --disabled-password --gecos "nginx user" --group nginx 

# Kiểm tra xem nhóm tài khoản nginx được tạo
sudo tail -n 1 /etc/passwd /etc/group /etc/shadow
Kiểm tra cú pháp Nginx và các lỗi tiềm ẩn.
sudo nginx -t
# Nó sẽ bắn ra lỗi -> nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory)

# Thì bạn sẽ phải tạo thư mục cache NGINX và cấp quyền cho nó
sudo mkdir -p /var/cache/nginx/client_temp /var/cache/nginx/fastcgi_temp /var/cache/nginx/proxy_temp /var/cache/nginx/scgi_temp /var/cache/nginx/uwsgi_temp
sudo chmod 700 /var/cache/nginx/*
sudo chown nginx:root /var/cache/nginx/*

# Sau đó kiếm tra lại thì bạn sẽ nhận được thông báo SUCCESS
sudo nginx -t
Tạo tệp service cho Nginx để có thể start và stop hoặc restart nó.
sudo vim /etc/systemd/system/nginx.service
Copy/paste nội dung bên dưới và tệp /etc/systemd/system/nginx.service.
[Unit]
Description=nginx - high performance web server
Documentation=https://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target
Đặt mặc định Nginx sẽ mặc định chạy khi bạn khởi động server. Và ngoài ra chúng ta cũng chạy luôn Nginx để kiểm tra thành quả
sudo systemctl enable nginx.service
sudo systemctl start nginx.service
Kiểm tra xem Nginx có tự động khởi động sau khi khởi động lại server hay không.
sudo systemctl is-enabled nginx.service
# enabled
Kiểm tra trạng thái Nginx.
sudo systemctl status nginx.service
Lưu ý: Bạn có thể xác minh rằng Nginx đang chạy bằng cách truy cập miền hoặc địa chỉ IP trang web của bạn trong trình duyệt web. Bạn sẽ thấy trang chào mừng của Nginx. Đó là thông báo cho thấy Nginx đang hoạt động trên Server của bạn.
Nginx mặc định tạo các tệp .default sao lưu trong etc/nginx. Xoá các tệp .default khỏi thư mục etc/nginx.
sudo rm /etc/nginx/*.default
Tạo các thư mục conf.dsnippetssites-available và sites-enabled trong thư mục .Bạn có thể cấu hình Nginx theo cách bạn muốn. Đây chỉ là cấu trúc thư mục cơ bản được sử dụng phổ biến nhất.
sudo mkdir /etc/nginx/{conf.d,snippets,sites-available,sites-enabled}
Thay đổi quyền và quyền sở hữu nhóm đối với các tệp log của Nginx
sudo chmod 640 /var/log/nginx/*
sudo chown nginx:adm /var/log/nginx/access.log /var/log/nginx/error.log
Cấu hình log cho Nginx.
sudo vim /etc/logrotate.d/nginx
Điền vào tệp với đoạn text bên dưới, sau đó lưu và thoát.
/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
            if [ -f /var/run/nginx.pid ]; then
                    kill -USR1 `cat /var/run/nginx.pid`
            fi
    endscript
}

Tóm tắt

Bây giờ bạn đã cài đặt phiên bản mới nhất của Nginx từ mã nguồn. Nó được biên dịch dựa trên một số thư viện quan trọng như OpenSSL. Thông thường, phiên bản OpenSSL do hệ thống cung cấp đã lỗi thời. Bằng cách sử dụng phương pháp cài đặt này với phiên bản OpenSSL mới hơn, bạn có thể tận dùng các mật mã hiện đại như CHACHA20_POLY1305 và các giao thức như TLS 1.3 được hỗ trợ trong OpenSSL 1.1.1. Hơn nữa, bằng cách biên dịch Nginx này, bạn có thể điều chỉnh chức năng mà Nginx của bạn sẽ cung cấp linh hoạt hơn nhiều so với cài đặt bằng các câu lệnh được tạo sẵn. Ngoài ra, biên dịch từ source là một công việc rất tốn công sức, nhưng không có gì ngăn cản bạn gói tất cả các bước này trong một tập lệnh shell đặc biệt và tự động hoá quá trình này.