Reverse Proxy to App Engine missing Host - php

I have a reverse proxy pointing to a google appengine api. The api is a shared service layer so I point multiple sites to it via reverse proxies.
mysite1.com > myapp.appspot.com
mysite2.com > myapp.appspot.com
The problem is, in the php script on app engine I'm unable to access the original host name. If I look at the $_SERVER vars all I see is myapp.appspot.com, where I'd like to see mysite1.com
I tried setting the proxy header Host to the main site url and it breaks app engine. Is there a way to get the proxying url from app engine?

I have solved this using nginx:
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
You can then grab the X-Forwarded variables from the $_SERVER array as per the usual in PHP.

Related

How to get real ip of visitor if our app is behind a reverse proxy?

I'm using Siteground's nginx based dynamic cache reverse proxy which serves requests and static file using it, i want to get the IP address of the visitor but im unable to get anything there's nothing even shown while print_r($_SERVER).
Here is what i tried.
$hostname = gethostbyaddr(trim($_SERVER['HTTP_X_REAL_IP']));
$hostname = gethostbyaddr(trim($_SERVER['REMOTE_ADDR']));
If someone can help?
You have to set configurations on your reverse proxy in order to forward the real IP address to your web server.
For example using Nginx, you can set headers like this :
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
Here, the X-Real-IP will provide you the real IP address on your backend server.
You must refer to the documentation of the reverse proxy software you're using (apache, nginx, etc..) for more information.

auth_request + login screen vs browser redirects

When someone visits a site I want him to have a specific cookie set.
Such cookie is checked via auth_request and a 403 should end up in a login screen (HTML/PHP needed so no auth_basic).
On successful auth it shall redirect to "foo.example.org".
So I wrote a config and things in the proxy that do all of that.
Problem is: The browser enters foo.example.org, remembers the previous redirect and keeps redirecting to the login screen.
What can I change so that the browser does no redirect (out of his cache)?
Something like "foo.example.org?auth" would be a thing or having the auth completely internal.
server {
server_name foo.example.org;
location / {
auth_request /restricted;
error_page 403 = #error403;
proxy_pass http://10.12.34.56;
resolver 127.0.0.11 ipv6=off;
proxy_redirect off;
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-Host $server_name;
}
location #error403 {
return 307 /restricted;
}
location /restricted {
proxy_pass http://auth_server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
You are returning a 307 Temporary Redirect response instead of a 403 Forbidden, it's probably just cached in the browser so keeps redirecting. It's just doing what you are telling it to do.
You are making life hard for yourself anyway, it's actually much easier to do this.
Use a map directive to check for the cookie and set a custom variable based on the value of it. Lets assume they need cookie secret to have the value password to get in:
map $cookie_secret $notloggedin {
default 1;
password 0;
}
Now $notloggedin will always be set to 1 unless the client request has cookie secret=password, then it will be set to 0 which in Nginx also equates to empty/unset.
Now we drop that variable into an if condition in the location block. There is some confusion over the use of if conditions in locations and lots of people will tell you that you shouldn't use them, but the docs clearly state:
The only 100% safe things which may be done inside if in a location
context are:
return ...;
rewrite ... last;
So this will be ok.
location / {
if ($notloggedin) {
return https://example.com/login;
}
People without the cookie now get redirected to the login page.

Symfony port redirection behind reverse proxy

I have a Symfony 3.2 application (running on port 8443) using FosUserBundle. When anonymous users access 'https://[myurl].com:8443', they are redirected to 'https://[myurl].com:8443/login' for the login process. This redirection is working fine when accessing the application but now, we want to use a reverse proxy to forward the requests from customers to the application. Customers would use standard https port 443.
What happens is the following : Users access the application with 'https://myurl.com'.
The request is forwarded by the reverse proxy to the web server (IIS) hosting the application on port 8443.
The user making the request is redirected to 'https://myurl.com:8443/login' which does not work because 8443 is only opened server-side.
I tried different solutions in symfony but was not able to make it work :
-set up the reverse proxy in symfony : Request::setTrustedProxies(array('123.456.78.89'));
-set http_port/https_port in config.yml
-set $_SERVER['SERVER_PORT'] = 443;
Any idea on how can I solve this ?
Thanks
In addition to #Gor I think you should also configure your proxy to add X-Forwarded headers. In Nginx something like
location / {
proxy_pass http://myurl:8443;
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;
proxy_set_header X-Forwarded-Port $server_port;
}
Open the following file:
web/app.php
Right after this line:
$request = Request::createFromGlobals();
Insert this block:
// tell Symfony about your reverse proxy
Request::setTrustedProxies(
// the IP address (or range) of your proxy
['192.0.0.1', '10.0.0.0/8'],
// trust *all* "X-Forwarded-*" headers
Request::HEADER_X_FORWARDED_ALL
// or, if your proxy instead uses the "Forwarded" header
// Request::HEADER_FORWARDED
// or, if you're using AWS ELB
// Request::HEADER_X_FORWARDED_AWS_ELB
);
See:
"How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy"
http://symfony.com/doc/3.4/deployment/proxies.html

With Nginx, how do I preserve the client's IP address when using proxy_pass? [duplicate]

I'm running a service in localhost at 127.0.01:8000
and I'm proxying this by using:
proxy_pass http://127.0.0.1:8000;
Problem is that I need to pass the user's IP address to the service.
Any ideas?
I send the real IP to django by setting a custom header:
proxy_set_header X-Real-IP $remote_addr;
Those headers are available in request.META
See http://wiki.nginx.org/HttpRealIpModule

Can I integrate a node.js/express based chat into my PHP/jquery based site?

I have an established site that I want to make chat client for. I want to write it all myself for fun and to learn a little about node.js and express. Right now I have a chat system based on jQuery/PHP/MySQL and polling with ajax. It is slow and I only poll every 5 seconds so it looks slow too.
I can write the chat in node.js, but my question is: How can I include my chat in the my oldschool pages. I want it to be a box that is at the bottom corner of all my pages. I am not concerned with the css, only how to integrate it. Should the chat live at it's own domain (chat.example.com) and just allow cross site access?
Here is a reference to the Access Control Headers.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
If your PHP app is running say behind nginx. You could set up a route in nginx that forwards those requests to the chat server.
Here is an example:
upstream app_chat {
server 127.0.0.1:8080;
}
server {
listen 0.0.0.0:80;
server_name www.mydomain.com mydomain;
location /chat {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://app_chat/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
So from your client js
var sock = io.connect('ws://mydomain/chat');
sock.on('chat', function (msg) {
console.log('msg', msg);
});
Yes, you can. I don't know how complex your app is. But, running a node server on a different port will do.
Lets say your PHP app runs on port 80. Now, run your node.js server which handles the chat system on 8080. Then in your PHP page, include a JS file(chat.js).
chat.js
var connection = io.connect('YOUR_NODE_SERVER_URL'); //like http://localhost:8080
/*
your code
*/
That's it.

Categories