dynamic dns with google domains using ddclient on debian

Note: there’s a newer post covering this topic that involves containerization

After putting it off for ages due a perceived PITA process, I finally decided to check out how to set up dynamic dns to point at one of my servers that’s behind a changing IP. I was pleased at how surprisingly easy it is.

prereqs

I’m running debian 8 in a kvm vm, using bridged networking to give my web server it’s own identity.
The only package required is ddclient

configure google domains

Jump to the synthetic records section under your google domain dns settings and add the subdomain you want to forward to your dynamic host:

if you click on that blue “view credentials” link you’ll see the username and password google has randomly generated for you. you’ll need those details when you edit your ddclient.conf. note that until I’ve set up the config, the “data” section here shows 0.0.0.0 as my IP.

configure ddclient

for my setup, I’ve got several subdomains I want to forward to the same host. After checking out the ddclient manual, I’ve edited my ddclient.conf similar to the below:

protocol=dyndns2
use=web
server=domains.google.com
ssl=yes
protocol=dyndns2, login=host1login, password='host1password'
custom-subdomain.your-host1.com

test the ddclient configuration

the best way to test your configuration is by running the following command:
ddclient -daemon=0 -noquiet -verbose -debug
this will iterate all of your configured values and the give you pretty detailed debug output 

In the above, my subd.your-host1.com was a new host I added to the config, whereas subd.your-host2.com is one which I’d already updated during a prior test.

verify google has your ip

The final step to make sure everything looks good here is to refresh your google domains dns settings page. what you should see, as I do, is the data section now reflecting the ip for your dynamic host.

I also verified my /etc/default/ddclient config to make sure it’s got run_daemon set to true. When I installed ddclient via aptitude this was done automatically but you may want to double check yours if you find your client doesn’t update regularly. my default config looks like this:


# Configuration for ddclient scripts
# generated from debconf on Sun Feb 21 12:51:42 EST 2016
#
# /etc/default/ddclient
run_dhclient=”false”
run_daemon=”true”
daemon_interval="300"

hosting an nginx http reverse proxy in a debian vm - part 1 - resource by hostname

prereqs

I’m starting with a fresh console install of debian 8, running on kvm using bridged networking.
My test url is doom.mogness.net, which I’ve instructed my DNS to point back at my NAT router.
I’ve configured my NAT router to point to the new VM at port 80.
I’ve installed the following additional packages and their dependencies using aptitude

  • libpam-ssh – for ease of access to my new server (not required)
  • tcpdump – to monitor the tcp activity on my new server (not required)
  • vim – my editor of choice (not required)
  • nginx – the magical reverse proxy (required)

now I can watch any traffic to doom.mogness.net hit my VM and return the nginx “I’m working page” which lets me know I’ve got the network setup correctly.

nginx welcome

configure environment

Now, without really knowing whether or not nginx can do this, I’m going to try and get it to serve a simple http file for now. As luck would have it, nginx’s beginner’s guide describes something just like that.

nginx is configured to run under user www-data by default, so I’ve created a path that nginx can access on the vm “/data/www” giving the group www-data ownership
chown -R :www-data /data
and giving that group write access to the path.
chmod -R g+rw /data
finally, I’m adding myself to the www-data group so I can modify the contents without being root
adduser mog www-data

create a simple test file

I’ve authored the following glorious index.html to be served at doom.mogness.net for starters:

<html>
<head>
<title>Mogness DOOM Server Status</title>
</head>
<body style='background-color: black; color: white; font-size: 12px;'>
<p>Running on <b>Doomsday</b></p>
</body>
</html>

configure nginx

I found my way to /etc/nginx/sites-available and copied the default file for safekeeping before replacing it with the following very basic config file:

server {
listen 80;
listen [::]:80;

server_name doom.mogness.net;

root /data/www;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

test basic config

now, according to the documention, I should be able to just run
nginx -s reload
and be off to the races. let’s give it a go.

doom.mogness

well I’ll be damned, works just like that. Good deal.

hostname-based configuration

before I wrap up part one, I’d like to see if I can get a different hostname to return a different page when when targeting this machine. with a little configuration I should be able to get nginx to serve up something else. a few steps here I’m skipping over:

  • point a new subdomain (home.mogness.net) to the same NAT router.
  • create a cheezy html file to test /data/wwwhome/index.html

the key here will hopefully be the updates I’ve made to the nginx default config. I’ve added a second server section that serves home.mogness.net from a different directory that doom.mogness.net. It now looks like:
server {
listen 80;
listen [::]:80;

server_name doom.mogness.net;

root /data/www;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

server {
listen 80;
listen [::]:80;

server_name home.mogness.net;

root /data/wwwhome;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

so, let’s see if it works. first reload nginx
nginx -s reload
and this time let’s hit home.mogness.net
home.mogness

brilliant. just works. after verifing that doom.mogness.net is still returning the expected page (it is) we can see that nginx gives us flexibility at the top level to serve via the hostname, abstracting the difficulties of doing this ourselves. the next article in this series will start attempting to unwrap the true power of nginx by directing requests to actual servers instead of static files.