Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Working with Node.js
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Model Context Protocol
    • Vector Database
    • Heroku Inference
      • Inference Essentials
      • AI Models
      • Inference API
      • Quick Start Guides
    • Working with AI
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Add-ons
  • All Add-ons
  • Fixie Socks
Fixie Socks

This add-on is operated by Fixie

Static IP addresses for database requests and other TCP connections

Fixie Socks

Last updated February 22, 2025

Table of Contents

  • The difference between Fixie Socks and Fixie
  • Two ways to use Fixie Socks
  • Provisioning the add-on
  • Local setup
  • Using via Fixie-Wrench
  • Using via native SOCKSv5 support
  • Dashboard
  • Removing the add-on
  • Support

Fixie Socks is a Heroku add-on that enables users to make TCP connections from a known IP address via a SOCKS proxy. Common use cases are database connections, FTP, SCP, and SSH. By connecting via Fixie Socks, users can integrate with external services and databases that do IP allowlisting. Fixie Socks is language- and framework-agnostic.

Fixie Socks acts as a SOCKS V5 proxy for outbound traffic, tunneling your requests through a known IP address. Each Fixie subscriber is assigned a set of static IP addresses. Through this proxy, subscribers can connect to any database or service that requires a fixed IP range.

Fixie Socks provides customers with a standard SOCKS V5 proxy URL that can be used to establish connections from any server-side language, including Node, Java, and Go. Fixie Socks can also be used by SSH, SCP, cURL, and other command-line tools.

The difference between Fixie Socks and Fixie

Fixie Socks provides a fixed set of IP addresses via a SOCKS V5 proxy. As such, Fixie Socks is capable of proxying any TCP connection. You can make HTTP and HTTPS requests via Fixie Socks, but Fixie (an HTTP proxy) is generally a better fit for that use case. Fixie Socks is perfect for making requests to databases, FTP servers, and other lower-level connections because it allows you to tunnel arbitrary TCP connections.

Two ways to use Fixie Socks

1.) The easiest way to integrate your application with Fixie Socks is by adding the Fixie-Wrench binary to your project. Fixie-Wrench provides a tunnel on a local port through a Fixie Socks cluster, so that any application can make any TCP request to any remote service without significant code changes. Fixie-Wrench works for all kinds of TCP connections: database connections, HTTP requests, etc. For more information, see Using via Fixie-Wrench.

2.) Many libraries support SOCKSv5 proxies out of the box. If you’re using a language and library that supports SOCKSv5 proxies, you can integrate with Fixie Socks directly in your application code instead of using Fixie-Wrench. For more information, see Using via Native SOCKSv5 Support

Provisioning the add-on

Fixie Socks can be attached to a Heroku application via the CLI:

A list of all plans available can be found here.

$ heroku addons:create fixie-socks
-----> Adding fixie-socks to sharp-mountain-4005... done, v18 (free)

After you provision Fixie Socks, a FIXIE_SOCKS_HOST config var is available in your app’s configuration. This contains the SOCKSV5 proxy URL through which your application makes outbound requests. This can be confirmed using the heroku config:get command:

$ heroku config:get FIXIE_SOCKS_HOST
user:pass@criterium.usefixie.com:1080

After installing Fixie Socks, the application should be configured to fully integrate with the add-on.

Local setup

Environment setup

For local development, it is necessary to replicate the FIXIE_SOCKS_HOST environment variable.

FIXIE_SOCKS_HOST can be retrieved either from the Fixie Socks dashboard or via the Heroku CLI:

$ heroku config:get FIXIE_SOCKS_HOST -s  >> .env

Credentials and other sensitive configuration values should not be committed to source-control. In Git, exclude the .env file with: echo .env >> .gitignore.

For more information, see the Heroku Local article.

Using via Fixie-Wrench

Fixie-Wrench is a command line utility that makes it easy to proxy any TCP connection through Fixie Socks, even if your language or wrenchent library does not natively support SOCKSv5 proxies. By connecting through Fixie Socks, your application with have a stable set of outbound IP addresses, making it possible to address a remote service that performs IP address whitelisting from Heroku or other platforms that provide ephemeral instances.

