Server Bug Fix: How to create a reverse proxy to host specified in url?

Original Source Link

I need to configure proxy with apache to proxy requests like

http://example.com/proxy/www.anothersite.com/[some-params]

to

http://www.anothersite.com/[some-params]

I tried to do this like that:

<LocationMatch ^/proxy/(.*)$>
    ProxyPassMatch http://$1
</LocationMatch>

But how can I make all redirects that sends to me remote host go via proxy? For example, if I go to url:

http://example.com/proxy/another-site.com

and another-site.com send me redirect to yet-another-site.com, it shall forward my browser to

http://example.com/proxy/yet-another-site.com

You can use Apache ProxyPassReverse directive for this. You can find its documentation in Apache documentation

I would recommend not using Location or LocationMatch blocks, just use the 2 argument versions of ProxyPass and ProxyPassMatch. So in your case:

ProxyPassMatch ^/proxy/(.*)$ http://$1

However you cannot use Apache configuration to fix back end redirects as there is no corresponging ProxyPassReverseMatch directive (this directive simply cannot work this way). You would need to edit Location, Content-Location and URI headers using the Header directive (which duplicates what the the ProxyPassReverse directive does) and possibly use mod_sed/mod_substitute to fix and hard coded URLs in the HTML.

But it will be messy, very messy. The reason this sort of thing is not easy to do is that in general Apache is not an HTML content aware server, it’s an HTTP aware server, two very different things.

It maybe slightly easier to upgrade to apache v2.4 so you can use mod_proxy_html (which is HTML aware) or write your own handler in mod_lua or similar.

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: Apache2, Kerberos: gss_accept_sec_context() failed: An unsupported mechanism was requested

Original Source Link

I want to use Kerberos and Apache 2 on linux with mod_auth_kerb.

I added .htaccess to my project with following:

#SSLRequireSSL
AuthType Kerberos
AuthName "Kerberos Login"
KrbMethodNegotiate On
KrbMethodK5Passwd Off
KrbAuthRealms DOMAIN.COM
Krb5KeyTab /etc/httpd/httpd.keytab
KrbLocalUserMapping On
require valid-user

When I tried to test my single sign on on IE or Firefox I get the following error in apache log:

[Thu Jan 19 21:03:27 2012] [error] [client 10.65.0.1] gss_accept_sec_context() failed: An unsupported mechanism was requested (, Unknown error)

I don’t know what is it and what I should do to make it work.

My aim is to get REMOTE_USER to be filled by AD user name. But now I can’t do anything because of this error…

There was problem with principals. I recreated /etc/httpd/httpd.keytab and added HTTP principial correctly and all works fine!

I have discovered another reason for this error:
Windows tries to authenticate with NTLM. Actually that is the root of the problem.

I don’t understand how recreating the keytab helped, the error would then be something along the lines of “Key table entry not found”.
Windows tries to authenticate via NTLM when it cannot acquire a ticket from the KDC.
For me, the reason for that was that my server was not located within the same realm.
The domain was ad.domain.com, but my server was located at something.domain.com.
I am sure you can allow this somehow as well, but the easy fix is simply to change the hostname pointing to the server (and then creating a new keytab for that domain).

In a simple setup, using mod_auth_gssapi and FreeIPA as the krb5 server and to generate keytabs, I found out that adding the following next to the AuthType command addressed the issue.

BrowserMatch Windows gssapi-no-negotiate

Based on the answer from andsens, it seems indeed this is happening on Windows clients that try to use NTLM. GssapiAllowedMech krb5 and GssapiBasicAuthMech krb5 don’t give a successful outcome to the negotiation, so the only solution seems to be to disable the negotiation. I cannot guarantee this is accurate, though, but it worked for me.

The corresponding documentation is here

Tagged : / / /

Server Bug Fix: Nginx proxy SOAP request

Original Source Link

looking for a right way to accomplish the following:

there is an app that have URL(1) hardcoded and no way/time to change it in the source

http://dev.server.com/example.com/admin/soap/action/index?pr=1

and it should use (and get response from) URL(2)

http://example.com/admin/soap/action/index?pr=1

what should I configure in Nginx (apache as backup used) conf on dev.server.com in order to give that app when it asks URL(1) answer from URL(2)?

On dev.server.com Apache has virtual host: dev.server.com enabled.

