Using go-websocket behind Apache mod_proxy_wstunnel - apache

Note: Updated config and added trailing slash to websocket path. Still same problem
Is it possible to use go-websocket behind a Apache reverse proxy with mod_proxy_wstunnel?
I tried and failed to get things working.
I tried to use the Chat example behind an Apache reverse proxy (with mod_proxy_wstunnel enabled). And it doesn't work. The proxy is a success, while the websocket part does not work at all.
My Apache config looks similar to this:
<VirtualHost *:80>
DocumentRoot /var/www/foobar
ServerName foobar.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyPass /ws/ ws://localhost:8080/ws/
ProxyPassReverse /ws/ ws://localhost:8080/ws/
ErrorLog logs/error_log-foobar
CustomLog logs/access_log-foobar common
LogLevel debug
</VirtualHost>
And of course I'm running the chat server on port 8080. I've tested it with SSH tunnel, and things work perfectly. Then I moved on to Apache.
The first time I tried, the javascript console complains this:
NetworkError: 403 Forbidden - http://foobar.com/ws/
The request seems to be stucked at the origin check.
Then I tried again after comment out the origin check, it get this:
NetworkError: 400 Bad Request - http://foobar.com/ws/
It seems the chat server do not get the upgrade request at all.
How should I debug this?
Where should I start looking?

Thanks everyone! After taking several advices above, I found the solution.
And for someone who might have similar issue, here is the solution to my question:
As Aralo suggested, trailing slash must be added to the WebSocket path (in my case: "/ws/"). It looks Apache will only handle WebSocket with a valid GET request.
James Henstridge was right. The order of ProxyPass relevant. ProxyPass of /ws/ must be put before the / line.
After consulting the Chat example code, I found an origin check in the function ServeWs() and removed.
Everything works now.
And thanks covener, reading logs does help.

