Customizing Digitalocean Floating IPs

Digitalocean allows, for free, the option to add an additional IP address to your virtual machine ("droplet"). These floating IPs are similiar to Amazon AWS Elastic IPs and are tied to your account and location, rather than any specific instance
This means that when an instance is destroyed, you can still preserve the floating address and migrate it to your new instance, providing it's in the same datacenter location. Floating IPs also have load balancing features, where if a site/instance goes down, it can automatically redirect to a backup instance. It is for these reasons it is recommended you use floating IPs for public services

How do they work

When you add a floating IP, your droplet gains an additional IP address in the 10.0.0.0/8 private range, known as the anchor IP.
Traffic to the floating IP is sent to the droplet's anchor IP
If you have services listening o0.0.0.0 then they will be available on both the instance and the floating address. I recommend binding management services to only to the instance IP and binding public services to the floating IP
By default, your floating IP is not used as a source address for the droplets egress traffic.

Using the API to find the IPs

You can find your normal (canonical) address, anchor address, and any attached floating addresses through the droplet api available at 169.254.169.254

floating_ip_address="$(curl -s 169.254.169.254/metadata/v1/floating_ip/ipv4/ip_address)"

ip_anchor="$(curl -s 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address)"

public_address="$(curl -s 169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)"

gw_public="$(curl -s 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/gateway)"

gw_anchor="$(curl -s 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/gateway)"

Running Different web servers on different addresses.

If you want to a service exclusively on the floating address, simply bind to the anchor IP address (private address in the 10.x.x.x net).

Using the floating address as your source address

[root@droplet ~]# dig @208.67.222.222 myip.opendns.com <br />
192.0.2.199<br />
[root@droplet ~]# ip r add to 208.67.222.222 via 10.10.0.1 dev eth0 <br />
[root@droplet ~]# dig @208.67.222.222 myip.opendns.com
203.0.113.55

Locking down access to the instance address

As mentioned earlier, external connections are routed by default through the instance address, rather than the floating address. (You don't see the floating address when you go to whats-my-ip)

We can, however, use the gateway in the anchor network instead. This will make the instance IP address invisible to the wider internet. Connections will be dropped because the droplet no longer has a route, so we add a static route to a few trusted networks.

Finding the BGP announced route (if you don't know it)

lookup_bgp_route() {
  host -t txt $(awk -F. '{print $4"."$3"."$2"."$1}'<<<$1).origin.asn.cymru.com  | cut -d\" -f2 | awk -F " | " '{print $3}'
};

# to get the Internet root of the current ssh client
# lookup_bgp_root ${SSH_CLIENT%% *}`

Adding your static routes and changing the defauLt route to the anchor

$ ip r add 203.0.113.0/24 via $gw_public
$ ip r add 192.0.2.0/24 via $gw_public

$ ip r change default via $gw_anchor
$ ip r save >/etc/ip.routes.$(date +%s)

/etc/network/interfaces

To persist it across boots

auto eth0
    iface eth0 inet static
            address $anchorip
            netmask 255.255.0.0
            gateway $anchorgw
            up ip -4 address add $instanceip dev eth0
            up ip -4 route add to $homeroute via $instancegw src $instanceip

So now my instance IP is not reachable by default, unless I add a route. Note, this isn't a substitute for firewalling, and for very sensitive services like ssh, I strongly recommend locking it down via the cloud firewall.