Trying to run Faye websocket on Apache using a proxy - ruby-on-rails

I'm trying to use Faye gem on thin server with Rails in a production environment but I cannot make it work. I'm using apache 2.4 and ws_tunnel also proxy modules are enabled. My setup is like below.
Apache configuration
<VirtualHost *:443>
ServerName mysite.example.com
ServerAlias mysite.example.com
DocumentRoot /var/www/html/mysite/current/public
SSLEngine on
SSLCertificateFile "/etc/httpd/conf/keys/ServerCertificate.cer"
SSLCertificateKeyFile "/etc/httpd/conf/keys/example.com.key"
SSLCertificateChainFile "/etc/httpd/conf/keys/CACertificate-1.cer"
RewriteEngine On
SSLProxyEngine On
ProxyRequests off
ProxyPreserveHost on
ProxyPass /faye !
ProxyPassReverse /faye !
ProxyPass / balancer://thinservers/
ProxyPassReverse / balancer://thinservers/
<Proxy *>
Require all granted
</Proxy>
<Location /faye>
ProxyPass ws://localhost:9292
ProxyPassReverse ws://localhost:9292
</Location>
RequestHeader set X_FORWARDED_PROTO 'https'
# Custom log file locations
ErrorLog /etc/httpd/logs/error-unilever.log
CustomLog /etc/httpd/logs/access-unilever.log combined
</VirtualHost>
Faye.ru file
require 'faye'
Faye::WebSocket.load_adapter('thin')
app = Faye::RackAdapter.new(:mount => '/faye', :timeout => 25)
run app
And I'm starting faye with the following command
rackup faye.ru -E production -s thin
This way I can reach the faye.js by typing the following url from the browser.
https://mysite.example.com/faye/faye.js
But When I type https://mysite.example.com/faye/ for example, I get the following result
Sure you're not looking for /faye ?<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at
root#localhost to inform them of the time this error occurred,
and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
which is strange because I only get "Sure you're not looking for /faye ?" in the development.
I'm calling the Faye in application.js as
client = new Faye.Client("https://mysite.example.com/faye/faye")
And I get an error like
POST https://mysite.example.com/faye/faye 400 (Bad Request)
I also tried to use the wss protocol in the proxy settings and also giving my certificate paths to thin to start with SSL but nothing worked.
I assume this may be happening because of the proxy or the ws_tunnel module because when I run the following command from the shell in the server
curl http://localhost:9292
I get only "Sure you're not looking for /faye ?" message.
Does anyone came accross something like this?
I would appreciate if someone could help me.
Thanks in advance.

For those who's having the same issue, my advice is to no matter which version of Apache you are using, just change it to nginx without any hesitation. It's been very easy to configure and run it.
I'm using the below configuration for my app named example. After setting up nginx correctly, everything else worked quite well.
hope this helps someone
# app: example
# locally running on port 7000
upstream example {
server 127.0.0.1:7000;
server 127.0.0.1:7001;
}
# Faye is set to run on port 9292
upstream example_socket{
server 127.0.0.1:9292;
}
server {
# listen 80 if it's a non SSL site
listen 443;
server_name www.example.com;
location /faye {
proxy_pass http://example_socket;
# Including common configurations
include /etc/nginx/conf.d/proxy.conf;
include /etc/nginx/conf.d/proxy_socket.conf;
}
location / {
root /var/www/vhost/example/current/public;
proxy_pass http://example;
# Including common configurations
# can be found on Internet easily
include /etc/nginx/conf.d/proxy.conf;
}
}

Related

Load Balancer Health Check After Applying AWS SSL certificates

