Category: Tips

Tips

  • Pi-Hole & DNS over HTTPS

    Pi-Hole & DNS over HTTPS

    There are some cool things about running your own DNS server. I use it to reference some web services that I run internally more easily, like my Unifi Controller, PiAware, and my home-grown Linux Server. It’s a lot easier than trying to keep track of the IP addresses of everything in your network.

    For that reason, I’ve been running my own DNS server for awhile now. For awhile, I was just running my own BIND instance. Unfortunately, probably because I’m just not familiar with it, it wasn’t very stable. Luckily, something even better came along: Pi-Hole.

    What’s Pi-Hole?

    Pi-Hole is a stable, free, and lightweight DNS server with built-in adblocking abilities. The coolest part is that it blocks ads across your network (assuming you tell all your devices to use it as their DNS server), even devices that don’t support things like adblocking extensions. In my case, it’s the perfect solution.

    My Old Approach

    For awhile, I’ve been running Pi-Hole in Docker on my Linux server. To keep my DNS encrypted (because really, who wants to expose all their DNS requests to their ISP?), I’ve been routing queries over a VPN. The problem with this is that if, for some reason, my VPN connection fails, my DNS stops, which means all my devices think they’re not connected to the Internet. Obviously, that’s not ideal.

    One other bit is that (probably through my own stupidity) my Docker container running Pi-Hole doesn’t automatically start up when I reboot the server. This has been a bother sometimes, even if it’s not something really serious. So I’ve decided to switch things up & figure out a way to make it more robust.

    Pi-Hole on a Raspberry Pi

    I’ve decided to start running Pi-Hole on a machine dedicated to the task. Since it’s designed for a Raspberry Pi, and I had an extra one (or two…) lying around, this seemed like a good way to go.

    So I downloaded Raspbian, flashed it onto a Micro SD card, and touched a new file called ssh to enable SSH access without having to plug in a mouse, keyboard, and monitor. Then I went to my router’s control panel to find the IP address of the Raspberry Pi so I could ssh in. Raspbian boots up with username pi and password raspberry – log in & change your password before continuing (ssh pi@<IP ADDRESS> and then passwd pi to change it).

    Finally, after changing the password, I ran through the Pi-Hole installation guide to get Pi-Hole itself set up. It’s about as simple and straightforward as it gets, honestly.

    When you finish the installation, make sure you take note of the web admin password that it outputs – you’ll need it later. If you don’t, you’ll be able to reset it from the command line when you need it).

    DNS over HTTPS

    To encrypt our DNS queries outside the network, we’re gonna make Pi-Hole use cloudflared‘s DNS proxy feature. The nice thing about this is that this service will only handle DNS traffic, and since the Raspberry Pi is only running cloudflared and Pi-Hole, there’s a lot less risk of things interfering with it than on my server. Plus, running both Pi-Hole and cloudflared as services mean they start automatically and can automatically restart if they fail.

    Installing cloudflared is pretty simple, since it’s a Golang binary. For a Raspberry Pi, download the ARM package from the Cloudflare Developers site. Assuming you’re using the command line, use these steps to download, extract, and move it into place:

    wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
    tar xzvf cloudflared-stable-linux-arm.tgz
    sudo chmod +x ./cloudflared
    sudo mv ./cloudflared /usr/local/bin

    Then, to verify it’s working, run cloudflared -v – it should output the version (as of now, it’s 2019.12.0).

    Run cloudflared as a Service

    Next up, we need to set up cloudflared‘s proxy-dns command as a service. First up, create a new user to run the service:

    sudo useradd -Mr -s /bin/nologin cloudflared

    Then, change the permissions on the executable so that it’s owned by our new user:

    sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared

    To actually make the service, we put the following into /etc/systemd/system/cloudflared.service:

    [Unit]
    Description=cloudflared DNS Proxy
    After=syslog.target network-online.target
    
    [Service]
    Type=simple
    User=cloudflared
    ExecStart=/usr/local/bin/cloudflared proxy-dns --port=5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query
    Restart=on-failure
    RestartSec=5
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target

    This will tell systemd how to run our service – we’re pointing it to Cloudflare’s https endpoints for DNS and telling it to listen on port 5053. It’ll restart automatically if it fails, and it won’t start up until after the network is online. Now we can start it up:

    sudo systemctl enable cloudflared
    sudo systemctl start cloudflared

    If you run sudo systemctl status cloudflared, it should now show you active (running) in the output. To test that it’s working properly, run nslookup -port=5053 google.com 127.0.0.1 (from your Raspberry Pi). You should see something like this as output:

    Server:         127.0.0.1
    Address:        127.0.0.1#5053
    
    Non-authoritative answer:
    Name:   google.com
    Address: 172.217.14.206
    Name:   google.com
    Address: 2607:f8b0:400a:803::200e

    With this command, we’re telling nslookup to point to localhost on port 5053, which is where we’re running our cloudflared proxy. If you get an error, you’ll have to troubleshoot it.

    Point Pi-Hole to Cloudflared

    The last thing we need to do is tell Pi-Hole to use our cloudflared proxy as its DNS server so that all its DNS requests are encrypted by HTTPS. Access your Pi-Hole’s web interface by entering its IP address in your browser. Click ‘login’ on the left and enter the password that Pi-Hole output when you first installed it. If you lost the password (or didn’t write it down), you can reset it by entering pihole -a -p '<PASSWORD>' in the SSH console of your Raspberry Pi.

    Then click ‘Settings’ in the left panel, then ‘DNS’ in the tabs at the top after that. In the resulting settings panel, uncheck all the boxes on the left-hand side, and enter 127.0.0.1#5053 in the ‘Custom 1 (IPv4)’ box on the right. Make sure you check its box, too.

    Then scroll down & click ‘Save’ at the bottom.

    Finally, run a DNS query against your Pi-Hole (from another machine), putting your Pi’s IP address in:

    > nslookup google.com <IP ADDRESS>
    Server:         <IP ADDRESS>
    Address:        <IP ADDRESS>#53
    
    Non-authoritative answer:
    Name:   google.com
    Address: 172.217.14.238

    If you get output like that ^, your Pi-Hole is correctly configured! Next up, make sure to make all your machines use your Pi-Hole’s IP address as their DNS server. The easiest way to do it network-wide is to set your DHCP server (normally your router) to use that IP as its only DNS server. Here’s what it looks like from my DHCP server config:

    Once you’ve done that, your machines should start using the Pi-Hole as their DNS server as soon as they renew their DHCP lease. You can speed this along by forcing them to reconnect.

    Once you’ve done that & they start using the Pi-Hole, your Pi-Hole Dashboard should start showing some traffic (and an increase in the number of clients), like this:

    I hope this was helpful to you! I’ve you’ve got any questions, drop them in the comments below, and I’ll do my best to answer them.

  • Moving or Distributing Your Docker Build Cache

    Recently, I hit an issue where building docker images on containers meant that the Docker cache wasn’t being persisted from one build to the next. So even if you ran an identical build on the next run, it’d still rebuild every step, costing you valuable time.

    Luckily, it’s not too difficult to save your Docker cache and to restore it (or distribute it) to other machines. It’s a bit more difficult than it used to be, but with a bit of scripting magic, it’s easy enough.

    How it Used to Be

    Apparently (though before I started working much with Docker), when you used to push a Docker image to a remote repository, it’d include all layers of that image. That means when you pulled in image, you’d get its entire history as well. This made things easier for distributing or restoring the cache, because all you had to do was pull the image. Unfortunately, it also made things clunky, in that you had to download more data than you actually needed to run the image.

    Shortly after that, Docker supported saving the entire cache using docker save -o file.tar <image_name> and restoring it using docker load -i file.tar. But now, docker save has been streamlined, too, so saving your cache isn’t quite as simple as it used to be.

    Saving Your Cache

    Luckily, despite those changes, you can still use the docker save command to get your image’s full cache – the catch is that you have to save all the layers listed in your image’s docker history.

    So, to save your image’s cache, run the following command: docker save -o output.tar $(docker history -q <image_name>[:image_tag] | tr '\n' ' ' | tr -d '<missing>')

    This runs docker history with the -q (quiet) tag, so it only shows the ids of each layer. Since you’re probably building FROM another image, much of the history will show <missing>, because you don’t have the entire history of the image you’re building FROM.

    Next up, the command pipes the output to tr twice, to clear out any \ns and any <missing> output. So, in the end, you get a list of image IDs passed directly to docker save.

    Loading Your Cache

    Loading your cache is exactly how it used to be – after you’ve copied or moved the tar file containing your cache, just run docker load -i <filename> and you’ll have your cache all ready to go!

  • Using Docker for WordPress Theme & Plugin Development

    Using Docker for WordPress Theme & Plugin Development

    In the time since I actually learned something about deploying to the web, I’ve been extremely unhappy with my WordPress development workflow. As a result, I haven’t developed any WordPress themes or plugins in quite a few years. I’ve just used themes and plugins as-is, but I’ve finally decided that I want to actually build myself a decent theme.

    WordPress Development Challenges

    There are a few challenges associated with developing on WordPress. First, you (of course) want your theme/plugin files under source control, but they still have to be inside the WordPress directory (okay, you could solve this with symlinks). But then you’re still running a local install of Apache, PHP, and MySQL, or else you’re doing your development directly on a VM or something. I generally prefer not having MySQL and Apache running all the time on my development machine. And, as you may suspect, I certainly don’t want the core WordPress files under source control. That’d just make for plenty of trouble when upgrading WordPress or installing/enabling/disabling themes or plugins.

    A Containerized Solution

    Luckily, it’s actually really easy now to set up a docker-based solution. So you can develop and run the site locally, keep your files under source control, but not have to be running an Apache/MySQL/PHP stack on your development machine (at least not directly).

    First up, you’ll need to install Docker (if you haven’t already). I won’t go into the details here, but you can get a start by heading to the Docker Community Edition page. Once you’ve got it installed, create a new directory for your project (unless you’ve already got one). Inside that directory, create a new file called docker-compose.yml.

    We’re going to use Docker Compose, which is a tool which can launch multiple containers and link them together as necessary. This is super useful for use cases like ours, because we need to set up a container for both WordPress and MySQL. In your docker-compose.yml file, put the following:

    version: '2'
    
    services: 
        wordpress: 
            image: wordpress:php7.1
            ports:
                - 8080:80
            environment:
                WORDPRESS_DB_PASSWORD: super-secure-password
            volumes:
                - ./{DIRECTORY}:/var/www/html/wp-content/{themes/plugins}/{DIRECTORY}
        mysql:
            image: mariadb
            environment:
                MYSQL_ROOT_PASSWORD: super-secure-password
    

    Of course, you’ll want to replace super-secure-password with an actual password (not quite so important for local development), and replace the two {DIRECTORY}s with the directory that you’re developing your project in. In my case, it’s a starter theme. Finally, replace {themes/plugins} with the proper directory, depending on whether you’re developing a plugin or a theme. I used themes, since I’m developing a theme.

    Now, what this is doing is telling Docker that we want two images: One ‘WordPress’ image (you can see the list of available versions on this Docker Store page) and one ‘MySQL image’. In this case, I’m using mariadb.

    We’re then configuring the containers by passing them environment variables – the same password being passed to both images. This’ll actually let them connect to each other. In case you hadn’t guessed it, these are set up by the creators of each image to allow you to configure them on-the-fly.

    Finally, we’re mapping a local directory to /var/www/html/wp-content/..., which will place our local files in the correct directory in the actual WordPress container. It’s pretty awesome.

    All you need to do now is run docker-compose up, wait for your containers to start, and then access your brand-spanking-new WordPress development site at http://localhost:8080. You’ll have to go through the installation, and if you want to, you can load in some sample data. When you want to stop it, just hit Ctrl+C in that console. Finally, you can enable your theme/plugin in your WordPress settings.

    I’ll leave it up to you to decide how exactly you want to deploy it, though.

    Conclusion

    Docker compose makes this super easy, and it takes very little configuration to get up and running. The extra bonus is that you can check your docker-compose.yml file into your source control, and then you’ve got it saved for later development (or development from another machine). All you need is Docker (and an Internet connection, at least to start).

  • ‘Download to Phone’ in Google Music

    2014-10-06 20.37.24

    I’ve been a happy Google Play Music All Access subscriber since the service was initially introduced. The thing that hooked me wasn’t just that it had a great selection of the music I like, but also that I could add my own music to their cloud if they didn’t have it. The ability to add your own music to your music streaming service is, well, pretty dang awesome.

    Anyway, the one thing that I’ve been a tad bit frustrated with is that, while I’m listening to music on my computer, I can’t select any option to download that album, track, or whatever to my phone. I love being able to install apps to my phone without picking up the phone, but not being able to download music to my phone without picking it up, opening the music app, finding the album, and selecting the ‘Download’ option was a tad bit frustrating.

    Well, I’ve just discovered a solution: Create a playlist called something like ‘Download to Phone’, tell your phone to download that playlist, and any time you want something downloaded to your phone, just add it to your ‘Download to Phone’ playlist. Next thing you know, you’ll have that music on your phone for your offline listening adventures!

  • Quick Site Searches in Chrome

    I’ve been exclusively using Google’s Chrome web browser for a while now, (for several reasons, about which I will post later) but I just recently discovered an amazing feature. And when I say amazing, I really do mean it.

    How often do you want to specifically look something up on Wikipedia? Youtube? CNN? For me, it happens quite often. (more…)

  • Secure Your Electronic Devices

    Prey - Open Source Security for your Phone & LaptopAs I’m sure I don’t need to tell you, the modern world, with our dependence on fancy-schmancy gadgets (with which I have an undying obsession, I might add), and the vulnerabilities that come along with such gadgets, it is essential that we care for our expensive gadgets. For that reason, I suggest you install some security to assist in protecting your beloved gadgets and sensitive information that you put on those gadgets. (more…)

  • Simple Email Tweak = Better Email

    I recently found a super awesome trick for e-mail. All you do is add a + to your email address with some term after it. Like this:

    [email protected]

    (more…)