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==";