Expose port on all interfaces using Webrick - ruby

I am new to Ruby.
I am working with a script that deploys a HTTPServer using WEBrick.
When the script runs, it logs out :
check_1 | [2018-12-20 17:51:47] INFO WEBrick::HTTPServer#start: pid=1 port=4567
When I do a netstat on the machine, I notice that the service is listening only on 127.0.0.1
$ netstat -tulpn
root#c4a20aa7bd8c:/opt/service# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:4567 0.0.0.0:* LISTEN 1/ruby1.9.3
I want to listen on all the IPs so that I can communicate with this service from another container.
How or what configs will be necessary ?
My script definition for the server is :
#!/usr/bin/ruby
require 'rubygems'
require 'sinatra'
require 'sinatra/reloader' if development?
also_reload 'config.yml'
require "sinatra/config_file"
require 'mechanize'
require "json"
require 'open-uri'
require 'mongo'
require 'uri'
require 'addressable/uri'
require 'cgi'
include Mongo
require 'nokogiri'
set :server, 'webrick'

The answer you're looking for is in the Sinatra config docs: http://sinatrarb.com/configuration.html
Specifically the :bind option. Example: set :bind, '0.0.0.0'

Related

Can't access sinatra service outside of container

I am getting ERR_EMPTY_RESPONSE in the browser after lunching the Sinatra container in docker. If I connect to the docker container and run curl localhost:4567 it works, but outside of the container - doesn't
web.rb
require 'sinatra'
set :bind, '0.0.0.0'
get '/' do
'Hello world!'
end
Dockerfile
FROM ruby:3.0.2
EXPOSE 4567
COPY ./web.rb .
RUN gem install sinatra
RUN gem install puma
CMD ["ruby", "web.rb"]
The solution was in binding application to 0.0.0.0 host
require 'sinatra'
set :bind, '0.0.0.0'
get '/' do
'Hello world!'
end

How to make Sinatra listen on two ports with socat

I had a classical Sinatra application which was accessible on two ports. After migrating it to modular style the second port is not working anymore.
My initial implementation was:
require 'sinatra'
set :port, 8080
set :bind, '0.0.0.0'
----some routes-----
...
The resulting implementation was:
require 'sinatra/base'
require_rel 'lib'
class MyApp < Sinatra::Base
register Sinatra::SomeRegister
helpers Sinatra::SomeHelper
set :port, 8080
set :bind, '0.0.0.0'
----some routes-----
...
run!
end
The application is run using:
socat tcp-l:8181,fork,reuseaddr tcp:localhost:8080 &
ruby /path/my_app.rb
The application doesn't respond on port 8181 anymore.
The fix was to install socat first:
apt-get update && apt-get --allow-unauthenticated -y install socat

How to run Sinatra App in Passenger with Nginx?

I'm trying to run a very simple Sinatra app using my existing Nginx & Passenger setup. I'm familiar with running Rails on Passenger but this is my first time setting up Sinatra.
I've installed Sinatra through bundler and RVM. Take a look at my configuration and tell me what I'm doing wrong.
Nginx conf:
server {
listen 80;
server_name demo.my-example.com;
root /home/user/demo.my-example.com/sinatra;
passenger_ruby /usr/local/rvm/wrappers/ruby-2.3.1#my_gemset/ruby;
passenger_enabled on;
}
/home/user/demo.my-example.com/sinatra/config.ru
require 'rubygems'
Gem.clear_paths
disable :run, :reload
set :environment, :production
require "./stripe"
run StripeApp
/home/user/demo.my-example.com/sinatra/stripe.rb
require 'sinatra/base'
class StripeApp < Sinatra::Base
get '/' do
"Hello world"
end
end
/home/user/demo.my-example.com/sinatra/config.ru
require 'rubygems'
Gem.clear_paths
require "./stripe"
run StripeApp

Why isn't my Sinatra app working with SSL?