Fixie-Wrench does port-forwarding, similar to SSH port forwarding, so your remote database, FTP server, or other service will appear to be running locally from the perspective of your application code.

To install Fixie-Wrench into your project: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/usefixie/fixie-wrench/HEAD/install.sh)"

Then, update your Procfile to start Fixie-Wrench:

web: ./bin/fixie-wrench LOCAL_PORT:REMOTE_HOST:REMOTE_PORT & ...

For more information, see the Fixie-Wrench readme and the example app.

Using via native SOCKSv5 support

Many languages and database drivers natively support SOCKSv5 proxies like Fixie Socks. The list below is not exhaustive, but provides examples for many popular use cases. If you do not see your language/library below, you can always use Fixie-Wrench (documented above).

Using with Node.js

With Node.js, the general pattern is to establish a SOCKS connection using a client library like socksjs and then provide this stream to the database driver, request library, or other library of your choosing.

Connecting to MySQL via Fixie Socks with Node.js

MySql2 connects via a SOCKS connection provided as the stream property. Because Fixie Socks terminates idle connections after 60 seconds of inactivity, we suggest using connection pooling (this is a best practice regardless) or manual error handling. The example below uses connection pooling:

'use strict';

const SocksConnection = require('socksjs');
const mysql = require('mysql2');
const fixieUrl = process.env.FIXIE_SOCKS_HOST;
const fixieValues = fixieUrl.split(new RegExp('[/(:\\/@)/]+'));

const mysqlServer = {
  host: 'your-host.example.com',
  port: 3306
};

const dbUser = 'user';
const dbPassword = 'password';
const db = 'database';

const fixieConnection = new SocksConnection(mysqlServer, {
  user: fixieValues[0],
  pass: fixieValues[1],
  host: fixieValues[2],
  port: fixieValues[3],
});

const mysqlConnPool = mysql.createPool({
  user: dbUser,
  password: dbPassword,
  database: db,
  stream: fixieConnection
});

mysqlConnPool.getConnection(function gotConnection(err, connection) {

  if (err) throw err;

  queryVersion(connection);
});

function queryVersion(connection) {
  connection.query('SELECT version();', function (err, rows, fields) {

      if (err) throw err;

      console.log('MySQL/MariaDB version: ', rows);
      connection.release();
      process.exit();
  });
}

Connecting to Postgres or Amazon Redshift via Fixie Socks with Node.js

As with mysql, you can pass a custom stream to the node-postgres library. This will work both for connections to Postgres databases as well as to Amazon Redshift:

'use strict';

const pg = require('pg');
const SocksConnection = require('socksjs');

const fixieUrl = process.env.FIXIE_SOCKS_HOST;
const fixieValues = fixieUrl.split(new RegExp('[/(:\\/@)/]+'));

const pgServer = {
  host: 'YOUR-HOST',
  port: 5432
};

const fixieConnection = new SocksConnection(pgServer, {
  user: fixieValues[0],
  pass: fixieValues[1],
  host: fixieValues[2],
  port: fixieValues[3],
});

const connectionConfig = {
  user: 'YOUR-DB-USERNAME',
  password: 'YOUR-DB-PASSWORD',
  database: 'YOUR-DATABASE',
  stream: fixieConnection,
  ssl: true // Optional, depending on db config
};

var client = new pg.Client(connectionConfig);

client.connect(function (err) {
  if (err) throw err;
  client.query('SELECT 1+1 as test1', function (err, result) {
    if (err) throw err;
    console.log(result.rows[0]);
    client.end(function (err) {
      if (err) throw err;
    });
  });
});

Connecting to MongoDB via Fixie Socks with Node.js

Starting with v6.0 of the MongoDB driver, you must install the socks package: npm i socks

Then provide these options when instantiating the client:

const fixieData = process.env.FIXIE_SOCKS_HOST.split(new RegExp('[/(:\\/@/]+'));
const socksOptions = {
  proxyHost: fixieData[2],
  proxyPort: fixieData[3]
  proxyUsername: fixieData[0],
  proxyPassword: fixieData[1]
};
const client = new MongoClient(dbUri, socksOptions);

