This add-on is operated by Pirateradio
Route outbound traffic from your app through a static IP address.
Proximo
Last updated June 02, 2023
Table of Contents
Proximo does not provide any inbound access to an application.
Because the Heroku dyno grid is dynamic in nature, the IP address that a given dyno will be assigned over time will be both dynamic and unpredictable. This dynamic sourcing of outbound traffic can make it difficult to integrate with APIs or make connections through firewalls that require IP-based allowlisting.
Proximo overcomes this limitation by providing a known, static IP address and a tunnel through which your app can send outbound traffic so that it is always sourced from your assigned IP. You can then provide this IP address to an API partner or use it to form the basis of inbound firewall rules to connect to a protected resource such as an internal API or database.
Provisioning the Proximo add-on
Proximo can be attached to a Heroku application via the CLI:
A list of all available plans can be found here.
$ heroku addons:create proximo:development
Adding proximo to sharp-mountain-4005... done, v18 ($5/mo)
Your static IP address is 127.0.0.1
Once Proximo has been added a PROXIMO_URL
config var will be available to the app. This can be confirmed using the heroku config
command.
$ heroku config | grep PROXIMO_URL
PROXIMO_URL: http://proxy:password@proxy-12-34-45-56.proximo.io
After installing Proximo the application should be configured to fully integrate with the add-on.
Determining your static IP address
Your static IP address will be shown when you add the add-on.
$ heroku addons:create proximo:development
Adding proximo to sharp-mountain-4005… done, v18 ($5/mo)
Your static IP address is 127.0.0.1
Forwarding traffic through Proximo
Proximo provides a small piece of software to vendor into your application. This binary can wrap your processes and automatically forward outbound TCP connections made by the wrapped process over your proxy.
Installing the Proximo wrapper
The source code for the Proximo wrapper is available on Github.
The Proximo wrapper is installed into your app directory:
$ cd ~/myapp
$ curl http://downloads.proximo.io/proximo-stacklet.tgz | tar xz
$ git add bin/proximo vendor/dante
$ git commit -m "add proximo stacklet"
Using the Proximo wrapper
Modify your Procfile to prepend bin/proximo
to any command whose connections you would like to forward through your proxy:
web: bin/proximo [your existing command]
The Proximo wrapper does not work with Node.js, PHP, or JVM based applications including Java, Scala, Clojure, Groovy and JRuby. Users of these languages should use Proximo as a SOCKS or HTTP proxy directly. See below for an example of configuring a JVM application to forward traffic across a SOCKS proxy.
Configuring the Proximo wrapper
By default, the bin/proximo
wrapper will forward all outbound traffic from the wrapped process across your proxy. If you’d like to send only a subset of traffic, you can limit with PROXIMO_MASK
:
$ heroku config:set PROXIMO_MASK="172.18.32.0/24"
This would send any outbound traffic to 172.18.32.*
over your proxy.
Using the Proximo HTTP Proxy
If you’d rather use Proximo as a standard HTTP proxy, use PROXIMO_URL
on port 80. You can send HTTP or HTTPS requests through this proxy.
These code snippets show how to redirect outbound HTTP requests through the Proximo HTTP proxy.
Node.js
Example App: github.com/pirateradio/proximo-node
http = require("http")
url = require("url")
proxy = url.parse(process.env.PROXIMO_URL)
options =
hostname: proxy.hostname
port: proxy.port || 80
path: "http://api.someservice.com/endpoint"
headers:
"Proxy-Authorization": "Basic #{new Buffer(proxy.auth).toString("base64")}"
http.get options, (res) ->
console.log "status code", res.statusCode
console.log "headers", res.headers
Python
Example App: github.com/pirateradio/proximo-python
import os
import urllib2, urllib
if os.environ.get('PROXIMO_URL', '') != '':
proxy = urllib2.ProxyHandler({'http': os.environ.get('PROXIMO_URL', '')})
auth = urllib2.HTTPBasicAuthHandler()
opener = urllib2.build_opener(proxy, auth, urllib2.HTTPHandler)
urllib2.install_opener(opener)
conn = urllib2.urlopen('http://api.someservice.com/endpoint')
resp = make_response(conn.read())
Ruby
Example App: github.com/pirateradio/proximo-ruby
require "rest-client"
RestClient.proxy = ENV["PROXIMO_URL"] if ENV["PROXIMO_URL"]
res = RestClient.get("http://api.someservice.com/endpoint")
puts "status code", res.code
puts "headers", res.headers
Java
Example App: github.com/jkutner/proximo-example
URL proximo = new URL(System.getenv("PROXIMO_URL"));
String userInfo = proximo.getUserInfo();
String user = userInfo.substring(0, userInfo.indexOf(':'));
String password = userInfo.substring(userInfo.indexOf(':') + 1);
System.setProperty("socksProxyHost", proximo.getHost());
Authenticator.setDefault(new ProxyAuthenticator(user, password));
//...
private class ProxyAuthenticator extends Authenticator {
private final PasswordAuthentication passwordAuthentication;
private ProxyAuthenticator(String user, String password) {
passwordAuthentication = new PasswordAuthentication(user, password.toCharArray());
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return passwordAuthentication;
}
}
Viewing your audit logs
You can open your audit logs from the command line.
$ heroku addons:open proximo -a myapp
Migrating between plans
Use the heroku addons:upgrade
command to migrate to a new plan.
$ heroku addons:upgrade proximo:starter
Upgrading proximo:dedicated to sharp-mountain-4005... done, v18 ($25/mo)
Your plan has been updated to: proximo:starter
Your static IP address is 127.0.0.1
Determining your static IP address
Examine your PROXIMO_URL
config var to find your assigned static IP address.
$ heroku config:get PROXIMO_URL
http://proxy:(redacted)@proxy-123-234-345-456.proximo.io
The static IP address for this application would be 123.234.345.456.
Removing the Proximo add-on
This will unregister your static IP and you will not be able to retrieve it!
Proximo can be removed via the CLI.
$ heroku addons:destroy proximo
Removing proximo from sharp-mountain-4005... done, v20 (free)
Support
All Proximo support and runtime issues should be submitted via one of the Heroku Support channels. Any general issues or feedback is welcome in #proximo
on Freenode.
Enterprise Support
Users of the proximo:enterprise
plan will be provided dedicated contact information and an escalation path to page an on-call engineer.