I am new to NGINX. I'm wondering if it is possible to, with a single request to NGINX, make two proxy calls that affect the outcome of the response.
Specifically, I'm wanting to add a token to the response of an NGINX request where the token is given as a response header from a separate service.
Theoretically, it might look something like...
location / {
# Call to token service and set the response to a variable, maybe?
# proxy_pass Make the actual call
# Add token from step one to response headers
}
I don't know if this is supported by NGINX, if I need to delve into a custom module, or if this is just a bad idea.
Thanks.
Got it!
location / {
if ($http_x_entry_id = "") {
return 302 /entry;
}
auth_request /token/test-token;
auth_request_set $token $upstream_http_x_test_token;
set $test_ui test-ui;
proxy_pass http://$test_ui;
add_header X-My-Token "$token";
}
location /token/test-token {
internal;
set $token_api token-api;
error_page 500 =401 /error/401;
error_page 400 =401 /error/401;
proxy_method POST;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header Host $http_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;
rewrite /token/(.*) "/$1/$http_x_entry_id" break;
proxy_pass http://$token_api:8080;
}
Related
I am trying to use Oauth2-proxy as a gateway to my web site with Google auth. The Oauth login page appears, and you can click "Sign In" which takes you to a Google login page, but after logging in it redirects straight back to the Oauth login page. I suspect it has something to do with cookies but I don't know where I'm going wrong.
NGINX config:
server {
listen 443;
server_name my.website.com;
ssl on;
ssl_certificate /etc/ssl/my.website.com.pem;
ssl_certificate_key /etc/ssl/my.website.com.key;
location /oauth2/ {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
}
location = /oauth2/auth {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
# pass information via X-User and X-Email headers to backend,
# requires running with --set-xauthrequest flag
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
# if you enabled --pass-access-token, this will pass the token to the backend
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
# When using the --set-authorization-header flag, some provider's cookies can exceed the 4kb
# limit and so the OAuth2 Proxy splits these into multiple parts.
# Nginx normally only copies the first `Set-Cookie` header from the auth_request to the respon$
# so if your cookies are larger than 4kb, you will need to extract additional cookies manually.
auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1;
# Extract the Cookie attributes from the first Set-Cookie header and append them
# to the second part ($upstream_cookie_* variables only contain the raw cookie content)
if ($auth_cookie ~* "(; .*)") {
set $auth_cookie_name_0 $auth_cookie;
set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1";
}
# Send both Set-Cookie headers now if there was a second part
if ($auth_cookie_name_upstream_1) {
add_header Set-Cookie $auth_cookie_name_0;
add_header Set-Cookie $auth_cookie_name_1;
}
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:8888"; # This is where my web server is hosted
}
}
Oauth2-proxy config:
cookie_secret="" # Filled in with a base64 string
provider="google"
email_domains="*"
client_secret="" # Filled in with Google auth client secret
client_id="" # Filled in with Google auth client ID
cookie_secure="false" # No idea what to set this as, tried both false and true, same result
redirect_url="https://my.website.com/oauth2/auth/"
upstreams="http://127.0.0.1:8888/" # My website server
Oauth2-proxy startup command:
~/oauth2-proxy-v6.1.1.linux-amd64/oauth2-proxy --config=/home/username/work/src/github.com/oauth2-proxy/oauth2-proxy/contrib/local-environment/oauth2-proxy.cfg
Any ideas would be greatly appreciated!
According to the documentation
--redirect-url is the OAuth Redirect URL, should be set to supported callback endpoint , e.g. "https://internalapp.yourcompany.com/oauth2/callback".
/oauth2/callback endpoint - the URL used at the end of the OAuth cycle. The oauth app will be configured with this as the callback url.
The actual generated url has a state parameter, that includes the original URL to return back.
As I understand, callback retrieves from the state the original (protected by the proxy) url and redirects browser to it.
The answer I accepted is correct, but I also had to make some cookie changes and figured I should just post my final, working code.
I was able to get it working with these changes:
Under location /oauth2/:
proxy_set_header X-Auth-Request-Redirect "https://my.website.com";
Under location /:
auth_request_set $auth_cookie $upstream_http_set_cookie;
In Oauth2-proxy config (additional or replacement lines):
redirect_url = "https://my.website.com/oauth2/callback"
set_xauthrequest = true
upstreams = ["file:///dev/null"]
cookie_domains = [".website.com"]
cookie_secure = false
cookie_samesite = "lax"
edit: final contents of the config files:
NGINX config:
server {
listen 443;
server_name my.website.com;
ssl on;
ssl_certificate /etc/ssl/my.website.com.pem;
ssl_certificate_key /etc/ssl/my.website.com.key;
location /oauth2/ {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect "https://my.website.com";
}
location = /oauth2/auth {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1;
if ($auth_cookie ~* "(; .*)") {
set $auth_cookie_name_0 $auth_cookie;
set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1";
}
if ($auth_cookie_name_upstream_1) {
add_header Set-Cookie $auth_cookie_name_0;
add_header Set-Cookie $auth_cookie_name_1;
}
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:8888"; # This is where my web server is hosted
}
}
Oauth2-proxy config:
cookie_secret="" # Filled in with a base64 string
provider="google"
email_domains="*"
client_secret="" # Filled in with Google auth client secret
client_id="" # Filled in with Google auth client ID
cookie_domains=[".website.com"]
cookie_secure="false"
cookie_samesite="lax"
redirect_url="https://my.website.com/oauth2/callback"
upstreams="http://127.0.0.1:8888/" # My website server
set_xauthrequest=true
upstreams=["file:///dev/null"]
You are going back to the oauth page because you have set (in Oauth2-proxy config)
redirect_url="https://my.website.com/oauth2/auth/"
Change it to just https://my.website.com/ for example,to land on your website home screen.
I'm wondering how to explicitly set up auth checks in one place for every location. Doing something like below seems like it's prone to errors (missing an entry, typos, unnecessary duplication, etc)
nginx.conf
location / {
auth_request /someAuth;
auth_request_set $someVar $someOtherVar;
proxy_pass https://somewhere.com:1234;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /foo {
auth_request /someAuth;
auth_request_set $someVar $someOtherVar;
proxy_pass https://somewhereElse.com:6578;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /bar {
auth_request /someAuth;
auth_request_set $someVar $someOtherVar;
proxy_pass https://somewhereOther.com:9876;
proxy_set_header X-Forwarded-For $remote_addr;
}
Maybe using a map directive in a way like
map $uri $proxy {
~^/foo https://somewhereElse.com:6578;
~^/bar https://somewhereOther.com:9876;
default https://somewhere.com:1234;
}
server {
...
location / {
auth_request /someAuth;
auth_request_set $someVar $someOtherVar;
proxy_pass $proxy;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Please note that such a configuration would require a resolver directive.
I have some issues with a "basic" rewriting rule under a proxy_pass location type :
location ~* /test1/network/v1/operator/ke3/dataUp {
rewrite ^(?<begin>/test1/network/v1/operator/ke3/dataUp)(?<parametersPart>.*)(?<mustDie>/dataUp)$ $parametersPart break;
proxy_pass http://server_preproduction;
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 https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
I expect any calls sent to : .../test1/network/v1/operator/ke3/dataUp?param1=GHJ¶m2=865/dataUp
To be equal to : .../test1/network/v1/operator/ke3/dataUp?param1=GHJ¶m2=865
So I just want to parse the parameters section in order to remove any extra /dataUp from the original request.
But when I try to use any kind of regex to do so, nginx seems to return to the location / and use the default request...
I'm sure that the proper location is use, becanse when I use a rewrite like : rewrite ^(?<begin>/test1/network/v1/operator/ke3/dataUp)(?<parametersPart>.*)$ TEST$parametersPart break;
The log on the proxy server received : TEST?param1=GHJ¶m2=865/dataUp
I do not add a / at the end of the proxy_pass because I want replace all the url.(but it's not mandatory ! I tried lot of combinations...)
If someone can save my day :p
Thanks !!
I find a way to manipulate the argument with a simple if statement...
if ($query_string ~ "^(?<argsok>/dataUp.*)(?<argsko>/dataUp)$") {
proxy_pass http://server_preproduction/$argsok;
}
I have nginx reverse-proxy to my site on IIS and here is my nginx config:
UPDATE
upstream backend {
server 43.128.77.101;
}
server {
server_name domain.subdomain.com;
location /products {
if ($query_string ~ Jeans){
return 301 /get-all-products/?filter=jeans;
}
if ($query_string ~ Shirts){
return 301 /get-all-products/?filter=shirts;
}
if ($query_string ~ Hats){
return 301 /get-all-products/?filter=hats;
}
}
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
It redirects from /products page to certain URLs by query string. But for page /products-available it fails with error 404. Nginx error log contains error:
"/usr/share/nginx/html/products-available" failed (2: No such file or directory)
The page /products-available doesn't need any redirections. I want it to pass on backend IIS server as it is. How can I tell nginx to pass it through? What am I doing wrong?
Thank you.
This would be because you are only defining the behavior of Nginx for a given path (/products).
If you want to define a default behavior for Nginx requests that don't match the /products path (like /products-available) you can add the following after your current location section to proxy any other path request to a different application/port.
location / {
proxy_pass http://127.0.0.1:3000;
}
You can see more information on sending a request to a different application in https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#passing-a-request-to-a-proxied-server
I would like to redirect all http traffic to https with a handful of exceptions. Anything with /exception/ in the url I would like to keep on http.
Have tried the following suggested by Redirect all http to https in nginx, except one file
but it's not working. The /exception/ urls will be passed from nginx to apache for some php processing in a laravel framework but that shouldn't matter.
Any suggestions for improvement much appreciated!
server {
listen 127.0.0.1:80;
location / {
proxy_pass http://127.0.0.1:7080;
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-Accel-Internal /internal-nginx-static-location;
access_log off;
}
location /exception/ {
# empty block do nothing
# I've also tried adding "break;" here
}
return 301 https://localhost$request_uri;
}
Nginx finds the longest matching location and processes it first, but your return at the end of the server block was being processed regardless. This will redirect everything but /exception/ which is passed upstream.
server {
listen 127.0.0.1:80;
access_log off;
location / {
return 301 https://localhost$request_uri;
}
location /exception/ {
proxy_pass http://127.0.0.1:7080;
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-Accel-Internal /internal-nginx-static-location;
}
}