If you are using Mongoose, you can then provide that client to Mongoose:

 await mongoose.connect(mongoClient.db("your-database").databaseName, {
  dbName: "your-database",
  client
 });

Establishing an SSH connection over Fixie Socks with Node.js

The SSH2 library can be used to establish an SSH connection and execute commands over Fixie Socks.

var socks = require('socksv5'),
    SSHClient = require('ssh2').Client;

const fixieUrl = process.env.FIXIE_SOCKS_HOST;
const fixieValues = fixieUrl.split(new RegExp('[/(:\\/@)/]+'));

socks.connect({
  host: 'ssh.example.org',
  port: 22,
  proxyHost: fixieValues[2],
  proxyPort: fixieValues[3],
  auths: [socks.auth.UserPassword(fixieValues[0], fixieValues[1])]
}, function(socket) {
  var conn = new SSHClient();
  conn.on('ready', function() {
    conn.exec('uptime', function(err, stream) {
      if (err) throw err;
      stream.on('close', function(code, signal) {
      conn.end();
      }).on('data', function(data) {
        console.log('STDOUT: ' + data);
      }).stderr.on('data', function(data) {
        console.log('STDERR: ' + data);
      });
    });
  }).connect({
    sock: socket,
    username: 'ssh-user',
    privateKey: require('fs').readFileSync('/here/is/my/key')
  });
});

Making HTTP or HTTPS requests over Fixie Socks with Node.js

The socks package provides an agent that can be used by the Node’s http and https libraries, as well as by popular higher-level libraries like request.

'use strict';

const http = require('http');
const Socks = require('socks');

const fixieUrl = process.env.FIXIE_SOCKS_HOST;
const fixieValues = fixieUrl.split(new RegExp('[/(:\\/@)/]+'));

const socksAgent = new Socks.Agent({
    proxy: {
        ipaddress: fixieValues[2],
        port: fixieValues[3],
        type: 5,
        authentication: {
            username: fixieValues[0],
            password: fixieValues[1]
        }
    }},
    true, // true HTTPS server, false for HTTP server
    false // rejectUnauthorized option passed to tls.connect()
);

function resHandler(res) {
  let responseBody = '';
  res.on('data', (chunk) => {
    responseBody += chunk;
  });
  res.on('error', () => {
    process.exit(1);
  });
  res.on('end', () => {
    console.log(responseBody);
    socksAgent.encryptedSocket.end();
  });
}


http.get({ hostname: 'example.com', port: '443', agent: socksAgent}, resHandler);

Using with Go

Golang’s net/proxy package provides a Socks5 proxy dialer that can be used with Fixie Socks. This dialer can be used for any TCP connection. The example below uses this to make an HTTP request:

package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
  "os"
  "strings"
  "golang.org/x/net/proxy"
)

const URL = "http://www.example.com"

func main() {
  fixie_data := strings.Split(os.Getenv("FIXIE_SOCKS_HOST"), "@")
  fixie_addr := fixie_data[1]
  auth_data := strings.Split(fixie_data[0], ":")
  auth := proxy.Auth{
    User: auth_data[0],
    Password: auth_data[1],
  }

  dialer, err := proxy.SOCKS5("tcp", fixie_addr, &auth, proxy.Direct)
  if err != nil {
    fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err)
    os.Exit(1)
  }
  httpTransport := &http.Transport{}
  httpClient := &http.Client{Transport: httpTransport}

  httpTransport.Dial = dialer.Dial

  req, err := http.NewRequest("GET", URL, nil)
  if err != nil {
    fmt.Fprintln(os.Stderr, "can't create request:", err)
    os.Exit(2)
  }
  resp, err := httpClient.Do(req)
  if err != nil {
    fmt.Fprintln(os.Stderr, "can't GET page:", err)
    os.Exit(3)
  }
  defer resp.Body.Close()
  b, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    fmt.Fprintln(os.Stderr, "error reading body:", err)
    os.Exit(4)
  }
  fmt.Println(string(b))
}