Also I’ve tried to proxy in apache instead of nginx by using ProxyPass:

    <Directory /var/www/dev>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride all
            Order allow,deny
            allow from all
    </Directory>
    <Location /example.com/admin/soap>
       ProxyPass http://example.com/admin/soap
    </Location>

Try with this location in Nginx config file:

location /example.com/admin/soap/action/index {
   proxy_pass http://example.com/admin/soap/action/index;
}

A possible solution on apache is:

<Location /example.com/admin/soap/action/index>
   ProxyPass http://example.com/admin/soap/action/index
</Location>

Tagged : / /

Server Bug Fix: OpenSSL able to negotiate a cipher that isn’t supported

Original Source Link

We have to be a little limited with out cipher selection for various reasons, and one of the ciphers we can’t use is AES256-GCM-SHA384.

We can prove that that cipher is available with this command:

$ openssl s_client -cipher AES256-GCM-SHA384 -connect hostname:443

…which works fine on Centos 6.6, OpenSSL 1.0.1e-fips 11 Feb 2013. It connects and displays:

New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384

It doesn’t work from my Mac (OpenSSL 0.9.8zd 8 Jan 2015) or from the server itself (OpenSSL 1.0.1m 19 Mar 2015 (Library: OpenSSL 1.0.0d 8 Feb 2011)), in both cases returning a message like:

38200:error:1410D0B9:SSL routines:SSL_CTX_set_cipher_list:no cipher
match:/SourceCache/OpenSSL098/OpenSSL098-52.20.2/src/ssl/ssl_lib.c:1223

That the connection from Centos works is confusing to me, because running this on the (Solaris) server:

$ openssl ciphers | sed "s/:/\n/g" | grep -i gcm

…produces an empty list, as though GCM ciphers don’t exist. The same command on the Centos install lists a handful of selections.

The Apache instance is using the copy of OpenSSL that I’m looking at and not some other random one.

I suspect that I’m missing a key point. Does anyone have an idea of what might be going on?

You likely have two OpenSSL installations on your CentOS server.

Run the command ldd /usr/local/apache/modules/mod_ssl.so using the path to mod_ssl.so defined in your httpd.conf. This will return the libraries linked to mod_ssl.so. Are they using the same libraries as your system OpenSSL?

My guess is that your Apache is configured to use a different OpenSSL than the default system OpenSSL. This is why Apache can accept the AES256-GCM-SHA384 cipher, but your use of the system openssl command fails. Often times installations or upgrades of OpenSSL performed after the OS installation will get installed to /usr/local/ssl with the library folder at /usr/local/ssl/lib.

Tagged : /

Server Bug Fix: Independently config test an .htaccess file

Original Source Link

I know apachectl has the configtest option, but as far as I can tell it’s only for checking the entire config chain for the system apache. I would like to have a tool that can test an individual .htaccess file for errors as part of a continuous integration toolchain. Is there any way to do that with or without apachectl?

I came across few online tools to validate .htaccess Syntax/Directives and few basic things htaccess-validator and code syntax checker and validator.

PS: To narrow down analyses/error and speed up validation, limit the no. of Directives while validation.

Tagged : / /

Server Bug Fix: fastcgi_pass directory not available on Apache + Nginx, how to find it?

Original Source Link

