NGINX basic authentication based on environment variable - nginx

I'm setting up a docker image with nginx-lua installed. The scenario is to have a basic authentication on staging, but not in production. My idea was to have an ENV variable with the name of the stage and check the value in the nginx.conf file.
The content of the docker-compose.yml file (for staging, and for production the STAGE env will be prod of course):
docs-router:
build: ./nginx
environment:
- API_BASE_URI=staging.example.com
- DOCS_STATIC_URI=docs-staging.example.com
- STAGE=staging
ports:
- "8089:8089"
- "8090:8090"
The content of the nginx.conf file:
...
env API_BASE_URI;
env DOCS_STATIC_URI;
env STAGE;
...
http {
server {
listen 8089 default_server;
charset utf-8;
resolver 8.8.8.8;
access_log off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^(/.*\.(?:apib|svg))?$ {
set_by_lua_block $api_base_uri { return os.getenv("API_BASE_URI") }
set_by_lua_block $stage { return os.getenv("STAGE") }
set $unprotected "prod";
if ($stage = $unprotected) {
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
proxy_pass https://$api_base_uri$1;
proxy_set_header Host $api_base_uri;
}
...
}
}
But it's not working. Any idea, how can I achieve this?

I just find a solution with some help from Serverfault. It's not the best one because the URLs are in the nginx.conf file, but it solves my problem:
I just removed the variable form the docker-compose.yml file:
docs-router:
build: ./nginx
environment:
- API_BASE_URI=staging.example.com
- DOCS_STATIC_URI=docs-staging.example.com
ports:
- "8089:8089"
- "8090:8090"
And then I mapped the URLs in the nginx.conf file:
...
env API_BASE_URI;
env DOCS_STATIC_URI;
...
http {
##
# URL protection
##
map $http_host $auth_type {
default "off";
stage1.example.com "Restricted";
stage2.example.com "Restricted";
}
server {
listen 8089 default_server;
charset utf-8;
resolver 8.8.8.8;
access_log off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^(/.*\.(?:apib|svg))?$ {
set_by_lua_block $api_base_uri { return os.getenv("API_BASE_URI") }
auth_basic $auth_type;
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass https://$api_base_uri$1;
proxy_set_header Host $api_base_uri;
}
...
}
}
If there is a better / nicer solution for this, please let me know.

Related

Ngixn rewrite and reverse proxy to docker container

I am running 3 services using docker compose on 3 ports: svc1:8081, svc2:8082, and svc3:8083 respectively. I have nginx installed on my host machine (not as a docker container), I want to reverse proxy all the requests to appropriate services so I am rewriting the url inside the nginx location block and performing a reverse proxy.
I am unable to get the results as something the files are not loading (mainly the static file to docker container)
My nginx config is as follows:
server {
listen 80;
server_name - ;
location /svc1/ {
rewrite ^/svc1(.*)$ $1 break;
proxy_pass http://localhost:8081;
}
location /svc2/ {
rewrite ^/svc2(.*)$ $1 break;
proxy_pass http://localhost:8082;
}
location /svc3/ {
rewrite ^/svc3(.*)$ $1 break;
proxy_pass http://localhost:8083;
}
}
I would be thankful if anyone can point if I am doing any wrong. Thanks in advance for your help.
Try this:
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Referer $http_referer;
# Additionally those headers if websocket/reload is used:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
location /svc1/ {
proxy_pass http://localhost:8081/;
}
location /svc2/ {
proxy_pass http://localhost:8082/;
}
location /svc3/ {
proxy_pass http://localhost:8083/;
}
}
Don't forget to restart nginx after changing conf!

nginx: not matching the correct way