Alright so, I decided to make sure i can get this ssl stuff working BEFORE building the api.. and I feel 95% of the way there.
So, I have a cert and key from namecheap. All should be good there.
Here is my app.rb
require 'sinatra/base'
require 'webrick'
require 'webrick/https'
require 'openssl'
class MyServer < Sinatra::Base
set :bind, '0.0.0.0'
get '/' do
"Hello, world!\n"
end
end
CERT_PATH = './ssl'
webrick_options = {
:Port => 443,
:Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
:DocumentRoot => "/ruby/htdocs",
:SSLEnable => true,
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
:SSLCertificate => OpenSSL::X509::Certificate.new( File.open(File.join(CERT_PATH, "server.crt")).read),
:SSLPrivateKey => OpenSSL::PKey::RSA.new( File.open(File.join(CERT_PATH, "server.key")).read),
:SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ],
:app => MyServer
}
Rack::Server.start webrick_options
I run the program with
sudo ruby app.rb
And what's interesting is, on localhost (testing from my macbook pro, running El Capitan) i can access https://localhost and it just says the cert isn't trusted, and asks if I want to go in anyway. Great.
My ec2 instance, however, I can now access via a domain name, one that matches the cert of course. But the site just returns a ERR_CONNECTION_REFUSED (this is what displays in chrome)
But of course, that shows whether or not I run the sinatra server.
Ok, so it sounds easy. Security group, right?
Well, according to ec2, I'm using a security group that has tpc port 443 enabled on inbound. (HTTPS)
So, what gives? What am I not doing right? Why does it do what I expect on localhost but not on the ec2 instance?
Any help would be super appreciated.
Other information:
The server does appear to be running. sudo ruby app.rb gives me valid info about my cert, followed by
[2016-01-22 03:36:52] DEBUG WEBrick::HTTPServlet::FileHandler is mounted on /.
[2016-01-22 03:36:52] DEBUG Rack::Handler::WEBrick is mounted on /.
[2016-01-22 03:36:52] INFO WEBrick::HTTPServer#start: pid=2499 port=443
If I remove webrick and change the port to 80, everything works fine. I can access this app from my site's domain, on http (not https) of course.
From the local machine, I am getting a response.
$ wget https://localhost
--2016-01-22 04:11:48-- https://localhost/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:443... connected.
ERROR: cannot verify localhost's certificate, issued by ‘/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA’:
Unable to locally verify the issuer's authority.
ERROR: no certificate subject alternative name matches requested host name ‘localhost’.
To connect to localhost insecurely, use `--no-check-certificate'.
This seems correct! So, it does seem to be something with the server setup. I can't connect to it. =/ Again. Security group allows 443 and 80.
Things added since I asked the question originally, but still hasn't fixed the issue:
set :bind, '0.0.0.0'
Generally you don't want any ruby webservers actually handling SSL. You make them serve plain HTTP (that is accessible only via localhost). Then you install a reverse proxy that handles all of the SSL communicate.
For example
Install nginx (reverse proxy) and configure it to listen on port 443.
Set your
ruby app server to listen on port 127.0.0.1:80 (accept local
connections only)
All requests hit nginx, which strips the SSL,
and send the plain HTTP request to your ruby webserver.
A very simple nginx config to get you started:
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/your.key;
ssl on;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
server {
listen 443 ssl;
server_name you.example.com;
location / {
proxy_pass http://localhost:8080; # your ruby appserver
}
}

Sinatra Heroku PostgreSQL connection bad

I get "connection bad" when I try to connect to my PostgreSQL database from my Sinatra application. I'm using Heroku to deploy the app and my workstation is currently Windows. i tried, still same error message:
heroku addons:create heroku-postgresql:hobby-dev
From the log:
PG::ConnectionBad - could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
From config/enviironments.rb:
db = URI.parse(ENV["DATABASE_URL"] || "postgres://localhost")
ActiveRecord::Base.establish_connection(
:adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme,
:host => db.host,
:username => db.user,
:password => db.password,
:database => db.path[1..-1],
:encoding => 'utf8'
)
This is the main app.rb file:
require 'sinatra'
require 'haml'
require 'sass/plugin/rack'
require 'pony'
require 'active_record'
require 'pg'
require 'postgresql'
require './vars.rb'
require './includes/functions'
require './config/environments'
Sass::Plugin.options[:style] = :compressed
use Sass::Plugin::Rack
set :haml, :format => :html5
get '/admin' do
admin_haml :'admin/index'
end
get '/admin/users' do
admin_haml :'admin/users'
end
This is the function to test PostgreSQL:
def dbdeb
conn = PG.connect :user => "postgres"
output = conn.server_version
conn.close
return output
end
This is the gemfile:
source 'http://rubygems.org'
ruby '2.2.3'
gem 'sinatra', '1.1.0'
gem 'haml', '4.0.7'
gem 'sass', '3.4.20'
gem 'activerecord','4.2.5'
gem 'sinatra-activerecord'
gem 'pg'
gem 'postgresql'
gem 'pony','1.11'
What did I do wrong?
It looks as if you do not have a DATABASE_URL environment variable defined for your Heroku app.
Try running the following command to see what environment variables are set on your Heroku app:
$ heroku config
This should list what variables are available. As you will see, there is no DATABASE_URL variable set.
To set this variable, you need to create a Heroku Postgres database:
$ heroku addons:create heroku-postgresql:hobby-basic
This will create two environment variables in your Heroku app:
DATABASE_URL
HEROKU_POSTGRES_COLOR
You can find more about this in the Heroku postgres docs: https://devcenter.heroku.com/articles/heroku-postgresql#create-a-new-database

Resources