I want to proxy multiple domains to my vuejs app.
I have a VueJS application, with the following route: https://app.pingr.io/status/{id}.
What I want to do is to allow users to redirect their domains to this route. So, imagine we have a https://status.some-domain.com host, which is redirected using CNAME to https://app.pingr.io/status/status.some-domain.com.
I really can't figure out the nginx configuration for this.
What I have right now:
server {
listen 80 default_server;
server_name _;
location / {
#resolver 127.0.0.1 [::1];
#resolver 8.8.8.8;
proxy_pass https://app.pingr.io/status/test/;
}
location /js/ {
proxy_pass https://app.pingr.io/js/;
proxy_ssl_server_name on;
proxy_set_header Accept-Encoding "";
}
location /css/ {
proxy_pass https://app.pingr.io/css/;
proxy_set_header Accept-Encoding "";
}
}
Before passing $host variable to proxy_pass at first I'm trying to just proxy to /status/test with working js/css/images.
I managed to get js/css work, however instead of getting the content of /status/test route, I get redirected to the home page. I displayed routes in router.beforeEach, so I can see that the first route I'm being redirected to is home route.
I was trying different configurations, like including proxy_set_header host and other stuff, which actually broke the whole thing even more.
So what is the right way to do this? Once again, users should be able to redirect their domains to my vuejs route and pass their domain to a part of this route. The domain should be rewritten, so that it looks like the page belongs to their server/domain.
I'm trying to get NGINX's resolver to automatically update the DNS resolution cache, so I'm transitioning to using a variable as the proxy_pass value to achieve that. However, when I do use a variable, it makes all requests go to the root endpoint of the request and cuts off any additional paths of the url. Here's my config:
resolver 10.0.0.2 valid=10s;
server {
listen 80;
server_name localhost;
location /api/test-service/ {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# If these 2 lines are uncommented, 'http://example.com/api/test-service/test' goes to 'http://example.com/api/test-service/'
set $pass_url http://test-microservice.example.com:80/;
proxy_pass $pass_url;
# If this line is uncommented, things work as expected. 'http://example.com/api/test-service/test' goes to 'http://example.com/api/test-service/test'
# proxy_pass http://test-microservice.example.com:80/;
}
This doesn't make any sense to me because the hardcoded URL and the value of the variable are identical. Is there something I'm missing?
EDIT: Ah, so I've found the issue. But I'm not entirely sure how to handle it. Since this is a reverse proxy, I need the proxy_pass to REMOVE the /api/test-service/ from the URI before it passes it to the proxy. So..
This:
http://example.com/api/test-service/test
Should proxy to this:
http://test-microservice.example.com:80/test
But instead proxies to this:
http://test-microservice.example.com:80/api/test-service/test
When I'm not using a variable, it drops it no problem. But the variable adds it. Is that just inherently what using the variable will do?
There is a small point you missed in documentation
When variables are used in proxy_pass:
location /name/ {
proxy_pass http://127.0.0.1$request_uri;
}
In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.
So you config needs to be changed to
set $pass_url http://test-microservice.example.com:80$request_uri;
proxy_pass $pass_url;
I'm using Nginx in front of Apache and have an issue with URL encoding.
Requests for :
GET /forum/index.php%3Ftopic%3D14454.3775%3Bwap2
Produces this error in Apache (when proxy_passed from Nginx) :
/forum/index.php?topic=14454.3775;wap2' not found or unable to stat
When I request the url above (not encoded) it gets processed just fine.
The solution I found is I need to change:
proxy_pass http://127.0.0.1:80;
to
proxy_pass http://127.0.0.1:80/;
When the forward slash is excluded, the original request will not be decoded. When I add the forward slash, this is the error message I receive :
"proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block
My nginx config block is :
location ~* ^/forum/index.php
{
charset ISO-8859-1;
include /etc/nginx/proxypass.conf;
proxy_pass http://127.0.0.1:80;
}
How can I fix the proxy_pass directive and include the forward slash so the request url is decoded before it's passed over to Apache?
EDIT:
Request:
GET /index.php HTTP/1.1" 200 16481 "http://www.example.com/forum/index.php%3Ftopic%3D14454.3775%3Bwap2
Error:
script '/www/example.com/httpdocs/forum/index.php?topic=14454.3775;wap2' not found or unable to stat
I managed to solve the issue by doing this.
If there is a better way to handle this, please let me know.
location ~* /forum/index.php(.*)
{
include /nginx/proxypass.conf;
if ($args) {
proxy_pass http://127.0.0.1:80/forum/index.php?$args;
}
proxy_pass http://127.0.0.1:80/forum/index.php$1;
}
I want to use nginx as a revers ssl proxy.
I have a reset service with multiple apis and I want to have a place holder in the location configuration and use it in the proxy_pass
location /myapp/(\s+)/(\s+) {
proxy_pass http://localhost:9000/$1/$2;
}
Any idea how do I do it ?
Ok, so for development purposes, we have a dedicated web server. It's not currently connected directly to the internet, so I've setup an apache reverse proxy on another server, which forwards to the development server.
This way, I can get web access to the server.
The problem is, the routes in Laravel are now being prefixed with the internal server IP address, or the servers computer name.
For example, I go to http://subdomain.test.com but all the routes, generated using the route() helper, are displaying the following url: http://10.47.32.22 and not http://subdomain.test.com.
The reverse proxy is setup as such:
<VirtualHost *:80>
ServerName igateway.somedomain.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://10.47.32.22:80/
ProxyPassReverse / http://10.47.32.22:80/
<Location />
Order allow,deny
Allow from all
</Location>
</VirtualHost>
I have set the actual domain name in config\app.php.
Question
How can I set the default URL to use in routing? I don't want it using the internal addresses, because that defeats the point of the reverse proxy.
I've tried enclosing all my routes in a Route::group(['domain' ... group, which doesn't work either.
I ran into the same (or similar problem), when a Laravel 5 application was not aware of being behind an SSL load-balancer.
I have the following design:
client talks to an SSL load balancer over HTTPS
SSL load balancer talks to a back-end server over HTTP
That, however, causes all the URLs in the HTML code to be generated with http:// schema.
The following is a quick'n'dirty workaround to make this work, including the schema (http vs. https):
Place the following code on top of app/Http/routes.php
In latest version of laravel, use web/routes.php
$proxy_url = getenv('PROXY_URL');
$proxy_schema = getenv('PROXY_SCHEMA');
if (!empty($proxy_url)) {
URL::forceRootUrl($proxy_url);
}
if (!empty($proxy_schema)) {
URL::forceSchema($proxy_schema);
}
then add the following line into .env file:
PROXY_URL = http://igateway.somedomain.com
If you also need to change schema in the generated HTML code from http:// to https://, just add the following line as well:
PROXY_SCHEMA = https
In latest version of laravel forceSchema method name has changed to forceScheme and the code above should look like this:
if (!empty($proxy_schema)) {
URL::forceScheme($proxy_schema);
}
Ok, so I got it. Hopefully this will help someone in the future.
It seems like Laravel ignores the url property in the config\app.php file for http requests (it does state it's only for artisan), and it instead uses either HTTP_HOST or SERVER_NAME provided by apache to generate the domain for URLs.
To override this default url, go to your routes.php file and use the following method:
URL::forceRootUrl('http://subdomain.newurl.com');
This will then force the URL generator to use the new url instead of the HTTP_HOST or SERVER_NAME value.
Go to app/Http/Middleware/TrustProxies.php and change the protected variable $proxies like this:
protected $proxies = ['127.0.0.1'];
Just this! Be happy!
Because laravel route is created not from the config/app itself rather than from the server. My solution is adding the proxy_set_header Host to the nginx's config.
server {
listen 80;
server_name my.domain.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host my.domain.com;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8000;
}
}
i'm using laravel 8 with nginx docker inside a running nginx on the machine, so yeah it's double nginx
add this code in App\Providers\AppServiceProvider class
if (Str::contains(Config::get('app.url'), 'https://')) {
URL::forceScheme('https');
}
Seems the Laravel have more convinient solution.. Check answer there: How do I configure SSL with Laravel 5 behind a load balancer (ssl_termination)?
Following up #TimeLord's solution:
In latest version of laravel the name for forced schema has changed and now it is:
URL::forceScheme()
I know this topic is old a.f but I've been solving this issue by replacing the following line in my DatabaseSessionHandler.pdf [#Illuminate/Session]:
protected function ipAddress()
{
return $_SERVER['HTTP_X_FORWARDED_FOR'];
// return $this->container->make('request')->ip();
}
Of course you need to migrate the sesssion table first and set up the config
(.env Variable SESSION_DRIVER=database)
For nginx, you don't need to do anything extra in Laravel. The fix can be done at from nginx config;
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name sub.domain.dev;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host sub.domain.dev;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8000;
}
}
Figured out a way that much cleaner and only does exactly what the loadbalancer tells it to, add this function to your RouteServiceProvider
protected function enforceProtocol()
{
if(request()->server->has('HTTP_X_FORWARDED_PROTO')){
URL::forceScheme(request()->server()['HTTP_X_FORWARDED_PROTO']);
}
}
and in the boot section, simple call it like so
public function boot()
{
$this->enforceProtocol();
//other stuff
}