Initial commit

This commit is contained in:
Oliver Traber 2023-11-06 00:30:32 +01:00
commit d914f0a03c
Signed by: Bluemedia
GPG key ID: C0674B105057136C
17 changed files with 350 additions and 0 deletions

11
.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
.vscode
### Hugo ###
# Generated files by hugo
/public/
/resources/_gen/
/assets/jsconfig.json
hugo_stats.json
# Temporary lock file while building
.hugo_build.lock

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "themes/hugo-profile"]
path = themes/hugo-profile
url = https://github.com/BluemediaGER/hugo-profile.git

6
archetypes/default.md Normal file
View file

@ -0,0 +1,6 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

160
config.yaml Normal file
View file

@ -0,0 +1,160 @@
baseURL: https://staging.bluemedia.dev/
languageCode: en-us
title: Bluemedia
theme: hugo-profile
outputs:
home:
- "HTML"
- "RSS"
- "JSON"
page:
- "HTML"
- "RSS"
Paginate: 3
enableRobotsTXT: true
markup:
goldmark:
renderer:
unsafe: true
Menus:
main:
- identifier: blog
name: Blog
title: Blog posts
url: /blog
weight: 1
params:
# General settings
title: "Bluemedia"
description: Text about my cool site
favicon: "/fav.png"
useBootstrapCDN: false
singlePages:
readTime:
enable: true
content: "min read"
scrollprogress:
enable: true
# Design settings
animate: true
color:
textColor: "#23282f"
secondaryTextColor: "#23282f"
primaryColor: "#23282f"
font:
fontSize: 1.2rem
fontWeight: 500
navbar:
menus:
disableExperience: true
disableEducation: true
disableAchievements: true
# Hero
hero:
enable: true
intro: "Hi there! My name is"
title: "Oliver aka Bluemedia"
subtitle: "I'm a sysadmin, hacker, and open-source enthusiast"
image: /images/hero.jpg
button:
enable: true
name: "Find out more"
url: "#about"
download: false
newPage: false
socialLinks:
fontAwesomeIcons:
- icon: fab fa-github
url: https://github.com/BluemediaGER
- icon: fab fa-mastodon
url: https://chaos.social/@Bluemedia
- icon: fa fa-link
url: https://bluemedia.dev/social
# About
about:
enable: true
title: "About Me"
image: "/images/about.jpg"
content: |-
Whether at my main job, at events of the Chaos Computer Club, or with my own AS in the DN42 network: I do a lot of stuff with technology.
And I'm always curious to discover even more.
Using that knowledge I try to create something valuable for myself and others. Whether it is a small project of my own, or a contribution to a larger project.
skills:
enable: true
title: "Here are a few technologies I've been using recently:"
items:
- "PowerDNS"
- "MariaDB Galera"
- "MinIO"
- "Keycloak"
- "Ansible"
- "Checkmk"
# Projects
projects:
enable: true
items:
- title: ScanOS
content: A modern operating system for enterprise-grade network image scanners.
image: /images/projects/scan-os.png
badges:
- "Embedded Systems"
- "Python 3"
- "FastAPI"
- "Vue.js 3"
- "Tailwind CSS"
links:
- icon: fab fa-github
url: https://github.com/BluemediaGER/ScanOS
- title: Fancy Gatus
content: A simplified and modern status page based on data from a Gatus instance. The goal is to only display the most important information in a way that is understandable for end users.
image: /images/projects/fancy-gatus.png
featured:
name: Demo
link: https://status.bluemedia.dev
badges:
- "Gatus"
- "Status page"
- "Vue.js 3"
links:
- icon: fab fa-github
url: https://github.com/BluemediaGER/fancy-gatus
- title: Keycloak Modern Login
content: A clean and modern Keycloak login theme that's built using Vue.js 3, Tailwind CSS and Typescript. It is easily extensible and bypasses the complexity of FreeMarker templates.
image: /images/projects/keycloak-modern-login.jpg
badges:
- "Keycloak"
- "Vue.js 3"
- "Tailwind CSS"
links:
- icon: fab fa-github
url: https://git.bluemedia.dev/Bluemedia/keycloak-modern-login
# Contact
contact:
enable: true
content: My inbox is always open. Feel free to contact me if you have a question or just want to talk about cool computer stuff. I'll try my best to get back to you!
email: hi@bluemedia.dev
btnName: Say hi!
footer:
recentPosts:
path: "blog"
count: 3
title: Recent Posts
enable: true
disableFeaturedImage: false

View file