i have the following nginx configuration
GIVES WRONG RESULTS
upstream webapp {
server webapp:8000;
}
upstream db {
server phppgadmin:80;
}
server {
listen 80;
server_name db.*;
location / {
proxy_pass http://db;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
server {
listen 80;
location / {
proxy_pass http://webapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static {
autoindex on;
alias /staticfiles/;
}
location /media {
autoindex on;
alias /mediafiles/;
}
}
My ip address of the pc is xx.xx.xx.xx
what I observed is that
db.xx.xx.xx.xx - shows the db upstream
and also xx.xx.xx.xx - shows the db upstream
GIVES CORRECT RESULTS
where as when i change the order it shows properly
upstream webapp {
server webapp:8000;
}
upstream db {
server phppgadmin:80;
}
server {
listen 80;
location / {
proxy_pass http://webapp;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static {
autoindex on;
alias /staticfiles/;
}
location /media {
autoindex on;
alias /mediafiles/;
}
}
server {
listen 80;
server_name db.*;
location / {
proxy_pass http://db;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
Now
db.xx.xx.xx.xx - shows the db upstream
and xx.xx.xx.xx - shows the webapp upstream
QUESTION
I am not able to understand in the first case how come xx.xx.xx.xx is matched by server_name db.*; Or why the second one shows the intended behaviour
note
Ofcourse in my /etc/hosts i have setup
xx.xx.xx.xx app.xx.xx.xx.xx
xx.xx.xx.xx db.xx.xx.xx.xx
Nginx selects server block by port (with IP, if given) and Host header. If there is no match, it uses a block where default_server is set. In your case there is no match by Host and neither there is a default_server so I think it just picked first. Either add server_name to the block with the webapp upstream or make it a default one:
listen 80 default_server;

Setting up nginx reverse proxy for jfrog artifactory and Jenkins

I am trying to set up a homeserver with Jenkins and Jfrog Artifactory OSS using docker-compose and Nginx as a reverse proxy.
The docker host has "homeserver" as hostname and my goal is to reach the Jenkins over http://homeserver/jenkins and artifactory over http://homeserver/artifactory.
While setting this up for Jenkins was no problem, I can't get artifactory to run as I want it to.
My docker-compose.yml is as follows:
version: '3.8'
services:
reverseproxy:
image: nginx
container_name: homeserver-reverse-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
jenkins:
image: jenkins/jenkins:lts
container_name: homeserver-jenkins
environment:
- JENKINS_OPTS="--prefix=/jenkins"
artifactory:
image: docker.bintray.io/jfrog/artifactory-oss:latest
container_name: homeserver-artifactory
volumes:
- artifactory-data:/var/opt/jfrog/artifactory
ports:
- "8081:8081"
- "8082:8082"
volumes:
artifactory-data:
I started off with the following nginx configuration:
events {}
http {
upstream jenkins {
server homeserver-jenkins:8080;
}
server {
server_name homeserver;
location /jenkins {
proxy_set_header Host $host:$server_port;
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;
proxy_pass http://jenkins;
proxy_read_timeout 90;
proxy_http_version 1.1;
proxy_request_buffering off;
}
rewrite ^/$ /ui/ redirect;
rewrite ^/ui$ /ui/ redirect;
location / {
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
chunked_transfer_encoding on;
client_max_body_size 0;
proxy_read_timeout 2400s;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
proxy_pass http://homeserver-artifactory:8082;
proxy_next_upstream error timeout non_idempotent;
proxy_next_upstream_tries 1;
proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^/artifactory/ {
proxy_pass http://homeserver-artifactory:8081;
}
}
}
}
This lets me access Jenkins as intended over http://homeserver/jenkins.
Artifactory is running (and accessible) with this configuration, but only directly at /.
Note that the parts for artifactory are exactly what the Jfrog website suggests as configuration.
That is not what I want, though.
In order to switch artifactory to http://homeserver/artifactory I see two possible options:
Configure artifactory to include an URL prefix (like I configured Jenkins with the JENKINS_OPTS="--prefix=/jenkins". However I could not figure out how to do this. The artifactory system.yml lets me configure the ports, but not the URL. Setting the Base URL over the web interface does not seem to work either, it just affects the redirected URLs and generated links (precisely at is stated in the tooltip of the website).
Change the nginx configuration and rewrite the request URIs. I tried, but it just doesn't work as I hoped it would.
Here is what I tried for the second option:
events {}
http {
upstream jenkins {
server homeserver-jenkins:8080;
}
server {
server_name homeserver;
location /jenkins {
# rewrite ^/jenkins(.*)$ $1 break;
proxy_set_header Host $host:$server_port;
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;
proxy_pass http://jenkins;
proxy_read_timeout 90;
# proxy_redirect http://homeserver-jenkins:8080
proxy_http_version 1.1;
proxy_request_buffering off;
}
rewrite ^/jfrog/$ /jfrog/ui/ redirect;
rewrite ^/jfrog/ui$ /jfrog/ui/ redirect;
location /jfrog/ {
if ($http_x_forwarded_proto = '') {
set $http_x_forwarded_proto $scheme;
}
rewrite ^/jfrog(.*)$ $1 break;
chunked_transfer_encoding on;
client_max_body_size 0;
proxy_read_timeout 2400s;
proxy_pass_header Server;
proxy_cookie_path ~*^/.* /;
proxy_pass http://homeserver-artifactory:8082;
proxy_next_upstream error timeout non_idempotent;
proxy_next_upstream_tries 1;
proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~ ^/artifactory/ {
proxy_pass http://homeserver-artifactory:8081;
}
}
}
}
I already tried here to change the location from http://homeserver/artifactory to http://homeserver/jfrog to avoid clashes with the nested location block - don't know if that's important or not.
When trying to run this configuration, I get a lot of error messages from my reverseproxy like
"GET /ui/css/chunk-vendors.4485dbea.css HTTP/1.1" 404 154
and the Jfrog logo bitmap in the loading screen does not show, and neither does the website itself load correctly.
After checking the network traffic with firefox it seems to me that the problem comes from the <link/> elements in the HTML document which is loaded when visiting http://homeserver/jfrog/ui/.
For example the CSS which led to the error message above comes from:
<link href="/ui/css/chunk-vendors.4485dbea.css" rel="preload" as="style">
Firefox then tries to load http://homeserver/ui/css/chunk-vendors.4485dbea.css. This does not work, the correct URL would be http://homeserver/jfrog/ui/css/chunk-vendors.4485dbea.css.

grafana behind a nginx reverse proxy

I try to run grafana and nginx as reverse proxy in a kubernetes cluster and I already found this answer but this seems not to work for me. At least I get the same {{alert.title}}-Message as Oles. That's why I would like ask again and maybe someone can give me a hint what I am doing wrong?
The configuration for the grafana deployment contains the following part:
env:
- name: GF_SERVER_DOMAIN
value: "k8s-4"
- name: GF_SERVER_ROOT_URL
value: "http://k8s-4/grafana"
and I don't modify the grafana.ini inside the container/pod.
Further I configure the nginx in the default.conf as following:
server {
listen 80;
server_name localhost k8s-4;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /grafana/ {
proxy_pass http://k8s-4:30080/grafana;
proxy_set_header X-Forwarded-Host k8s-4;
proxy_set_header X-Forwarded-Server k8s-4;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
But as I say above this leads to the alert.title Error. But if I set the context to the root Element and configured the tools as follows:
deployment:
env:
- name: GF_SERVER_DOMAIN
value: "k8s-4"
- name: GF_SERVER_ROOT_URL
value: "http://k8s-4"
nginx - default.conf
server {
listen 80;
server_name localhost k8s-4;
location / {
proxy_pass http://k8s-4:30080/grafana;
proxy_set_header X-Forwarded-Host k8s-4;
proxy_set_header X-Forwarded-Server k8s-4;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /grafana/ {
}
}
it works...
That's why I am quite sure this is a problem with the deployment of grafana but I don't see the error. Maybe someone here can give me a little hint?
Your first server setup is almost correct, you need to change the proxy_pass line to:
proxy_pass http://k8s-4:30080/;

configuring subdirectory app in nginx

Can someone help me configure my nginx where:
/app -> is the local html pages
/ -> is the https server which does not have app folder
The following conf didnt work for me: (
server {
listen 80;
ssl_verify_client off;
server_name localhost;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass https://xx.xx.xx.xx/;
}
location /app {
root "c:\LOCAL_PATH\app";
index index.html;
}
}
Exhanging your location /-block for the following oughta do it:
location / { rewrite ^ https://$host$request_uri?; }

Resources