Reverse Proxy for IP Camera
Solution 1:
As said above it can be solved by
proxy_set_header Authorization "Basic dXNlcjpwYXNzd29yZA==";
where dXNlcjpwYXNzd29yZA==
is result of command: echo -n "user:password" | base64
i guess you already tried that
anyway, i believe correct location will looks like
location / {
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_pass http://IP_CAMERA;
proxy_set_header Authorization "Basic dXNlcjpwYXNzd29yZA==";
proxy_set_header Authorization "Basic $http_authorization"; # For interactive mode
}
without /cgi-bin/mjpg/video.cgi
because it will passing at browser or http client side
OR If it doesn't work for you, it can be related to this case https://stackoverflow.com/questions/14839712/nginx-reverse-proxy-passthrough-basic-authenication
If Camera have some realm checks you can know expected Realm via Dev Tools at Headers tab - Response headers section.
But you will need compile nginx with headers-more-nginx-module
You can make it with this script
cd /usr/src
NGINXFILE=$(wget -qO- http://nginx.org/en/download.html | tr ' ' '\n' | egrep -o 'nginx.+?tar.gz' | head -1)
wget http://nginx.org/download/${NGINXFILE}
tar zxvf ${NGINXFILE}
cd ${NGINXFILE%.*.*}
cp -r /etc/nginx /root/nginx_$(date +%F) #Backup current nginx configs
cd /usr/src
git clone https://github.com/openresty/headers-more-nginx-module.git
./configure --add-module=/usr/src/headers-more-nginx-module --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --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/run/nginx.pid --lock-path=/var/run/nginx.lock --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 --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
make
make install
once it done you can try such config:
location / {
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
more_set_input_headers 'Authorization: Basic dXNlcjpwYXNzd29yZA==';
#more_set_input_headers 'Authorization: $http_authorization'; # For interactive mode
proxy_set_header Accept-Encoding "";
proxy_pass http://IP_CAMERA;
proxy_redirect default;
more_set_headers -s 401 'www-authenticate: Basic realm="Authentication Required"';
}
where www-authenticate: Basic realm="Authentication Required"
your actual data of this header
I checked both cases, it works for me, i tested it on custom flask application. Unfortunatelly i have not such camera for personal debug
Solution 2:
Edit with Amcrest-specific solution
At some point (around 2017?) Amcrest released a firmware update that removed Basic Authentication from their IP cameras, leaving Digest Authentication as the only option.
This Stack Overflow answer may be your best option for stripping the Digest Authentication out like you want using FastCGI and nginx.
Either that or perhaps you can find a way to downgrade the firmware on your camera to support Basic Authentication again.
Previous Answer
Are you Base64-encoding the username and password with a colon in between?
For HTTP basic authentication, you will need to do the following:
proxy_set_header Authorization "Basic xxx";
Replace the xxx
with Base64(<username>:<password>)
. That is, find yourself a Base-64 encoder, enter the username, a literal colon (:
) character, and the password, and replace the xxx
with the resulting string.
For example, if the username is admin
, and the password is hunter2
, we could run the following at a Bash prompt:
printf %s 'admin:hunter2' | base64
and put the resulting string in the header like this:
proxy_set_header Authorization "Basic YWRtaW46aHVudGVyMg==";