Server Bug Fix: ProxyPass Apache 2.4 simple proxypass not working

Original Source Link

i have the following situation:
i need to call the following url http://myapp.mydomain.com

and the url should reply as following
http://myapp.mydomain.com/index.jsp

On my apache 2.4
i tryied different setup but none seems to work,

First attempt

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass /myapp http://127.0.0.1:8080/myapp
    ProxyPassReverse /myapp http://127.0.0.1:8080/myapp
</VirtualHost>

Second attempt

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass /myapp/ http://127.0.0.1:8080/myapp/
    ProxyPassReverse /myapp/ http://127.0.0.1:8080/myapp/
</VirtualHost>

Third attempt

    <Location "/myapp/">
        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:8080/myapp/
        ProxyPassReverse / http://127.0.0.1:8080/myapp/
   </Location>

Fourth attempt

<Location "/myapp/">
    ProxyPreserveHost On
    ProxyPass /myapp/ http://127.0.0.1:8080/myapp/
    ProxyPassReverse /myapp/ http://127.0.0.1:8080/myapp/

None of the configuration seem to work,
the url https://myapp.mydomain.com brings up the welcome page of the tomcat.
And what ever configuration i apply to apache, the only way to make it work is to manually add on the link the mountpoint of proxy, as following

http://myapp:mydomain.com/myapp/index.jsp

Any suggestion on how can i make this work?
Thanks in advance.

Use below ProxyPass inside VirtualHost and test.

ProxyPass / http://127.0.0.1:8080/myapp/
ProxyPassReverse / http://127.0.0.1:8080/myapp/

Tagged : / /

Server Bug Fix: REMOTE_USER through Apache reverse proxy

Original Source Link

I have an Apache webserver with mod_proxy enabled and a Virtualhost, proxy.domain.com. This proxy is configured to prompt the user for credentials with AuthType Basic. Then, the content of web.domain.com is available through the proxy with ProxyPass and ProxyReverse. However, the REMOTE_USER variable is empty. I read different things to achieve this with mod_rewrite and mod_headers but all my tries have failed. Does anybody has been luckier than me?

Thanks.

This is possible with mod_headers, mod_rewrite, and mod_proxy.

On the proxy, I assume you have your authentication working and setting REMOTE_USER appropriately. If so, then put the value of REMOTE_USER into a Proxy-User header to the backend like this:

RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER}] # note mod_rewrite's lookahead option
RequestHeader set Proxy-User %{PROXY_USER}e

Here’s what happens:

  1. The RewriteRule fires for every request and sets the environment variable PROXY_USER equal to the value of REMOTE_USER, which should have been set already by an auth module.
  2. The RequestHeader sets a request header named Proxy-User with the value of PROXY_USER

Now on the backend, you can pull that header value and set REMOTE_USER like this:

RewriteCond %{HTTP:Proxy-user} ^(.*)$
RewriteRule .* - [E=REMOTE_USER:%1]

Here’s what happens:

  1. The RewriteCondition checks the value of the Proxy-User header to see if it matches the pattern ^.*$ (which it will). The parentheses tells mod_rewrite to store that value in %1.
  2. The RewriteRule then sets the environment variable REMOTE_USER with the value in %1.

On apache 2.4, trying to get the env vars produced by mod_authnz_ldap and mod_kerb, this is what worked.

Let’s say you are looking for AUTHORIZE_sAMAccountName,

RewriteEngine On
RewriteRule .* - [E=THE_ACCOUNT_NAME:%{ENV:AUTHORIZE_sAMAccountName}] 
RequestHeader set MY_ACCOUNT_NAME %{THE_ACCOUNT_NAME}e

After that, the HEADER can be for example logged:

CustomLog /tmp/custom.log "%h %l %u %t "%r" %>s %b %{MY_ACCOUNT_NAME}i"

References:

On the backend side you can also use standard mod_auth_basic if you don’t want to mess with mod_rewrite. Assuming you pass the user in as X-Remote-User:

<Location />
  AuthBasicFake "%{HTTP:X-Remote-User}" "password"
</Location>

This only works in 2.4 but has the extra benefit of setting up the other aspects of true mod_auth (i.e. PHP’s auth support)

Example to populate header X-Remote-User with the content of REMOTE_USER variable after being authenticated and send that header to a backend proxy (apache 2.4.6).

# Example for Apache 2.4.6

<VirtualHost *:80>

RewriteEngine on
<Location />

    ###############################################
    # Your authentication logic here
    AuthType .......
    AuthName .......
    AuthBasicProvider .......
    .... etc
    Require valid-user
    ###############################################

    RewriteCond %{LA-U:REMOTE_USER} (.+)
    RewriteRule . - [E=RU:%1]
    RequestHeader set X-Remote-User %{RU}e