Using with Java

Java supports a system property socksProxyHost, which can be used to route every outbound request through Fixie Socks. Additionally, Java 7 introduced ProxySelector, which can be used to conditionally proxy requests depending on the hostname.

A simple example that proxies all outbound requests through Fixie Socks:

URL fixie = new URL(System.getenv("FIXIE_SOCKS_HOST"));
String[] fixieUserInfo = fixie.getUserInfo().split(':');
String fixieUser = fixieUserInfo[0];
String fixiePassword = fixieUserInfo[1];
System.setProperty("socksProxyHost", fixie.getHost());
Authenticator.setDefault(new ProxyAuthenticator(fixieUser, fixiePassword));

//...

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;
  }
}

Using with Ruby

Out of the box, any Ruby library that accepts Net::SSH::Proxy::SOCKS5 object can use Fixie Socks. Here is a simple example of configuring the object that holds the proxy details:

proxy_uri = URI.parse("socks://#{FIXIE_SOCKS_HOST}")
socks_proxy = Net::SSH::Proxy::SOCKS5.new(
  proxy_uri.host,
  proxy_uri.port,
  user: proxy_uri.user,
  password: proxy_uri.password,
)

Leveraging the example above, here is an example of making an SFTP request through Fixie Socks using net-sftp gem:

Net::SFTP.start(
  ...
  proxy: socks_proxy,
) do |sftp|
  sftp.download!("/path/to/file")
end

Curl via Fixie Socks

Curl accepts a socks5 argument:

curl --socks5 $FIXIE_SOCKS_HOST http://example.com

SSH and SCP via Fixie Socks

SSH and SCP accept a ProxyCommand option. Using this option, you can pass in an ncat command that establishes a connection via the Fixie Socks proxy. This requires ncat v7 or newer.

Ncat does not accept proxy authentication via the standard proxy url schema, so instead you must provide it as a separate argument:

ssh -o ProxyCommand='ncat --proxy-type socks5 --proxy YOUR-FIXIE-DOMAIN.usefixie.com:1080 --proxy-auth fixie:YOUR-FIXIE-TOKEN %h %p' serveruser@server.ip.address

FTP via Fixie Socks

Making FTP requests via Fixie Socks is straight forward, but depending on the configuration of the FTP server, you may need to specify a specific Fixie IP address instead of using your load-balanced Fixie Socks proxy URL.

FTP uses multiple TCP connections (a control connection and a transfer connection). If your FTP server supports “passive promiscuous” connections, connecting through the standard Fixie Socks URL works without issue. If, however, the server does not support “passive promiscuous” connections, both the control and transfer connection must go through the same IP. For this use case, you can proxy directly through a specific Fixie Socks IP instead of through a load-balanced Fixie Socks proxy group. You can find the IP address and credentials in the Fixie Socks dashboard.

An example using cURL:

curl -v 'ftp://ftp2.census.gov/robots.txt' --socks5-hostname $FIXIE_SOCKS_IP_SPECIFIC_URL

cURL versions prior 7.48 had a bug which left the SOCKS connection open after the FTP transfer completed. We recommend using cURL 7.48 or later.

Dashboard

The Fixie Socks dashboard allows you to view your connection logs and account settings.

The dashboard can be accessed via the CLI:

$ heroku addons:open fixie-socks
Opening fixie-socks for sharp-mountain-4005

or by visiting the Heroku Dashboard and selecting the application in question. Select Fixie Socks from the add-ons menu.

Removing the add-on

Fixie Socks can be removed via the CLI.

This will destroy all associated data and cannot be undone! If your application is configured to make requests through Fixie Socks, those requests will fail after removing the add-on.

$ heroku addons:destroy fixie-socks
-----> Removing fixie-socks from sharp-mountain-4005... done, v20 (free)

Support

All Fixie Socks support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome via email at team@usefixie.com.

Keep reading

  • All Add-ons

Feedback

Log in to submit feedback.

Zara 4 FlightFormation Autoscale

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices