Apache mod_proxy_uwsgi and unix domain sockets - apache

I have a uwsgi server running for unix domain socket
[uwsgi]
...
socket = /var/run/someuwsgi.sock
socket = localhost:9987
...
The mod_proxy_uwsgi is installed
In apache config has that line:
ProxyPass /some uwsgi://localhost:9987
And it is working.
Question: what should be the apache config line to go through unix domain socket
/var/run/someuwsgi.sock
?
I tried
ProxyPass /some uwsgi:///var/run/someuwsgi.sock
and got
Bad Request
Your browser sent a request that this server could not understand.
Also tried
ProxyPass /some uwsgi://unix:///var/run/someuwsgi.sock
and got
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /some/.
Reason: DNS lookup failure for: unix:
Thanks!

Starting from Apache 2.4.7, support for Unix sockets has been added. The syntax is pretty simple:
ProxyPass / unix:/tmp/uwsgi.sock|uwsgi://

Unfortunately the apache proxy api does not (currently) support unix sockets

From the comments on the other answer and my experience this seems to be the correct syntax:
ProxyPass /some unix:/var/run/someuwsgi.sock|uwsgi://localhost
https://httpd.apache.org/docs/trunk/en/mod/mod_proxy.html#proxypass
In 2.4.7 and later, support for using a Unix Domain Socket is available by using a target which prepends unix:/path/lis.sock|. For example, to proxy HTTP and target the UDS at /home/www.socket, you would use unix:/home/www.socket|http://localhost/whatever/. Since the socket is local, the hostname used (in this case localhost) is moot, but it is passed as the Host: header value of the request.

Related

Using Apache to route gRPC calls to gRPC server

I am having trouble connecting to my gRPC server through anything but the port its running on. I am using Apache/2.4.54.
In my Apache config I have the following lines:
Protocols h2 http/1.1
ProxyPass /rpc h2://127.0.0.1:5051
ProxyPassReverse /rpc https://127.0.0.1:5051
Any time I try to connect my client to the server at example.com/rpc, I get code 14 DNS resolution failed. I can connect and run a method just fine when I use example.com:5051. Any insight as to whats going wrong here?

How to use Apache as a reverse-proxy for WebSockets with Undertow as the server

I have WebSockets enabled using an Undertow server. When I run the Undertow server directly, WebSockets work well. I serve my pages using HTTPS and I test the endpoint using "wss:" in javascript: it works.
But now, I try to use Apache as a reverse proxy and I want it to let WebSocket connections reach the Undertow server. This is my current Virtual Host:
<VirtualHost *:80 *:443>
ServerName test.example.org
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.org/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.org/chain.pem
ProxyPass / http://test.example.org:44444/
ProxyPassReverse / http://test.example.org:44444/
</VirtualHost>
Here, Undertow is started as a HTTP server (not HTTPS) on port 44444 and the SSL security is done by Apache.
All the HTML pages work well, but when I try to start a WebSocket connection, I get this error (Chrome) :
WebSocket connection to 'wss://test.example.org/websockets/echo' failed: Error during WebSocket handshake: 'Upgrade' header is missing
And, when I look at the Network tab, I see that indeed two headers are missing in the response from the server, when the "wss://" call is made: "Connection: Upgrade" and "Upgrade: WebSocket". Those headers are present when I connect to Undertow directly, without Apache.
The "Sec-WebSocket-Accept" and "Sec-WebSocket-Location" headers are there but, and I guess this is a second issue, "Sec-WebSocket-Location" is 'ws://test.example.org/websockets/echo' not 'wss://test.example.org/websockets/echo' since Undertow runs on HTTP, not HTTPS.
Last thing, the mod_proxy_wstunnel documentation says "The connection is automatically upgraded to a websocket connection". What does this mean? Apache is upgrading the HTTP connection to a WebSocket connection by itself? This is not what I want! I want to handle the initial HTTP request and the upgrading processes by myself, using Undertow. I use informations from the initial HTTP connection to validate if the user can be connected to the requested endpoint and, if so, I programmatically call Undertow's WebSocketProtocolHandshakeHandler#handleRequest(exchange) to upgrade to a WebSocket connection. I just want Apache to let everything pass without interfering.
Any help on how to run WebSockets using Undertow behind an Apache reverse-proxy?
I got tired and decided to try Nginx.
Within 3 hours, not only did I get WebSockets working, but all my sites on a server were moved to it. Super easy.
The magical lines for WebSockets, in nginx.conf, are:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
I understand that "Upgrade" is a special "hop-by-hop" header which has to be explicitly configured to be kept.
I hope there is a similar solution for Apache, but man, there is so few documentation about this!

Monit only using HTTP for HTTPS website