</Location>

    ProxyTimeout 300
    ProxyPass / http://localhost:81/
    ProxyPassReverse / http://localhost:81/

</VirtualHost>

Tagged : / /

Server Bug Fix: How to ProxyPass to a ‘/path/’ instead of root ‘/’?

Original Source Link

I am using Ubuntu-15.10 wily, Apache-2.4.12

I’ve been trying to use ProxyPass in an SSL enabled VirtualHost like so:

ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
    Require all granted
</Proxy>
ProxyPass /myapp/ http://127.0.0.1:8090/
ProxyPassReverse /myapp/ http://127.0.0.1:8090/

With above configuration, I assumed that whatever is being served by the server on that port, e.g. web will be appended to https://www.example.com/myapp/web.

However, this is not what I get. In Apache logs I get:

... File does not exist: /var/www/html/web, referer: https://www.example.com/myapp/

Is this because I don’t understand what ProxyPass is supposed to do? Or is there something wrong with my configuration that I need to correct?

ADDENDUM (18 Feb 2016)

I have turned on logging for mod_proxy and I see the following which doesn’t make sense:

... connecting http://127.0.0.1:8090/ to 127.0.0.1:8090
... connected / to 127.0.0.1:8090
... fam 2 socket created to 127.0.0.1
... connection established with 127.0.0.1:8090 (127.0.0.1)
... connection complete to 127.0.0.1:8090 (127.0.0.1)
... http: has released connection for (127.0.0.1)
... proxy: connection shutdown

I am assuming that one of the addresses in the first line is the intrnal placeholder and the other is the URL being retrieved. But why in the second line the retrieved url gets connected to / instead of /myapp/ as per ProxyPass?

I found a solution, but it is not what I hoped for nor what I expected from my readings on ProxyPass. It might be a mistake on my part, or the documentation is not as clear as it should be. ProxyPass can not append proxied URL to a path of an invented name. So, I had to make my application load from a directory on the designated port rather than from the root of the URL as such:

ProxyPass /myapp http://127.0.0.1:8090/myapp
ProxyPassReverse /myapp http://127.0.0.1/myapp

Furthermore, A RewriteRule must be used as well if there are resources that need to be loaded, e.g. queries, images, scripts, etc.

The Rewrite rules would be:

RewriteEngine On
RewriteRule ^(.*) http://0.0.0.0:8090/$1 [P,L]

I feel like there are many other solution that might involve other proxy modules and possibly RewriteRule, however, this is the one that is as simple as my knowledge in apache got.

So, the bottom-line, at least the first component of the path must be present on both ends in order for ProxyPass to do it’s job. I can not use ProxyPath to load on a path I make up without further complications in proxy settings.

I hope someone finds this answer of help.

Tagged : / /

Server Bug Fix: Apache ProxyPass to Tomcat – how to remove context path from URL?

Original Source Link

I have Apache conf:

<IfModule mod_ssl.c>
<VirtualHost *:443>

    ServerName project.example.com
    ServerAlias ci
    ProxyRequests Off

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPreserveHost on
    ProxyPass / http://localhost:1111/project

    SSLCertificateFile /etc/letsencrypt/live/sub.example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/sub.example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateChainFile /etc/letsencrypt/live/sub.example.com/chain.pem

</VirtualHost>
</IfModule>

When I enter project.example.com, I get https://project.example.com/project/users/sign_in in a browser. How to remove context path from URL?
I want to remove project from URL and get https://project.example.com/users/sign_in ?

I think you’re missing the trailing slash:

ProxyPass / http://localhost:1111/project/

It’s also a good idea to define a corresponding ProxyPassReverse:

ProxyPassReverse / http://localhost:1111/project/

So first would be removing the context root from the application. Unless you define the context as / (blank) you cannot access the application without the context root.

This Solution should give you an idea of how to change the context root.
Once you are done with the steps you should be able to access your application at http://localhost:1111/.

Then coming to the httpd configuration remove the project name :

ProxyPass / http://localhost:1111/

Tagged : / / / /

Server Bug Fix: Reverse proxy Rest-API endpoint

Original Source Link

I have trouble configuring the reverse proxy for my setup.

I have a frontend built using Angular and a backend built using Spring (running Spring boot currently)

Now, i have already configured apache to receive request for frontend. Frontend can now display angular application correctly.

However, there is a REST-API calls to backend inside angular application always throw 404. Tried checking backend (spring), i have access logs. It means that maybe reverse proxy is working but when i try to check the network logs in browsers, request to API call always shows 404. See image below