I created a load balancer with autoscaling group. It was working really fine until i applied SSL certificates and redirected the traffic to HTTPS. The load balancer health check is http one and i cannot move that check over to https because the certificates are applied on load balancer. So the current stack is Rails 4.2 , operating system is ubuntu, http entertainer is nginx and i have 5 instances running on Load Balancer. So i created a redirect on nginx like below
if ($scheme = http) {
return 301 mydomain.com$request_uri;
}
Then i tried this
if ($request_uri != "/public/health.html" ) {
set $balancer P;
}
if ($scheme = http) {
set $balancer "${balancer}C";
}
if ($balancer = PC) {
return 303 mydomain.com$request_uri;
}
With these redirections my site went down and on browser i was having an error of multiple redirections. This issue is making me crazy. Kindly please help. Your help will be appreciated a lot. Thanks
I had the exact same problem with my tomcat server (instances) and apachae server (load balancer). I also was getting multiple redirects in browser. I did two things:
Changed Load balancer listeners:
Changed a little in apache config:
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule ssl_module modules/mod_ssl.so
Listen 443
<VirtualHost *:80>
<Proxy *>
Order deny,allow
Allow from all
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
Rewriterule ^(.*)$ https://www.example.com/ [L,R=301]
</Proxy>
RequestReadTimeout header=35 body=35
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
<VirtualHost *:443>
RequestReadTimeout header=35 body=35
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
SSLEngine on
SSLCertificateFile /path/where/cert/stored/2_example.com.crt
SSLCertificateKeyFile /path/where/cert/stored/private-key.pem
SSLCertificateChainFile /path/where/cert/stored/1_root_bundle.crt
ErrorLog /var/log/httpd/elasticbeanstalk-error_log
</VirtualHost>
I kept port 80 opened for health checks and 443 for site. This configuration might help you. Do let me know if you were able to solve your problem.
Very short and effective solution, that will work 100% on any AWS settings. Put this in your application controller.
before_filter :move_to_https if RAILS.env == "production"
def move_to_https
redirect_to request.url.gsub("http","https") unless request.url.include?("https")
end
This will convert any domain traffic to https and ip's will never be exposed via load balancer.
Something like this in your nginx configuration should work:
server {
listen 80;
server_name www.example.com;
location = /public/health.html {
return 200;
}
location / {
return 301 https://$http_host$request_uri;
}
}

Redirect loop when connecting to Gerrit

I'm attempting to get Gerrit running behind an Apache 2.2.15 proxy and running into a redirect loop when I try to connect. Am I missing something?
[2013-11-26 07:44:04,701] INFO com.google.gerrit.sshd.SshDaemon : Started Gerrit SSHD on *:29418
[2013-11-26 07:44:04,706] INFO org.eclipse.jetty.server.Server : jetty-8.1.7.v20120910
/tmp/gerrit_1340818739918966007_app/gerrit_war/}
[2013-11-26 07:44:06,211] INFO org.eclipse.jetty.server.AbstractConnector : Started SelectChannelConnector#127.0.0.1:8081
[2013-11-26 07:44:06,213] INFO com.google.gerrit.pgm.Daemon : Gerrit Code Review 2.8-rc2 ready
Apache Config:
Listen 8083
<VirtualHost *:8083>
ServerName host.domain.com
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Location "/gerrit/login/">
AuthType shibboleth
ShibRequestSetting requireSession 1
Require valid-user
</Location>
RequestHeader set REMOTE_USER %{REMOTE_USER}s
ProxyPass /gerrit/ http://localhost:8081/gerrit/
</VirtualHost>
gerrit config:
[gerrit]
canonicalWebUrl = http://host.domain.com:8083/gerrit/
[auth]
type = HTTP
httpHeader = REMOTE_USER
[httpd]
listenUrl = proxy-http://127.0.0.1:8081/gerrit/
There are two things I notice in your setup
You try to have the Location on the gerrit/login/. This is not going to work as Gerrit will require the authentication details to be present.
You are missing the AllowEncodedSlashes On and nocanon statement. But I am not sure if this is only applicable to Apache 2.4 that I am using
This is part of my configuration:
AllowEncodedSlashes On
ReWriteEngine On
ProxyPass /gerrit http://localhost:8081/gerrit nocanon
Your gerrit.config looks ok.

Apache2 Configuration That Allows a Subdomain Point to an Machine:Port