I have a CentOS, Apache and Nginx installation. It uses php 5 handler as fcgi. This server uses WHM cpanel and easyapache. fcgi apply by using easyapache. These installation done by my hosting company. When I’m adding following code to Nginx vhost it giving me No such file or directory error.

    location ~ .php$ {
            try_files $uri /index.php;
            include fastcgi_params;
            fastcgi_pass unix:/var/run/php5-fpm.sock;

When I’m searching .sock file in the server, it don’t display .sock extension file. How to I find the correct fastcgi_pass directory and file in ths VPS?

My guess is that php-fpm daemon is certainly binded to a TCP port and not a Unix socket.

Open your www.conf file and check if you have something like this :

listen = 127.0.0.1:9000

and/or :

netstat -anp | grep -i fpm | grep -i listen
tcp     0      0 127.0.0.1:9000        0.0.0.0:*     LISTEN      2640/php-fpm

On my CentOS 6.5, file www.conf is located here : /etc/php-fpm.d/www.conf. It could be a different location on your system. Search for it !

If php-fpm is binded to a TCP port, you have 2 options :


Option 1 :

Keep your www.conf unchanged :

listen = 127.0.0.1:9000

But modify your Nginx vhost like this :

fastcgi_pass 127.0.0.1:9000;

Option 2 :

Keep your Nginx vhost unchanged :

fastcgi_pass unix:/var/run/php-fpm.sock;

But modify your www.conf like this :

;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock;

Tagged : / / / /

Server Bug Fix: Servicing ws:// in Node.js via Tomcat and Apache

Original Source Link

I’ve Googled various combinations of keywords but I cannot find a suitable description of what to do to get this to work. Currently, I have a web site running Apache 2 with everything except ports 80 and 443 blocked. I’ve set up Tomcat to route through :80 and :443 using:

<Location /tomcat/>
ProxyPass ajp://localhost:8009/tomcat/
Order allow,deny
Allow from all
</Location>

Furthermore, existing Node.js http[s] apps have also been successfully routed via code like this:

<Location /app_8201/>
ProxyPass http://localhost:8201/
</Location>

I’m running Apache/2.2.15, Tomcat 6 and Node.js v0.10.26 on CentOS under Azure. Websocket support is present as running sample apps referring localhost:9999 works OK. There looks as if there should be a ProxyPass ws://localhost:9999, but if I follow the instructions here:

<Location /ws/>
ProxyPass http://localhost:9999
ProxyPassReverse http://localhost:9999
</Location>

I get an HTTP 500 error trying to access the directory ws by either http or ws.

I use mod_proxy_ajp instead of mod_jk as it is my understanding the ajp is “better”.

WebSocket support first appeared in Apache 2.4.5 through the mod_proxy_wstunnel module, there is no support in previous versions like Apache 2.2.

The protocol must be explicitly selected via ws:// or wss://, the AJP and HTTP protocol modules for mod_proxy don’t know anything about WebSockets:

<Location /ws>
    ProxyPass ws://localhost:9999
    ProxyPassReverse ws://localhost:9999
</Location>

Tagged : / / /

Server Bug Fix: Apache failed to start with PrivateTmp=true after I changed the /tmp folder

Original Source Link

Apache service cannot start and I know the reason but not sure how to fix it:

Apache error:

 apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: failed (Result: exit-code) since Tue 2020-06-02 15:32:34 UTC; 3s ago
  Process: 1918 ExecStop=/usr/sbin/apachectl stop (code=exited, status=226/NAMESPACE)
  Process: 2028 ExecStart=/usr/sbin/apachectl start (code=exited, status=226/NAMESPACE)
 Main PID: 1609 (code=exited, status=0/SUCCESS)

Jun 02 15:32:34 ip-172-26-6-28 systemd[1]: Starting The Apache HTTP Server...
Jun 02 15:32:34 ip-172-26-6-28 systemd[2028]: apache2.service: Failed to set up mount namespacing: No such file or
Jun 02 15:32:34 ip-172-26-6-28 systemd[2028]: apache2.service: Failed at step NAMESPACE spawning /usr/sbin/apachect
Jun 02 15:32:34 ip-172-26-6-28 systemd[1]: apache2.service: Control process exited, code=exited status=226
Jun 02 15:32:34 ip-172-26-6-28 systemd[1]: apache2.service: Failed with result 'exit-code'.
Jun 02 15:32:34 ip-172-26-6-28 systemd[1]: Failed to start The Apache HTTP Server.

The error appeared when I created a symbolic link from /var/tmp to /tmp:

sudo mv /var/tmp /var/tmpold
sudo ln -s /tmp /var/tmp
sudo cp -prf /var/tmpold/* /tmp/
sudo rm -rf /var/tmpold/

The issue occurs because apache tries to mount it’s private dependencies in the /var/tmp but cannot do it because of the symbolic link.

The private dependencies are governed by this setting in apache2.conf file:

PrivateTmp=true

If I set PrivateTmp=false, apache starts without any issues.

The question is, how can I keep the PrivateTmp to true and still mount the private dependencies either in /var/tmp or /tmp folders?

Any suggestion will be appreciated!

Tagged : / / /

Server Bug Fix: How to do port forwarding from EC2 public IP to another EC2 IP?

Original Source Link

I’m running two apps on a single EC2 instance:

  1. Website on Apache running on Port 80
  2. Java Application on port 8080 which is used by my android app.

The way I access Java application by hitting the URL example.com:8080.

Now I want to move my Java application to java.example.com:8080 without changing the hostname example.com:8443 which is hardcoded inside my android app.

So is it possible for re-routing all requests coming to example.com:8080 to java.example.com:8080?

Thanks in advance for the help!

Tagged : / / /