I am using Go secure WebSocket (wss://) server behind Apache 2.4.18 on CentOS 7. Here are the settings:
Make sure the system has mod_proxy_wstunnel:
# find /usr/lib64/httpd/modules/ | grep ws
/usr/lib64/httpd/modules/mod_proxy_wstunnel.so
Add the following line in 00-proxy.conf:
# vim /etc/httpd/conf.modules.d/00-proxy.conf
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
Restart Apache:
# systemctl restart httpd
Check the setting:
# httpd -M | grep -iE 'proxy'
proxy_module (shared)
proxy_fcgi_module (shared)
proxy_http_module (shared)
proxy_wstunnel_module (shared)
Edit httpd-vhosts.conf:
# vim /etc/httpd/conf.d/httpd-vhosts.conf
<VirtualHost *:443>
ServerName go.mydomain.com:443
ProxyPreserveHost On
ProxyRequests off
SSLProxyEngine On
SSLCertificateFile "/etc/pki/tls/certs/mydomain.com/mydomain.crt"
SSLCertificateKeyFile "/etc/pki/tls/certs/mydomain.com/mydomain.key"
### The configured ProxyPass and ProxyPassMatch rules are checked
### in the order of configuration. The first rule that matches wins.
ProxyPassMatch ^/(ws(/.*)?)$ wss://192.168.0.1:443/$1
ProxyPass / https://192.168.0.1:443/
ProxyPassReverse / https://192.168.0.1:443/
ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
ServerName go.mydomain.com:80
ProxyPreserveHost On
ProxyRequests off
###
ProxyPassMatch ^/(ws(/.*)?)$ ws://192.168.0.1:80/$1
ProxyPass / http://192.168.0.1:80/
ProxyPassReverse / http://192.168.0.1:80/
ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
CustomLog "/var/log/httpd/go.mydomain.com-access_log" common
</VirtualHost>

Related

Apache, Issue routing a certain endpoint to a different port using Location

I'm trying to route any links that start with /api/ to port 3002 on my server but they always get routed to 3008. For example https://example.com/api/customers should be proxied/routed to localhost:3002
<VirtualHost *:443>
ServerAdmin (redacted)
ServerName (redacted)
ServerAlias (redacted)
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/(redacted)/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/(redacted)/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/(redacted)/chain.pem
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Location "/api\/(.*)/">
ProxyPass http://localhost:3002/
ProxyPassReverse http://localhost:3002/
</Location>
<Location "/">
ProxyPass http://localhost:3008/
ProxyPassReverse http://localhost:3008/
</Location>
</VirtualHost>
Using this config going to domain.com works and shows my website but domain.com/api/customers returns an error from the webapp on port 3008 so it's not being routed correctly (it should go to 3002).
The apps on port 3008 and 3002 are running correctly so that's not the issue.
I've tried putting domain/ first and domain/api last in the config file but that didnt seem to fix it. And the config file is enabled
I've tried different regexes to match the api endpoint aswell but this one should work
Apache is listening on port 443
These mods are enabled which should be needed for this:
proxy_module (shared)
proxy_http_module (shared)
proxy_wstunnel_module (shared)
Please let me know if you want any extra information
Modify your config as below and have a try.
Post the access log and curl response if not working.
curl -ILKv https://domain.name/api/anything
curl -ILKv https://domain.name/api
https://httpd.apache.org/docs/2.4/mod/mod_proxy.html
ProxyRequests Off
<Proxy *>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Proxy>
ProxyPass /api http://localhost:3002
ProxyPassReverse /api http://localhost:3002
I ended up solving it like this:
RewriteEngine on
RewriteRule "/api\/(.*)" "http://localhost:3002/api/$1" [P]
<Location "/">
ProxyPass http://localhost:3008/
ProxyPassReverse http://localhost:3008/
</Location>

Apache web server configuration - HTTP to HTTPS not working

I've been at this for two weeks now and still nothing. What's even odd is I've done this on a different server and it worked so I don't understand why this isn't working. Really frustrated here.
I'm trying to configure my apache web server on my RHEL so that HTTP requests are redirected to HTTPS when then points to my tomcat.
This is my configuration:
<VirtualHost *:80>
ServerName server.com
Redirect / https://server.com/
</VirtualHost>
<VirtualHost *:443>
ServerName server.com
ServerAlias www.server.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/pki/tls/certs/cert.cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/key.key.pem
#SSLCACertificateFile /etc/pki/tls/certs/ca-chain.cert.pem
</VirtualHost>
Believe me when I say I have tried so many different combinations yet nothing. I have commented and un-commented the Include conf.d/ssl.conf, still no effect.
Please, what am I doing wrong here?
First of all: "isn't working" is quite a weak description. I might or might not hit what your problem is, but I see several options:
First: Test if the forward works
Second: What's the result when you're connecting to the https server? You can try this without the forward - just type the https protocol yourself and figure out if you can rule out the forward configuration completely.
I've done this on a different server and it worked
You're forwarding to localhost:8080. If that other server had tomcat installed (and running) on port 8080, but the one that you're trying now doesn't - well, here's your solution. localhost is always "the same" computer.
As Ortomala Lokni mentions in a comment: Your ProxyPassReverse directive is lacking a /:
ProxyPassReverse / http://localhost:8080/
Note that with this configuration, tomcat will not know that the original request has been sent through https - thus any CONFIDENTIAL declaration on tomcat assumes that the request has been sent in the clear - and it will try to redirect to https. As the ProxyPass still forwards through http, Tomcat will never know that the request actually was encrypted. There are hacks to work around this (e.g. secure="true" on the connector configuration) or more proper solution (like forwarding through AJP instead of http)
ProxyPass / ajp://localhost:8009/
(notice the changed port)
There's potential for more going wrong - in case these hints don't help, please specify "isn't working" more.
thanks ever so much! Especially you, Olaf Kock. Your suggestion was golden! Just like you suggested, I decided to forget about the forwarding and focus on what happens when I try connecting to the HTTPS directly, and that's when I came across this error:
proxy: HTTP: disabled connection for (localhost)
I did a little search and found out that I had to run this command to get things rolling: /usr/sbin/setsebool -P httpd_can_network_connect 1
(Note, there are other variations of this command, like: setsebool -P httpd_can_network_connect on or sudo setsebool -P httpd_can_network_connect on)
Then I had to setup these in the ssl.conf file under the <VirtualHost _default_:443> tag:
ServerName server.com
ServerAlias www.server.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
And it worked!
However, I didn't want to have to reference the ssl.conf file. I wanted everything in the httpd.conf file, and so after tinkering a bit, this is what worked for me, and I believe should work for anyone with a similar problem.
So, after commenting out the include conf.d/ssl.conf line
LoadModule ssl_module modules/mod_ssl.so
Listen 443
#For HTTP requests, redirecting to HTTPS
<VirtualHost *:80>
ServerName server.com
Redirect / https://server.com/
</VirtualHost>
#For HTTPS requests
<VirtualHost *:443>
ServerName server.com
ServerAlias www.server.com
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/cert.cert.pem
SSLCertificateKeyFile /etc/pki/tls/private/key.key.pem
#SSLCACertificateFile /etc/pki/tls/certs/ca-chain.cert.pem
</VirtualHost>
Obviously, you should have installed your mod_ssl in the first place.
Thanks everyone!

Enable PUT and DELETE methods on Apache 2.4

I'd like to enable on my Apache 2.4 under linux the PUT and DELETE methods. When clients try to invoke such methods I get a "405 Method Not Allowed" as answer.
On server side my PHP script handle such requests but it seems filtered by the server itself (that's makes the difference from the similar already answered question - Moreover other questions seems to refers to an old version of Apache).
Can I manage some configurations on .htaccess file or I have to modify the .conf files under /etc/apache2?
Thanks a lot.
Try the following changes on your server:
Open "/etc/httpd/conf/httpd.conf" and look for the following blocks:
<Limit GET POST OPTIONS PROPFIND>
Order allow,deny Allow from all
</Limit>
<LimitExcept GET POST OPTIONS PROPFIND>
Order deny,allow Deny from all
</LimitExcept>
Then just add PUT and DELETE after PROPFIND. Then Restart httpd by "/sbin/service httpd restart" or service httpd restart.
Note: In some servers , mostly the ones with a control panel (DA,cPanel,..) you may change this file :/etc/httpd/conf/extra/httpd-directories.conf
I hope it solves your problem.
For Debian/Ubuntu.
In your conf:
<Location "/">
AllowMethods GET PUT
</Location>
In console:
sudo a2enmod allowmethods
sudo systemctl restart apache2.service
You can use allowmethods_module to enable that.
It's been available since apache version 2.3 but still experimental though.
<Location "/path/to/directory">
AllowMethods PUT DELETE
</Location>
I got the same error and the root cause is the redirects to https (80-443) are not occurring which one of the things are causing the docker client to fail while allowing the browser to work. I added below directives in Apache httpd (apache2) and it worked for me.
<VirtualHost *:80>
RedirectPermanent / https://%{SERVER_NAME}/
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key
# General setup for the virtual host
ServerName example.org
ServerAdmin help#example.com
ErrorLog /tmp/error_log
SSLProxyEngine On
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
ProxyPreserveHost On
ProxyPass / http://<BackendIP>/ connectiontimeout=10 timeout=3600
ProxyPassReverse / http://<BackendIP>/
</VirtualHost>

Apache redirect to another port

I've struggled with this for some time and am definitely doing something wrong.
I have Apache server and a JBoss server on the same machine. I'd like to redirect traffic for mydomain.example to JBoss localhost:8080/example. The DNS is currently setup for mydomain.example and it will go straight to port 80 when entered into the browser.
My question is how do I redirect to a different port when a certain domain name comes to Apache (in this case, mydomain.example)?
<VirtualHost ip.addr.is.here>
ProxyPreserveHost On
ProxyRequests Off
ServerName mydomain.example
ProxyPass http://mydomain.example http://localhost:8080/example
ProxyPassReverse http://mydomain.example http://localhost:8080/example
</VirtualHost>
After implementing some suggestions:
Still not forwarding to port 8080
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName mydomain.example
ServerAlias www.mydomain.example
ProxyPass http://mydomain.example http://localhost:8080/example
ProxyPassReverse http://mydomain.example http://localhost:8080/example
</VirtualHost>
You should leave out the domain http://example.com in ProxyPass and ProxyPassReverse and leave it as /. Additionally, you need to leave the / at the end of example/ to where it is redirecting. Also, I had some trouble with http://example.com vs. http://www.example.com - only the www worked until I made the ServerName www.example.com, and the ServerAlias example.com. Give the following a go.
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName www.example.com
ServerAlias example.com
ProxyPass / http://localhost:8080/example/
ProxyPassReverse / http://localhost:8080/example/
</VirtualHost>
After you make these changes, add the needed modules and restart apache
sudo a2enmod proxy && sudo a2enmod proxy_http && sudo service apache2 restart
I solved this issue with the following code:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName myhost.example
ServerAlias www.myhost.example
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
I also used:
a2enmod proxy_http
I wanted to do exactly this so I could access Jenkins from the root domain.
I found I had to disable the default site to get this to work. Here's exactly what I did.
$ sudo vi /etc/apache2/sites-available/jenkins
And insert this into file:
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName mydomain.example
ServerAlias mydomain
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
</VirtualHost>
Next you need to enable/disable the appropriate sites:
$ sudo a2ensite jenkins
$ sudo a2dissite default
$ sudo service apache2 reload
Found this out by trial and error. If your configuration specifies a ServerName, then your VirtualHost directive will need to do the same. In the following example, awesome.example.com and amazing.example.com would both be forwarded to some local service running on port 4567.
ServerName example.com:80
<VirtualHost example.com:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName awesome.example.com
ServerAlias amazing.example.com
ProxyPass / http://localhost:4567/
ProxyPassReverse / http://localhost:4567/
</VirtualHost>
I know this doesn't exactly answer the question, but I'm putting it here because this is the top search result for Apache port forwarding. So I figure it'll help somebody someday.
This might be an old question, but here's what I did:
In a .conf file loaded by Apache:
<VirtualHost *:80>
ServerName something.com
ProxyPass / http://localhost:8080/
</VirtualHost>
Explanation: Listen on all requests to the local machine's port 80. If I requested "http://something.com/somethingorother", forward that request to "http://localhost:8080/somethingorother". This should work for an external visitor because, according to the docs, it maps the remote request to the local server's space.
I'm running Apache 2.4.6-2ubuntu2.2, so I'm not sure how the "-2ubuntu2.2" affects the wider applicability of this answer.
You have to make sure that the proxy is enabled on the server. You can do so by using the following commands:
a2enmod proxy
a2enmod proxy_http
service apache2 restart
If you don't have to use a proxy to JBoss and mydomain.example:8080 can be "exposed" to the world, then I would do this.
<VirtualHost *:80>
ServerName mydomain.example
Redirect 301 / http://mydomain.example:8080/
</VirtualHost>
Just use a Reverse Proxy in your apache configuration (directly):
ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar
Look here for apache documentation of how to use the mod
My apache listens to 2 different ports,
Listen 8080
Listen 80
I use the 80 when i want a transparent URL and do not put the port after the URL
useful for google services that wont allow local url?
But i use the 8080 for internal developing where i use the port as a reference for a "dev environment"
You need 2 things:
Add a ServerAlias www.mydomain.example to your config
change your proxypass to ProxyPassMatch ^(.*)$ http://localhost:8080/example$1, to possibly keep mod_dir and trailing slashes from interfering.
Apache supports name based and IP based virtual hosts. It looks like you are using both, which is probably not what you need.
I think you're actually trying to set up name-based virtual hosting, and for that you don't need to specify the IP address.
Try < VirtualHost *:80> to bind to all IP addresses, unless you really want ip based virtual hosting. This may be the case if the server has several IP addresses, and you want to serve different sites on different addresses. The most common setup is (I would guess) name based virtual hosts.
This is working in ISPConfig too. In website list get inside a domain, click to Options tab, add these lines: ;
ProxyPass / http://localhost:8181/
ProxyPassReverse / http://localhost:8181/
Then go to website and wolaa :) This is working HTTPS protocol too.
Try this one-
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName www.adminbackend.example.com
ServerAlias adminbackend.example.com
ProxyPass / http://localhost:6000/
ProxyPassReverse / http://localhost:6000/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This is how I redirected part of the requests to one url and rest to another url:
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName localhost
ProxyPass /context/static/content http://localhost:80/web/
ProxyPassReverse /context/static/content http://localhost:80/web/
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
All are excellent insights to accessing ports via domain names on virtual servers. Do not forget, however, to enable virtual servers; this may be commented out:
NameVirtualHost *:80
<Directory "/home/dawba/www/">
allow from all
</Directory>
We run WSGI with an Apache server at the domain sxxxx.com and a golang server running on port 6800. Some firewalls seem to block domain names with ports. This was our solution:
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName wsgi.sxxxx.example
DocumentRoot "/home/dxxxx/www"
<Directory "/home/dxxx/www">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
ScriptAlias /py/ "/home/dxxxx/www/py/"
WSGIScriptAlias /wsgiprog /home/dxxxx/www/wsgiprog/Form/Start.wsgi
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName sxxxx.com
ServerAlias www.sxxxx.com
ProxyPass / http://localhost:6800/
ProxyPassReverse / http://localhost:6800/
</VirtualHost>

What is the simplest apache mod_proxy configuration for Glassfish?

I have a server with Apache2 (on port 80) and Glassfish (on port 8080). I'd like to configure Apache to transparently proxy al request to a certain virtual host to the glassfish Server.
I tried this, but it doesen't work:
<VirtualHost *>
ServerName tognettiimmobiliare.com
ServerAlias www.tognettiimmobiliare.com
ProxyRequests on
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyPass / http://tognettiimmobiliare.com:8080/tognettiWEB/
ProxyPassReverse / http://tognettiimmobiliare.com:8080/tognettiWEB/
</VirtualHost>
Can anybody tell me why? Thanks
I am proxying Jenkins and Redmine from a different port with mod_proxy, my configuration looks something like this, sans an additional <Proxy> part which I believe is not needed:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
ProxyPass /jenkins/ http://localhost:8080/jenkins/
ProxyPassReverse /jenkins/ http://localhost:8080/jenkins/
ProxyPass /redmine/ http://localhost:81/redmine/
ProxyPassReverse /redmine/ http://localhost:81/redmine/
There are two things to keep in mind:
The context needs to be the same in both proxy and proxied URLs, like /jenkins/ and .../jenkins/
You should not use external URLs for the proxied page because it will then try to route out to the internet and connect from there, this is slow and firewalls might block the port. Use local machine names or IPs.
I use a simple VirtualHost like so which works.
<VirtualHost *:80>
# ServerName www.itmanx.com
ProxyPass / http://www.itmanx.int/
ProxyPassReverse / http://www.itmanx.int/
</VirtualHost>
make sure you have mod_proxy and mod_proxy_http loaded
I enabled JK on Glassfish by going to Configurations -> server-config -> HTTP Service -> Http Listeners -> jk-listener and enabled it.
Then set up the in my Apache config to proxy this way so the SSL data also gets transmitted.
<Location /util>
SSLOptions +StdEnvVars +ExportCertData
ProxyPass ajp://localhost:8004/util
</Location>
One caveat though, mod_proxy_wstunnel does not seem to work with this or at least I haven't found out how to yet since I use WSS and https://issues.apache.org/bugzilla/show_bug.cgi?id=55320 needs 2.4.10 which is not released yet.