I'm trying to monitor a VHost on the local Apache instance via Monit. The same domain accepts both http and https traffic, so I wanted to monitor both.
Also, the IP that the domain resolves to goes to a server that load balances the traffic between the current Apache instance and another server running Apache. I need Monit to monitor the local instance, and I was hoping to avoid adding any records in the /etc/hosts file, so I was thinking that Monits config setting with http headers [] would suffice, and I think it is (Just monitoring localhost, but setting the headers Host to the vhost domain).
Anyways, the main problem I seem to be running into, is even though I configure Monit to monitor the host via both http and https protocols, it monitors both hosts via just http, however the port is set to 443 for the one I need using https protocol.
The Monit config file for Apache is:
check process httpd with pidfile /var/run/httpd/httpd.pid
start program = "/bin/systemctl restart httpd.service" with timeout 60 seconds
stop program = "/bin/systemctl stop httpd.service"
check host localhost with address localhost
if failed
port 80
protocol http
with http headers [Host: www.domain.com, Cache-Control: no-cache]
and request / with content = "www.domain.com"
then restart
if failed
port 443
protocol https
with http headers [Host: www.domain.com, Cache-Control: no-cache]
and request / with content = "www.domain.com"
then restart
if 5 restarts within 5 cycles
then timeout
And here's the Monit status for that check:
[root#server enabled-monitors]# monit status localhost
The Monit daemon 5.14 uptime: 14m
Remote Host 'localhost'
status Connection failed
monitoring status Monitored
port response time FAILED to [localhost]:443/ type TCPSSL/IP protocol HTTP
port response time 0.001s to [localhost]:80/ type TCP/IP protocol HTTP
data collected Tue, 26 Apr 2016 10:44:32
So it's fairly obvious to me that the https is failing because its still trying to use port HTTP, even though I have protocol https in the configuration.
Any input would be much appreciated. I have a feeling this may be a bug, and ill create an issue in the Monit Github repo, but I wan't to make sure it's not something silly that I overlooked.
Thank you!
Late reply here, but I thought I would still post for readers who stumbled upon the same issue.
The problem seems to be not with Monit using port HTTP despite check configured for HTTPS. It always reports HTTP protocol in status (a display bug).
The real issue is likely with Monit not supporting SNI for SSL, so it ignores the with http headers [Host: www.domain.com ... in your https check. Thus the check fails because Monit is actually testing https://localhost.
I've filed bug with Monit developers here.

reverse proxy apache to localhost server

I've got a web app running on localhost:3000. I also have an apache server. I would like to reverse proxy the apache server so that requests to /mywebapp get forwarded to the server running on localhost:3000.
I currently have the following config at the bottom of my httpd.conf file, but I'm getting a server error when I try to access it:
ProxyPass /mywebapp http://localhost:3000
ProxyPassReverse /mywebapp http://localhost:3000
Edit - further details:
I'm running a jetty server with java -jar myapp.jar. I'd like to forward requests to an apache server listening on :80 to the jetty server.
I've got mod_proxy_http.so and mod_proxy.so enabled.
I can tell the server is running on localhost - it responds to curl with the appropriate http response. So I'm pretty sure the issue is with my apache setup, but I can't think what the problem would be.
Apache conf file in conf.d for reference: http://pastebin.com/vhXwjbQe
And I've got this in my httpd.conf:
Include conf.d/*.conf
It's hard to give a generic answer because every situation is different so here are some debugging questions to ask yourself:
if the protocol and port correct on the internal service, http and 3000.
Is the service actually listening for connections from localhost? is it running in a docker container etc that would require it to be listening on a different interface? You can check for this by looking at the output from mywebapp's logs and see if the request are making it through the proxy.
Do the paths on the internal service include the prefix that is being passed to Apache or does apache need to strip these off. if for instance mywebapp expects the path "/foo/bar" and apache's reverse proxy is sending it with the context path included "/mywebapp/foo/bar" then it will not match any path in mywebapp.

How can I forward websocket request to Apache Tomcat from Apache httpd?

I have server setup like Apache2 + mod_jk + two instances of Tomcat (7.0.33). Now I am using atmosphere with tomcat. Atmosphere with long-polling is working just fine. But now I want to use web sockets as transport protocol in atmosphere. But it seems Apache is unable to forward request to Tomcat and it gives me error
Can't establish a connection to the server at ws://localhost/Myapp/update/?X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=1.1&X-Atmosphere-Transport=websocket&X-Cache-Date=0&Content-Type=application/json.
Since Apache 2.4.6, Apache httpd forwards/proxies websockets
Mod_Jk implies in the translation of the request from the HTTP into AJP/13 protocol which implies that the web server should have some ability to handle/process the request.
You may be better served by using mod_proxy instead to establish the apache-tomcat communication.
Apache doesn't support WebSocket, so you need to use Ningx or HAProxy.
I think you can do it using a module called mod_proxy_wstunnel
https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
I don't think this existed when the question was originally asked. In version 2.4.5 Apache added support for this mod.