Even though it shows 404, i can receive the request in backend and confirmed it through logs.

Need a another set of eyes to look at this. what am i missing? maybe i may have misunderstood other configuration directive here. Please do share your insights or fix for that matter. Appreciate it.

Here is my .conf file in apache

Listen 9999
<VirtualHost *:9999>

  ServerAdmin [email protected]
  DocumentRoot "/var/www/html/test"
  ServerName test
  ErrorLog "/var/log/httpd/test-error.log"
  CustomLog "/var/log/httpd/test-access.log" combined
  TransferLog "/var/log/httpd/test-transfer.log"

  <Directory "/var/www/html/test">
        AllowOverride All

        <IfModule mod_rewrite.c>
          RewriteEngine On
          RewriteBase /
          RewriteRule ^index.html$ - [L]
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule . /index.html [L]
        </IfModule>

  </Directory>

  ProxyRequests Off

  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  ProxyPass /api http://localhost:8080/api/v1
  ProxyPassReverse /api http://localhost:8080/api/v1


</VirtualHost>

image1

Tagged : / / /

Server Bug Fix: nginx reverse proxy inside docker with proxy_redirect default

Original Source Link

I’m trying to run lets-chat inside docker behind nginx acting as a reverse proxy so that lets-chat will be accessible on /chat over HTTP.

In the past when using nginx as a reverse proxy inside of docker for another docker container I set resolver 127.0.0.11 valid=300s; so that nginx uses the docker DNS server and set proxy_pass as a variable so that the nginx container can start without needing the upstream web service to be ready. Example.

However, lets-chat seems to need proxy_redirect default; which the nginx configuration does not allow combined with a variable proxy_pass.

Does anyone know a way around this to get the desired effect? I’ve tried a few manual redirects with no luck. My relevant nginx config is below.

# use docker's nameserver for changing container IPs
resolver 127.0.0.11 valid=300s;
resolver_timeout 5s;

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /chat/ {
        # I would like this part to work
        #set $chat_backend http://chat_server:8080/;
        #proxy_pass $chat_backend;

        # But I can only get it to work like this
        proxy_pass http://chat_server:8080/;
        proxy_redirect /  /chat/;
        proxy_redirect default; # this line errors when setting a variable to proxy_pass

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

Thanks.

From the manual, the following statements are equivalent:

location /chat/ {
    proxy_pass http://chat_server:8080/;
    proxy_redirect default;
}
location /chat/ {
    proxy_pass http://chat_server:8080/;
    proxy_redirect http://chat_server:8080/ /chat/;
}

proxy_redirect default does not work if the value of proxy_pass is not a literal string, however, proxy_redirect itself can also be constructed from variables.

So this solution may work for you:

location /chat/ {
    set $chat_backend http://chat_server:8080/;
    proxy_pass $chat_backend;

    proxy_redirect /             /chat/;
    proxy_redirect $chat_backend /chat/;
    ...
}

Tagged : / / /

Server Bug Fix: How to remove the path with an nginx proxy_pass in http and https?

Original Source Link

I have read the similar issue below but got a problem that will explain later in the question:

I have a config like below that proxy_pass to an upstream:

location /api2/ {
    client_max_body_size 10m;

    if ($scheme = 'https') {
        proxy_pass https://api.example.com;
    }

    if ($scheme = 'http') {
        proxy_pass http://api.example.com;
    }

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
}

Here the api2 section is sent to the upstream. In the question I’ve linked above uses / at the end of proxy_pass to omit the api2 part. When I add the / at the end of proxy_pass I get the below error:

nginx: [emerg] "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 in /etc/nginx/sites-enabled/mysite:160

When I searched for the above error, the community says that you need to remove / in proxy_pass to solve the error.

So the question is why I’m getting api2 in the upstream? How should I remove api2 when proxying?

When I change the config to:

location /api2/ {
    client_max_body_size 10m;

    proxy_pass http://api.example.com/;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
}

It works, but the https requests have problem sending request.

In the upstream section I get the below error:

GET //api2/my_endpoint HTTP/1.1" 404

Well, the thing is that proxy_pass when you don’t explicitly specify the URI you are proxying to, doesn’t touch it too. At all. So you get the exact input URI, e.g. /api2/.

If you need to tamper with URI while proxying it, you need to use rewrite directive. The most simple solution would be doing something like this inside your location clause:

rewrite ^/api2/(.*) /$1 break;

Also not that proxying to the same URL but with two different schemes look redundant. I’d say that you should either terminate TLS on your proxy, or, if the intermediate transport is the subject of compromising, get rid of the plain HTTP.

Tagged : /