@ -0,0 +1,73 @@
---
title: "Hosting your own authoritative DNS servers using PowerDNS"
date: 2021-12-22T13:25:44+01:00
draft: false
author: "Bluemedia (Oliver)"
tags:
- Cloud
- Docker
- Hosting
- DNS
- PowerDNS
image: "/images/general/server-rack.jpg"
summary: "In this post, I'd like to discuss my idea and plans for running my own authoritative DNS server based on PowerDNS."
socialShare: false
toc:
---
## Intro
A quick disclaimer at first: This post is not intended to be a complete guide on how to build your own system. It is more intended as an example of how I solved my personal requirements. PowerDNS is a very powerful tool and offers many ways to solve problems in different ways. In the end, everyone has to decide for themselves what they think is an ideal configuration and whether they want to leave it to the “big bad internet” like this.
**Should you run your own authoritative DNS servers?**
*In most cases, probably not.*
**Am I doing it anyway?**
*Of course I do.*
**Why, you may ask?**
*Because I can, and its a good way to learn more about DNS.*
Im generally a big fan of having important services under my own control, as you may have noticed already from some other posts. This allows me to customize them exactly as I want to. My infrastructure is mostly automated, so I dont have to waste my free time on maintaining it. Unfortunately, my registrar, where I get almost all my domain names, doesnt have a particularly great API for managing DNS records. This is, of course, a problem in such a case.
Because of this, Ive been using Cloudflare as my DNS provider for a while now. The free package with the included features is quite usable, and they have a really great API. After the second major outage of Cloudflare, however, I realized that it might not be the best idea to make half of the Internet depend on one provider. For this reason and also because Im generally interested in the topic from a technical perspective, it ended up on my to-do list at some point.
## Starting off with a plan
So what are the things you need to consider if you really want to run such a service yourself?
In my opinion, you should know what you are doing before you actually start doing it. Accordingly, the topic has started for me by first reading up on “best practices” for DNS and the documentation of my desired software ([PowerDNS](https://www.powerdns.com/)) over a good cup of coffee. While doing so, a more or less finished concept formed in my head, which Im fairly certain is perfectly acceptable as is.
Based on my initial starting position, I knew it had to be highly available, fault-tolerant, and relatively inexpensive. These things are not necessarily opposed to each other here.
To meet my requirements, Im using two small servers at different providers (Hetzner and Netcup) located at different sites (Nuremberg and Falkenstein). Furthermore, because both servers are in different top-level domains (.dev and.re), even the theoretical failure of an entire top-level domain can be compensated.
Each server runs a MariaDB instance and PowerDNS with a minimal configuration. NS1 is the primary system, which is also used for administration. NS2 hosts a read-only replica of the PowerDNS database and PowerDNS itself. Both externally accessible PowerDNS instances have read-only access to the database and no enabled special functions, such as the HTTP API. They merely act as “dumb” resolvers.
On NS1, there is also another PowerDNS instance running inside Docker, this time with write access to the database and an enabled HTTP API, as well as an instance of [PowerDNS-Admin](https://github.com/PowerDNS-Admin/PowerDNS-Admin) for the actual administration. From the outside, PowerDNS-Admin is accessible via an Nginx reverse proxy that takes care of things like TLS termination and logging. Both servers are connected by a WireGuard tunnel for the MariaDB replication traffic.
PowerDNS-Admin is a comprehensive administration toolkit for PowerDNS. It provides full multi-tenancy in terms of zone management and can manage API keys restricted to individual zones. It also provides a well-organized web interface for the overall administration.
This is how my finished concept looks on the drawing board:
![](/images/posts/authorative-dns-server-using-powerdns/pdns-architecture.png)
## Keeping security in mind
If you operate such a service publicly, you should also take some time to think about security. After all, you dont want your own infrastructure to be immediately taken over by the next best troll or abused for DDoS.
Therefore, it is necessary to think about the following rules:
- Only absolutely necessary services should be accessible from external sources
- Systems must be protected against unauthorized access (e.g., SSH only via public key authentication)
- Always use strong passwords and 2FA everywhere (in this case, PowerDNS-Admin)
- All software should be kept up-to-date and patches should be installed in a timely manner after their release
With DNS, there are some additional things that will save you and others from trouble:
- Both PowerDNS instances are authoritative-only and do not allow recursive queries
- Zone transfer (AXFR) should be disabled if not required, or at least restricted to certain IPs. This prevents all DNS entries (entire zones) from being retrieved at once
- You should configure appropriate rate limits in PowerDNS to make it as difficult as possible for attackers to abuse your servers for DNS reflection attacks (DDoS amplification)
## Conclusion
With a bit of ingenuity, the right planning, and the relevant documentation, an idea like this can certainly become a reality. This opens up countless possibilities to customize the system to your own needs. You need an additional DNS server? Just set up another replica. If necessary, all of this can also be automated.
By now, Ive been running my two DNS servers productively for almost two months and have already survived the first failures without any problems. Both servers were offline for a short period of time due to problems with their respective host systems, but due to the separation of the two instances, it was still possible to resolve the domains at any time.
Because PowerDNS is very resource-saving and I dont expect many DNS requests anyway, I can use the smallest server size that the respective hosting company offers. This brings my total cost to about 6 euros per month, which is still quite impressive in my opinion.

View file

@ -0,0 +1,58 @@
---
title: "Custom boot images in the Oracle Cloud Free Tier"
date: 2023-10-15T22:56:59+02:00
draft: false
author: "Bluemedia (Oliver)"
tags:
- Cloud
- Hosting
- QuickTip
image: "/images/general/hdd-open.jpg"
summary: "I recently tinkered with the Oracle cloud platform and managed to use custom boot images even in the Free Tier. Check out this post if youre also missing your favorite OS image!"
socialShare: false
toc:
---
## Intro
I recently started using the Oracle Cloud Free Tier to host some lab servers and external monitoring. The overall package is quite nice: You get 4 Ampere A1 (arm64) CPU cores and 24 GB of RAM, two AMD (x86) VMs with 1 core and 512 MB of RAM each, 200 GB of block volume space, as well as some databases, a load balacer, and other stuff. All for free.
When creating a compute instance, there are some common OS images to choose from, like Oracle Linux, Ubuntu, Rocky Linux, and more. But my personal favorite, Debian, is unfortunately not part of the portfolio.
The Oracle Cloud platform offers a way to upload custom images, but this feature is not available in the free tier as it requires a pay-as-you-go account. Somebody sane would now choose one of the available images and call it a day, but instead I started to test some things…
## Messing around with block volumes
Taking a look at how volumes work, we can note the following things:
- There are “block volumes” and “boot volumes”
- We can attach multiple volumes to a single compute instance
- We cant select block volumes (created in the "Storage" -> "Block Storage" section) as a boot volume when creating a compute instance
- When deleting a compute instance, we can opt to keep the boot volume
- Boot volumes have additional metadata that shows which OS image is installed on them
- Detached boot volumes from deleted instances can be attached to other instances like any other block volume
Thinking about the constraints above, I got an idea how we might be able to use custom images. The plan looks as follows:
- Create a compute instance
- Delete the compute instance, while keeping the boot volume
- Attach the now detached boot volume as a secondary volume to any other compute instance
- Write the custom image to the secondary volume
- Detatch the secondary volume
- Create a new compute instance using the detached boot volume instead of an OS image
- Profit!
## Checking if it actually works
Kind of hyped to have found a loophole that might actually work, I started to test if it indeed does:
- I downloaded the Debian Bookworm “genericcloud-arm64” image in the qcow2 format to an existing compute instance
- After that, I created a new Ampere A1 instance, selected Ubuntu as the OS image and deleted it right after provisioning
- I then attached the detached boot volume to my existing instance and wrote the qcow2 image to that volume using `qemu-img`:
`qemu-img convert -f qcow2 -O raw debian-12-genericcloud-arm64.qcow2 /dev/sdb`
- As the last step, I detached the volume again and created another compute instance using that volume as its boot volume
And there we go! The instance booted without any problems and I was able to log in over SSH as usual. It seems that the Oracle Cloud platform just uses standard cloudinit, so even the injection of my SSH key worked.
## Conclusion
The approach described is definitely not as nice as simply uploading your own images. If you want to provision instances automatically (e.g. with OpenTofu), this is not suitable. It is definitely not supported by Oracle and may not work with any image. However, since I only use the Oracle Cloud for testing purposes anyway, its fine for me.
By default, metrics like CPU and RAM usage will probably be missing in the cloud portal because the Oracle agent is missing in the custom image. However, this has the funny side effect that the instance is apparently no longer reclaimed if it idles for too long.

View file

@ -0,0 +1,39 @@
---
title: "Revisited: Authoritative DNS servers using PowerDNS"
date: 2023-10-15T20:28:55+02:00
draft: false
author: "Bluemedia (Oliver)"
tags:
- Cloud
- Docker
- Hosting
- DNS
- PowerDNS
image: "/images/general/server-rack.jpg"
summary: "My DNS setup has changed quite a bit since I wrote about it two years ago. Time to take a look at how it evolved!"
socialShare: false
toc:
---
## Intro
About two years ago, I wrote an article about how I host my own authoritative DNS servers using PowerDNS. They are still running, but the setup has evolved quite a bit since then. So I think its time for a short update!
## From multi to single TLD
Originally, both servers resided in different TLDs (.dev and .re). Since the renewal price for the .re domain increased, I decided to ditch the multi-TLD setup and move both servers to the same TLD. After all, the chances that all DNS servers for the whole .dev TLD become unavailable are quite low.
I also used this opportunity to rename both servers to match my new naming concept. They now live on as ns1.dns.infra.bluemedia.dev and ns2.dns.infra.bluemedia.dev.
## More containers!
In the original design, PowerDNS as well as the database were installed directly on the host operating system. Additionally, the first server also hosted a dockerized management environment. This design proved to be quite clunky and hard to maintain. Because of this, I decided to move everything inside containers and also get rid of the second PowerDNS instance on the management host.
## Full high availability
Back when I started with the project, only the first server hosted the management environment. The second server was configured solely as a read-only replica. Since I wanted to take a closer look at MariaDB Galera anyways, I decided to move to full high availibility.
In the current setup, both servers form a multi-primary MariaDB Galera cluster. To maintain quorum, I additionally added Galera Arbitrator (garbd) running on a third server. This setup now allows me to run the management environment on both servers and perform load balancing between them. The load balancing uses DNS round-robin, enhanced with PowerDNS Lua records, so that the DNS records of an unavailable server get automatically dropped from the zone.
The new design looks like this:
![](/images/posts/revisited-authoritative-dns-using-powerdns/new-pdns-architecture.jpg)

BIN
static/fav.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
static/images/about.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 KiB

BIN
static/images/hero.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB