Skip to content

Lightweight, zero-dependency, self-configuration for FreeBSD droplets on DigitalOcean

Notifications You must be signed in to change notification settings

morganwdavis/freebsd-digitalocean

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

freebsd-digitalocean

Lightweight, zero-dependency, self-configuration for FreeBSD droplets on DigitalOcean

Features

  • Allows you to run a FreeBSD droplet that auto-configures itself at boot time.
  • No dependency on extra packages or ports -- it's just a simple shell script.
  • Automatically sets up:
    • IPv4 and IPv6 public and private network addressing and routing
    • Floating IP anchor addresses
    • Hostname and DNS servers
    • freebsd user's authorized public keys
  • Replaces networking configurations in /etc/rc.conf with just one digitalocean_enable="YES" setting.
  • Runs "user-data" as shell commands e.g. to install packages or run a chef/puppet/ansible/... worker
  • Completely configurable.

Preparation

WARNING: Any custom networking scripts you may have created in /etc/rc.conf.d will be replaced. Backup if needed.

Droplets built from DigitalOcean's base FreeBSD images have extra packages and scripts that will no longer be required for auto configuration. They should be disabled first to avoid conflicts. When you're confident your cleaned-up droplet is working properly with this solution, you can remove the preinstalled stuff you do not need:

Unnecessary packages:

  • curl
  • dmidecode
  • e2fsprogs
  • gettext-runtime
  • gpart (is in base, no clue why DO installs it from pkg)
  • indexinfo
  • jq
  • libffi
  • libiconf
  • libnghttp2
  • oniguruma
  • python27
  • lots of py27-* packages
  • readline
  • rsync
  • sudo (doas is much more elegant and safer)

Unnecessary users:

  • freebsd

Settings in /etc/rc.conf that can/should be removed:

  • hostname
  • cloudinit_enable
  • digitaloceanpre
  • digitalocean
  • all ifconfig and route-related lines
  • basically everything from the comment DigitalOcean Dynamic Configuration lines and the immediate line below it, are removed each boot. until the end of the file

Extraneous files and directories:

  • /usr/local/etc/rc.d/cloud* (cloudconfig, cloudfinal, cloudinit, cloudinitlocal)
  • /usr/local/etc/rc.d/digitalocean (digitalocean, digitaloceanpre)

Installation and testing

  1. As root, run update.sh which essentially does this for you:

    install -m 700 digitalocean /usr/local/etc/rc.d
    install -m 644 digitalocean.conf /usr/local/etc
    install -m 700 digitalocean.sh /usr/local/sbin
    
  2. Add digitalocean_enable="YES" to /etc/rc.conf

  3. If needed, edit /usr/local/etc/digitalocean.conf (self-documenting)

  4. Test it by entering service digitalocean start
    (Note: this builds configuration files but does not change any active network settings)

  5. Sanity-check the hostname, network, and routing files in /etc/rc.conf.d

  6. Optional: If you configured the droplet_user (typically freebsd), check its home directory for .ssh/authorized_keys

  7. If all looks good, you can restart the droplet

Hint: sshd is configured to allow root-login with ssh-keys; so no additional user is needed. However, it is highly recommended to add a normal user and disable ssh root login.

Zero downtime network updates

It is possible to reconfigure the FreeBSD instance while running without needing to reboot. To restart networking and routing, enter these commands:

service digitalocean restart

service netif restart && service routing restart

Dynamically updated hosts files

Setting the config option hosts_file to point to a file (such as /etc/hosts) will cause special DO_* entries found in that file to be updated with their corresponding IP addresses. Example:

0.0.0.0         public-ip		# DO_PUB_IPV4
0.0.0.0         private-ip		# DO_PVT_IPV4
0.0.0.0         anchor-ip		# DO_ANCHOR_IPV4
0.0.0.0         floating-ip		# DO_FLOATING_IPV4
0.0.0.0         gateway-ip		# DO_GW_IPV4

The script searches for a line with a DO_* entry, such as DO_PUB_IPV4, and replaces the first column address with the corresponding metadata address value. This creates an alias for services that listen on an address by referring to its symbolic DO_ name. The DO_* symbols are required exactly as shown for matching purposes. Optionally, any other symbolic names may be included on the line, such as the *-ip examples above. In the case of the /etc/hosts file, this would allow a service to bind to the address associated with anchor-ip, provided the service permits host names.

Your own scripts can also lookup these metadata addresses easily by using getent(1):

anchor_ip=`getent hosts anchor-ip | cut -f1 -d' '`

(Use _IPV6 suffixed symbols for IPv6 adddresses.)

Why I made this

I didn't want to use DigitalOcean's implementation for auto-configuration. Extra packages of networking support tools and the special freebsd user account increase attack surfaces. Those packages will require updates at some point. They take up disk space, create persistent processes in memory, and steal CPU cycles. This shell script-based solution does the trick.

What's next?

I'd love to get some feedback from others running and testing this just to make sure it's solid and has all features working well. After that, I could see making this an actual FreeBSD package. That is, of course, if DigitalOcean doesn't adopt something equivalent in their upcoming base images.

Updates

About

Lightweight, zero-dependency, self-configuration for FreeBSD droplets on DigitalOcean

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages