Outgoing Static IP for Unsupported Regions Proxy Guide

As some of you may be aware, while we do offer outgoing Static IP to some regions, it isn't available everywhere quite yet, so I'm writing a step-by-step guide on how to roll your own proxy, with a static IP, that you can use to funnel external API requests through that require a whitelisted IP address.

Please note that this guide is not for the faint of heart and can get pretty technical. We are unable to troubleshoot any issues that may arise from using this guide, but if you have any questions feel free to reply to this thread and I'll do my best!

If you're familiar with this process and have any concerns, corrections, or additions please let me know. I'm not a network administrator; just a friendly marketing team member trying to share some hopefully helpful info. Proceed at your own risk.

What You'll Need

  • A DigitalOcean account (use this link to get $200 in credit over 60 days once you spend $25)

  • A domain name (It is highly recommended that you utilize a subdomain with some sort of obfuscated address. Just mash your keyboard a bit.)

  • A cup of coffee โ˜•

Step-by-step

  1. In your DigitalOcean account, choose Droplets from the left-hand menu, and choose Create Droplet.

  2. Set up your droplet with the following settings:

    1. Your region and datacenter of choice

    2. Ubuntu OS, version 20.04 LTS x64

    3. Droplet Type: Basic

    4. CPU Options: Regular, 1 CPU / 1 GB RAM

      1. Note that you may need to scale up your droplet depending on the volume of traffic.

    5. Your authentication method of choice. SSH key is a little more complex to set up, but also more secure. If you choose an SSH key, follow Digital Ocean's guide for how to generate that key.

  3. Click Create Droplet at the bottom of the page.

  4. In the left-hand menu, choose Networking > Reserved IPs

  5. Click Add a Reserved IP

  6. Choose Assign to Droplet, select your newly created droplet from the drop(let)-down menu, and confirm your selection.

  7. Head over to your domain registrar, and set up the following DNS settings.

    1. Record Type: A

    2. Host: 'proxy' or whatever subdomain you'd like to use

    3. Address: the new reserved IP of your droplet

    4. TTL: As fast as possible ๐ŸŽ๏ธ

  8. Head back to the Droplets section and click on the droplet you created earlier.

  9. On the next page, choose Access > Launch Droplet Console

  10. Copy and paste the following into the console. The commands should immediately begin executing. This will take a minute, so sit back and enjoy the show (and that cup of coffee we talked about.)

apt update && apt upgrade -y
apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt update
apt install docker-ce -y

Note: If you see a message about OpenSSH configuration, just press Enter to proceed.

  1. Once it's done, you'll be back at the prompt and ready to copy and paste some more. Copy and paste the following, same as before. This one should only take a second. Note that you may need to execute the last command separately -- if you see it just hanging out in your prompt, just press enter to run it.

curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
  1. Now that we have all the software installed that we need, let's make a folder for our proxy server files to live in.

mkdir proxy_server && cd proxy_server

Creating the Configuration Files

  1. Paste the following into your terminal and press enter (if necessary).

nano Dockerfile
  1. This opens a program called 'nano', which is a horrific text editing experience that Linux nerds (respectfully) love. I'll make it as easy as I can! Just copy and paste the following code into your terminal.

FROM nginx:alpine
RUN apk add --no-cache nginx-mod-http-js openssl
COPY nginx.conf /etc/nginx/nginx.conf
COPY proxy.js /etc/nginx/proxy.js
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
  1. Press Crtl + X, then type Y and press enter.

  2. Let's do it again!

nano nginx.conf
  1. Here's the content to paste. In this part, you'll need to replace proxy.example.com with the domain you're using. You can do this in nano (painfully) by using the arrow keys to navigate around, or just do it in your own text editor of choice and copy/paste from there. Note that you'll need to replace this in three spots: server_name, ssl_certificate, and ssl_certificate key

load_module modules/ngx_http_js_module.so;
events {
    worker_connections 1024;
}
http {
    js_import proxy.js;
    server {
        listen 443 ssl;
        server_name proxy.example.com;  # Change to your subdomain
        ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;
        location / {
            js_content proxy.handleRequest;
        }
    }
}
  1. Crtl + X, Y, and then enter.

  2. Again!

nano proxy.js
async function handleRequest(r) {
    const targetUrl = r.headersIn['X-Target-URL'];
    if (!targetUrl) {
        r.return(400, "X-Target-URL header is required");
        return;
    }
    try {
        const response = await ngx.fetch(targetUrl, {
            method: r.method,
            headers: r.headersIn,
            body: r.requestBody
        });
        r.headersOut['Content-Type'] = response.headers.get('Content-Type');
        r.return(response.status, await response.text());
    } catch (error) {
        r.return(500, `Error: ${error.message}`);
    }
}
export default {handleRequest};
  1. One more time!

nano docker-compose.yml
version: '3'
services:
  proxy:
    build: .
    ports:
      - "443:443"
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
    restart: unless-stopped
  1. More commands to paste! You might need to hit 'enter' on the last one. In these commands, we're just setting up some firewall rules. You'll have to confirm your changes with 'y' when prompted.

ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
  1. Now, we're going to set up an SSL certificate, which is required to make sure your connection to the proxy is secure. Make sure to replace your domain name in the second command before executing. You'll be asked a few questions to generate the certificate; pretty simple stuff.

apt install certbot python3-certbot-nginx -y
certbot --nginx -d proxy.example.com  # Replace with your subdomain
  1. Finally, we'll build and run our proxy server.

docker-compose up -d

If all goes well...

...you should be ready to go! Head over to Xano, and create an External API Request. You'll send a request to your proxy, and send a header of X-Target-URL with the link the proxy should forward the request to. Give it a shot!

If it didn't go well...

That's okay! It might be hard for me to provide direct support on this, but I'll do my best!

Is this secure?

Relatively. There are more advanced options that you should probably consider implementing (that are outside of the scope of this guide) such as rate limiting and authentication. That being said, if your subdomain is obscure enough and you aren't sending client facing requests directly to it, it's safe by obscurity if nothing else.

1