I own the domain, "peterlee.com.cn", and I added an A Record in my domain control panel:
RR Destination IP TTL
rs.peterlee.com.cn 10.50.10.75 1 hour
I have an RoR (Ruby on Rails) project running on 10.50.10.75:9051, which means the user can visit my RoR application by http://10.50.10.75:9051
I want to let the user visit it by http://rs.peterlee.com.cn, so I added the following VirtualHost File/Site:
<VirtualHost *:80>
ServerName rs.peterlee.com.cn
DocumentRoot /usr/website/myapp/current/public
PassengerEnabled off
ProxyPass / http://127.0.0.1:9051/
ProxyPassReverse / http://127.0.0.1:9051/
RackEnv production
RailsEnv production
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect all requests to the maintenance page if present
RewriteCond %{REQUEST_URI} !\.(css|gif|jpg|png)$
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [L]
</IfModule>
</VirtualHost>
After enabling the site and restarting the Apache2, I tried http://rs.peterlee.com.cn, it gives me the 500 Internal Server Error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, [no address given] and inform them of the time the error occurred, and anything you might have done that may have caused the error.
More information about this error may be available in the server error log.
Apache/2.2.22 (Ubuntu) Server at rs.peterlee.com.cn Port 80
Thanks.
Peter
I found the following warning in /var/log/apache2/error.log:
[Thu Jul 19 10:22:20 2012] [warn] proxy: No protocol handler was valid for the URL /. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
[Thu Jul 19 10:22:20 2012] [warn] proxy: No protocol handler was valid for the URL /favicon.ico. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
So I enable the following modules:
sudo a2enmod proxy proxy_balancer proxy_http
After restarting Apache2, it worked!
Thanks anyway.
BTW: I start the service using Passenger:
passenger start -a 127.0.0.1 -p 9051 -e production -d

Apache crashing when I add Far-Future Expires clause from Rails Guide

In an attempt to serve my precompiled assets with Apache, per this Rails Guide I try to change this:
<VirtualHost *:82>
ServerName localhost
DocumentRoot "C:/RubyStack-3.2.5-0/projects/release_checklist/public"
<Directory "C:/RubyStack-3.2.5-0/projects/release_checklist/public">
Allow from all
Options -MultiViews
</Directory>
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPreserveHost On
</VirtualHost>
To this:
<VirtualHost *:82>
ServerName localhost
DocumentRoot "C:/RubyStack-3.2.5-0/projects/release_checklist/public"
<Directory "C:/RubyStack-3.2.5-0/projects/release_checklist/public">
Allow from all
Options -MultiViews
</Directory>
ProxyPass / http://localhost:3001/
ProxyPassReverse / http://localhost:3001/
ProxyPreserveHost On
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
</VirtualHost>
in my httpd.conf file. However, the Apache server won't start when the second option has been added. What am I doing wrong?
What error does it give you? Are you sure you have mod_expires compiled into apache and that the module is loaded?
Invalid command 'ExpiresActive', perhaps misspelled or defined by a module not included in the server configuration
Yeah, that's usually the error you get if you use a directive that's mapped to a module that isn't loaded (or just a mispelled directive, which appears the same to apache). You'll need to check httpd.conf and make sure the LoadModule expires_module modules/mod_expires.so line is not commented out, of if it's missing, to add it. Depending on your apache's version, the line can be slightly different.

How can I get my app running with InstantRails 1.0 on windows

I'm trying to get my application to run on InstantRails 1.0. The application works fine using WeBrick, but when I try to run it using Apache in InstantRails, I get:
[Wed May 26 12:26:53 2010] [error] [client 127.0.0.1] couldn't spawn child process: c:/instantrails-1.0/rails_apps/guest/public/dispatch.cgi
In the apache error log, and my browser shows:
Application error
Rails application failed to start properly"
The cookbook application that comes with InstantRails works just fine.
My apache config looks like:
<VirtualHost *>
ServerName guest.havelick.com
# handle all requests through SCGI
SCGIMount /dispatch.fcgi 127.0.0.1:9999
DocumentRoot ${path}/rails_apps/guest/public
<Directory ${path}/rails_apps/guest/public>
Options +FollowSymLinks
Order allow,deny
allow from all
</Directory>
AddDefaultCharset utf-8
ErrorDocument 500 /500.html
ErrorDocument 404 /404.html
</VirtualHost>
and the SCGI port matches that which I am using in the InstantRails config.
What can I do to troubleshoot this?
I figured this out. The default .htaccess file has:
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
Whereas InstantRails expects:
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

Resources