secret="qwerty123"
location="/test"
path="/lbclive.smil/"
nva="1550000000"
dirs="1"
file="playlist.m3u8"
token=$(echo -n "${path}?nva=${nva}&dirs=${dirs}" | openssl sha1 -hmac $secret -binary | xxd -p | cut -c1-20)
secret="qwerty123"
location="/test"
path="/lbclive.smil/"
nva="1550000000"
ip="127.0.0.1"
dirs="1"
file="playlist.m3u8"
token=$(echo -n "${path}?nva=${nva}&ip=${ip}&dirs=${dirs}" | openssl sha1 -hmac $secret -binary | xxd -p | cut -c1-20)
secret="qwerty123"
location="/test"
path="/lbclive.smil/"
nva="1550000000"
ip="::1"
dirs="1"
file="playlist.m3u8"
token=$(echo -n "${path}?nva=${nva}&ip=${ip}&dirs=${dirs}" | openssl sha1 -hmac $secret -binary | xxd -p | cut -c1-20)
secret='1234567890'
location="/testlocationlive"
path="/testlive.smil/"
nva="1538337566"
dirs="1"
file="playlist.m3u8"
token=$(echo -n ${path}?nva=${nva}&dirs=${dirs} | openssl sha1 -hmac $secret -binary | xxd -p | cut -c1-20)
secret='1234567890'
location="/testlocationlive"
path="/testlive.smil/"
nva="1538337566"
ip="127.0.0.1"
dirs="1"
file="playlist.m3u8"
token=$(echo -n ${path}?nva=${nva}&ip=${ip}&dirs=${dirs} | openssl sha1 -hmac $secret -binary | xxd -p | cut -c1-20)
echo "$location/token=nva=$nva~dirs=$dirs~hash=0$token$path$file"
echo "$location/token=nva=$nva~ip=$ip~dirs=$dirs~hash=0$token$path$file"
/testlocationlive/token=nva=1538337566~dirs=1~hash=004acb40fa3d37b94fdcd/testlive.smil/playlist.m3u8
/testlocationlive/token=nva=1538337566~ip=127.0.0.1~dirs=1~hash=004acb40fa3d37b94fdcd/testlive.smil/playlist.m3u8
Python 2.7 pip virtualenv git gcc
apt-get update && \
apt-get install -y python-dev python-pip python-virtualenv git
yum install -y python-devel python2-pip python-virtualenv git gcc
set -e
mkdir -p /var/lib/auth_token
cd /var/lib/auth_token
git clone --depth 1 https://github.com/freddygood/guacamole10.git app
cd app
virtualenv venv
. venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
deactivate
pip install -r requirements-rhel.txt
deactivate
cd /var/lib/auth_token/app
. venv/bin/activate
uwsgi --ini uwsgi.ini
cp /var/lib/auth_token/app/auth_token.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable auth_token.service
systemctl start auth_token.service
cp /var/lib/auth_token/app/auth_token.conf /etc/init/
start auth_token
There is a config file /var/lib/auth_token/app/config.py for configuration standalone application:
host = '0.0.0.0'
port = 8080
debug = True
cache_timeout=60
secret_default = 'qwertyuiop'
secret = {
'testlocationlive': '1234567890',
'salloum': 'djdheylsksjlak248du'
}
geoip_blacklist_default = []
geoip_blacklist = {
'lbcgrouplive': [ 'US', 'AU', 'CA' ],
'salloum': [ 'US', 'RU', 'NL' ]
}
-
cache_timeout - time to cache validate token function (integer)
-
secret_default - default secret (string)
-
secret - secret by location (dict). Used during the validation token. The script matches first part of URL (with no leading slash) with keys of the dictionary. If a key not found the default secret will be used. For example:
-
/testlocationlive/token.. - secret
1234567890
will be used -
/verynicelocation/token.. - secret
qwertyuiop
will be used -
geoip_blacklist_default - default geoip blacklist, usually []
-
geoip_blacklist - geoip blacklist by location (dict of lists)
There is /var/lib/auth_token/app/uwsgi.ini file for configuration uwsgi daemon:
[uwsgi]
master = true
module = wsgi
socket = 0.0.0.0:8080
processes = 16
harakiri = 15
- socket - ip and port to listen
- processes - number of workers, way to scale
- harakiri - kill and restart worker in case it hangs
The application must be restarted to apply configuration files changes
systemctl restart auth_token.service
restart auth_token.service
systemctl reload auth_token.service
reload auth_token.service
If upstart reload doesn't work as expected, to reload run command:
ps auxf | grep uwsgi
root 13351 0.0 0.0 87776 20636 ? S 23:08 0:00 \_ uwsgi --ini uwsgi.ini <- root process
root 13354 0.0 0.0 87776 14964 ? S 23:08 0:00 \_ uwsgi --ini uwsgi.ini
root 13355 0.0 0.0 87776 14968 ? S 23:08 0:00 \_ uwsgi --ini uwsgi.ini
root 13356 0.0 0.0 87776 14968 ? S 23:08 0:00 \_ uwsgi --ini uwsgi.ini
...
Locate root process then send him HUP signal
kill -HUP 13351
To update db nightly
cp crontab /etc/cron.daily/auth_token_geoip_db_update
chmod +x /etc/cron.daily/auth_token_geoip_db_update
The application might be deployed on the same servers with nginx and on dedicated servers as well.
Each edge server with nginx has it's own instance of application and sends requests to it 127.0.0.1:8080
There are dedicated servers with the application working in parallel. Requests must be balanced with upstream module in nginx.
Insert the block within http section (before servers definition)
upstream auth_token {
server 127.0.0.1:8080;
}
Create one location per server
# Auth token common location
location = /auth_token {
internal;
include uwsgi_params;
rewrite / $request_uri break;
uwsgi_pass auth_token;
uwsgi_pass_request_body off;
}
Create the block per each location
# Unsecured testlocationlive location
location /testlocationlive {
return 403;
}
# Secured test_location_live location
location /test_location_live/token {
location ~* (\.(m3u8|manifest|Manifest|mpd|dvr|DVR))$ {
auth_request /auth_token1;
rewrite ^/test_location_live/token=.*hash=[a-z0-9]+(/.*)$ /test_location_publish$1 break;
add_header Chunk-Cache-Status $upstream_cache_status;
proxy_pass http://test_location_proxy;
proxy_cache_valid 200 302 1s;
}
auth_request /auth_token1;
rewrite ^/test_location_live/token=.*hash=[a-z0-9]+(/.*)$ /test_location_publish$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Media-Cache-Status $upstream_cache_status;
proxy_buffering on;
proxy_ignore_headers Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_cache test_location_zone;
proxy_cache_key $proxy_host$uri;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 5s;
proxy_cache_revalidate off;
proxy_cache_lock on;
proxy_cache_lock_age 1s;
proxy_cache_lock_timeout 2s;
proxy_read_timeout 500s;
proxy_pass http://test_location_proxy;
}
Only for dev and test purpose - ability to check validity of token and secured URL without hitting any files
# Checking token service
location /_check_auth_token {
auth_request /auth_token;
error_page 404 =200 @check_auth_passed;
}
location @check_auth_passed {
return 200;
}
Response code 200 or 403
curl -sv http://nginx.testcdn.yes/_check_auth_token/token=nva=1537000000~dirs=1~hash=06bffd04a860d31992619/testlive.smil/playlist.m3u8
Create the block per each secured location
# GeoIP checking testlocationlive location
location = /testlocationlive/geoip {
internal;
include uwsgi_params;
uwsgi_pass auth_token;
uwsgi_pass_request_body off;
}
Add line to geoip secured location with playlist
auth_request /testlocationlive/geoip;
# GeoIP checking location
location = /testlocationlive/geoip {
internal;
include uwsgi_params;
uwsgi_pass auth_token;
uwsgi_pass_request_body off;
}
location /testlocationlive {
location ~* (\.(m3u8|manifest|Manifest|mpd|dvr|DVR))$ {
auth_request /testlocationlive/geoip;
add_header Chunk-Cache-Status $upstream_cache_status;
proxy_cache_valid 200 302 2s;
rewrite ^/testlocationlive/(.+\.(m3u8|manifest|Manifest|mpd|dvr|DVR))$ /testpublish/$1 break;
proxy_pass http://158.179.158.179:11935;
}
...