<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>ungleich blog</title><link href="https://ungleich.ch/u/blog/" rel="alternate"/><link href="https://ungleich.ch/u/blog/feed.xml" rel="self"/><id>urn:uuid:ba00609b-052f-335c-8572-7175799fdc65</id><updated>2024-10-19T00:00:00Z</updated><author><name/></author><entry><title>IPv6 only email services coming soon</title><link href="https://ungleich.ch/u/blog/2024-10-19-ipv6-only-mail-service-coming-soon/" rel="alternate"/><updated>2024-10-19T00:00:00Z</updated><author><name>ungleich mail team</name></author><id>urn:uuid:89cd7a62-2c9c-320c-8727-d2997b6b9e9b</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Soon we will offer IPv6 only email services.
So far it has been decided that the SMTP part will be IPv6 only, the
IMAP/webmail part might be dual stack or IPv6 only as well.&lt;/p&gt;
&lt;h2&gt;Next generation services - going one step further&lt;/h2&gt;
&lt;p&gt;When you know us, you know that we have been pushing IPv6 only
services since 2017.
&lt;a href="https://ipv6onlyhosting.com"&gt;IPv6 only VMs&lt;/a&gt; - we got it.
&lt;a href="../../products/ipv6-to-ipv4-proxy/"&gt;IPv6 only websites&lt;/a&gt; - we got it.
IPv6 only routers and networks?
We
&lt;a href="../../products/vigir/"&gt;got&lt;/a&gt;
&lt;a href="../../products/viwib-wifi-ipv6-box/"&gt;plenty&lt;/a&gt;
&lt;a href="../../products/ipv6-vpn/"&gt;of&lt;/a&gt;
&lt;a href="../../products/ipv6-mobile-internet-router/"&gt;them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now we played a bit with the though of, what if there was an email
domain that can only receive emails from IPv6 capable hosts? It would
certainly be a challenge, but more for the legacy only providers, not
for us.&lt;/p&gt;
&lt;p&gt;So stay tuned and expect an IPv6 only email service soon to be
available.&lt;/p&gt;
</content></entry><entry><title>Our staticcms has been moved to kubernetes!</title><link href="https://ungleich.ch/u/blog/2024-10-13-staticcms-moved-to-kubernetes/" rel="alternate"/><updated>2024-10-13T00:00:00Z</updated><author><name>ungleich web team</name></author><id>urn:uuid:83f1130c-addc-3aaf-982b-f4c861b4d859</id><content type="html">&lt;h2&gt;Moved to kubernetes&lt;/h2&gt;
&lt;p&gt;This website and all static content has been moved to Kubernetes as of
2024-10-13. The motivation and background is very similar to what
&lt;a href="https://www.nico.schottelius.org/blog/2024-10-11-moving-into-k8s/"&gt;Nico wrote on his
blog&lt;/a&gt;
already some days ago.&lt;/p&gt;
&lt;h2&gt;Build system for teams&lt;/h2&gt;
&lt;p&gt;Differently to what Nico is doing with his private homepage, this
website will be moved into a "fancy build" system. The background is
that while for a single person running &lt;code&gt;make&lt;/code&gt; on the laptop which
modifies argocd cluster configurations, for a team of people working
on the website, things are a bit more difficult.&lt;/p&gt;
&lt;p&gt;For once, not every computer at ungleich is running Linux, we do have
some non-Linux machines and also machines not run by our kubernetes
team, so there is no direct argocd access. And neither is docker build
available on some machines.&lt;/p&gt;
&lt;p&gt;How the build pipeline will look exactly is still to be defined, but
once we have settled on one, you will link the details here - so stay
tuned for updates.&lt;/p&gt;
&lt;h2&gt;Static websites pattern&lt;/h2&gt;
&lt;p&gt;One thing we would like to share is already the structure of the helm
chart we are using for deployment: We have one helm chart that uses a
list of containers that should be deployed. Deployed by argocd
it essentially looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: staticweb-nico
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: nico
    server: 'https://kubernetes.default.svc'
  source:
    path: apps/prod/staticweb
    repoURL: '...'
    helm:
      valuesObject:
        websites:
          - name: www-nico
            image:
              harbor.k8s.ungleich.ch/nico/www.nico.schottelius.org:559c0c45
            fqdn: www.nico.schottelius.org
  project: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The name attribute is used for defining the k8s &lt;code&gt;Deployment&lt;/code&gt;, the fqdn
is passed to the nginx-ingress and the image should be pretty clear.&lt;/p&gt;
&lt;p&gt;You may notice that we use our own image registry based on
harbor. Not only is this much faster for pulling images, but it also
solves problems with other registries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;github (ghrc.io) is legacy IP only and cannot be used from the
Internet&lt;/li&gt;
&lt;li&gt;docker hub has very strict pull limits, often not allowing us to
pull in images. While this can be worked around with using a login
token, it add a certain complexity to our infrastructure deploying
logins for various registries.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This brings us to something some of you might have noticed already:&lt;/p&gt;
&lt;h2&gt;Our containers are publicly reachable&lt;/h2&gt;
&lt;p&gt;Anyone can download any container hosted on our harbor instance
without authentication. This is by design, as containers should only
contain public data. All our containers contain public, open source
applications only.&lt;/p&gt;
&lt;p&gt;Data is being injected either by an sqldump in the beginning (if it is
an existing application) or generated at startup or passed in as a
secret independently of the container.&lt;/p&gt;
&lt;p&gt;From our perspective this principle allows easy and strict separation
of private vs. public data.&lt;/p&gt;
</content></entry><entry><title>cdist does not (yet) fully support OpenWrt</title><link href="https://ungleich.ch/u/blog/2024-08-02-openwrt-no-cdist-yet/" rel="alternate"/><updated>2024-08-02T00:00:00Z</updated><author><name>ungleich networking team</name></author><id>urn:uuid:00b5068c-83bc-3c30-864f-51c89de73753</id><content type="html">&lt;h2&gt;cdist config management&lt;/h2&gt;
&lt;p&gt;As many of you know, we use
&lt;a href="https://cdi.st"&gt;cdist&lt;/a&gt; for configuration management at ungleich. And
we try to manage everything that is not (yet) in kubernetes with it.&lt;/p&gt;
&lt;p&gt;Today's short blog entry is about using cdist with openwrt.&lt;/p&gt;
&lt;h2&gt;OpenWrt at ungleich&lt;/h2&gt;
&lt;p&gt;[OpenWrt](&lt;a href="https://openwrt.org"&gt;https://openwrt.org&lt;/a&gt;] is a popular, open source operating
system used on routers, switches, etc. We use it for providing IPv6
and IPv4 connectivity to customers world wide.&lt;/p&gt;
&lt;p&gt;So far most of our devices are configured using shell scripts from our
&lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-tools"&gt;ungleich-tool git
repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However as configurations get more complex, we thought about moving
our configuration also into cdist.&lt;/p&gt;
&lt;h2&gt;OpenWrt is similar, but not the same&lt;/h2&gt;
&lt;p&gt;OpenWrt is, generally speaking, "just another Linux distribution",
albeit with a very, very small footprint. It has to be, because the
storage on a typical router can be in the size of a couple Megabytes.
Right, not Gigabyte, not Terabyte.&lt;/p&gt;
&lt;p&gt;For instance this "large" router has about 9 Megabytes of storage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 4.0M      4.0M         0 100% /rom
tmpfs                   217.0M    240.0K    216.8M   0% /tmp
/dev/mtdblock6            9.1M    420.0K      8.7M   4% /overlay
overlayfs:/overlay        9.1M    420.0K      8.7M   4% /
tmpfs                   512.0K         0    512.0K   0% /dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It does however have 512 MiB of RAM...:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# free -m
              total        used        free      shared  buff/cache   available
Mem:         444428       57120      370184         240       17124      354048
Swap:             0           0           0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, openwrt is a Linux distribution, but its environment is a bit more
challenging than a general purpose Linux distribution.&lt;/p&gt;
&lt;h2&gt;cdist &amp;amp; openwrt&lt;/h2&gt;
&lt;p&gt;Cdist uses so called "types" to configure systems idempotently. They
usually require some shell support on the target system, but nothing
fancy.&lt;/p&gt;
&lt;p&gt;However in the case of openwrt, cdist is missing some support, as of
version 7.0.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;cdist uses the system default ssh and if that uses SFTP instead of
SCP by default, it will fail, as openwrt, as of 23.05.3, only
supports legacy scp (-O). Manually patching cdist source code to
include "-O" fixes this issue for the moment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the most basic cdist type __file uses "cksum" to create a checksum
over files to decide whether or not to copy a file. cksum was chosen
in the first place, as it is very basic and can be found
everywhere. Well, everywhere but on openwrt...&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Future of cdist &amp;amp; openwrt&lt;/h2&gt;
&lt;p&gt;Both above issues can in theory be addressed, but the __file type is
very basic and needs some checksumming support. Without it, cdist
lacks a major feature and can be considered not (yet) usable.&lt;/p&gt;
&lt;p&gt;Let's see what the future brings.&lt;/p&gt;
</content></entry><entry><title>Migrating from Twitter to Mastodon</title><link href="https://ungleich.ch/u/blog/2022-11-11-migrating-from-twitter-to-mastodon/" rel="alternate"/><updated>2022-11-11T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:89847259-3711-3fae-b6cf-0c2049352b23</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;If you are in a hurry, here is the minimal amount of information you
need to move from Twitter to Mastodon:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ipv6.social"&gt;Find a server you like&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create an account&lt;/li&gt;
&lt;li&gt;Follow people you like&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ready and go!&lt;/p&gt;
&lt;h2&gt;The longer story&lt;/h2&gt;
&lt;p&gt;Mastodon is not Twitter and will never be. However both Mastodon and
Twitter are social media networks. Mastodon however is
&lt;strong&gt;decentralised&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Decentralised Social Media&lt;/h2&gt;
&lt;p&gt;What does that mean, decentralised? It means anyone can run a Mastodon
server and connect to everyone else. This is very much how the
Internet was designed: a place of many systems that talk to each
other.&lt;/p&gt;
&lt;p&gt;Twitter on the other side is a centralised solution. All data and
communication is hosted by Twitter. If Twitter is going down, everyone
is affected.&lt;/p&gt;
&lt;p&gt;Mastodon on the other hand is much more robust. You can and have to
choose a Mastodon instance that you like.&lt;/p&gt;
&lt;h2&gt;Which Mastodon instance to use?&lt;/h2&gt;
&lt;p&gt;There are plenty of instances around and you can choose the one you
trust most or your friends are on. There are various lists of Mastodon
instances, such as the one at
&lt;a href="https://joinmastodon.org/servers"&gt;joinmastodon.org&lt;/a&gt; or at
&lt;a href="instances.social/list"&gt;instances.social&lt;/a&gt;
(thanks to
&lt;a href="https://tech.lgbt/@AltoidLover/109325600888809019"&gt;@AltoidLover@tech.lgbt&lt;/a&gt;
for the pointer).&lt;/p&gt;
&lt;p&gt;Or, you can even
&lt;a href="https://docs.joinmastodon.org/user/run-your-own/"&gt;run your own Mastodon
instance&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Your own Mastodon instance&lt;/h2&gt;
&lt;p&gt;Why would you want to run your own Mastodon instance in the first
place? Let's take a few steps back, to understand the fundamental
difference between Twitter and the Fediverse. The Fedi-what?&lt;/p&gt;
&lt;p&gt;We so far said Mastodon everywhere, but in reality, Mastodon is just
one software that allows you to communicate decentralised. In general,
we refer to the decentralised communication as the "FEDIVERSE". That's
settled, now let's go back to why anyone would want to run their own
instance.&lt;/p&gt;
&lt;p&gt;First of all, running your own mastodon instance allows you to use
your own, custom domain. So my handle is
&lt;a href="https://ipv6.social/@nico"&gt;@nico@ipv6.social&lt;/a&gt; and it indicates I am
somewhat interested in #IPv6 related topics, just from the domain of
the instance I am on.&lt;/p&gt;
&lt;p&gt;If you already have a domain, many people also choose to use the
subdomain "social", like social.example.com.&lt;/p&gt;
&lt;p&gt;There is a second, maybe equally significant point when it comes to
Mastodon. That is the question of who is going to take care of the
instance, who is going to update the software and who is actually
going to pay for running the instance?&lt;/p&gt;
&lt;h2&gt;In the fediverse, you are not a product&lt;/h2&gt;
&lt;p&gt;Compared to Twitter, where advertisement turns the user into a
product, in the fediverse you are not a product. That also means that
the organisation running a Mastodon instance does actually need to pay
for the service. Whether that is running a VPS, running a Raspberry PI
or having it hosted by someone else, somebody has to provide the
resource for it.&lt;/p&gt;
&lt;p&gt;This is fundamentally different compared to Twitter, but also
Facebook, where you are basically also just a product.&lt;/p&gt;
&lt;p&gt;The big advantage of this is that there is no advertisement, no
central user analytics, but much more freedom. Like we say in
Switzerland, you &lt;a href="https://dict.leo.org/forum/viewGeneraldiscussion.php?idForum=4&amp;amp;idThread=1051992&amp;amp;lp=ende&amp;amp;lang=en"&gt;Khasch nit z'Füferli und z Weggli
ha&lt;/a&gt;
or in proper English: you cannot have everything. And that's a good
thing.&lt;/p&gt;
&lt;h2&gt;Importing Twitter Followers into the Fediverse&lt;/h2&gt;
&lt;p&gt;You might have noticed that more and more Twitter accounts add their
fediverse handle like
&lt;a href="https://ipv6.social/@ungleich"&gt;@ungleich@ipv6.social&lt;/a&gt;
to their Twitter
handle. There is a nifty tool available that scans your account for
the handles and imports them on the fediverse site for you. It is
called &lt;a href="https://pruvisto.org/debirdify/"&gt;Debirdify&lt;/a&gt; and it's a good
start to get a list of people to follow. Debirdify can actually scan
your followers and the ones you follow, too.&lt;/p&gt;
&lt;h2&gt;More guides&lt;/h2&gt;
&lt;p&gt;If you interested in reading Is there more
about moving from Twitter to Mastodon, there are other articles you
might be interested in, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://techcrunch.com/2022/11/08/what-is-mastodon/"&gt;A beginner’s guide to Mastodon, the open source Twitter alternative
(techcrunch)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tobru.ch/how-to-mastodon/"&gt;How-To Mastodon (Tobru, covers Swiss specific
aspects)&lt;/a&gt; (thanks for
&lt;a href="https://mstdn.social/@tobru"&gt;@tobru@mstdn.social&lt;/a&gt; for the pointer)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mastodon Hosting by ungleich&lt;/h2&gt;
&lt;p&gt;Shameless plug at the end - we have just
launched &lt;a href="../../products/mastodon-hosting/"&gt;Mastodon hosting by ungleich&lt;/a&gt;
to provide you an easy way to start in the fediverse. Remember, you
don't have to go with us, but the beauty of the fediverse is you can
host your own, use somebody else's server or use a hosted Mastodon
instance.&lt;/p&gt;
&lt;h2&gt;P.S.: A Post Twitter World&lt;/h2&gt;
&lt;p&gt;Twitter might not yet be done and even at ungleich we have a lot of
references to our Twitter account. We don't know whether everyone will
move to the fediverse, but we very much welcome a push towards
decentralisation of the Internet.&lt;/p&gt;
&lt;p&gt;For many years, probably about a decade or two, we have become more
and more reliant on centralised services. These services might have
made our lives easier, but also much more dependent on a few
organisations.&lt;/p&gt;
&lt;p&gt;It is a good thing to review what we are using from time to time and
today we are looking stronger at Twitter - tomorrow we might consider
a different search engine - who knows?&lt;/p&gt;
&lt;p&gt;I am looking forward to hearing you in the fediverse and if you have any
comment, do not hesitate to reach out to &lt;a href="https://ipv6.social/@nico"&gt;@nico@ipv6.social&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>[WIP] Migrating Ceph Nautilus into Kubernetes + Rook</title><link href="https://ungleich.ch/u/blog/2022-08-27-migrating-ceph-nautilus-into-kubernetes-with-rook/" rel="alternate"/><updated>2022-08-27T00:00:00Z</updated><author><name>ungleich storage team</name></author><id>urn:uuid:1f89e536-a209-39e9-8e36-1b9e66d2d2c6</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At ungleich we are running multiple Ceph clusters. Some of them are
running Ceph Nautilus (14.x) based on
&lt;a href="https://www.devuan.org/"&gt;Devuan&lt;/a&gt;. Our newer Ceph Pacific (16.x)
clusters are running based on &lt;a href="https://rook.io/"&gt;Rook&lt;/a&gt; on
&lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; on top of
&lt;a href="https://alpinelinux.org/"&gt;Alpine Linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this blog article we will describe how to migrate
Ceph/Native/Devuan to Ceph/k8s+rook/Alpine Linux.&lt;/p&gt;
&lt;h2&gt;Work in Progress [WIP]&lt;/h2&gt;
&lt;p&gt;This blog article is work in progress. The migration planning has
started, however the migration has not been finished yet. This article
will feature the different paths we take for the migration.&lt;/p&gt;
&lt;h2&gt;The Plan&lt;/h2&gt;
&lt;p&gt;To continue operating the cluster during the migration, the following
steps are planned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup a k8s cluster that can potentially communicate with the
existing ceph cluster&lt;/li&gt;
&lt;li&gt;Using the &lt;a href="https://rook.io/docs/rook/v1.9/Troubleshooting/disaster-recovery/"&gt;disaster
recovery&lt;/a&gt;
guidelines from rook to modify the rook configuration to use the
previous fsid.&lt;/li&gt;
&lt;li&gt;Spin up ceph monitors and ceph managers in rook&lt;/li&gt;
&lt;li&gt;Retire existing monitors&lt;/li&gt;
&lt;li&gt;Shutdown a ceph OSD node, remove it's OS disk, boot it with Alpine
Linux&lt;/li&gt;
&lt;li&gt;Join the node into the k8s cluster&lt;/li&gt;
&lt;li&gt;Have rook pickup the existing disks and start the osds&lt;/li&gt;
&lt;li&gt;Repeat if successful&lt;/li&gt;
&lt;li&gt;Migrate to ceph pacific&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Original cluster&lt;/h3&gt;
&lt;p&gt;The target ceph cluster we want to migrate lives in the 2a0a:e5c0::/64
network. Ceph is using:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public network  = 2a0a:e5c0:0:0::/64
cluster network = 2a0a:e5c0:0:0::/64
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Kubernetes cluster networking inside the ceph network&lt;/h3&gt;
&lt;p&gt;To be able to communicate with the existing OSDs, we will be using
sub networks of 2a0a:e5c0::/64 for kubernetes. As these networks
are part of the link assigned network 2a0a:e5c0::/64, we will use BGP
routing on the existing ceph nodes to create more specific routes into
the kubernetes cluster.&lt;/p&gt;
&lt;p&gt;As we plan to use either &lt;a href="https://cilium.io/"&gt;cilium&lt;/a&gt; or
&lt;a href="https://www.tigera.io/project-calico/"&gt;calico&lt;/a&gt; as the CNI, we can
configure kubernetes to directly BGP peer with the existing Ceph
nodes.&lt;/p&gt;
&lt;h2&gt;The setup&lt;/h2&gt;
&lt;h3&gt;Kubernetes Bootstrap&lt;/h3&gt;
&lt;p&gt;As usual we bootstrap 3 control plane nodes using kubeadm. The proxy
for the API resides in a different kuberentes cluster.&lt;/p&gt;
&lt;p&gt;We run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubeadm init --config kubeadm.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;on the first node and join the other two control plane nodes. As
usual, joining the workers last.&lt;/p&gt;
&lt;h3&gt;k8s Networking / CNI&lt;/h3&gt;
&lt;p&gt;For this setup we are using calico as described in the
&lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki/The_ungleich_kubernetes_infrastructure#section-23"&gt;ungleich kubernetes
manual&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;VERSION=v3.23.3
helm repo add projectcalico https://docs.projectcalico.org/charts
helm upgrade --install --namespace tigera calico projectcalico/tigera-operator --version $VERSION --create-namespace
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;BGP Networking on the old nodes&lt;/h3&gt;
&lt;p&gt;To be able to import the BGP routes from Kubernetes, all old / native
hosts will run bird. The installation and configuration is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt-get update
apt-get install -y bird2

router_id=$(hostname | sed 's/server//')

cat &amp;gt; /etc/bird/bird.conf &amp;lt;&amp;lt;EOF

router id $router_id;

log syslog all;
protocol device {
}
 # We are only interested in IPv6, skip another section for IPv4
protocol kernel {
        ipv6 { export all; };
}
protocol bgp k8s {
        local     as 65530;
        neighbor range 2a0a:e5c0::/64 as 65533;
        dynamic name "k8s_"; direct;

        ipv6 {
            import filter { if net.len &amp;gt; 64 then accept; else reject; };
            export none;
        };
}
EOF
/etc/init.d/bird restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The router id must be adjusted for every host. As all hosts have a
unique number, we use that one as the router id.
The bird configuration allows to use dynamic peers so that any k8s
node in the network can peer with the old servers.&lt;/p&gt;
&lt;p&gt;We also use a filter to avoid receiving /64 routes, as they are
overlapping with the on link route.&lt;/p&gt;
&lt;h3&gt;BGP networking in Kubernetes&lt;/h3&gt;
&lt;p&gt;Calico supports BGP peering and we use a rather standard calico
configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
  name: default
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: true
  asNumber: 65533
  serviceClusterIPs:
  - cidr: 2a0a:e5c0:0:aaaa::/108
  serviceExternalIPs:
  - cidr: 2a0a:e5c0:0:aaaa::/108
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plus for each server and router we create a BGPPeer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: serverXX
spec:
  peerIP: 2a0a:e5c0::XX
  asNumber: 65530
  keepOriginalNextHop: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We apply the whole configuration using calicoctl:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./calicoctl create -f - &amp;lt; ~/vcs/k8s-config/bootstrap/p5-cow/calico-bgp.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a few seconds later we can observer the routes on the old / native
hosts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bird&amp;gt; show protocols
Name       Proto      Table      State  Since         Info
device1    Device     ---        up     23:09:01.393
kernel1    Kernel     master6    up     23:09:01.393
k8s        BGP        ---        start  23:09:01.393  Passive
k8s_1      BGP        ---        up     23:33:01.215  Established
k8s_2      BGP        ---        up     23:33:01.215  Established
k8s_3      BGP        ---        up     23:33:01.420  Established
k8s_4      BGP        ---        up     23:33:01.215  Established
k8s_5      BGP        ---        up     23:33:01.215  Established
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Testing networking&lt;/h3&gt;
&lt;p&gt;To verify that the new cluster is working properly, we can deploy a
tiny test deployment and see if it is globally reachable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.20.0-alpine
        ports:
        - containerPort: 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the corresponding service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using curl to access a sample service from the outside shows that
networking is working:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -v http://[2a0a:e5c0:0:aaaa::e3c9]
*   Trying 2a0a:e5c0:0:aaaa::e3c9:80...
* Connected to 2a0a:e5c0:0:aaaa::e3c9 (2a0a:e5c0:0:aaaa::e3c9) port 80 (#0)
&amp;gt; GET / HTTP/1.1
&amp;gt; Host: [2a0a:e5c0:0:aaaa::e3c9]
&amp;gt; User-Agent: curl/7.84.0
&amp;gt; Accept: */*
&amp;gt;
* Mark bundle as not supporting multiuse
&amp;lt; HTTP/1.1 200 OK
&amp;lt; Server: nginx/1.20.0
&amp;lt; Date: Sat, 27 Aug 2022 22:35:49 GMT
&amp;lt; Content-Type: text/html
&amp;lt; Content-Length: 612
&amp;lt; Last-Modified: Tue, 20 Apr 2021 16:11:05 GMT
&amp;lt; Connection: keep-alive
&amp;lt; ETag: "607efd19-264"
&amp;lt; Accept-Ranges: bytes
&amp;lt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx!&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Welcome to nginx!&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;For online documentation and support please refer to
&amp;lt;a href="http://nginx.org/"&amp;gt;nginx.org&amp;lt;/a&amp;gt;.&amp;lt;br/&amp;gt;
Commercial support is available at
&amp;lt;a href="http://nginx.com/"&amp;gt;nginx.com&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Thank you for using nginx.&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
* Connection #0 to host 2a0a:e5c0:0:aaaa::e3c9 left intact
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far we have found 1 issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sometimes the old/native servers can reach the service, sometimes
they get a timeout&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In old calico notes on github it is referenced that overlapping
Pod/CIDR networks might be a problem. Additionally we cannot use
kubeadm to initialise the podsubnet to be a proper subnet of the node
subnet:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[00:15] server57.place5:~# kubeadm init --service-cidr 2a0a:e5c0:0:cccc::/108 --pod-network-cidr 2a0a:e5c0::/100
I0829 00:16:38.659341   19400 version.go:255] remote version is much newer: v1.25.0; falling back to: stable-1.24
podSubnet: Invalid value: "2a0a:e5c0::/100": the size of pod subnet with mask 100 is smaller than the size of node subnet with mask 64
To see the stack trace of this error execute with --v=5 or higher
[00:16] server57.place5:~#
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Networking 2022-09-03&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Instead of trying to merge the cluster networks, we will use
separate ranges&lt;/li&gt;
&lt;li&gt;According to the &lt;a href="https://www.spinics.net/lists/ceph-users/msg73421.html"&gt;ceph users mailing list
discussion&lt;/a&gt;
it is actually not necessary for mons/osds to be in the same
network. In fact, we might be able to remove these settings
completely.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So today we start with&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;podSubnet: 2a0a:e5c0:0:14::/64&lt;/li&gt;
&lt;li&gt;serviceSubnet: 2a0a:e5c0:0:15::/108&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using BGP and calico, the kubernetes cluster is setup "as usual" (for
ungleich terms).&lt;/p&gt;
&lt;h3&gt;Ceph.conf change&lt;/h3&gt;
&lt;p&gt;Originally our ceph.conf contained:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public network  = 2a0a:e5c0:0:0::/64
cluster network = 2a0a:e5c0:0:0::/64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As of today they are removed and all daemons are restarted, allowing
the native cluster to speak with the kubernetes cluster.&lt;/p&gt;
&lt;h3&gt;Setting up rook&lt;/h3&gt;
&lt;p&gt;Usually we deploy rook via argocd. However as we want to be easily
able to do manual intervention, we will first bootstrap rook via helm
directly and turn off various services&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;helm repo add rook https://charts.rook.io/release
helm repo update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will use rook 1.8, as it is the last version to support Ceph
nautilus, which is our current ceph version. The latest 1.8 version is
1.8.10 at the moment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;helm upgrade --install --namespace rook-ceph --create-namespace --version v1.8.10 rook-ceph rook/rook-ceph
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Joining the 2 clusters, step 1: monitors and managers&lt;/h3&gt;
&lt;p&gt;In the first step we want to add rook based monitors and managers
and replace the native ones. For rook to be able to talk to our
existing cluster, it needs to know&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the current monitors/managers ("the monmap")&lt;/li&gt;
&lt;li&gt;the right keys to talk to the existing cluster&lt;/li&gt;
&lt;li&gt;the fsid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As we are using v1.8, we will follow
&lt;a href="https://www.rook.io/docs/rook/v1.8/ceph-disaster-recovery.html"&gt;the guidelines for disaster recover of rook
1.8&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Later we will need to create all the configurations so that rook knows
about the different pools.&lt;/p&gt;
&lt;h3&gt;Rook: CephCluster&lt;/h3&gt;
&lt;p&gt;Rook has a configuration of type &lt;code&gt;CephCluster&lt;/code&gt; that typically looks
something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    # see the "Cluster Settings" section below for more details on which image of ceph to run
    image: quay.io/ceph/ceph:{{ .Chart.AppVersion }}
  dataDirHostPath: /var/lib/rook
  mon:
    count: 5
    allowMultiplePerNode: false
  storage:
    useAllNodes: true
    useAllDevices: true
    onlyApplyOSDPlacement: false
  mgr:
    count: 1
    modules:
      - name: pg_autoscaler
        enabled: true
  network:
    ipFamily: "IPv6"
    dualStack: false
  crashCollector:
    disable: false
    # Uncomment daysToRetain to prune ceph crash entries older than the
    # specified number of days.
    daysToRetain: 30
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For migrating, we don't want rook in the first stage to create any
OSDs. So we will replace &lt;code&gt;useAllNodes: true&lt;/code&gt; with &lt;code&gt;useAllNodes: false&lt;/code&gt;
and &lt;code&gt;useAllDevices: true&lt;/code&gt; also with &lt;code&gt;useAllDevices: false&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Extracting a monmap&lt;/h3&gt;
&lt;p&gt;To get access to the existing monmap, we can export it from the native
cluster using &lt;code&gt;ceph-mon -i {mon-id} --extract-monmap {map-path}&lt;/code&gt;.
More details can be found on the &lt;a href="https://docs.ceph.com/en/latest/rados/operations/add-or-rm-mons/"&gt;documentation for adding and
removing ceph
monitors&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Rook and Ceph pools&lt;/h3&gt;
&lt;p&gt;Rook uses &lt;code&gt;CephBlockPool&lt;/code&gt; to describe ceph pools as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: hdd
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3
  deviceClass: hdd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this particular cluster we have 2 pools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one (ssd based, device class = ssd)&lt;/li&gt;
&lt;li&gt;hdd (hdd based, device class = hdd-big)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The device class "hdd-big" is specific to this cluster as it used to
contain 2.5" and 3.5" HDDs in different pools.&lt;/p&gt;
&lt;h3&gt;[old] Analysing the ceph cluster configuration&lt;/h3&gt;
&lt;p&gt;Taking the view from the old cluster, the following items are
important for adding new services/nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have a specific fsid that needs to be known&lt;ul&gt;
&lt;li&gt;The expectation would be to find that fsid in a configmap/secret in rook&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We have a list of running monitors&lt;ul&gt;
&lt;li&gt;This is part of the monmap and ceph.conf&lt;/li&gt;
&lt;li&gt;ceph.conf is used for finding the initial contact point&lt;/li&gt;
&lt;li&gt;Afterwards the information is provided by the monitors&lt;/li&gt;
&lt;li&gt;For rook it would be expected to have a configmap/secret listing
the current monitors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The native clusters have a "ceph.client.admin.keyring" deployed which
allows adding and removing resources.&lt;ul&gt;
&lt;li&gt;Rook probably has a secret for keyrings&lt;/li&gt;
&lt;li&gt;Maybe multiple depending on how services are organised&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Analysing the rook configurations&lt;/h3&gt;
&lt;p&gt;Taking the opposite view, we can also checkout a running rook cluster
and the rook disaster recovery documentation to identify what to
modify.&lt;/p&gt;
&lt;p&gt;Let's have a look at the secrets first:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cluster-peer-token-rook-ceph                 kubernetes.io/rook                    2      320d
default-token-xm9xs                          kubernetes.io/service-account-token   3      320d
rook-ceph-admin-keyring                      kubernetes.io/rook                    1      320d
rook-ceph-admission-controller               kubernetes.io/tls                     3      29d
rook-ceph-cmd-reporter-token-5mh88           kubernetes.io/service-account-token   3      320d
rook-ceph-config                             kubernetes.io/rook                    2      320d
rook-ceph-crash-collector-keyring            kubernetes.io/rook                    1      320d
rook-ceph-mgr-a-keyring                      kubernetes.io/rook                    1      320d
rook-ceph-mgr-b-keyring                      kubernetes.io/rook                    1      320d
rook-ceph-mgr-token-ktt2m                    kubernetes.io/service-account-token   3      320d
rook-ceph-mon                                kubernetes.io/rook                    4      320d
rook-ceph-mons-keyring                       kubernetes.io/rook                    1      320d
rook-ceph-osd-token-8m6lb                    kubernetes.io/service-account-token   3      320d
rook-ceph-purge-osd-token-hznnk              kubernetes.io/service-account-token   3      320d
rook-ceph-rgw-token-wlzbc                    kubernetes.io/service-account-token   3      134d
rook-ceph-system-token-lxclf                 kubernetes.io/service-account-token   3      320d
rook-csi-cephfs-node                         kubernetes.io/rook                    2      320d
rook-csi-cephfs-plugin-sa-token-hkq2g        kubernetes.io/service-account-token   3      320d
rook-csi-cephfs-provisioner                  kubernetes.io/rook                    2      320d
rook-csi-cephfs-provisioner-sa-token-tb78d   kubernetes.io/service-account-token   3      320d
rook-csi-rbd-node                            kubernetes.io/rook                    2      320d
rook-csi-rbd-plugin-sa-token-dhhq6           kubernetes.io/service-account-token   3      320d
rook-csi-rbd-provisioner                     kubernetes.io/rook                    2      320d
rook-csi-rbd-provisioner-sa-token-lhr4l      kubernetes.io/service-account-token   3      320d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TBC&lt;/p&gt;
&lt;h3&gt;Creating additional resources after the cluster is bootstrapped&lt;/h3&gt;
&lt;p&gt;To let rook know what should be there, we already create the two
&lt;code&gt;CephBlockPool&lt;/code&gt; instances that match the existing pools:&lt;/p&gt;
&lt;p&gt;```apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: one
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3
  deviceClass: ssd&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And for the hdd based pool:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: hdd
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3
  deviceClass: hdd-big&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Saving both of these in ceph-blockpools.yaml and applying it:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl -n rook-ceph apply -f ceph-blockpools.yaml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
### Configuring ceph after the operator deployment

As soon as the operator and the crds have been deployed, we deploy the
following
[CephCluster](https://rook.io/docs/rook/v1.8/ceph-cluster-crd.html)
configuration:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: quay.io/ceph/ceph:v14.2.21
  dataDirHostPath: /var/lib/rook
  mon:
    count: 5
    allowMultiplePerNode: false
  storage:
    useAllNodes: false
    useAllDevices: false
    onlyApplyOSDPlacement: false
  mgr:
    count: 1
    modules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  - name: pg_autoscaler
    enabled: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;network:
    ipFamily: "IPv6"
    dualStack: false
  crashCollector:
    disable: false&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Uncomment daysToRetain to prune ceph crash entries older than the
# specified number of days.
daysToRetain: 30
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
We wait for the cluster to initialise and stabilise before applying
changes. Important to note is that we use the ceph image version
v14.2.21, which is the same version as the native cluster.



### rook v1.8 is incompatible with ceph nautilus

After deploying the rook operator, the following error message is
printed in its logs:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2022-09-03 15:14:03.543925 E | ceph-cluster-controller: failed to reconcile CephCluster "rook-ceph/rook-ceph". failed to reconcile cluster "rook-ceph": failed to configure local ceph cluster: failed the ceph version check: the version does not meet the minimum version "15.2.0-0 octopus"&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
So we need to downgrade to rook v1.7. Using `helm search repo
rook/rook-ceph --versions` we identify the latest usable version should be `v1.7.11`.

We start the downgrade process using
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;helm upgrade --install --namespace rook-ceph --create-namespace --version v1.7.11 rook-ceph rook/rook-ceph&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
After downgrading the operator is starting the canary monitors and
continues to bootstrap the cluster.

### The ceph-toolbox

To be able to view the current cluster status, we also deploy the
ceph-toolbox for interacting with rook:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: rook-ceph-tools
  namespace: rook-ceph # namespace:cluster
  labels:
    app: rook-ceph-tools
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rook-ceph-tools
  template:
    metadata:
      labels:
        app: rook-ceph-tools
    spec:
      dnsPolicy: ClusterFirstWithHostNet
      containers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    - name: rook-ceph-tools
      image: rook/ceph:v1.7.11
      command: ["/bin/bash"]
      args: ["-m", "-c", "/usr/local/bin/toolbox.sh"]
      imagePullPolicy: IfNotPresent
      tty: true
      securityContext:
        runAsNonRoot: true
        runAsUser: 2016
        runAsGroup: 2016
      env:
        - name: ROOK_CEPH_USERNAME
          valueFrom:
            secretKeyRef:
              name: rook-ceph-mon
              key: ceph-username
        - name: ROOK_CEPH_SECRET
          valueFrom:
            secretKeyRef:
              name: rook-ceph-mon
              key: ceph-secret
      volumeMounts:
        - mountPath: /etc/ceph
          name: ceph-config
        - name: mon-endpoint-volume
          mountPath: /etc/rook
  volumes:
    - name: mon-endpoint-volume
      configMap:
        name: rook-ceph-mon-endpoints
        items:
          - key: data
            path: mon-endpoints
    - name: ceph-config
      emptyDir: {}
  tolerations:
    - key: "node.kubernetes.io/unreachable"
      operator: "Exists"
      effect: "NoExecute"
      tolerationSeconds: 5
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
### Checking the deployments

After the rook-operator finished deploying, the following deployments
are visible in kubernetes:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[17:25] blind:~% kubectl -n rook-ceph get deployment
NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
csi-cephfsplugin-provisioner        2/2     2            2           21m
csi-rbdplugin-provisioner           2/2     2            2           21m
rook-ceph-crashcollector-server48   1/1     1            1           2m3s
rook-ceph-crashcollector-server52   1/1     1            1           2m24s
rook-ceph-crashcollector-server53   1/1     1            1           2m2s
rook-ceph-crashcollector-server56   1/1     1            1           2m17s
rook-ceph-crashcollector-server57   1/1     1            1           2m1s
rook-ceph-mgr-a                     1/1     1            1           2m3s
rook-ceph-mon-a                     1/1     1            1           10m
rook-ceph-mon-b                     1/1     1            1           8m3s
rook-ceph-mon-c                     1/1     1            1           5m55s
rook-ceph-mon-d                     1/1     1            1           5m33s
rook-ceph-mon-e                     1/1     1            1           4m32s
rook-ceph-operator                  1/1     1            1           102m
rook-ceph-tools                     1/1     1            1           17m&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Relevant for us are the mgr, mon and operator. To stop the cluster, we
will shutdown the deployments in the following order:

* rook-ceph-operator: to prevent deployments to recover

### Data / configuration comparison

Logging into a host that is running mon-a, we find the following data
in it:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[17:36] server56.place5:/var/lib/rook# find
.
./mon-a
./mon-a/data
./mon-a/data/keyring
./mon-a/data/min_mon_release
./mon-a/data/store.db
./mon-a/data/store.db/LOCK
./mon-a/data/store.db/000006.log
./mon-a/data/store.db/000004.sst
./mon-a/data/store.db/CURRENT
./mon-a/data/store.db/MANIFEST-000005
./mon-a/data/store.db/OPTIONS-000008
./mon-a/data/store.db/OPTIONS-000005
./mon-a/data/store.db/IDENTITY
./mon-a/data/kv_backend
./rook-ceph
./rook-ceph/crash
./rook-ceph/crash/posted
./rook-ceph/log&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Which is pretty similar to the native nodes:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[17:37:50] red3.place5:/var/lib/ceph/mon/ceph-red3# find
.
./sysvinit
./keyring
./min_mon_release
./kv_backend
./store.db
./store.db/1959645.sst
./store.db/1959800.sst
./store.db/OPTIONS-3617174
./store.db/2056973.sst
./store.db/3617348.sst
./store.db/OPTIONS-3599785
./store.db/MANIFEST-3617171
./store.db/1959695.sst
./store.db/CURRENT
./store.db/LOCK
./store.db/2524598.sst
./store.db/IDENTITY
./store.db/1959580.sst
./store.db/2514570.sst
./store.db/1959831.sst
./store.db/3617346.log
./store.db/2511347.sst&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
### Checking how monitors are created on native ceph

To prepare for the migration we take 1 step back and verify how
monitors are created in the native cluster. The script used for
monitoring creation can be found on
[code.ungleich.ch](https://code.ungleich.ch/ungleich-public/ungleich-tools/src/branch/master/ceph/ceph-mon-create-start)
and contains the following logic:

* get "mon." key
* get the monmap
* Run ceph-mon --mkfs using the monmap and keyring
* Start it

In theory we could re-use these steps on a rook deployed monitor to
join our existing cluster.

### Checking the toolbox and monitor pods for migration

When the ceph-toolbox is deployed, we get a ceph.conf and a keyring in
/etc/ceph. The keyring is actually the admin keyring and allows us to
make modifications to the ceph cluster. The ceph.conf points to the
monitors and does not contain an fsid.

The ceph-toolbox gets this informatoin via 1 configmap
("rook-ceph-mon-endpoints") and a secret ("rook-ceph-mon").

The monitor pods on the other hand have an empty ceph.conf and no
admin keyring deployed.

### Try 1: recreating a monitor inside the existing cluster

Let's try to reuse an existing monitor and join it into the existing
cluster. For this we will first shut down the rook-operator, to
prevent it to intefere with our migration. Then
modify the relevant configmaps and secrets and import the settings
from the native cluster.

Lastly we will patch one of the monitor pods, inject the monmap from
the native cluster and then restart it.

Let's give it a try. First we shutdown the rook-ceph-operator:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;% kubectl -n rook-ceph scale --replicas=0 deploy/rook-ceph-operator
deployment.apps/rook-ceph-operator scaled&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Then we patch the mon deployments to not run a monitor, but only
sleep:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;for mon in a b c d e; do
kubectl -n rook-ceph patch deployment rook-ceph-mon-${mon} -p \
'{"spec": {"template": {"spec": {"containers": [{"name": "mon", "command": ["sleep", "infinity"], "args": []}]}}}}';&lt;/p&gt;
&lt;p&gt;kubectl -n rook-ceph patch deployment rook-ceph-mon-$mon  --type='json' -p '[{"op":"remove", "path":"/spec/template/spec/containers/0/livenessProbe"}]'
done&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Now the pod is restarted and when we execute into it, we will see that
no monitor is running in it:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;% kubectl -n rook-ceph exec -ti rook-ceph-mon-a-c9f8f554b-2fkhm -- sh
Defaulted container "mon" out of: mon, chown-container-data-dir (init), init-mon-fs (init)
sh-4.2# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4384   664 ?        Ss   19:44   0:00 sleep infinity
root         7  0.0  0.0  11844  2844 pts/0    Ss   19:44   0:00 sh
root        13  0.0  0.0  51752  3384 pts/0    R+   19:44   0:00 ps aux
sh-4.2#&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Now for this pod to work with our existing cluster, we want to import
the monmap and join the monitor to the native cluster. As with any
mon, the data is stored below `/var/lib/ceph/mon/ceph-a/`.

Before importing the monmap, let's have a look at the different rook
configurations that influence the ceph components

### Looking at the ConfigMap in detail: rook-ceph-mon-endpoints

As the name says, it contains the list of monitor endpoints:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl -n rook-ceph edit configmap rook-ceph-mon-endpoints
...&lt;/p&gt;
&lt;p&gt;csi-cluster-config-json: '[{"clusterID":"rook-ceph","monitors":["[2a0a:e5c0:0:15::fc2]:6789"...
  data: b=[2a0a:e5c0:0:15::9cd9]:6789,....
  mapping: '{"node":{"a":{"Name":"server56","Hostname":"server56","Address":"2a0a:e5c0::...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
As eventually we want the cluster and csi to use the in-cluster
monitors, we don't need to modify it right away.

### Looking at Secrets in detail: rook-ceph-admin-keyring

The first interesting secret is **rook-ceph-admin-keyring**, which
contains the admin keyring. The old one of course, so we can edit this
secret and replace it with the client.admin secret from our native
cluster.

We encode the original admin keyring using:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;cat ceph.client.admin.keyring  | base64 -w 0; echo ""&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And then we update the secret it:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl -n rook-ceph edit secret rook-ceph-admin-keyring&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
[done]

### Looking at Secrets in detail: rook-ceph-config

This secret contains two keys, **mon_host** and
**mon_initial_members**. The **mon_host** is a list of monitor
addresses. The **mon_host** only contains the monitor names, a, b, c, d and e.

The environment variable **ROOK_CEPH_MON_HOST** in the monitor
deployment is set to to **mon_host** key of that secret, so monitors
will read from it.



### Looking at Secrets in detail: rook-ceph-mon

This secret contains the following interesting keys:

* ceph-secret: the admin key (just the base64 key no section around
  it) [done]
* ceph-username: "client.admin"
* fsid: the ceph cluster fsid
* mon-secret: The key of the [mon.] section

It's important to mention to use `echo -n` when inserting
the keys or fsids.

[done]

### Looking at Secrets in detail: rook-ceph-mons-keyring

Contains the key "keyring" containing the [mon.] and [client.admin]
sections:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[mon.]
    key = ...&lt;/p&gt;
&lt;p&gt;[client.admin]
    key = ...
    caps mds = "allow"
    caps mgr = "allow &lt;em&gt;"
    caps mon = "allow &lt;/em&gt;"
    caps osd = "allow *"&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Using `base64 -w0 &amp;lt;  ~/mon-and-client`.

[done]

### Importing the monmap

Getting the current monmap from the native cluster:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ceph mon getmap -o monmap-20220903&lt;/p&gt;
&lt;p&gt;scp root@old-monitor:monmap-20220903&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Adding it into the mon pod:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl cp monmap-20220903 rook-ceph/rook-ceph-mon-a-6c46d4694-kxm5h:/tmp&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Moving the old mon db away:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;cd /var/lib/ceph/mon/ceph-a
mkdir _old
mv [a-z]* _old/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Recreating the mon fails, as the volume is mounted directly onto it:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;% ceph-mon -i a --mkfs --monmap /tmp/monmap-20220903 --keyring /tmp/mon-key
2022-09-03 21:44:48.268 7f1a738f51c0 -1 '/var/lib/ceph/mon/ceph-a' already exists and is not empty: monitor may already exist&lt;/p&gt;
&lt;p&gt;% mount | grep ceph-a
/dev/sda1 on /var/lib/ceph/mon/ceph-a type ext4 (rw,relatime)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
We can workaround this by creating all monitors on pods with other
names. So we can create mon b to e on the mon-a pod and mon-a on any
other pod.

On rook-ceph-mon-a:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;for mon in b c d e;
do ceph-mon -i $mon --mkfs --monmap /tmp/monmap-20220903 --keyring /tmp/mon-key;
done&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
On rook-ceph-mon-b:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mon=a
ceph-mon -i $mon --mkfs --monmap /tmp/monmap-20220903 --keyring /tmp/mon-key&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Then we export the newly created mon dbs:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;for mon in b c d e;
do kubectl cp rook-ceph/rook-ceph-mon-a-6c46d4694-kxm5h:/var/lib/ceph/mon/ceph-$mon ceph-$mon;
done&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;for mon in a;
do kubectl cp rook-ceph/rook-ceph-mon-b-57d888dd9f-w8jkh:/var/lib/ceph/mon/ceph-$mon ceph-$mon;
done&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And finally we test it by importing the mondb to mon-a:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl cp ceph-a
rook-ceph/rook-ceph-mon-a-6c46d4694-kxm5h:/var/lib/ceph/mon/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And the other mons:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl cp ceph-b rook-ceph/rook-ceph-mon-b-57d888dd9f-w8jkh:/var/lib/ceph/mon/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
### Re-enabling the rook-operator

As the deployment
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl -n rook-ceph scale --replicas=1 deploy/rook-ceph-operator&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Operator sees them running (with a shell)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2022-09-03 22:29:26.725915 I | op-mon: mons running: [d e a b c]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Triggering recreation:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;% kubectl  -n rook-ceph delete deployment rook-ceph-mon-a
deployment.apps "rook-ceph-mon-a" deleted&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Connected successfully to the cluster:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;services:
    mon: 6 daemons, quorum red1,red2,red3,server4,server3,a (age 8s)
    mgr: red3(active, since 8h), standbys: red2, red1, server4
    osd: 46 osds: 46 up, 46 in&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
A bit later:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mon: 8 daemons, quorum  (age 2w), out of quorum: red1, red2, red3, server4, server3, a, c,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;d
    mgr: red3(active, since 8h), standbys: red2, red1, server4
    osd: 46 osds: 46 up, 46 in&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And a little bit later also the mgr joined the cluster:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;services:
    mon: 8 daemons, quorum red2,red3,server4,server3,a,c,d,e (age 46s)
    mgr: red3(active, since 9h), standbys: red1, server4, a, red2
    osd: 46 osds: 46 up, 46 in&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
And a few minutes later all mons joined successfully:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;mon: 8 daemons, quorum red3,server4,server3,a,c,d,e,b (age 31s)
mgr: red3(active, since 105s), standbys: red1, server4, a, red2
osd: 46 osds: 46 up, 46 in
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
We also need to ensure the toolbox is being updated/recreated:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;kubectl  -n rook-ceph delete pods rook-ceph-tools-5cf88dd58f-fwwlc&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;

### Original monitors vanish

Did not add bgp peering.
Cannot reach ceph through the routers.

Seems like rook did remove them.

Updating the ceph.conf for the native nodes:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mon host            = rook-ceph-mon-a.rook-ceph.svc..,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
### Post monitor migration issue 1: OSDs start crashing

A day after the monitor migration some OSDs start to crash. Checking
out the debug log we found the following error:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2022-09-05 10:24:02.881 7fe005ce7700 -1  Processor -- bind unable to bind to v2:[2a0a:e5c0::225:b3ff:fe20:3554]:7300/3712937 on any port in range 6800-7300: (99) Cannot assign requested address
2022-09-05 10:24:02.881 7fe005ce7700 -1  Processor -- bind was unable to bind. Trying again in 5 seconds
2022-09-05 10:24:07.897 7fe005ce7700 -1  Processor -- bind unable to bind to v2:[2a0a:e5c0::225:b3ff:fe20:3554]:7300/3712937 on any port in range 6800-7300: (99) Cannot assign requested address
2022-09-05 10:24:07.897 7fe005ce7700 -1  Processor -- bind was unable to bind after 3 attempts: (99) Cannot assign requested address
2022-09-05 10:24:07.897 7fe0127b1700 -1 received  signal: Interrupt from Kernel ( Could be generated by pthread_kill(), raise(), abort(), alarm() ) UID: 0
2022-09-05 10:24:07.897 7fe0127b1700 -1 osd.49 100709 &lt;strong&gt;&lt;em&gt; Got signal Interrupt &lt;/em&gt;&lt;/strong&gt;
2022-09-05 10:24:07.897 7fe0127b1700 -1 osd.49 100709 &lt;strong&gt;&lt;em&gt; Immediate shutdown (osd_fast_shutdown=true) &lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Trying to bind to an IPv6 address that is **not** on the system.

https://tracker.ceph.com/issues/24602

Calico/CNI does IP rewriting and thus tells the OSD the wrong IPv6
address.

Adding
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;public_addr = 2a0a:e5c0::92e2:baff:fe26:642c&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
to the node. Verifying the binding after restarting the crashing OSD:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[10:35:06] server4.place5:/var/log/ceph# netstat -lnpW | grep 3717792
tcp6       0      0 2a0a:e5c0::92e2:baff:fe26:642c:6821 :::&lt;em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 :::6822                 :::&lt;/em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 :::6823                 :::&lt;em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 2a0a:e5c0::92e2:baff:fe26:642c:6816 :::&lt;/em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 2a0a:e5c0::92e2:baff:fe26:642c:6817 :::&lt;em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 :::6818                 :::&lt;/em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 :::6819                 :::&lt;em&gt;                    LISTEN      3717792/ceph-osd
tcp6       0      0 2a0a:e5c0::92e2:baff:fe26:642c:6820 :::&lt;/em&gt;                    LISTEN      3717792/ceph-osd
unix  2      [ ACC ]     STREAM     LISTENING     16880318 3717792/ceph-osd     /var/run/ceph/ceph-osd.49.asok&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
### Post monitor migration issue 1: OSDs start crashing

After roughly a week an OSD on the native cluster started to fail on
restart with the following error:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;unable to parse addrs
in 'rook-ceph-mon-a.rook-ceph.svc.p5-cow.k8s.ooo,
rook-ceph-mon-b.rook-ceph.svc.p5-cow.k8s.ooo,
rook-ceph-mon-c.rook-ceph.svc.p5-cow.k8s.ooo,
rook-ceph-mon-d.rook-ceph.svc.p5-cow.k8s.ooo,
rook-ceph-mon-e.rook-ceph.svc.p5-cow.k8s.ooo'&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Checking the cluster, it seems rook has replaced mon-a with mon-f:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[22:38] blind:~% kubectl -n rook-ceph get svc
NAME                       TYPE        CLUSTER-IP             EXTERNAL-IP   PORT(S)             AGE
csi-cephfsplugin-metrics   ClusterIP   2a0a:e5c0:0:15::f2ac   &lt;none&gt;        8080/TCP,8081/TCP   7d5h
csi-rbdplugin-metrics      ClusterIP   2a0a:e5c0:0:15::5fc2   &lt;none&gt;        8080/TCP,8081/TCP   7d5h
rook-ceph-mgr              ClusterIP   2a0a:e5c0:0:15::c31c   &lt;none&gt;        9283/TCP            7d5h
rook-ceph-mon-b            ClusterIP   2a0a:e5c0:0:15::9cd9   &lt;none&gt;        6789/TCP,3300/TCP   7d5h
rook-ceph-mon-c            ClusterIP   2a0a:e5c0:0:15::fc2    &lt;none&gt;        6789/TCP,3300/TCP   7d5h
rook-ceph-mon-d            ClusterIP   2a0a:e5c0:0:15::b029   &lt;none&gt;        6789/TCP,3300/TCP   7d5h
rook-ceph-mon-e            ClusterIP   2a0a:e5c0:0:15::8c86   &lt;none&gt;        6789/TCP,3300/TCP   7d5h
rook-ceph-mon-f            ClusterIP   2a0a:e5c0:0:15::2833   &lt;none&gt;        6789/TCP,3300/TCP   3d13h&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
At this moment it is unclear why ceph does it, but if the native hosts
had already been migrated, this would probably not have caused an
issue. However as long as ceph.conf files are deployed with static
references to the monitors, this problem might repeat.


## Changelog

### 2023-05-18

* rook 1.7.11 does not work on kubernetes 1.26.1 anymore
* PodSecurityPolicy is missing
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Kubernetes API could not find policy/PodSecurityPolicy for
requested resource rook-ceph/00-rook-ceph-operator. Make sure the
"PodSecurityPolicy" CRD is installed on the destination cluster.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
Same issue on rook 1.8.10:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;      kind: PodSecurityPolicy
      message: &amp;gt;-
        The Kubernetes API could not find policy/PodSecurityPolicy for
        requested resource rook-ceph/00-rook-privileged. Make sure the
        "PodSecurityPolicy" CRD is installed on the destination cluster.
      name: 00-rook-privileged
      namespace: rook-ceph
      status: SyncFailed
      syncPhase: Sync
      version: v1beta1
  revision: v1.8.10
  source:
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
* rook 1.9.12 deploys in kubernetes 1.26.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2023-05-18 11:44:36.169248 E | ceph-cluster-controller: failed to reconcile CephCluster "rook-ceph/rook-ceph". failed to reconcile cluster "rook-ceph": failed to configure local ceph cluster: failed the ceph version check: the version does not meet the minimum version "15.2.0-0 octopus"
```&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;requires 15.2.0 octopus as a minimum&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2022-09-10&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Added missing monitor description&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2022-09-03&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Next try starting for migration&lt;/li&gt;
&lt;li&gt;Looking deeper into configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2022-08-29&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Added kubernetes/kubeadm bootstrap issue&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2022-08-27&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The initial release of this blog article&lt;/li&gt;
&lt;li&gt;Added k8s bootstrapping guide&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Follow up or questions&lt;/h2&gt;
&lt;p&gt;You can join the discussion in the matrix room &lt;code&gt;#kubernetes:ungleich.ch&lt;/code&gt;
about this migration. If don't have a matrix
account you can join using our chat on &lt;a href="https://chat.with.ungleich.ch"&gt;https://chat.with.ungleich.ch&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>[matrix] Conduit beta at ungleich</title><link href="https://ungleich.ch/u/blog/2022-07-10-launching-ipv6only-conduit-matrix-server/" rel="alternate"/><updated>2022-07-10T00:00:00Z</updated><author><name>ungleich matrix team</name></author><id>urn:uuid:332fb645-46a4-3bc9-a353-b94cf19008bd</id><content type="html">&lt;h2&gt;News from the Matrix Home Server department&lt;/h2&gt;
&lt;p&gt;Here at ungleich we always have a look around, which Matrix home
server to use. Obviously, you all know about
&lt;a href="https://github.com/matrix-org/synapse"&gt;synapse&lt;/a&gt;, the reference
server.
Some of you might also know about
&lt;a href="https://github.com/matrix-org/dendrite"&gt;dendrite&lt;/a&gt;, an experimental,
maybe at some point in the future replacement of synapse.&lt;/p&gt;
&lt;p&gt;But did you know about &lt;a href="https://conduit.rs/"&gt;conduit&lt;/a&gt;, a tiny Matrix
homeserver written in Rust? Well, now you do.&lt;/p&gt;
&lt;h2&gt;Next generation Matrix Home Server?&lt;/h2&gt;
&lt;p&gt;At ungleich we like to see what is coming next and conduit certainly
has the potential to become an interesting, production grade
homeserver. At the moment there are some
&lt;a href="https://gitlab.com/famedly/conduit/-/milestones/3#tab-issues"&gt;issues open for the 1.0
milestone&lt;/a&gt;,
however conduit is actually already quite usable.&lt;/p&gt;
&lt;p&gt;How stable you ask? Well, ...&lt;/p&gt;
&lt;h2&gt;Phasing in public beta server at ungleich&lt;/h2&gt;
&lt;p&gt;To give you a preview, we have setup an &lt;strong&gt;IPv6 only&lt;/strong&gt; instance of
conduit at &lt;a href="https://conduit.ungleich.ch"&gt;conduit.ungleich.ch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This server is open for public use, anyone (well, anyone with
IPv6...) can register. However note: &lt;strong&gt;this is only a test
instance&lt;/strong&gt;. We might at any point in the future delete, replace or
reset it. It is not backed and not a production service. It's main
intent is to allow you to easily test out Conduit.&lt;/p&gt;
&lt;p&gt;If you are looking for a production grade homeserver for yourself,
have a look at our &lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;hosted Matrix
offerings&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That said - give it a shot. We think Conduit is a promising
homeserver, especially given its focus on low resource usage.&lt;/p&gt;
&lt;h2&gt;... why IPv6 only?&lt;/h2&gt;
&lt;p&gt;There are several reason for it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv6 only is much easier to setup than IPv6+IPv4&lt;/li&gt;
&lt;li&gt;This is a public beta service for which we try to keep the effort
low&lt;/li&gt;
&lt;li&gt;It's good test for us to see if conduit works in our IPv6 only
networks&lt;/li&gt;
&lt;li&gt;Global IPv6 traffic is nearing 50% and &lt;a href="https://stats.labs.apnic.net/ipv6"&gt;many countries already
exceed 50%&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you cannot access the conduit server because you don't have IPv6,
you can always get IPv6 via &lt;a href="../../products/ipv6-vpn/"&gt;the IPv6VPN&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Follow up or questions&lt;/h2&gt;
&lt;p&gt;You can join the discussion either on the conduit server or you can
also join our chat on &lt;a href="https://chat.with.ungleich.ch"&gt;https://chat.with.ungleich.ch&lt;/a&gt; (IPv6+IPv4 Synapse
based Matrix server).&lt;/p&gt;
&lt;p&gt;If you have anything to share about conduit, feel free to join the
room #conduit:fachschaften.org.&lt;/p&gt;
</content></entry><entry><title>Let's get started with Kubernetes</title><link href="https://ungleich.ch/u/blog/2022-06-03-k8s-course-diesbach/" rel="alternate"/><updated>2022-06-03T00:00:00Z</updated><author><name>ungleich k8s team</name></author><id>urn:uuid:e9cd949b-c4d8-3040-b843-53d7af0b57e3</id><content type="html">&lt;h2&gt;It's time for Kubernetes&lt;/h2&gt;
&lt;p&gt;Like everybody else, you might have been following the topic of kubernetes for a while and
maybe you wondered whether or not it's about time to learn
kubernetes. So have we at ungleich. Over the years we tested kubernetes
many times and quite often had the verdict "no, not yet".&lt;/p&gt;
&lt;p&gt;About one and a half year ago, our verdict finally changed. After much testings and learnings,
we came to the conclusion that Kubernetes is stable enough to be
running in the ungleich environment. Speaking of our environment, it is not only IPv6-only, but
also needs to support a huge variety of workloads.&lt;/p&gt;
&lt;h2&gt;Open Source and Open Teaching&lt;/h2&gt;
&lt;p&gt;Applying Kubernetes on our own datacenter required a lot of intense learning and 
real-life problem solving. We won't say that was always easy, but it has been quite rewarding. 
One of the main takeaways is that it can be tough to kickstart Kubernetes. 
Since it has a lot of different use-cases, concepts
and configurations, it can be easily overwhelming.&lt;/p&gt;
&lt;p&gt;At ungleich we have always been standing for Open Source and
&lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure"&gt;Open
Communication&lt;/a&gt;
and we want to continue this by passing on our knowledge about
Kubernetes.&lt;/p&gt;
&lt;h2&gt;Is Kubernetes for me?&lt;/h2&gt;
&lt;p&gt;That depends and there are many factors to consider. If you are an
organisation and you want to standardise your application deployments
or increase the efficiency of deployments, Kubernetes is a good choice.&lt;/p&gt;
&lt;p&gt;If you are an engineer or a developer and you are considering
improving your career, learning Kubernetes is a good choice.&lt;/p&gt;
&lt;h2&gt;2 Beginner Courses starting in Digital Glarus&lt;/h2&gt;
&lt;p&gt;For this reason we will start 2 beginner courses this June
(&lt;strong&gt;Update: only 2 places left&lt;/strong&gt;) in the beautiful Hacking Villa in
Diesbach, Switzerland.&lt;/p&gt;
&lt;h3&gt;Setting up Kubernetes&lt;/h3&gt;
&lt;p&gt;The first course, &lt;a href="https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-setup/"&gt;Kubernetes Setup
Course&lt;/a&gt;
focuses on how to set up Kubernetes clusters. It is intended for
Sysadmins and DevOps engineers that want to operate Kubernetes
clusters.&lt;/p&gt;
&lt;h3&gt;Using Kubernetes&lt;/h3&gt;
&lt;p&gt;After having a cluster setup, the big question is how to actually use
it. Our second course, the &lt;a href="https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-usage/"&gt;Kubernetes Usage
Course&lt;/a&gt;
is focussing on the aspect of understanding the concepts of
Kubernetes.&lt;/p&gt;
&lt;h2&gt;On-Site and Online&lt;/h2&gt;
&lt;p&gt;Both courses are available On-Site in Switzerland as well as Online
(choose the "Learning only" package for this one). If you choose to be
onsite, you will visit us in the beautiful Swiss Alps and lodge in &lt;a href="https://ungleich.ch/en-us/cms/school-digital-glarus/location/"&gt;a
historic, protected building.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/hacking-villa-diesbach.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Intense + Personal + Relaxing&lt;/h2&gt;
&lt;p&gt;At ungleich we know that intense learning (6 hours per day, 3 hours in
the morning, 3 hours in the afternoon) also requires fitting calming
down to be able to concentrate.&lt;/p&gt;
&lt;p&gt;For this reason we have local recommendations for hiking paths,
swimming or - if you join the winter course - skiing.&lt;/p&gt;
&lt;p&gt;Our experience has shown that learnings in small groups with 
personal training are most effective. For this reason the size of the
training groups is limited to 6 people.&lt;/p&gt;
&lt;h2&gt;A or B or A+B?&lt;/h2&gt;
&lt;p&gt;If you are considering participating in the setting up or using
Kubernetes course: you can take either of them or both of them, they
work independently of each other.&lt;/p&gt;
&lt;p&gt;Note: for both courses we have 2 places free - if you are interested,
you can apply directly on the course websites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-setup/"&gt;https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-setup/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-usage/"&gt;https://ungleich.ch/en-us/cms/school-digital-glarus/k8s-usage/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Looking forward to seeing you&lt;/h2&gt;
&lt;p&gt;Ever since we started our company ungleich we have done things a bit 
differently, focusing on sustainability and open source. Since the launch of project Digital Glarus in 2015, many people from all over the world 
have visited us, learned with us and a lot of them even stayed in our community via our 
&lt;a href="https://ungleich.ch/u/projects/open-chat/"&gt;Open Chat&lt;/a&gt;. We look
forward to welcoming you to Digital Glarus or teaching you online and
maybe staying with us even longer.&lt;/p&gt;
&lt;p&gt;Our Open Chat is based on Matrix and if you are curious about what we
do and write about Kubernetes, feel free to join&lt;/p&gt;
&lt;h1&gt;kubernetes:ungleich.ch.&lt;/h1&gt;
</content></entry><entry><title>Hosting Django Apps in Kubernetes [WIP]</title><link href="https://ungleich.ch/u/blog/2022-06-03-django-hosting-in-kubernetes/" rel="alternate"/><updated>2022-06-03T00:00:00Z</updated><author><name>ungleich django team</name></author><id>urn:uuid:65b30878-446e-3a75-8515-e8c5164ba94c</id><content type="html">&lt;h2&gt;Situation&lt;/h2&gt;
&lt;p&gt;At ungleich we are hosting quite a lot of Django applications. As of
2022-06-03, most of them are still deployed on a traditional VM based
setup.&lt;/p&gt;
&lt;p&gt;We are using this blog entry to document a possible blueprint and the
progress of migration at ungleich.&lt;/p&gt;
&lt;h2&gt;General design&lt;/h2&gt;
&lt;p&gt;Our Kubernetes clusters usually use
&lt;a href="https://argo-cd.readthedocs.io/en/stable/"&gt;ArgoCD&lt;/a&gt; for deployments,
so Django applications should potentially be defined the same way.&lt;/p&gt;
&lt;p&gt;Most of our kubernetes applications are defined in helm charts and
thus the "general django application" should probably also be defined
in a helm chart.&lt;/p&gt;
&lt;h2&gt;Freedom of choice&lt;/h2&gt;
&lt;p&gt;While as a hoster it might be tempting to define a specific image that
Django applications should be using (like
&lt;a href="https://hub.docker.com/_/python"&gt;python&lt;/a&gt;), but we want to give us and
our customers the freedom to choose the image they use themselves. It
might potentially even come from a private registry.&lt;/p&gt;
&lt;h2&gt;Interface definition&lt;/h2&gt;
&lt;p&gt;All of our Django applications are using Postgresql for storing
data. Postgresql is used by quite some other applications that we
deployed in k8s, so this is a no-brainer. Django hosting at ungleich,
even in k8s, will be based on Postgresql.&lt;/p&gt;
&lt;p&gt;Static data of Django applications can easily be stored on a PVC. This
has the drawback that filesystem PVCs based on ceph block devices are
usually RWO and thus in case of restart, there will be a short downtime.&lt;/p&gt;
&lt;p&gt;This is, generally speaking probably accepted, like a deploy would
have caused a short downtime on a VM as well.&lt;/p&gt;
&lt;p&gt;However alternatives would be a shared filesystem (such as
NFS/CephFS), but they are usually slower than dedicated block
devices - so reliability can be traded against speed. Maybe we offer
both options or add an NFS server as an option to our Django Hosting.&lt;/p&gt;
&lt;h2&gt;Django startup / processes&lt;/h2&gt;
&lt;p&gt;On startup, Django will need to ensure the database schema
has been upgraded to the latest version. so something like &lt;code&gt;python
manage.py migrate&lt;/code&gt; should probably be called in an InitContainer for
most apps. We could specify that the customer provided container
supports multiple commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/init - anything that needs to be done &lt;em&gt;once&lt;/em&gt; on startup&lt;/li&gt;
&lt;li&gt;/run  - something that runs the actual site&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some django apps however utilise Celery
or &lt;a href="https://django-q.readthedocs.io/en/latest/"&gt;Django Q&lt;/a&gt;
for async tasks. We don't know which system is used, but it would be easy to
add a flag to the hosting whether or not a third container
should be utilised. Thus we could define:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If async container is defined, enable it and run /async (or similar)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Secrets&lt;/h2&gt;
&lt;p&gt;Django applications usually have some kind of secrets and most Django
applications have DIFFERENT types of secrets. Thus defining a specific
environment variable does not seem to be a smart idea.&lt;/p&gt;
&lt;p&gt;Instead, we should probably offer to store secrets in something like
&lt;a href="https://github.com/bitnami-labs/sealed-secrets"&gt;SealedSecrets&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Database connection information is provided by default and is
cluster/app specific.&lt;/p&gt;
&lt;h2&gt;Deployment&lt;/h2&gt;
&lt;p&gt;We are likely going with a git-ops style deployment in which
everything is defined for the Django app. This repository is read
write for each client/customer.&lt;/p&gt;
&lt;p&gt;This probably includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(Possible encrypted) Secrets&lt;/li&gt;
&lt;li&gt;Image definitions&lt;/li&gt;
&lt;li&gt;Maybe even (part of) a pod definition?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some parameters are likely to be stored in a different, ungleich only
writable repository, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Size of RAM&lt;/li&gt;
&lt;li&gt;Number of CPUs&lt;/li&gt;
&lt;li&gt;Storage size (Postgresql, Static files, ...)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Status&lt;/h2&gt;
&lt;p&gt;This document is still WIP and will be used as a basis for
deploying our own Django apps first.&lt;/p&gt;
</content></entry><entry><title>URGENT: Infrastructure update Announcement</title><link href="https://ungleich.ch/u/blog/2022-04-01-infrastructure-update/" rel="alternate"/><updated>2022-04-01T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:f4158cf3-91f2-32a3-b91f-67967d37db90</id><content type="html">&lt;h2&gt;APRIL's FOOLS DAY&lt;/h2&gt;
&lt;p&gt;None of the news below is true - this was just part of our 2022
April's fools day contribution.&lt;/p&gt;
&lt;h2&gt;Urgent release: ungleich infrastructure update&lt;/h2&gt;
&lt;p&gt;To the attention to every ungleich customer: today we are updating our
infrastructure to the latest technologies. All changes will be applied
at 23:42 CEST today.&lt;/p&gt;
&lt;p&gt;What does that mean to you? The following sections answer this in detail.&lt;/p&gt;
&lt;h2&gt;Network upgrades: Turning IPv4 off&lt;/h2&gt;
&lt;p&gt;As of today all IPv4 traffic will be disabled. IPv4 has become
too expensive and it is not worth keeping it online.&lt;/p&gt;
&lt;p&gt;The migration will be as follows: every IPv4 address like A.B.C.D will be
translated to an IPv6 address like 2a0a:e5c0:b00::A.B.C.D.&lt;/p&gt;
&lt;p&gt;As a bonus, every customer will get their own "cafe" IPv6 network.&lt;/p&gt;
&lt;p&gt;Additionally every server will be connected also via
&lt;a href="https://scion-architecture.net/"&gt;SCION&lt;/a&gt;, the new Internet.&lt;/p&gt;
&lt;h2&gt;Network upgrade: Removal of old connections: no more 2G/3G/4G&lt;/h2&gt;
&lt;p&gt;You may be aware that slow Internet connections are draining server
resources: long lasting connections without much data transfer is a
burden for every server. For that reason, we will disable access to
our data center from any 2G/3G/4G mobile connection.&lt;/p&gt;
&lt;p&gt;You are required to use 5G, 6G, 7G, Fiber or 56k modems to access Data Center
Light. The latter was included as a fallback, in case you don't have
support for a modern Internet connection.&lt;/p&gt;
&lt;h2&gt;Storage migration&lt;/h2&gt;
&lt;p&gt;Our storage is so far based on Ceph, a distributed storage. To follow
modern standards, we are migrating all our data to the blockchain.&lt;/p&gt;
&lt;p&gt;To avoid vendor logins and possible shortcomes of a particular
blockchain, we are introducting the "ungleich blockchain", which
stores data on &lt;strong&gt;all&lt;/strong&gt; available blockhains.&lt;/p&gt;
&lt;p&gt;If you are worried about privacy implications of all data being
public, don't worry: we are encrypting all data using an
&lt;a href="https://en.wikipedia.org/wiki/Enigma_machine"&gt;Enigma machine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Optionally, on request, we can also encrypt your data as NFTs.&lt;/p&gt;
&lt;p&gt;In regards to performance, we expect a huge performance increase, as
all data will be saved everywhere.&lt;/p&gt;
&lt;h2&gt;Computing power&lt;/h2&gt;
&lt;p&gt;As you might have read recently, we are investigating heating houses
with the server heat. This project is now in productive state and we
require much more computing power.&lt;/p&gt;
&lt;p&gt;For that reason, at the same time today, our whole server
infrastructure will be replaced with &lt;a href="https://en.wikipedia.org/wiki/Timeline_of_quantum_computing_and_communication"&gt;quantum
computers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As qubits, the equivalent of bits on quantum computers, operate on
probabilities, all calculations for our customers are not guaranteed
anymore, but instead they will be executed by a certain probability.&lt;/p&gt;
&lt;p&gt;The exact probability is derived from your society behaviour
points. If you are &lt;a href="https://en.wikipedia.org/wiki/The_Good_Place"&gt;in the good
place&lt;/a&gt; you get an
additional uncertainty factor of 3.14.&lt;/p&gt;
&lt;h2&gt;Removal of Kubernetes&lt;/h2&gt;
&lt;p&gt;We recently introduced &lt;a href="https://kubernetes.io/"&gt;kubernetes&lt;/a&gt; in our
infrastructure. After only 2 years of R&amp;amp;D we will have to shutdown all
Kubernetes based clusters. The main reason is that the actual
complexity of Kubernetes systems is &lt;strong&gt;not high enough&lt;/strong&gt;. Plainly
speaking, our engineers are bored. For that reason:&lt;/p&gt;
&lt;p&gt;We will replace Kubernetes with a &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;home
made&lt;/a&gt; solution
that consists solely of a manually managed cluster of Windows
Servers. Microsoft is a direct partner in this and provides us with
a new Windows version: &lt;strong&gt;Microsoft Windows Quantum ME 3.11&lt;/strong&gt;.
We expect great stability from this release with a minimum complexity
factor of 1000x added.&lt;/p&gt;
&lt;h2&gt;Maintenance and Customer support&lt;/h2&gt;
&lt;p&gt;We have always been very community orientated. Today we wanted to take
the next big step and we turn over the customer support and system
maintenance to the community. What does that mean specifically?&lt;/p&gt;
&lt;p&gt;Anyone interested in maintaining our infrastructure can get full root
access on all systems.&lt;/p&gt;
&lt;p&gt;As everyone now has full root access, the customer support is also
shifted to a decentralised, &lt;a href="https://en.wikipedia.org/wiki/BitTorrent"&gt;bittorrent
based&lt;/a&gt; support community.&lt;/p&gt;
&lt;p&gt;If you have any questions to the recent changes, please connect the
decentrally organised support community. Unfortunately, due do the
decentralisation, we cannot offer a single contact reference.&lt;/p&gt;
&lt;p&gt;However the Web3 advocate of your choice will certainly be able to
provide you answers.&lt;/p&gt;
</content></entry><entry><title>100: the number of servers at ungleich</title><link href="https://ungleich.ch/u/blog/2022-02-14-100-servers-at-ungleich/" rel="alternate"/><updated>2022-02-14T00:00:00Z</updated><author><name>ungleich devops team</name></author><id>urn:uuid:d1fff39c-5d7b-3142-a58c-565772e5502b</id><content type="html">&lt;h2&gt;The day of celebration, 2022-02-14&lt;/h2&gt;
&lt;p&gt;Today is the day that we put &lt;strong&gt;server100&lt;/strong&gt; online in our data center.
Server100. Who would have thought that when we started our journey
with the Data Center Light around 2017?&lt;/p&gt;
&lt;p&gt;Just on this Valentine's day, we have actually received 2 new servers
to support the growing storage needs of our customers, so server100 is
celebrating in the data center with server101.&lt;/p&gt;
&lt;h2&gt;Big data&lt;/h2&gt;
&lt;p&gt;You might remember this slogan from the 2017's, "Big data" or "what
can you do if you have a lot of data". We see big data a bit
differently. We don't ever analyse our customer data or sell it to
third parties, because we know that for every of our customers privacy
is an important.&lt;/p&gt;
&lt;p&gt;No, at ungleich big data means "storing a lot of data". And that is
what server100 and server101 are going to do: each of them will
&lt;strong&gt;provide around 400 Terabyte&lt;/strong&gt; of storage.&lt;/p&gt;
&lt;p&gt;This is a bit of a special case in our infrastructure, as these
servers are dedicated to specific customers. Usually, all of our
storage is provided by our Ceph clusters, but in this case these
machines are providing independent storage.&lt;/p&gt;
&lt;h2&gt;Kubernetes + IPv6 everywhere&lt;/h2&gt;
&lt;p&gt;They are however integrated into our kubernetes clusters so that the
actual workload is scheduled via kubernetes to these specific hosts.&lt;/p&gt;
&lt;p&gt;As usual, the servers are running in IPv6 only networks, but have
access to the Internet via NAT64.&lt;/p&gt;
&lt;h2&gt;More about server100&lt;/h2&gt;
&lt;p&gt;So, what kind of server is this server100 anyway? It is a 24 bay,
Supermicro X9QRi-F with 64 cores and 512GB RAM. It is connected to our
network with 2x 10 Gbit/s network cards running LACP bonding. Not only
in terms of computing it is big, it is with it's 1620W PSU also one of
the "heaviest" servers in our data center (the average PSU is
rated somewhere in the 1000W area).&lt;/p&gt;
&lt;p&gt;Some more insights coming from the terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[17:33] server100.place10:~# cat /proc/cpuinfo  | grep ^process | wc -l
64
[17:33] server100.place10:~# free -g
              total        used        free      shared  buff/cache   available
Mem:            503           0         502           0           1         501
Swap:             0           0           0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously, the uptime is not yet that high...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[17:46] server100.place10:~# uptime
 17:46:42 up  1:37,  load average: 0.00, 0.00, 0.00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;... neither are the measured temperatures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@2157f4626763:/# ipmitool sensor  | grep degrees
CPU1 Temp        | 27.000     | degrees C  | ok    | 0.000     | 0.000     | 0.000     | 97.000    | 100.000   | 102.000
CPU2 Temp        | 28.000     | degrees C  | ok    | 0.000     | 0.000     | 0.000     | 97.000    | 100.000   | 102.000
CPU3 Temp        | 28.000     | degrees C  | ok    | 0.000     | 0.000     | 0.000     | 97.000    | 100.000   | 102.000
CPU4 Temp        | 27.000     | degrees C  | ok    | 0.000     | 0.000     | 0.000     | 97.000    | 100.000   | 102.000
PCH Temp         | 43.000     | degrees C  | ok    | -11.000   | -8.000    | -5.000    | 90.000    | 95.000    | 100.000
System Temp      | 16.000     | degrees C  | ok    | -9.000    | -7.000    | -5.000    | 80.000    | 85.000    | 90.000
Rear Left Temp   | 17.000     | degrees C  | ok    | -9.000    | -7.000    | -5.000    | 80.000    | 85.000    | 90.000
Rear Right Temp  | 14.000     | degrees C  | ok    | -9.000    | -7.000    | -5.000    | 80.000    | 85.000    | 90.000
root@2157f4626763:/#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the addition of server100 and server101 we are about to
crack the 10 TiB RAM barrier. Prior to the deployment of these two, a
total of 8 TiB had been deployed in the Data Center Light.&lt;/p&gt;
&lt;p&gt;As you can see, we have a lot of fun with our latest servers. And this
brings us to the important point: celebration.&lt;/p&gt;
&lt;h2&gt;Celebration&lt;/h2&gt;
&lt;p&gt;Over the years we learned many great stories and have done many great
projects together with our customers and partners. Many of them have
turned into friends and we know the spirit of each and every project
that came to us.&lt;/p&gt;
&lt;p&gt;In this sense we want to celebrate reaching that big number
with you and will give a 100% discount on any hosting order of 100 CHF
or more for the first month.&lt;/p&gt;
&lt;p&gt;Checkout the details on the &lt;a href="../../offers/100-servers-100-percent-discount"&gt;100 servers - 100 percent
discount&lt;/a&gt; page. And now,
happy 100 everyone!&lt;/p&gt;
&lt;p&gt;If you feel like celebrating, you can also join us on our &lt;a href="../../projects/open-chat"&gt;open chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>IPv6 addresses for free</title><link href="https://ungleich.ch/u/blog/2021-12-23-ipv6-addresses-for-free/" rel="alternate"/><updated>2021-12-23T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:e28ad312-b094-3afe-8df4-40befea10719</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Are you, your organisation or someone you know interested in public, static, addressable IPv6
address space? But have you refrained from getting it because of cost issues?
And/or would you be interested in affordable (free/almost free) IPv6 address space?&lt;/p&gt;
&lt;p&gt;If yes, then please reach out to us via:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;E-Mail: ipv6@ungleich.ch&lt;/li&gt;
&lt;li&gt;&lt;a href="https://IPv6.chat"&gt;Matrix: #ipv6:ungleich.ch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/ungleich"&gt;Twitter: @ungleich&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who are you?&lt;/li&gt;
&lt;li&gt;What do you need or plan to use the IPv6 space for?&lt;/li&gt;
&lt;li&gt;Are we allowed to share your information publicly?&lt;/li&gt;
&lt;li&gt;What are your financial constraints?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last question is mainly to find out why you would not apply to
become an LIR at one of the RIRs. However if you don't want to share,
the last question can be skipped.&lt;/p&gt;
&lt;p&gt;Note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This is not about routing or connectivity, but merely about
assignment of address space.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The background: free = ULA&lt;/h2&gt;
&lt;p&gt;At the moment the only "free" available IPv6 address space is
ULA space. However there is no official ULA registry, even though we
provide a &lt;a href="https://ula.ungleich.ch/"&gt;ULA registry at ungleich&lt;/a&gt;. We are
not the only ones though, &lt;a href="https://dn42.dev/howto/Address-Space"&gt;DN42&lt;/a&gt;
also registers ULA space.&lt;/p&gt;
&lt;p&gt;ULA space is not only not officially managed, but also comes with the
drawback that it will never be routed through the Internet.&lt;/p&gt;
&lt;h2&gt;Global Unique Addresses (GUA) are paid&lt;/h2&gt;
&lt;p&gt;Global Unique Addresses, even if not routed or announced in the
Internet, are something you can get from an RIR, if you are a
registered LIR. Being an LIR costs 1400 Euro per year + a one time
fee.&lt;/p&gt;
&lt;p&gt;One theory is that every organisation can afford this, but at ungleich
we imagine this is stopping organisations from pursuing GUA.&lt;/p&gt;
&lt;h2&gt;This survey&lt;/h2&gt;
&lt;p&gt;This is why we started this page, to find out which organisations
are looking for IPv6 address space or are using ULA because of cost
issues. Answering this survey helps to find out whether or not there
should be afford to either&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Establish an official ULA registry&lt;/li&gt;
&lt;li&gt;To provide GUA address space for free&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So please spread the word - the more answers there are, the easier it
will be to continue the discussion. We plan to publish all answers
that are allowed to be shared publicly in a git repository.&lt;/p&gt;
</content></entry><entry><title>Running Workadventure in Kubernetes IPv6 only</title><link href="https://ungleich.ch/u/blog/2021-12-19-workadventure-ipv6-kubernetes/" rel="alternate"/><updated>2021-12-19T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:370eff1b-ad5b-3434-bda7-62e3a59e8364</id><content type="html">&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;At ungleich we are often running software in IPv6 only environments
and recently even more in IPv6 only Kubernetes clusters. Today we had
a look at running &lt;a href="https://workadventu.re/"&gt;WorkAdventure&lt;/a&gt; in an IPv6
only kubernetes cluster.&lt;/p&gt;
&lt;h2&gt;Status: waiting for bugfix&lt;/h2&gt;
&lt;p&gt;At the moment it looks like as if WorkAdventure cannot run in IPv6
only Kubernetes clusters. The frontend displays the infamous "Network
Error" messages. When checking the backend, it displays an error that
it cannot resolve the redis hostname, which &lt;a href="https://github.com/thecodingmachine/workadventure/issues/1657"&gt;seems to be a bug in the
resolver
code&lt;/a&gt;,
as the hostname does resolve, albeit only to an IPv6 address.&lt;/p&gt;
&lt;h2&gt;The code&lt;/h2&gt;
&lt;p&gt;As usual you can find our code in the
&lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-k8s/src/branch/master/apps/workadventure"&gt;ungleich-k8s
repository&lt;/a&gt;,
which contains development iterations at the moment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;v1: initial conversions from docker-compose using kompose&lt;/li&gt;
&lt;li&gt;v2: Adjust manifests so that pods generally speaking run&lt;/li&gt;
&lt;li&gt;v3: Turned into a helm chart with most services running stable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to give it a spin yourself, here is how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup an IPv6 only kubernetes cluster&lt;/li&gt;
&lt;li&gt;Ensure you have helm locally installed&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure you have&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the ungleich-k8s repo (see link above)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd apps/workadventure/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And use&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;helm upgrade --install workadventure v3/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;We are currently waiting to hear back from the redis bug report and
will continue developing after the backend is running stable in an
IPv6 only environment.&lt;/p&gt;
&lt;p&gt;If you are interested in this development, feel free to
&lt;a href="../../projects/open-chat/"&gt;join us on the open kubernetes chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>Running Django in Kubernetes IPv6 only</title><link href="https://ungleich.ch/u/blog/2021-12-19-django-ipv6-kubernetes/" rel="alternate"/><updated>2021-12-19T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:74a102dc-39cc-3d19-9984-a8f232871ad3</id><content type="html">&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;At ungleich we run quite some amount of
&lt;a href="https://www.djangoproject.com/"&gt;Django applications&lt;/a&gt;, some for
ourselves, some on behalf of our customers. Most of them are currently
running "natively" on virtual machines. Our objectives are to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slowly move our own workload into IPv6 only kubernetes clusters&lt;/li&gt;
&lt;li&gt;Slowly move our customer applications into IPv6 only kubernetes
clusters&lt;/li&gt;
&lt;li&gt;Offer modern Django Hosting based on Kubernetes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Status 2021-12-19: initial design phase&lt;/h2&gt;
&lt;p&gt;At the moment we are looking into what we require for running Django
applications inside Kubernetes. Some parts are still open, some are
already set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL as the database: this is our standard so far and we don't
plan to change it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Undefined at the moment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where/how to generate and serve static files&lt;ul&gt;
&lt;li&gt;Same container?&lt;/li&gt;
&lt;li&gt;Separate container?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Backup sidecare&lt;ul&gt;
&lt;li&gt;Restic?&lt;/li&gt;
&lt;li&gt;pg_dump?&lt;/li&gt;
&lt;li&gt;media / upload files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;App server&lt;ul&gt;
&lt;li&gt;uwsgi&lt;/li&gt;
&lt;li&gt;(g)unicorn&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;One container providing port 80&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The outside world does not need to know what is running inside&lt;/li&gt;
&lt;li&gt;Thus the django container should:&lt;ul&gt;
&lt;li&gt;Expose port 80&lt;/li&gt;
&lt;li&gt;Serve staticfiles on its own&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;One can use &lt;em&gt;any&lt;/em&gt; of the wsgi/asgi servers&lt;ul&gt;
&lt;li&gt;Will provide example for some of them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Follow up&lt;/h2&gt;
&lt;p&gt;If you are interested in Kubernetes or Django, feel free to
&lt;a href="../../projects/open-chat/"&gt;join us on our open chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>Public release of the ungleich container registries</title><link href="https://ungleich.ch/u/blog/2021-12-11-ungleich-container-registries/" rel="alternate"/><updated>2021-12-11T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:3ac0eb0e-72f4-3226-91c4-9c3e87536fca</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Today we opened up two public container registries from ungleich.
You can use them to pull container images released by ungleich or to
utilise the container registry caches.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You can pull public ungleich container releases from &lt;a href="https://harbor.ungleich.svc.p10.k8s.ooo/ungleich-public"&gt;https://harbor.ungleich.svc.p10.k8s.ooo/ungleich-public&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You can use the hub.docker.com cache on &lt;a href="https://harbor.ungleich.svc.p10.k8s.ooo/dockerhub"&gt;https://harbor.ungleich.svc.p10.k8s.ooo/dockerhub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You can use the quay.io cache on &lt;a href="https://harbor.ungleich.svc.p10.k8s.ooo/quayio"&gt;https://harbor.ungleich.svc.p10.k8s.ooo/quayio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You can use the hub.docker.com cache on
&lt;a href="https://harbor.ungleich.svc.c2.k8s.ooo/dockerhub"&gt;https://harbor.ungleich.svc.c2.k8s.ooo/dockerhub&lt;/a&gt; (development cluster)&lt;/li&gt;
&lt;li&gt;You can use the quay.io cache on
&lt;a href="https://harbor.ungleich.svc.c2.k8s.ooo/quayio"&gt;https://harbor.ungleich.svc.c2.k8s.ooo/quayio&lt;/a&gt; (development cluster)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All registries are &lt;strong&gt;IPv6 only&lt;/strong&gt; and the caches are intended to be used
by &lt;a href="../../projects/data-center-light"&gt;Data Center Light customers&lt;/a&gt;
to avoid the IPv4 throttling that one encounters when
pulling images from IPv6 only VM.&lt;/p&gt;
&lt;p&gt;You can test the ungleich-public repository as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull harbor.ungleich.svc.p10.k8s.ooo/ungleich-public/ungleich-certbot:0.3.3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;If you are using &lt;a href="https://cri-o.io/"&gt;cri-o&lt;/a&gt; you can use a
registries.conf as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unqualified-search-registries = ["docker.io"]

[[registry]]
prefix = "docker.io"
location = "harbor.ungleich.svc.p10.k8s.ooo/dockerhub"

[[registry]]
prefix = "quay.io"
location = "harbor.ungleich.svc.p10.k8s.ooo/quayio"

[[registry.mirror]]
location = "harbor.ungleich.svc.c2.k8s.ooo/dockerhub"

[[registry.mirror]]
location = "harbor.ungleich.svc.c2.k8s.ooo/quayio"
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Next steps and more of it&lt;/h2&gt;
&lt;p&gt;More caches are to follow and we will add a list of publicly available
images in the future. We do not plan to make the registries IPv4
accessible, as all workload inside Data Center Light is IPv6 reachable
and we think there is no need for IPv4 connectivity anymore.
You can read more about
&lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki/The_ungleich_kubernetes_infrastructure"&gt;the ungleich kubernetes
infrastructure&lt;/a&gt;
or join the &lt;a href="../../projects/open-chat/"&gt;#kubernetes:ungleich.ch Matrix chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>IPv6, VPN and DNS entries</title><link href="https://ungleich.ch/u/blog/ipv6-vpn-dns-entries/" rel="alternate"/><updated>2021-10-13T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:293b8700-8518-3b2b-9d13-9d05f6246c27</id><content type="html">&lt;h2&gt;TL; DR&lt;/h2&gt;
&lt;p&gt;With IPv6, DNS management of protected networks can be
simplified. IPv6 VPNs can use simplified DNS configurations to
simplify the network configurations by just using public, restricted
DNS entries.&lt;/p&gt;
&lt;h2&gt;VPN and DNS in the IPv4 world&lt;/h2&gt;
&lt;p&gt;VPNs in the IPv4 world are often used to create site-to-site tunnels,
allowing different networks to talk to each other. A typical case is
that organisation A needs to access protected resources of
organisation B and maybe even vice-versa. So a typical VPN looks like
this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Organisation A
-------------

Protected Host A ---------- Router/VPN gateway
(10.0.0.42/24)                      |
                                    |
                                    |
Organisation B                  (Internet)
--------------                      |
                                    |
                                    |
Protected Host B ---------- Router/VPN gateway
(10.20.0.42/24)
Host name: lakeside.int.org-b.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if the Protected Host A and Protected Host B want to communicate
with each other on IP basis, this is no problem (I am not elaborating
on the problems of IP collisions in this article, a follow up article
will follow soon).&lt;/p&gt;
&lt;p&gt;However if Protected Host A wants to reach the Protected Host B via
its internal DNS name &lt;strong&gt;lakeside.int.org-b.example.com&lt;/strong&gt;, this is
usually a problem, for multiple reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Protected Host A might not know the right internal DNS server to
query for int.org-b.example.com.&lt;/li&gt;
&lt;li&gt;Protected Host A might know the right internal DNS server to
query for int.org-b.example.com, but might not have access to it via
the VPN&lt;/li&gt;
&lt;li&gt;The DNS records for int.org-b.example.com often are intentionally
not published to public DNS for multiple reasons: privacy related or
because administrators don't like to publish RFC1918 records into
public DNS records&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;VPN and DNS in the IPv6 world&lt;/h2&gt;
&lt;p&gt;There are multiple ways of how VPNs can be built in the IPv6 world,
including usage of the private IPv4 addresses equivalent named Unique
Local Address (ULA). However instead of using ULA, I will today show
an approach that is more "IPv6 native", using Global Unique Addresses
(GUA), or what is simply known as "public IPv6 address".&lt;/p&gt;
&lt;p&gt;While you might have heard it, I will repeat nonetheless: there are
enough IPv6 addresses for every practical use case that we imagine at
the moment. This is important, because we can use &lt;strong&gt;globally unique
IPv6 addresses&lt;/strong&gt; inside the VPN.&lt;/p&gt;
&lt;p&gt;Isn't that a problem? Publicly reachable IPv6 addresses inside a VPN?
It would, if the addresses were &lt;strong&gt;globally reachable&lt;/strong&gt;. In the IPv6
world nothing speaks against having &lt;strong&gt;globally unique, but non-routed
IPv6 addresses&lt;/strong&gt;. This is actually a perfect match and much better
than we can do in the IPv4 world:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Both organisations A and B can acquire globally unique
addresses. Let's say they organisation A acquires 2001:db8:0::/48 and
organisation B acquires 2001:db8:1::/48.&lt;/li&gt;
&lt;li&gt;Both organisations have two options: they can announce their IPv6
range to the Internet and block access to their internal network or&lt;/li&gt;
&lt;li&gt;both they can even consider not to announce their network at all
(there is not route in the Internet for it)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In either case, both organisations will usually select a sub network
of size /64 for the resources they want to expose via the VPN. Let's
say organisation A chooses 2001:db8:0:cafe::/64 and organisation B
chooses 2001:db8:1:7ea::/64. Putting this in context, their VPN now
looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Organisation A
-------------

Protected Host A ---------- Router/VPN gateway
(2001:db8:0:cafe::42/64)            |
                                    |
                                    |
Organisation B                  (Internet)
--------------                      |
                                    |
                                    |
Protected Host B ---------- Router/VPN gateway
(2001:db8:1:7ea::42/64)            |
Host name: lakeside.int.org-b.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, how does this change the DNS server situation? Because we are
using IPv6, we have many more options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a) We can publish the DNS records of the domain
int.org-b.example.com globally. While access to the network
2001:db8:1:7ea::/64 is only possible via VPN, nothing speaks against
having the records in a public DNS server. However, some
administrators advocate to not publish them publicly for privacy
reasons. That is the same logic as publishing or not publish the
RFC1918 (10.x.y.z) addresses in the IPv4 world.&lt;/li&gt;
&lt;li&gt;b) We can publicly/globally delegate the domain
int.org-b.example.com to a nameserver that is only reachable via the
VPN.&lt;/li&gt;
&lt;li&gt;c) We can proceed the same as in the IPv4 world and have a
disconnect, internal DNS server that is responsible for
int.org-b.example.com.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Option (a) is often seen as a security risk and it can be debated
whether someone who can already guess the correct hostname and
retrieve it's IP address is really a significant higher security
thread than anybody just guessing IP addresses.&lt;/p&gt;
&lt;p&gt;Option (c) is the typical case for IPv4 based VPNs and is causing
above illustrated issues.&lt;/p&gt;
&lt;p&gt;Option (b) is the one that makes IPv6 VPNs much more interesting than
IPv4 based VPNs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The world can know that there is an internal domain
&lt;strong&gt;int.org-b.example.com&lt;/strong&gt; and find out which DNS servers are
responsible for it.&lt;/li&gt;
&lt;li&gt;However an attacker easily guesses that internal networks exist
anyway.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's have a look at sample nameserver entries in detail:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int.org-b.example.com. NS ns-int1.org-b.example.com.
int.org-b.example.com. NS ns-int2.org-b.example.com.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What does that mean? Anyone in the world can retrieve the information
that int.org-b.example.com has two DNS servers. However the DNS
servers responsible for org-b.example.com can hide the IP addresses of
ns-int1.org-b.example.com and ns-int2.org-b.example.com for everyone,
but hosts coming from organisation A. Or even if the IP addressses of
ns-int1.org-b.example.com and ns-int2.org-b.example.com are world
known, access to them can easily be prevented.&lt;/p&gt;
&lt;p&gt;The measures for this can for instance be DNS views or firewall
entries. In practice this means for VPNs in the IPv6 world:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Organisation A
-------------

Protected Host A: what is the IP address of lakeside.int.org-b.example.com?
DNS Server of Organisation B: 2001:db8:1:7ea::42


Outside party
------------
Outside Hosts: what is the IP address of lakeside.int.org-b.example.com?

a) DNS Server of Organisation B: there is no domain
   int.org-b.example.com (DNS view restriction)
b) DNS Server of Organisation B: these are the nameserver for
   int.org-b.example.com, but you cannot reach them (firewall protection)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;For IPv6 based VPNs you can get away without reconfiguring your source
networks for DNS servers of the destination party. The target party
always needs to ensure proper access control to internal resources, so
there is no additional overhead.&lt;/p&gt;
&lt;p&gt;DNS, correctly used in the IPv6 VPN world, is a really smooth
operation. This is why we recommend to use
&lt;a href="https://ipv6vpn.ch"&gt;IPv6 as a basis for VPNs&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>Bye, bye netboot</title><link href="https://ungleich.ch/u/blog/2021-08-31-datacenterlight-bye-bye-netboot/" rel="alternate"/><updated>2021-08-31T00:00:00Z</updated><author><name>ungleich infrastructure team</name></author><id>urn:uuid:dc4f2ce3-b6fc-3be8-b6d7-887993273342</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Since the very beginning of the &lt;a href="../../projects/data-center-light"&gt;Data Center Light
project&lt;/a&gt; our servers have been
&lt;em&gt;somewhat stateless&lt;/em&gt; and booted from their operating system from the
network.&lt;/p&gt;
&lt;p&gt;From today on this changes and our servers are switched to boot from
an disk (SSD/NVMe/HDD). While this first seems counter intuitive with
growing a data center, let us explain why this makes sense for us.&lt;/p&gt;
&lt;h2&gt;Netboot in a nutshell&lt;/h2&gt;
&lt;p&gt;There are different variants of how to netboot a server. In either
case, the server loads an executable from the network, typically via
TFTP or HTTP and then hands over execution to it.&lt;/p&gt;
&lt;p&gt;The first option is to load the kernel and then later switch to an NFS
based filesystem. If the filesystem is read write, you usually need
one location per server or you mount it read only and possibly apply
an overlay for runtime configuration.&lt;/p&gt;
&lt;p&gt;The second option is to load the kernel and an initramfs into memory
and stay inside the initramfs. The advantage of this approach is that
no NFS server is needed, but the whole operating system is inside the
memory.&lt;/p&gt;
&lt;p&gt;The second option is what we used in Data Center Light for the last
couple of years.&lt;/p&gt;
&lt;h2&gt;Netboot history at Data Center Light&lt;/h2&gt;
&lt;p&gt;Originally all our servers started with IPv4 PXE based
netboot. However as our data center is generally speaking IPv6 only,
the IPv4 DHCP+TFTP combination is an extra maintenance and also a
hindrance for network debugging: if you are in a single stack IPv6
only network, things are much easier to debug. No need to look for two
routing tables, no need to work around DHCP settings that might
interfere with what one wants to achieve via IPv6.&lt;/p&gt;
&lt;p&gt;As the IPv4 addresses became more of a technical debt in our
infrastructure, we started flashing our network cards with
&lt;a href="https://ipxe.org/"&gt;ipxe&lt;/a&gt;, which allows even older network cards to
boot in IPv6 only networks.&lt;/p&gt;
&lt;p&gt;Also in an IPv6 only netboot environment, it is easier to run
active-active routers, as hosts are not assigned DHCP leases. They
assign addresses themselves, which scales much nicer.&lt;/p&gt;
&lt;h2&gt;Migrating away from netbooting&lt;/h2&gt;
&lt;p&gt;So why are we migrating away from netbooting, even after we migrated
to IPv6 only networking? There are multiple aspects:&lt;/p&gt;
&lt;p&gt;On power failure, netbooted hosts lose their state. The operating
system that is loaded is the same for every server and needs some
configuration post-boot. We have solved this using
&lt;a href="https://www.cdi.st/"&gt;cdist&lt;/a&gt;, however the authentication-trigger
mechanism is non-trivial, if you want to keep your netboot images and
build steps public.&lt;/p&gt;
&lt;p&gt;The second reason is state synchronisation: as we are having multiple
boot servers, we need to maintain the same state on multiple
machines. That is solvable via CI/CD pipelines, however the level of
automation on build servers is rather low, because the amount of OS
changes are low.&lt;/p&gt;
&lt;p&gt;The third and main point is our ongoing migration towards
&lt;a href="https://kubernetes.io/"&gt;kubernetes&lt;/a&gt;. Originally our servers would
boot up, get configured for providing ceph storage or to be a
virtualisation host. The amount of binaries to keep in our in-memory
image was tiny, in the best case around 150MB. With the migration
towards kubernetes, every node is downloading the containers, which
can be comparable huge (gigabytes of data). The additional pivot_root
workarounds that are required for initramfs usage are just an
additional minor point that made us question our current setup.&lt;/p&gt;
&lt;h2&gt;Automating disk based boot&lt;/h2&gt;
&lt;p&gt;We have servers from a variety of brands and each of them comes with a
variety of disk controllers: from simple pass-through SATA controllers
to full fledged hardware raid with onboard cache and battery for
protecting the cache - everything is in the mix.&lt;/p&gt;
&lt;p&gt;So it is not easily possible to generate a stack of disks somewhere
and then add them, as the disk controller might add some (RAID0) meta
data to it.&lt;/p&gt;
&lt;p&gt;To work around this problem, we insert the disk that is becoming the
boot disk in the future into the netbooted servers, install the
operating system from the running environment and at the next
maintenance window ensure that the server is actually booting from it.&lt;/p&gt;
&lt;p&gt;If you are curious on how this works, you can checkout the script that
we use for
&lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-tools/-/blob/master/debian-devuan-install-on-disk.sh"&gt;Devuan/Debian&lt;/a&gt;
and
&lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-tools/-/blob/master/alpine-install-on-disk.sh"&gt;Alpine Linux&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;The road continues&lt;/h2&gt;
&lt;p&gt;While a data center needs to be stable, it also needs to adapt to
newer technologies or different flows. The disk based boot is our
current solution for our path towards kubernetes migration, but who
knows - in the future things might look different again.&lt;/p&gt;
&lt;p&gt;If you want to join the discussion, we have a
&lt;a href="../../projects/open-chat/"&gt;Hacking and Learning
(#hacking-and-learning:ungleich.ch)&lt;/a&gt; channel
on Matrix for an open exchange.&lt;/p&gt;
&lt;p&gt;Oh and in case &lt;a href="https://twitter.com/ungleich/status/1432627966316584968"&gt;you were wondering what we did
today&lt;/a&gt;, we
switched to disk based booting - that case is full of SSDs, not 1'000
CHF banknotes.&lt;/p&gt;
</content></entry><entry><title>Configuring bind to only forward DNS to a specific zone</title><link href="https://ungleich.ch/u/blog/how-to-configure-bind-dns-for-a-forward-zone-only/" rel="alternate"/><updated>2021-07-25T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:eda9b222-2e9b-39d0-bf46-f4adb85a4c91</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this article we'll show you an easy solution to host DNS zones on
IPv6 only or private DNS servers. The method we use here is &lt;strong&gt;DNS
forwarding&lt;/strong&gt; as offered in ISC BIND, but one could also see this as
&lt;strong&gt;DNS proxying&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;Sometimes you might have a DNS server that is authoritative for DNS
data, but is not reachable for all clients. This might be the case for
instance, if&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;your DNS server is IPv6 only: it won't be directly reachable from
the IPv4 Internet&lt;/li&gt;
&lt;li&gt;your DNS server is running in a private network, either IPv4 or IPv6&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In both cases, you need something that is publicly reachable, to
enable clients to access the zone, like show in the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img src="dns-proxy-forward.png" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;The problem: Forwarding requires recursive queries&lt;/h2&gt;
&lt;p&gt;ISC Bind allows to forward queries to another name server. However to
do so, it need to be configured to allow handling recursive querying.
However, if we allow recursive querying by any client, we basically
create an &lt;a href="https://www.ncsc.gov.ie/emailsfrom/DDoS/DNS/"&gt;Open DNS resolver, which can be quite
dangerous&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;ISC Bind by default has a root hints file compiled in, which allows it
to function as a resolver without any additional configuration
files. That is great, but not if you want to prevent it to work as
forwarder as described above. But we can easily fix that problem. Now,
let's have a look at a real world use case, step-by-step:&lt;/p&gt;
&lt;h3&gt;Step 1: Global options&lt;/h3&gt;
&lt;p&gt;In the first step, we need to set the global to allow recursion from
anyone, as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options {
    directory "/var/cache/bind";

    listen-on-v6 { any; };

    allow-recursion { ::/0; 0.0.0.0/0; };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However as mentioned above, this would create an open resolver. To
prevent this, let's disable the root hints:&lt;/p&gt;
&lt;h3&gt;Step 2: Disable root hints&lt;/h3&gt;
&lt;p&gt;The root hints are served in the root zone, also know as ".". To
disable it, we give bind an empty file to use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zone "." {
        type hint;
        file "/dev/null";
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: in case you do want to allow recursive function for some
clients, &lt;strong&gt;you can create multiple DNS views&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Step 3: The actual DNS file&lt;/h3&gt;
&lt;p&gt;In our case, we have a lot of IPv6 only kubernetes clusters, which are
named &lt;code&gt;xx.k8s.ooo&lt;/code&gt; and have a world wide rachable CoreDNS server built
in. In this case, we want to allow the domain c1.k8s.ooo to be world
reachable, so we configure the dual stack server as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zone "c1.k8s.ooo"  {
   type forward;
   forward only;
   forwarders { 2a0a:e5c0:2:f::a; };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 4: adjusting the zone file&lt;/h3&gt;
&lt;p&gt;In case you are running an IPv6 only server, you need to configure the
upstream DNS server. In our case this looks as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;; The domain: c1.k8s.ooo
c1                          NS      kube-dns.kube-system.svc.c1

; The IPv6 only DNS server
kube-dns.kube-system.svc.c1 AAAA    2a0a:e5c0:2:f::a

; The forwarding IPv4 server
kube-dns.kube-system.svc.c1 A       194.5.220.43
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DNS, IPv6, Kubernetes?&lt;/h2&gt;
&lt;p&gt;If you are curious to learn more about either of these topics, feel
&lt;a href="../../projects/open-chat/"&gt;free to join us on our chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>GLAMP #1 2021</title><link href="https://ungleich.ch/u/blog/glamp-1-2021/" rel="alternate"/><updated>2021-07-17T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:93f3e798-3aa0-3108-97e5-49b4ca15c23b</id><content type="html">&lt;h2&gt;Glamp 2021 has been CANCELLED&lt;/h2&gt;
&lt;p&gt;Due to the rising number of Coronavirus infections, travel
restrictions and travel uncertainties,
we have decided to CANCEL the GLAMP2021.&lt;/p&gt;
&lt;h2&gt;Tl;DR&lt;/h2&gt;
&lt;p&gt;Get your tent, connect it to power and 10Gbit/s Internet in the midst
of the Glarner mountains. Happenening Thursday 2021-08-19 to Sunday 2021-08-22.
Apply for participation by mail (information at the bottom of the page).&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It has been some time since our
&lt;a href="https://hack4glarus.ch"&gt;last Hack4Glarus&lt;/a&gt; and we have been missing
all our friends, hackers and participants. At ungleich we have been
watching the development of the Coronavirus world wide and as you
might know, we have decided against a Hack4Glarus for this summer, as
the Hack4Glarus has been an indoor event so far.&lt;/p&gt;
&lt;h2&gt;No Hack4Glarus = GLAMP&lt;/h2&gt;
&lt;p&gt;However, we want to try a different format that ensures proper
safety. Instead of an indoor Hack4Glarus in Linthal, we introduce
the Glarus Camp (or GLAMP in short) to you. An outdoor event with
sufficient space for distancing. As a camping site we can use the
surrounding of the Hacking Villa, supported by the Hacking Villa
facilities.&lt;/p&gt;
&lt;p&gt;Compared to the Hack4Glarus, the GLAMP will focus more on
&lt;em&gt;relaxation&lt;/em&gt;, &lt;em&gt;hangout&lt;/em&gt; than being a hackathon. We think times are
hard enough to give everyone a break.&lt;/p&gt;
&lt;h2&gt;The setting&lt;/h2&gt;
&lt;p&gt;Many of you know the &lt;a href="../../projects/hacking-villa/"&gt;Hacking Villa&lt;/a&gt; in
Diesbach already. Located just next to the pretty waterfall and the amazing
Legler Areal. The villa is connected with 10 Gbit/s to the
&lt;a href="../../projects/data-center-light/"&gt;Data Center Light&lt;/a&gt; and offers a lot
of fun things to do.&lt;/p&gt;
&lt;h2&gt;Coronavirus measures beforehand&lt;/h2&gt;
&lt;p&gt;To ensure safety for everyone, we ask everyone attending to provide a
reasonable proof of not spreading the corona virus with one of the
following proofs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have been vaccinated&lt;/li&gt;
&lt;li&gt;You had the corona virus and you are symptom free for at least 14
days&lt;/li&gt;
&lt;li&gt;You have been tested with a PCR test (7 days old at maximum) and the
result was negative&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All participants will be required to take an short antigen test on
site.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please do not attend if you feel sick for the safety of everyone else.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Coronavirus measures on site&lt;/h2&gt;
&lt;p&gt;To keep the space safe on site as well, we ask you to follow these
rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sleep in your own tent&lt;/li&gt;
&lt;li&gt;Wear masks inside the Hacking Villa&lt;ul&gt;
&lt;li&gt;Especially if you are preparing food shared with others&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Keep distance and respect others safety wishes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Hacking Villa Facilities&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Fast Internet (what do you need more?)&lt;/li&gt;
&lt;li&gt;A shared, open area outside for hacking&lt;/li&gt;
&lt;li&gt;Toilets and bath room located inside&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What to bring&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A tent + sleeping equipment&lt;/li&gt;
&lt;li&gt;Fun stuff&lt;ul&gt;
&lt;li&gt;Your computer&lt;/li&gt;
&lt;li&gt;Wifi / IoT / Hacking things&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you want wired Internet in your tent: a 15m+ Ethernet cable&lt;ul&gt;
&lt;li&gt;WiFi will be provided everywhere&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What is provided&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Breakfast every morning&lt;/li&gt;
&lt;li&gt;A place for a tent&lt;/li&gt;
&lt;li&gt;Power to the tent (Swiss plug)&lt;/li&gt;
&lt;li&gt;WiFi to the tent&lt;/li&gt;
&lt;li&gt;Traditional closing event spaghetti&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What you can find nearby&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A nearby supermarket (2km) reachable by foot, scooter, bike&lt;/li&gt;
&lt;li&gt;A waterfall + barbecue place (~400m)&lt;/li&gt;
&lt;li&gt;Daily attractions such as hacking, hiking, biking, hanging out&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Registration&lt;/h2&gt;
&lt;p&gt;As the space is limited, we can accomodate about 10 tents (roughly 23
people). To register, send an email to support@ungleich.ch based on
the following template:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Subject: GLAMP#1 2021

For each person with you (including yourself):

    Non Coronavirus proof:
    (see requirements on the glamp page)

    Name(s):
    (how you want to be called)

    Interests:
    (will be shown to others at the glamp)

    Skills:
    (will be shown to others at the glamp)

    Food interests:
    (we use this for pooling food orders)

    What I would like to do:
    (will be shown to others at the glamp)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The particaption fee is 70 CHF/person (to be paid on arrival).&lt;/p&gt;
&lt;h2&gt;Time, Date and Location&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Arrival possible from Wednesday 2021-08-18 16:00&lt;/li&gt;
&lt;li&gt;GLAMP#1 starts officially on Thursday 2021-08-19, 1000&lt;/li&gt;
&lt;li&gt;GLAMP#1 closing lunch Sunday 2021-08-22, 1200&lt;/li&gt;
&lt;li&gt;GLAMP#1 ends officially on to Sunday 2021-08-22, 1400&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Location: &lt;a href="../../projects/hacking-villa/"&gt;Hacking Villa&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;FAQ&lt;/h2&gt;
&lt;h3&gt;Where do I get Internet?&lt;/h3&gt;
&lt;p&gt;It is available everywhere at/around the Hacking Villa via WiFi. For
cable based Internet bring a 15m+ Ethernet cable.&lt;/p&gt;
&lt;h3&gt;Where do I get Electricity?&lt;/h3&gt;
&lt;p&gt;You'll get electricity directly to the tent. Additionally the shared
area also has electricity. You can also bring solar panels, if you
like.&lt;/p&gt;
&lt;h3&gt;Where do I get food?&lt;/h3&gt;
&lt;p&gt;Breakfast is provided by us. But what about the rest of the day?
There are a lot of delivery services available, ranging from Pizza,
Tibetan, Thai, Swiss (yes!), etc. available.&lt;/p&gt;
&lt;p&gt;Nearby are 2 Volg supermarkets, next Coop is in Schwanden, bigger
Migros in Glarus and very big Coop can be found in Netstal. The Volg
is reachable by foot, all others are reachable by train or bike.&lt;/p&gt;
&lt;p&gt;There is also a kitchen inside the Hacking Villa for cooking.
There is also a great barbecue place just next to the waterfall.&lt;/p&gt;
&lt;h3&gt;What can I do at the GLAMP?&lt;/h3&gt;
&lt;p&gt;There are
&lt;a href="http://hyperboleandahalf.blogspot.com/2010/04/alot-is-better-than-you-at-everything.html"&gt;alot&lt;/a&gt;
of opportunities at the GLAMP:&lt;/p&gt;
&lt;p&gt;You can ...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;just relax and hangout&lt;/li&gt;
&lt;li&gt;hack on project that you post poned for long&lt;/li&gt;
&lt;li&gt;hike up mountains (up to 3612m! Lower is also possible)&lt;/li&gt;
&lt;li&gt;meet other hackers&lt;/li&gt;
&lt;li&gt;explore the biggest water power plant in Europe (Linth Limmern)&lt;/li&gt;
&lt;li&gt;and much much more!&lt;/li&gt;
&lt;/ul&gt;
</content></entry><entry><title>Automatic A and AAAA DNS entries with NAT64 for kubernetes?</title><link href="https://ungleich.ch/u/blog/kubernetes-dns-entries-nat64/" rel="alternate"/><updated>2021-06-24T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:9a95b6f8-209f-355c-9f71-cf9f50229fe3</id><content type="html">&lt;h2&gt;The DNS kubernetes quiz&lt;/h2&gt;
&lt;p&gt;Today our blog entry does not (yet) show a solution, but more a tricky
quiz on creating DNS entries. The problem to solve is the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to make every IPv6 only service in kubernetes also IPv4
reachable?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's see who can solve it first or the prettiest. Below are some
thoughts on how to approach this problem.&lt;/p&gt;
&lt;h2&gt;The situation&lt;/h2&gt;
&lt;p&gt;Assume your kubernetes cluster is IPv6 only and all services
have proper AAAA DNS entries. This allows you
&lt;a href="../kubernetes-without-ingress/"&gt;to directly receive traffic from the
Internet&lt;/a&gt; to
your kubernetes services.&lt;/p&gt;
&lt;p&gt;Now to make that service also IPv4 reachable, we can deploy NAT64
service that maps an IPv4 address outside the cluster to an IPv6 service
address inside the cluster:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A.B.C.D --&amp;gt; 2001:db8::1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So all traffic to that IPv4 address is converted to IPv6 by the
external NAT64 translator.&lt;/p&gt;
&lt;h2&gt;The proxy service&lt;/h2&gt;
&lt;p&gt;Let's say the service running on 2001:db8::1 is named "ipv4-proxy" and
thus reachable at ipv4-proxy.default.svc.example.com.&lt;/p&gt;
&lt;p&gt;What we want to achieve is to expose every possible service
inside the cluster &lt;strong&gt;also via IPv4&lt;/strong&gt;. For this purpose we have created
an haproxy container that access *.svc.example.com and forwards it via
IPv6.&lt;/p&gt;
&lt;p&gt;So the actual flow would look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IPv4 client --[ipv4]--&amp;gt; NAT64 -[ipv6]-&amp;gt; proxy service
                                         |
                                         |
                                         v
IPv6 client ---------------------&amp;gt; kubernetes service
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The DNS dilemma&lt;/h2&gt;
&lt;p&gt;It would be very tempting to create a wildcard DNS entry or to
configure/patch CoreDNS to also include an A entry for every service
that is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*.svc IN A A.B.C.D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So essentially all services resolve to the IPv4 address A.B.C.D. That
however would also influence the kubernetes cluster, as pods
potentially resolve A entries (not only AAAA) as well.&lt;/p&gt;
&lt;p&gt;As the containers / pods do not have any IPv4 address (nor IPv4
routing), access to IPv4 is not possible. There are various outcomes
of this situation:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The software in the container does happy eyeballs and tries both
A/AAAA and uses the working IPv6 connection.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The software in the container misbehaves and takes the first record
and uses IPv4 (nodejs is known to have or had a broken resolver
that did exactly that).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So adding that wildcard might not be the smartest option. And
additionally it is unclear whether coreDNS would support that.&lt;/p&gt;
&lt;h2&gt;Alternative automatic DNS entries&lt;/h2&gt;
&lt;p&gt;The &lt;em&gt;.svc names in a kubernetes cluster are special in the sense that
they are used for connecting internally. What if coreDNS (or any other
DNS) server would instead of using &lt;/em&gt;.svc, use a second subdomain like
&lt;em&gt;abc&lt;/em&gt;.&lt;em&gt;namespace&lt;/em&gt;.v4andv6.example.com and generate the same AAAA
record as for the service and a static A record like describe above?&lt;/p&gt;
&lt;p&gt;That could solve the problem. But again, does coreDNS support that?&lt;/p&gt;
&lt;h2&gt;Automated DNS entries in other zones&lt;/h2&gt;
&lt;p&gt;Instead of fully automated creating the entries as above, another
option would be to specify DNS entries via annotations in a totally
different zone, if coreDNS was supporting this. So let's say we also
have control over example.org and we could instruct coreDNS to create
the following entries automatically with an annotation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc.something.example.org AAAA &amp;lt;same as the service IP&amp;gt;
abc.something.example.org A    &amp;lt;a static IPv4 address A.B.C.D&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In theory this might be solved via some scripting, maybe via a DNS
server like powerDNS?&lt;/p&gt;
&lt;h2&gt;Alternative solution with BIND&lt;/h2&gt;
&lt;p&gt;The bind DNS server, which is not usually deployed in a kubernetes
cluster, supports &lt;strong&gt;views&lt;/strong&gt;. Views enable different replies to the
same query depending on the source IP address. Thus in theory
something like that could be done, assuming a secondary zone
&lt;em&gt;example.org&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the request comes from the kubernetes cluster, return a CNAME
back to example.com.&lt;/li&gt;
&lt;li&gt;If the request comes from outside the kubernetes cluster, return an
A entry with the static IP&lt;/li&gt;
&lt;li&gt;Unsolved: how to match on the AAAA entries (because we don't CNAME
with the added A entry)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Other solution?&lt;/h2&gt;
&lt;p&gt;As you can see, mixing the dynamic IP generation and coupling it with
static DNS entries for IPv4 resolution is not the easiest tasks. If
you have a smart idea on how to solve this without manually creating
entries for each and every service,
&lt;a href="../../contact"&gt;give us a shout!&lt;/a&gt;&lt;/p&gt;
</content></entry><entry><title>Support for IPv6 link local addresses in browsers</title><link href="https://ungleich.ch/u/blog/ipv6-link-local-support-in-browsers/" rel="alternate"/><updated>2021-06-14T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:6970c846-f35e-32db-bf91-e328cf3dfa6e</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Link Local addresses
(&lt;a href="https://en.wikipedia.org/wiki/Link-local_address"&gt;fe80::/10&lt;/a&gt;) are
used for addressing devices in your local subnet. They can be
automatically generated and using the IPv6 multicast address
&lt;strong&gt;ff02::1&lt;/strong&gt;, all hosts on the local subnet can easily be located.&lt;/p&gt;
&lt;p&gt;However browsers like Chrome or Firefox do not support &lt;strong&gt;entering link
local addresses inside a URL&lt;/strong&gt;, which prevents accessing devices
locally with a browser, for instance for configuring them.&lt;/p&gt;
&lt;p&gt;Link local addresses need &lt;strong&gt;zone identifiers&lt;/strong&gt; to specify which
network device to use as an outgoing interface. This is because
&lt;strong&gt;you have link local addresses on every interface&lt;/strong&gt; and your network
stack does not know on its own, which interface to use. So typically a
link local address is something on the line of
&lt;strong&gt;fe80::fae4:e3ff:fee2:37a4%eth0&lt;/strong&gt;, where &lt;strong&gt;eth0&lt;/strong&gt; is the zone
identifier.&lt;/p&gt;
&lt;p&gt;Them problem is becoming more emphasised, as the world is moving more
and more  towards &lt;strong&gt;IPv6 only networks&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You might not even know the address of your network equipment anymore,
but you can easily locate iit using the &lt;strong&gt;ff02::1 multicast
address&lt;/strong&gt;. So we need support in browsers, to allow network
configurations.&lt;/p&gt;
&lt;h2&gt;Status of implementation&lt;/h2&gt;
&lt;p&gt;The main purpose of this document is to track the status of the
link-local address support in the different browsers and related
standards. The current status is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firefox says whatwg did not define it&lt;/li&gt;
&lt;li&gt;Whatwg says zone id is intentionally omitted and and reference w3.org&lt;/li&gt;
&lt;li&gt;w3.org has a longer reasoning, but it basically boils down to
"Firefox and chrome don't do it and it's complicated and nobody needs it"&lt;/li&gt;
&lt;li&gt;Chromium says it seems not to be worth the effort&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given that chain of events, if either Firefox, Chrome, W3.org or
Whatwg where to add support for it, it seems likely that the others
would be following.&lt;/p&gt;
&lt;h2&gt;IPv6 link local address support in Firefox&lt;/h2&gt;
&lt;p&gt;The progress of IPv6 link local addresses for Firefox is tracked
on &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=700999"&gt;the mozilla
bugzilla&lt;/a&gt;. The
current situation is that Firefox references to the lack of
standardisation by whatwg as a reason for not implementing it. Quoting
Valentin Gosu from the Mozilla team:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The main reason the zone identifier is not supported in Firefox is
that parsing URLs is hard.  You'd think we can just pass whatever
string to the system API and it will work or fail depending on whether
it's valid or not, but that's not the case. In bug 1199430 for example
it was apparent that we need to make sure that the hostname string is
really valid before passing it to the OS.

I have no reason to oppose zone identifiers in URLs as long as the URL
spec defines how to parse them.  As such, I encourage you to engage
with the standard at https://github.com/whatwg/url/issues/392 instead
of here.

Thank you!
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;IPv6 link local address support in whatwg&lt;/h2&gt;
&lt;p&gt;The situation at &lt;a href="https://whatwg.org/"&gt;whatwg&lt;/a&gt; is that there is a
&lt;a href="https://github.com/whatwg/url/issues/392"&gt;closed bug report on github&lt;/a&gt;
and &lt;a href="https://url.spec.whatwg.org/#concept-ipv6"&gt;in the spec it says&lt;/a&gt;
that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Support for &amp;lt;zone_id&amp;gt; is intentionally omitted.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That paragraph links to a bug registered at w3.org (see next chapter).&lt;/p&gt;
&lt;h2&gt;IPv6 link local address support at w3.org&lt;/h2&gt;
&lt;p&gt;At &lt;a href="https://www.w3.org/"&gt;w3.org&lt;/a&gt; there is a
bug titled
&lt;a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=27234#c2"&gt;Support IPv6 link-local
addresses?&lt;/a&gt;
that is set to status &lt;strong&gt;RESOLVED WONTFIX&lt;/strong&gt;. It is closed basically
based on the following statement from Ryan Sleevi:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Yes, we're especially not keen to support these in Chrome and have
repeatedly decided not to. The platform-specific nature of &amp;lt;zone_id&amp;gt;
makes it difficult to impossible to validate the well-formedness of
the URL (see https://tools.ietf.org/html/rfc4007#section-11.2 , as
referenced in 6874, to fully appreciate this special hell). Even if we
could reliably parse these (from a URL spec standpoint), it then has
to be handed 'somewhere', and that opens a new can of worms.

Even 6874 notes how unlikely it is to encounter these in practice -
  "Thus, URIs including a
   ZoneID are unlikely to be encountered in HTML documents.  However, if
   they do (for example, in a diagnostic script coded in HTML), it would
   be appropriate to treat them exactly as above."

Note that a 'dumb' parser may not be sufficient, as the Security Considerations of 6874 note:
  "To limit this risk, implementations MUST NOT allow use of this format
   except for well-defined usages, such as sending to link-local
   addresses under prefix fe80::/10.  At the time of writing, this is
   the only well-defined usage known."

And also
  "An HTTP client, proxy, or other intermediary MUST remove any ZoneID
   attached to an outgoing URI, as it has only local significance at the
   sending host."

This requires a transformative rewrite of any URLs going out the
wire. That's pretty substantial. Anne, do you recall the bug talking
about IP canonicalization (e.g. http://127.0.0.1 vs
http://[::127.0.0.1] vs http://012345 and friends?) This is
conceptually a similar issue - except it's explicitly required in the
context of &amp;lt;zone_id&amp;gt; that the &amp;lt;zone_id&amp;gt; not be emitted.

There's also the issue that zone_id precludes/requires the use of APIs
that user agents would otherwise prefer to avoid, in order to
'properly' handle the zone_id interpretation. For example, Chromium on
some platforms uses a built in DNS resolver, and so our address lookup
functions would need to define and support &amp;lt;zone_id&amp;gt;'s and map them to
system concepts. In doing so, you could end up with weird situations
where a URL works in Firefox but not Chrome, even though both
'hypothetically' supported &amp;lt;zone_id&amp;gt;'s, because FF may use an OS
routine and Chrome may use a built-in routine and they diverge.

Overall, our internal consensus is that &amp;lt;zone_id&amp;gt;'s are bonkers on
many grounds - the technical ambiguity (and RFC 6874 doesn't really
resolve the ambiguity as much as it fully owns it and just says
#YOLOSWAG) - and supporting them would add a lot of complexity for
what is explicitly and admittedly a limited value use case.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This bug references the Mozilla Firefox bug above and
&lt;a href="https://datatracker.ietf.org/doc/html/rfc6874#section-2"&gt;RFC3986 (replaced by RFC
6874)&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;IPv6 link local address support in Chrome / Chromium&lt;/h2&gt;
&lt;p&gt;On the chrome side there is a
&lt;a href="https://bugs.chromium.org/p/chromium/issues/detail?id=70762"&gt;huge bug
report&lt;/a&gt;
which again references a huge number of other bugs that try to request
IPv6 link local support, too.&lt;/p&gt;
&lt;p&gt;The bug was closed by cbentzel@chromium.org stating:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;There are a large number of special cases which are required on core
networking/navigation/etc. and it does not seem like it is worth the
up-front and ongoing maintenance costs given that this is a very
niche - albeit legitimate - need.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The bug at chromium has been made un-editable so it is basically
frozen, besides people have added suggestions to the ticket on how to
solve it.&lt;/p&gt;
&lt;h2&gt;Work Arounds&lt;/h2&gt;
&lt;h3&gt;IPv6 link local connect hack&lt;/h3&gt;
&lt;p&gt;Peter has &lt;a href="https://website.peterjin.org/wiki/Snippets:IPv6_link_local_connect_hack"&gt;documented on the IPv6 link local connect
hack&lt;/a&gt;
to make firefox use &lt;strong&gt;fe90:0:[scope id]:[IP address]&lt;/strong&gt; to reach
&lt;strong&gt;fe80::[IP address]%[scope id]&lt;/strong&gt;. Checkout his website for details!&lt;/p&gt;
&lt;h3&gt;IPv6 hack using ip6tables&lt;/h3&gt;
&lt;p&gt;Also from Peter is the hint that you can also use newer iptable
versions to achieve a similar mapping:&lt;/p&gt;
&lt;p&gt;"On modern Linux kernels you can also run&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ip6tables -t nat -A OUTPUT -d fef0::/64 -j NETMAP --to fe80::/64&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;if you have exactly one outbound interface, so that fef0::1 translates
to fe80::1"&lt;/p&gt;
&lt;p&gt;Thanks again for the pointer!&lt;/p&gt;
&lt;h3&gt;The prettysocks SOCKS5 proxy (update 2021-11-24)&lt;/h3&gt;
&lt;p&gt;On 2021-11-23 we have been notified that there is a new workaround
available:
&lt;a href="https://github.com/twisteroidambassador/prettysocks/tree/ipv6-literal"&gt;prettysock&lt;/a&gt;
is a Socks5 proxy written in python that allows the use of Microsoft's
&lt;strong&gt;ipv6-literal.net&lt;/strong&gt; domain, but from any OS or browser, which is
pointed to the proxy. So to access &lt;strong&gt;fe80::1ff:fe23:4567:890a%3&lt;/strong&gt;,
configure your browser to use the local prettysocks Socks5 proxy,
replace the link local address with
&lt;strong&gt;fe80--1ff-fe23-4567-890as3.ipv6-literal.net&lt;/strong&gt; and there you go.&lt;/p&gt;
&lt;p&gt;There are two interesting things to say about this solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is a very simple solution&lt;/li&gt;
&lt;li&gt;It is surprising that browser vendors haven't implement such a
simple solution themselves so far - does it need an RFC that defines
the domain to be used?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Other resources&lt;/h2&gt;
&lt;p&gt;If you are aware of other resources regarding IPv6 link local support
in browsers, please join the &lt;a href="https://IPv6.chat"&gt;IPv6.chat&lt;/a&gt; and let us
know about it.&lt;/p&gt;
</content></entry><entry><title>Making kubernetes kube-dns publicly reachable</title><link href="https://ungleich.ch/u/blog/kubernetes-making-dns-publicly-reachable/" rel="alternate"/><updated>2021-06-13T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:ca4d0313-3ea3-3388-b9e3-04372a49a705</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;If you have seen our
&lt;a href="../kubernetes-without-ingress/"&gt;article about running kubernetes
Ingress-less&lt;/a&gt;, you are aware that
we are pushing IPv6 only kubernetes clusters at ungleich.&lt;/p&gt;
&lt;p&gt;Today, we are looking at making the "internal" kube-dns service world
reachable using IPv6 and global DNS servers.&lt;/p&gt;
&lt;h2&gt;The kubernetes DNS service&lt;/h2&gt;
&lt;p&gt;If you have a look at your typical k8s cluster, you will notice that
you usually have two coredns pods running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% kubectl -n kube-system get pods -l k8s-app=kube-dns
NAME                       READY   STATUS    RESTARTS   AGE
coredns-558bd4d5db-gz5c7   1/1     Running   0          6d
coredns-558bd4d5db-hrzhz   1/1     Running   0          6d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These pods are usually served by the &lt;strong&gt;kube-dns&lt;/strong&gt; service:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% kubectl -n kube-system get svc -l k8s-app=kube-dns
NAME       TYPE        CLUSTER-IP           EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   2a0a:e5c0:13:e2::a   &amp;lt;none&amp;gt;        53/UDP,53/TCP,9153/TCP   6d1h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the kube-dns service is running on a publicly
reachable IPv6 address.&lt;/p&gt;
&lt;h2&gt;IPv6 only DNS&lt;/h2&gt;
&lt;p&gt;IPv6 only DNS servers have one drawback: they cannot be reached via DNS
recursions, if the resolver is IPv4 only.&lt;/p&gt;
&lt;p&gt;At &lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki"&gt;ungleich we run a variety of
services&lt;/a&gt;
to make IPv6 only services usable in the real world. In case of DNS,
we are using &lt;strong&gt;DNS forwarders&lt;/strong&gt;. They are acting similar to HTTP
proxies, but for DNS.&lt;/p&gt;
&lt;p&gt;So in our main DNS servers, dns1.ungleich.ch, dns2.ungleich.ch
and dns3.ungleich.ch we have added the following configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zone "k8s.place7.ungleich.ch"  {
   type forward;
   forward only;
   forwarders { 2a0a:e5c0:13:e2::a; };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells the DNS servers to forward DNS queries that come in for
k8s.place7.ungleich.ch to &lt;strong&gt;2a0a:e5c0:13:e2::a&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Additionally we have added &lt;strong&gt;DNS delegation&lt;/strong&gt; in the
place7.ungleich.ch zone:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;k8s NS dns1.ungleich.ch.
k8s NS dns2.ungleich.ch.
k8s NS dns3.ungleich.ch.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using the kubernetes DNS service in the wild&lt;/h2&gt;
&lt;p&gt;With this configuration, we can now access IPv6 only
kubernetes services directly from the Internet. Let's first discover
the kube-dns service itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% dig kube-dns.kube-system.svc.k8s.place7.ungleich.ch. aaaa

; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.16.16 &amp;lt;&amp;lt;&amp;gt;&amp;gt; kube-dns.kube-system.svc.k8s.place7.ungleich.ch. aaaa
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 23274
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: f61925944f5218c9ac21e43960c64f254792e60f2b10f3f5 (good)
;; QUESTION SECTION:
;kube-dns.kube-system.svc.k8s.place7.ungleich.ch. IN AAAA

;; ANSWER SECTION:
kube-dns.kube-system.svc.k8s.place7.ungleich.ch. 27 IN AAAA 2a0a:e5c0:13:e2::a

;; AUTHORITY SECTION:
k8s.place7.ungleich.ch. 13  IN  NS  kube-dns.kube-system.svc.k8s.place7.ungleich.ch.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the &lt;strong&gt;kube-dns&lt;/strong&gt; service in the &lt;strong&gt;kube-system&lt;/strong&gt;
namespace resolves to 2a0a:e5c0:13:e2::a, which is exactly what we
have configured.&lt;/p&gt;
&lt;p&gt;At the moment, there is also an etherpad test service
named "ungleich-etherpad" running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% kubectl get svc -l app=ungleichetherpad
NAME                TYPE        CLUSTER-IP              EXTERNAL-IP   PORT(S)    AGE
ungleich-etherpad   ClusterIP   2a0a:e5c0:13:e2::b7db   &amp;lt;none&amp;gt;        9001/TCP   3d19h
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let's first verify that it resolves:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% dig +short ungleich-etherpad.default.svc.k8s.place7.ungleich.ch aaaa
2a0a:e5c0:13:e2::b7db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if that works, well, then we should also be able to access the
service itself!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -I http://ungleich-etherpad.default.svc.k8s.place7.ungleich.ch:9001/
HTTP/1.1 200 OK
X-Powered-By: Express
X-UA-Compatible: IE=Edge,chrome=1
Referrer-Policy: same-origin
Content-Type: text/html; charset=utf-8
Content-Length: 6039
ETag: W/"1797-Dq3+mr7XP0PQshikMNRpm5RSkGA"
Set-Cookie: express_sid=s%3AZGKdDe3FN1v5UPcS-7rsZW7CeloPrQ7p.VaL1V0M4780TBm8bT9hPVQMWPX5Lcte%2BzotO9Lsejlk; Path=/; HttpOnly; SameSite=Lax
Date: Sun, 13 Jun 2021 18:36:23 GMT
Connection: keep-alive
Keep-Alive: timeout=5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(attention, this is a test service and might not be running when you
read this article at a later time)&lt;/p&gt;
&lt;h2&gt;IPv6 vs. IPv4&lt;/h2&gt;
&lt;p&gt;Could we have achived the same with IPv4? The answere here is "maybe":
If the kubernetes service is reachable from globally reachable
nameservers via IPv4, then the answer is yes. This could be done via
public IPv4 addresses in the kubernetes cluster, via tunnels, VPNs,
etc.&lt;/p&gt;
&lt;p&gt;However, generally speaking, the DNS service of a
kubernetes cluster running on RFC1918 IP addresses, is probably not
reachable from globally reachable DNS servers by default.&lt;/p&gt;
&lt;p&gt;For IPv6 the case is a bit different: we are using globally reachable
IPv6 addresses in our k8s clusters, so they can potentially be
reachable without the need of any tunnel or whatsoever. Firewalling
and network policies can obviously prevent access, but if the IP
addresses are properly routed, they will be accessible from the public
Internet.&lt;/p&gt;
&lt;p&gt;And this makes things much easier for DNS servers, which are also
having IPv6 connectivity.&lt;/p&gt;
&lt;p&gt;The following pictures shows the practical difference between the two
approaches:&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/k8s-v6-v4-dns.png" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Does this make sense?&lt;/h2&gt;
&lt;p&gt;That clearly depends on your use-case. If you want your service DNS
records to be publicly accessible, then the clear answer is yes.&lt;/p&gt;
&lt;p&gt;If your cluster services are intended to be internal only
(see &lt;a href="../kubernetes-without-ingress/"&gt;previous blog post&lt;/a&gt;, then
exposing the DNS service to the world might not be the best option.&lt;/p&gt;
&lt;h2&gt;Note on security&lt;/h2&gt;
&lt;p&gt;CoreDNS inside kubernetes is by default configured to allow resolving
for &lt;em&gt;any&lt;/em&gt; client that can reach it. Thus if you make your kube-dns
service world reachable, you also turn it into an open resolver.&lt;/p&gt;
&lt;p&gt;The following coredns configuration &lt;strong&gt;does&lt;/strong&gt; correctly block
requests, &lt;strong&gt;IF your coredns version is new enough&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  Corefile: |
    .:53 {
        acl k8s.place7.ungleich.ch {
             allow net ::/0
        }
        acl . {
              allow net 2a0a:e5c0:13::/48
              block
        }
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We tested this with
&lt;a href="https://github.com/coredns/coredns/issues/4697"&gt;coredns-1.8.4&lt;/a&gt; in
which the ACL behaviour is fixed.&lt;/p&gt;
&lt;h2&gt;More of this&lt;/h2&gt;
&lt;p&gt;We are discussing
kubernetes and IPv6 related topics in
&lt;strong&gt;the #hacking:ungleich.ch Matrix channel&lt;/strong&gt;
(&lt;a href="https://chat.with.ungleich.ch"&gt;you can signup here if you don't have an
account&lt;/a&gt;) and will post more about our
k8s journey in this blog. Stay tuned!&lt;/p&gt;
</content></entry><entry><title>Building Ingress-less Kubernetes Clusters</title><link href="https://ungleich.ch/u/blog/kubernetes-without-ingress/" rel="alternate"/><updated>2021-06-09T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:5daf6f7c-8032-38cb-ac7d-10c633163347</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;On &lt;a href="https://www.nico.schottelius.org/blog/k8s-ipv6-only-cluster/"&gt;our journey to build and define IPv6 only kubernetes
clusters&lt;/a&gt;
we came accross some principles that seem awkward in the IPv6 only
world. Let us today have a look at the &lt;em&gt;LoadBalancer&lt;/em&gt; and &lt;em&gt;Ingress&lt;/em&gt;
concepts.&lt;/p&gt;
&lt;h2&gt;Ingress&lt;/h2&gt;
&lt;p&gt;Let's have a look at the &lt;a href="https://kubernetes.io/docs/concepts/services-networking/ingress/"&gt;Ingress
definition&lt;/a&gt;
definiton from the kubernetes website:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ingress exposes HTTP and HTTPS routes from outside the cluster to
services within the cluster. Traffic routing is controlled by rules
defined on the Ingress resource.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the ingress basically routes from outside to inside. But, in the
IPv6 world, services are already publicly reachable. It just
depends on your network policy.&lt;/p&gt;
&lt;h3&gt;Update 2021-06-13: Ingress vs. Service&lt;/h3&gt;
&lt;p&gt;As some people pointed out (thanks a lot!), a public service is
&lt;strong&gt;not the same&lt;/strong&gt; as an Ingress. Ingress has also the possibility to
route based on layer 7 information like the path, domain name, etc.&lt;/p&gt;
&lt;p&gt;However, if all of the traffic from an Ingress points to a single
IPv6 HTTP/HTTPS Service, effectively the IPv6 service will do the
same, with one hop less.&lt;/p&gt;
&lt;h2&gt;Services&lt;/h2&gt;
&lt;p&gt;Let's have a look at how services in IPv6 only clusters look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% kubectl get svc
NAME                                      TYPE        CLUSTER-IP              EXTERNAL-IP   PORT(S)                      AGE
etherpad                                  ClusterIP   2a0a:e5c0:13:e2::a94b   &amp;lt;none&amp;gt;        9001/TCP                     19h
nginx-service                             ClusterIP   2a0a:e5c0:13:e2::3607   &amp;lt;none&amp;gt;        80/TCP                       43h
postgres                                  ClusterIP   2a0a:e5c0:13:e2::c9e0   &amp;lt;none&amp;gt;        5432/TCP                     19h
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All these services are world reachable, depending on your network
policy.&lt;/p&gt;
&lt;h2&gt;ServiceTypes&lt;/h2&gt;
&lt;p&gt;While we are at looking at the k8s primitives, let's have a closer
look at the &lt;strong&gt;Service&lt;/strong&gt;, specifically at 3 of the &lt;strong&gt;ServiceTypes&lt;/strong&gt;
supported by k8s, including it's definition:&lt;/p&gt;
&lt;h3&gt;ClusterIP&lt;/h3&gt;
&lt;p&gt;The k8s website says&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exposes the Service on a cluster-internal IP. Choosing this value
makes the Service only reachable from within the cluster. This is the
default ServiceType.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in the context of IPv6, this sounds wrong. There is nothing that
makes an global IPv6 address be "internal", besides possible network
policies. The concept is probably coming from the strict difference of
RFC1918 space usually used in k8s clusters and not public IPv4.&lt;/p&gt;
&lt;p&gt;This difference does not make a lot of sense in the IPv6 world though.
Seeing &lt;strong&gt;services as public by default&lt;/strong&gt;, makes much more sense.
And simplifies your clusters a lot.&lt;/p&gt;
&lt;h3&gt;NodePort&lt;/h3&gt;
&lt;p&gt;Let's first have a look at the definition again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exposes the Service on each Node's IP at a static port (the
NodePort). A ClusterIP Service, to which the NodePort Service routes,
is automatically created. You'll be able to contact the NodePort
Service, from outside the cluster, by requesting &amp;lt;NodeIP&amp;gt;:&amp;lt;NodePort&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Conceptually this can be similarily utilised in the IPv6 only world
like it does in the IPv4 world. However given that there are enough
addresses available with IPv6, this might not be such an interesting
ServiceType anymore.&lt;/p&gt;
&lt;h3&gt;LoadBalancer&lt;/h3&gt;
&lt;p&gt;Before we have a look at this type, let's take some steps back
first to ...&lt;/p&gt;
&lt;h2&gt;... Load Balancing&lt;/h2&gt;
&lt;p&gt;There are a variety of possibilities to do load balancing. From simple
round robin, to ECMP based load balancing, to application aware,
potentially weighted load balancing.&lt;/p&gt;
&lt;p&gt;So for load balancing, there is usually more than one solution and
there is likely not one size fits all.&lt;/p&gt;
&lt;p&gt;So with this said, let.s have a look at the
&lt;strong&gt;ServiceType LoadBalancer&lt;/strong&gt; definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Exposes the Service externally using a cloud provider's load
balancer. NodePort and ClusterIP Services, to which the external load
balancer routes, are automatically created.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So whatever the cloud provider offers, can be used, and that is a good
thing. However, let's have a look at how you get load balancing for
free in IPv6 only clusters:&lt;/p&gt;
&lt;h2&gt;Load Balancing in IPv6 only clusters&lt;/h2&gt;
&lt;p&gt;So what is the most easy way of reliable load balancing in network?
&lt;a href="https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing"&gt;ECMP (equal cost multi path)&lt;/a&gt;
comes to the mind right away. Given that
kubernetes nodes can BGP peer with the network (upstream or the
switches), this basically gives load balancing to the world for free:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                            [ The Internet ]
                                   |
     [ k8s-node-1 ]-----------[ network ]-----------[ k8s-node-n]
                              [  ECMP   ]
                                   |
                             [ k8s-node-2]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the real world on a bird based BGP upstream router
this looks as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[18:13:02] red.place7:~# birdc show route
BIRD 2.0.7 ready.
Table master6:
...
2a0a:e5c0:13:e2::/108 unicast [place7-server1 2021-06-07] * (100) [AS65534i]
    via 2a0a:e5c0:13:0:225:b3ff:fe20:3554 on eth0
                     unicast [place7-server4 2021-06-08] (100) [AS65534i]
    via 2a0a:e5c0:13:0:225:b3ff:fe20:3564 on eth0
                     unicast [place7-server2 2021-06-07] (100) [AS65534i]
    via 2a0a:e5c0:13:0:225:b3ff:fe20:38cc on eth0
                     unicast [place7-server3 2021-06-07] (100) [AS65534i]
    via 2a0a:e5c0:13:0:224:81ff:fee0:db7a on eth0
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which results into the following kernel route:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2a0a:e5c0:13:e2::/108 proto bird metric 32
    nexthop via 2a0a:e5c0:13:0:224:81ff:fee0:db7a dev eth0 weight 1
    nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:3554 dev eth0 weight 1
    nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:3564 dev eth0 weight 1
    nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:38cc dev eth0 weight 1 pref medium
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;We know, a TL;DR at the end is not the right thing to do, but hey, we
are at ungleich, aren't we?&lt;/p&gt;
&lt;p&gt;In a nutshell, with IPv6 the concept of &lt;strong&gt;Ingress&lt;/strong&gt;,
&lt;strong&gt;Service&lt;/strong&gt; and the &lt;strong&gt;LoadBalancer&lt;/strong&gt; ServiceType
types need to be revised, as IPv6 allows direct access without having
to jump through hoops.&lt;/p&gt;
&lt;p&gt;If you are interesting in continuing the discussion,
we are there for you in
&lt;strong&gt;the #hacking:ungleich.ch Matrix channel&lt;/strong&gt;
&lt;a href="https://chat.with.ungleich.ch"&gt;you can signup here if you don't have an
account&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Or if you are interested in an IPv6 only kubernetes cluster,
drop a mail to &lt;strong&gt;support&lt;/strong&gt;-at-&lt;strong&gt;ungleich.ch&lt;/strong&gt;.&lt;/p&gt;
</content></entry><entry><title>IPv4 as a service (ungleich tech talk #4)</title><link href="https://ungleich.ch/u/blog/ungleich-tech-talk-4-ipv4-as-a-service/" rel="alternate"/><updated>2021-03-25T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:0ae81f01-01a4-3ded-be62-e77ab4d6d55c</id><content type="html">&lt;p&gt;In the
&lt;a href="https://youtu.be/RcgB7S6lo54"&gt;fourth
ungleich tech talk&lt;/a&gt;
you can see how to get IPv4 via IPv6 using the IPv6VPN and
NAT64.&lt;/p&gt;
&lt;iframe width="560" height="315"
src="https://www.youtube.com/embed/RcgB7S6lo54" title="YouTube video
player" frameborder="0" allow="accelerometer; autoplay;
clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;We hope that you enjoy this video and
if you have any questions, feel free to join the &lt;a href="../../projects/ipv6-chat/"&gt;IPv6
chat&lt;/a&gt;. You can also read more about
&lt;a href="https://ungleich.ch/u/products/ipv4-as-a-service/"&gt;IPv4-as-a-service&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>An Introduction to NAT64</title><link href="https://ungleich.ch/u/blog/ungleich-tech-talk-3-nat64-introduction/" rel="alternate"/><updated>2021-03-09T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:08a73316-b6c5-3ba4-ae42-e8c6bf747679</id><content type="html">&lt;p&gt;In the
&lt;a href="https://www.youtube.com/watch?v=AeqS6Cjkd5E"&gt;third ungleich tech
talk&lt;/a&gt;
we give an introduction on NAT64 and how it works in general.&lt;/p&gt;
&lt;iframe width="560" height="315"
src="https://www.youtube.com/embed/AeqS6Cjkd5E" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media;
gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;We hope that you enjoy this video and
if you have any questions, feel free to join the &lt;a href="../../projects/ipv6-chat/"&gt;IPv6 chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>Accessing IPv4 only hosts via IPv6</title><link href="https://ungleich.ch/u/blog/ungleich-tech-talk-2-accessing-ipv4-only-devices-via-ipv6/" rel="alternate"/><updated>2021-02-28T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:7c77f86e-47d5-364a-9de3-0ced38df46b7</id><content type="html">&lt;p&gt;In the &lt;a href="https://www.youtube.com/watch?v=Gfe35IFdx-Q"&gt;second ungleich tech
talk&lt;/a&gt; you can find out
how to access IPv4 only devices from the IPv6 Internet using a simple
NAT64 translator.&lt;/p&gt;
&lt;iframe width="560" height="315"
src="https://www.youtube.com/embed/Gfe35IFdx-Q" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media;
gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;This is especially helpful if you are by default in IPv6 only
networks, but you still have legacy-only networks or legacy-only
devices that you need to access.&lt;/p&gt;
&lt;p&gt;In this ungleich tech talk we use the
&lt;a href="../../products/viwib-wifi-ipv6-box/"&gt;VIWIB&lt;/a&gt; as a NAT64 translator and
a reconfigured &lt;a href="../../products/vigir/"&gt;VIGIR&lt;/a&gt; as an IPv4 only demo
device.&lt;/p&gt;
&lt;p&gt;If you have any questions, feel free to join the &lt;a href="../../projects/ipv6-chat/"&gt;IPv6
chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>How to store your data without CO2 emission</title><link href="https://ungleich.ch/u/blog/how-to-sustainable-store-your-data/" rel="alternate"/><updated>2021-02-25T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:7ca7f3f8-3671-3c6b-974c-ac9f2056f475</id><content type="html">&lt;p&gt;When we talk about climate change or sustainability, we usually think
about things we can see such as factories, cars, or plastic waste. What we don't notice though is how much
we actually contribute to climate change by our digital behaviour.&lt;/p&gt;
&lt;p&gt;Even when we don't notice, we are still respopnsible for the consequences of our action. So what is the current state of digital data storage, and what can we do to change things for the better?&lt;/p&gt;
&lt;h2&gt;How data is stored&lt;/h2&gt;
&lt;p&gt;Your data is usually stored in one of the many data centers in the
world. To save your data, multiple disks or even multiple servers are
used to ensure that your data is safely stored.&lt;/p&gt;
&lt;p&gt;That means When you open up your mobile phone to browse pictures or to read your
email, you access the servers to retrieve your data.&lt;/p&gt;
&lt;h2&gt;How data centers operate&lt;/h2&gt;
&lt;p&gt;For servers to run they need electricity, on one hand for actually running the
servers that store your data and on cooling on the other hand. The
amount of energy used for cooling is quite significant, too. And this is an imoprtant question for the environment: how is the electricity for running and cooling the servers produced, with what source?&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/energysource.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, most of datacenters don't run only on renewable energy. Most of them use energy from the grid, and this energy can be produced by coal, nuclear power or renewable energy.&lt;/p&gt;
&lt;p&gt;On better cases datacenters use a mix of energy sources, making their energy source portfolio &lt;em&gt;somewhat&lt;/em&gt; green. Some datacenters do buy CO2 certificates to compensate for this fact.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/co2-offset.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;So this is the current state, even if you are living a very green and sustainable way by saying no to plastic, meat, and recycle as much as you can, you can still be contributing to CO2 emissions by using your default data storage. Because the default energy source of digital world is not green, at better cases it is somewhat green by mixed source or a bit green by offsetting the CO2 emission.&lt;/p&gt;
&lt;h2&gt;An alternative: the sustainable way of saving data&lt;/h2&gt;
&lt;p&gt;So how can we tackle this situation? Our project of &lt;a href="https://datacenterlight.ch"&gt;Data Center
Light&lt;/a&gt; came into the world by questioning the status quo.&lt;/p&gt;
&lt;p&gt;And this is how it is done:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;instead of buying energy, we produce it locally (using PV and a
local hydropower plant)&lt;/li&gt;
&lt;li&gt;instead of offsetting by buying certificates, we use 100% renewable energy&lt;/li&gt;
&lt;li&gt;instead of building new data centers, we reuse existing factory
halls&lt;/li&gt;
&lt;li&gt;instead of buying new servers, we buy 2nd hand (with new disks/ssds)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../image/environment-chat.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;The sustainable alternative&lt;/h2&gt;
&lt;p&gt;This way we want to set the new default that is as little energy as popssible, and as green as energy as possible.
By redesigning how our servers operate there is practically no CO2 emission from power
consumption and also the grey energy is minimised.&lt;/p&gt;
&lt;p&gt;With this setting, we are creating a place where everybody can make a sustainable choice in storing their data. Where one can save the data in a green storage at our &lt;a href="https://ungleich.ch/u/products/zero-carbon-cloud/"&gt;Zero Carbon Cloud,&lt;/a&gt; or run Virtual Private Servers at our &lt;a href="https://datacenterlight.ch"&gt;Data Center Light,&lt;/a&gt; &lt;a href="https://ungleich.ch/u/products/backup/"&gt;back up&lt;/a&gt;  their data with green energy, talk to each other via sustainable chat such as &lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;Zero Carbon Matrix&lt;/a&gt; or &lt;a href="https://ungleich.ch/u/products/zero-carbon-chat/"&gt;Zero Carbon Mattermost.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since the beginning of our journey we have received a lot of love and support from the tech and sustainability community. Our team at &lt;a href="https://ungleich.ch"&gt;ungleich&lt;/a&gt; is very proud of our growing range of products, because it was not only the result of our own effort that added a new product on the list. It was very much reflecting the need of the community that supported us, that demanded greener, more sustainable choices to be available.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/datacenterlight-hydro-solar.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Call to action&lt;/h2&gt;
&lt;p&gt;We are a team of people who believe that there are really a lot of things that can be done better. You can make big changes by simply start caring for things that you did not before. That's why we urge everybody to think about the digital data we're using daily - how and which energy is it using, and is it sustainable.&lt;/p&gt;
&lt;p&gt;If it is based on sustainable sources, support it, give it love so it can continue. If it is not based on sustainable sources, demand it to do better. We already have solutions, we just need everybody to do their part.&lt;/p&gt;
&lt;p&gt;If you have any thoughts to share, you can reach us at
&lt;strong&gt;sustainability at ungleich.ch&lt;/strong&gt; or in the &lt;a href="https://chat.with.ungleich.ch"&gt;ungleich
chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>The v6 pattern for IPv6 only hosts</title><link href="https://ungleich.ch/u/blog/the-v6-pattern-for-proxied-hosts/" rel="alternate"/><updated>2021-02-24T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:041e31da-244e-38b4-bdc3-f2373316e4e2</id><content type="html">&lt;iframe width="560" height="315"
src="https://www.youtube.com/embed/cANwo0IdZYU" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media;
gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;At ungleich we have a lot of IPv6-only web servers. Many of them are
are proxied from the IPv4 world, so the domain name points to two
different machines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the AAAA entry points to the server directly&lt;/li&gt;
&lt;li&gt;the A entry points to a proxy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This  sometimes makes configuring the right system a bit harder,
because on dual stack clients, accessing www.example.com brings you to
either machine. In the &lt;a href="https://www.youtube.com/watch?v=cANwo0IdZYU"&gt;first ungleich tech
talk&lt;/a&gt; we show how this
looks in detail and how we ensure that we configure the right machine.&lt;/p&gt;
&lt;p&gt;This is our first tech talk and we love to &lt;a href="../../contact/"&gt;hear your feedback&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>A love letter to ISC bind</title><link href="https://ungleich.ch/u/blog/love-letter-to-isc-bind/" rel="alternate"/><updated>2021-02-22T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:6906c17d-c28c-3ba7-8fde-814587e01488</id><content type="html">&lt;p&gt;Dear ISC bind,&lt;/p&gt;
&lt;p&gt;this is a love letter to you. You probably don't know me, but I have
been a long term user of yours.&lt;/p&gt;
&lt;p&gt;I started my time with you in the late 90's. It was when you were
called "bind 4". I was very happy with our relationship. You'd not
only take care of all authoritative requests, but also take care of
caching client requests. Me, still being young at the time, I did not
know nor care about security concerns in the beginning.&lt;/p&gt;
&lt;p&gt;But then over time I got more experienced and I read and tried DNS
cache poisoning and I was shocked. How could you? How could you accept
incorrect entries? I had so much trust in you and then that!&lt;/p&gt;
&lt;p&gt;Years passed and after my shock, I had a fling with
&lt;a href="https://cr.yp.to/djbdns.html"&gt;djbdns&lt;/a&gt; (together with qmail and
daemontools). Which right away took security more serious. So serious
that even managing djbdns with its own suite was almost like a crypto
analysis adventure (no offense, Dan!). Many years this was my software
solution of choice, compiled by source, patched by hand. Oh, the old
2000's!&lt;/p&gt;
&lt;p&gt;Over time the effort for managing software by source code and
/usr/local installations did not turn out to be very efficient. So I
looked around and found &lt;a href="https://www.powerdns.com/"&gt;powerdns&lt;/a&gt;,
&lt;a href="https://www.nlnetlabs.nl/projects/nsd/about/"&gt;nsd&lt;/a&gt; and
&lt;a href="https://www.nlnetlabs.nl/projects/unbound/about/"&gt;unbound&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I settled for the nsd/unbound combination for many years. Solid, easy
to use and nice separation of concerns. Thanks nlnetlabs! Then I
stumbled upon
&lt;a href="http://www.thekelleys.org.uk/dnsmasq/doc.html"&gt;dnsmasq&lt;/a&gt;. Dnsmasq
feels a bit like a younger sibling of bind: it does everything and
even includes dhcp and tftp support! Crazy, isn't it? Many years to
come, dnsmasq, first discovered on an embedded router, turned out to
be a very stable solution for even mid sized installations. And it
comes with a very simple configuration as well.&lt;/p&gt;
&lt;p&gt;But then 2017 happened. And ungleich started the &lt;a href="../../projects/data-center-light/"&gt;Data Center
Light&lt;/a&gt; project. An IPv6 first
hosting. And there you were, dear bind. Looking at me from the side of
the software projects, saying "I think it's time we have a talk.".&lt;/p&gt;
&lt;p&gt;And indeed, we did have a talk. A talk about implementing DNS64. About
different DNS64 prefixes in one configuration. About being
an authoritative name server that functions even if all upstreams are
down. A name server that even allows the most funky configuration of
&lt;em&gt;removing native AAAA entries&lt;/em&gt; for DNS64 networks that should only
access mapped IPv4 addresses. You can do it all, but you are still not
complicated. Who can say that from oneself?&lt;/p&gt;
&lt;p&gt;I admit, I was not always loyal to you. And I also admit that I am
still sceptical about mixing caching and authoritative features in one
process. But you do it so damn well. Not only have you been around for
decades and collected the wisdom over the years, but also have you
adapted to the time.&lt;/p&gt;
&lt;p&gt;This is why I am writing you this love letter today, to say
thanks. Thanks for making the life in a data center easier, thanks to
being flexible, thanks for improving over time and thanks to still
adhearing to the same configuration file format that I used in the
late 90's.&lt;/p&gt;
&lt;p&gt;Dear BIND, you are by far not perfect, but then neither is
reality. And this is your strength, solving real world problems.&lt;/p&gt;
&lt;p&gt;Thank you for doing so and thanks to all the involved developers for
creating bind.&lt;/p&gt;
&lt;p&gt;In love, yours,&lt;/p&gt;
&lt;p&gt;Nico&lt;/p&gt;
</content></entry><entry><title>The chat app of 2021</title><link href="https://ungleich.ch/u/blog/chat-app-of-2021/" rel="alternate"/><updated>2021-02-09T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:400076b0-eb05-31bd-87af-24ab4d7e829b</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At this point we've all seen many chat apps - some very popular and
some not. Some very secure and some not. Some very centralised and
some not.  The difficult thing when choosing a chat app is that the
most important differences are not something you can intuitively find
out. That is more a question of how each chat app was designed from
the beginning.&lt;/p&gt;
&lt;p&gt;What we are going to do in this post is that we will talk about what
we have used as chat so far and why, and we will discuss what you need
to consider when making a decision for yourself. What are the
differences between the chat apps out there, and what do those
differences mean to their end-users?&lt;/p&gt;
&lt;h2&gt;About us&lt;/h2&gt;
&lt;p&gt;Each community or individual has a different need for the chat and
what's best for others does not necessarily mean that's going to be
the best for you. Before starting we want to give you an idea about
who we are.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our team is rather deeply into technology probably more than most people.&lt;/li&gt;
&lt;li&gt;The age of our chat users is somewhere between 18-55 (with minor exceptions).&lt;/li&gt;
&lt;li&gt;Many of our chat users are working with laptops for a big part of the day.&lt;/li&gt;
&lt;li&gt;Most of our chat users are comfortable using English for communication.&lt;/li&gt;
&lt;li&gt;Our chat users are about 80 % male and 20 % female.&lt;/li&gt;
&lt;li&gt;A big part of our community values sustainability and the environment&lt;/li&gt;
&lt;li&gt;A big part of us is interested in software with its code publicly open - in other words, open source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The evolution of our chat was really finding what fits us the best. We
have started our team chat at Slack many years ago, then we moved to
Rocketchat, and then we moved to Mattermost. While keeping Mattermost
running, we started our Matrix instance on the side. We have gradually
moved more to Matrix over time and now have most of our main
conversations in Matrix. There were reasons for each of our moves, we
will explain them below.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ungleich-chat-evolution.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;What we based our decisions on&lt;/h2&gt;
&lt;h3&gt;Work chat&lt;/h3&gt;
&lt;p&gt;We (ungleich) are a company working with Free and Open Source and
Linux. Our work happens around many text information and we have many
parallel projects shared with people from different timezones. This
requires our chat to be as efficient and organised as possible, so
that everybody can get their work done and collaborate easily. This
was the reason why we were initially landing in Slack which has an
interface suitable for our work life. Apps designed for more casual,
mobile use such as Telegram and Signal did not fit our need.&lt;/p&gt;
&lt;h3&gt;Self-hosted&lt;/h3&gt;
&lt;p&gt;We need to mention that for a Swiss company like ourselves
&lt;a href="https://datacenterlight.ch/en-us/cms/hydropower/"&gt;that physically runs our servers with local hydropower,&lt;/a&gt; we knew
that it is senseless to have our chat somewhere in the U.S. (whose
privacy laws are more relaxed than ours) run by servers with fossil fuels.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/security-class.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;That's why we soon moved away from Slack to chats that we can host on
our own. We first moved to Rocketchat, and although the transition was
easy and smooth at the beginning its mobile version was not as smooth
as we liked it to be at that time and our team would miss getting
messages often while on the run between different data center
locations.&lt;/p&gt;
&lt;p&gt;After spending some time with Rocketchat we moved to &lt;a href="https://ungleich.ch/u/products/zero-carbon-chat/"&gt;self-hosted
Mattermost&lt;/a&gt; looking for a more stable experience. With its robust
performance and friendly UI (that we still think is one of the best
out there), our team became quite happy with Mattermost.&lt;/p&gt;
&lt;h3&gt;Decentralised&lt;/h3&gt;
&lt;p&gt;You might have noticed that we are not the most typical company:
renewable-only energy driven Linux, FOSS and IPv6 aficionados in the
Alps. This means we attract quite some people who have a lot of
stories and chats to share with us. More and more over the time it
became clear that our work chat is not only for our internal work -
but it's also for a community chat, a community with very diverse
backgrounds for that matter. Hobby computer lovers, mountain lovers,
hackers and makers, climate activists, penguin lovers, you name it.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ungleich-community.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;While happily staying on Mattermost we started to receive requests
from our community for enabling our chat to be more decentralised:
meaning not all the chat data staying in our server only
(centralisation), but enabling others to connect from their servers
too (decentralisation).&lt;/p&gt;
&lt;p&gt;This was a fair request and we knew it was the right way to go. As a
solution we started to phase in Matrix into our chat - we first
started it as a side chat from our main channels in Mattermost.&lt;/p&gt;
&lt;p&gt;Over time we moved most of our conversations to it, while keeping
Mattermost on the side. Using Matterbridge to bridge between the two
chats, this dual system has been working quite well, and it is
especially useful when one of the instances experiences downtime.&lt;/p&gt;
&lt;h2&gt;What you should consider when choosing a team chat&lt;/h2&gt;
&lt;p&gt;Above was our specific case and you probably have a different use for
the chat app. Should you consider Matrix? Mattermost? Or Slack? Some
questions need to be answered first to see what your requirements are.&lt;/p&gt;
&lt;h3&gt;1. Workspace or SMS&lt;/h3&gt;
&lt;p&gt;This depends on what your use case is. Are you looking for a secure
version of SMS, or are you looking for an organised place for
different groups and tasks to be handled? The former fits the use case
of Threema, Signal, Telegram, Whatsapp, and the latter is better handled
by Slack, Mattermost, Rocketchat, and Matrix.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/chat-usecase.jpg" alt=""&gt;&lt;/p&gt;
&lt;h3&gt;2. Can you be anonymous&lt;/h3&gt;
&lt;p&gt;This is closely linked to the #1, because the chat apps that function
as SMS replacement such as Signal, Telegram, Whatsapp, need a phone
number to work. So if staying anonymous is an important factor for you
this is something you want to consider in choosing a chat. For using
Matrix or Mattermost you do not need a phone number, and in the case
of Matrix you do not even need an email address that can identify you.&lt;/p&gt;
&lt;h3&gt;3. Where is the chat server&lt;/h3&gt;
&lt;p&gt;This is something most people don't think about: the physical location
of the servers where the chat is running. It mostly becomes a crucial
question in two ways.&lt;/p&gt;
&lt;p&gt;One is if you face the possibility of having to deal with
authorities - then you need to know which law will apply in case
you are being investigated.&lt;/p&gt;
&lt;p&gt;Two is if you care for the environmental and ethical impact of your
servers, such as &lt;a href="https://ungleich.ch/en-us/cms/blog/2019/06/28/how-run-really-green-datacenter/"&gt;what kind of energy source is being used and what is
the ethical stance of the
hosters.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/environment-chat.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;The ability to decide where your servers will physically be, either by
running the server by yourself or by somebody you can trust is a big
difference between some chat apps and others. Chats that offer home
servers, self-hosted options such as Matrix or Mattermost give you the
ability to choose, and any chat app that does not, locks you in the
choice of the chat provider.&lt;/p&gt;
&lt;h3&gt;4. Decentralised or centralised&lt;/h3&gt;
&lt;p&gt;Does all of our conversation only go to one company or to one country, or
can it be in the different small or big streams everywhere and be
independently open to each other? Most chats out there are the former,
and federated chats are the latter.&lt;/p&gt;
&lt;p&gt;Say there's a special house where everybody goes to for communication,
and you have to go there whenever you want to talk to anybody, and the
conversation stays only in that house. Anybody who wants to say
anything to anybody, has to go into this house. Doesn't it sound
really strange? That's what most chats are.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/decentralised-chat.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;But what if we can stay in our own home and call each other and still
can have a conversation? And the conversation does not only stay in
one house, but in everybody's house when it's their own
conversation? That's more like how Matrix imagined how chats should
work.&lt;/p&gt;
&lt;p&gt;This is the single most standout identity of Matrix, that it has
built-in federation. Means you can stay on your chat and go to other
Matrix instance and talk to them.&lt;/p&gt;
&lt;h3&gt;5. Are you into the latest, hottest technology&lt;/h3&gt;
&lt;p&gt;It might sound silly but it is still an important factor for a lot of
early adopters and people who just gotta have their hands on the
latest groundbreaking stuff (&lt;em&gt;cough&lt;/em&gt;). This is it. Matrix is the hottest
chat system of 2021 and hands down the most innovative project amongst
all the chat apps out there because of its federation and security
design.&lt;/p&gt;
&lt;h2&gt;The baselines that you shouldn't compromise&lt;/h2&gt;
&lt;p&gt;A lot of us brush off the topic of privacy thinking "But &lt;em&gt;I&lt;/em&gt; don't have
anything to hide." but it is not that simple. Even though you might
not have anything to hide now, people who you have a conversation with
might have a very different stance and you affect them with your
choices.&lt;/p&gt;
&lt;p&gt;Using a chat app for communication involves the privacy of everybody
in your network - family, friends, colleagues, and more. That's why
whatever chat you choose, there should be some baselines you shouldn't
compromise. These are what we think is important in choosing which
chat to use in 2021.&lt;/p&gt;
&lt;h2&gt;The baseline 1: End-to-End Encrypted&lt;/h2&gt;
&lt;p&gt;As a very base your chat should be End-to-End Encrypted (E2EE). E2EE
means even when the 3rd party (including law enforcement or the
hosting company itself) snoops into the chat data, they will just see
a series of useless encrypted texts that can not be decrypted.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/encrypted.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Not all chats have proper E2EE and especially not all chats have it as
default. Matrix has E2EE as a default for example, and Telegram does
not. It works quite the opposite way in fact: disabling E2EE has to be
manually opted in Matrix, whereas enabling E2EE can be done only by
choosing "Secret Chat" Function in Telegram.&lt;/p&gt;
&lt;h2&gt;The baseline 2: Not collecting your data&lt;/h2&gt;
&lt;p&gt;Even when the chat app can not read your conversation thanks to the
encryption, some chats do access a lot of other information, such as
with whom you are talking to for how often and for how long ("meta
data"). We tend to focus on not revealing the content of our
chat and to forget that the other information can be collected while
being unnoticed.&lt;/p&gt;
&lt;p&gt;Whatsapp is a particularly risky choice for this reason, because it
belongs to Facebook whose entire business model relies on collecting
user information for monetisation.&lt;/p&gt;
&lt;h2&gt;The baseline 3: Is the code open for public&lt;/h2&gt;
&lt;p&gt;The thing about closed code is that nobody outside the chat app
company can see how and what is built in the chat. Is it having some
back doors users are unaware of, is it monitoring the user activity
without letting the user know, with closed code we will never know.&lt;/p&gt;
&lt;p&gt;So for a chat (or any software for that matter) to be claimed secure,
its code has to be open for the public, so unbiased third parties can
review its sanity. If you think about it, it's quite simple - no
system can achieve robust integrity without transparency.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/penguin-customer-support.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Try it yourself&lt;/h2&gt;
&lt;p&gt;When it comes to technology, the best approach is trying it
yourself. Our ungleich chat, both Matrix and Mattermost, are open for
anybody to join: we heartily invite you to give it a try. Create an
account, join rooms, say hi and ask questions you might have.&lt;/p&gt;
&lt;p&gt;We claim our chat is one of the safest places to try a chat app you
are not sure about yet - it does not collect your data, it does not
need your phone number, it runs on 100% renewable energy.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://chat.with.ungleich.ch"&gt;Try our Matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../contact/"&gt;Get in touch with ungleich&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More about us and Matrix&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ungleich.ch/en-us/cms/matrix-for-climate/"&gt;Matrix for Climate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki/Ungleich_Matrix-as-a-Service_(MaaS"&gt;ungleich open infrastructure:MaaS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://matrix.org/foundation/"&gt;The Matrix foundation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content></entry><entry><title>No IPv6 in 2021? Not acceptable.</title><link href="https://ungleich.ch/u/blog/no-ipv6-in-2021-not-acceptable/" rel="alternate"/><updated>2021-01-09T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:2c6a534b-32dd-35c3-9499-85f11490780e</id><content type="html">&lt;p&gt;It's 2021 and it's time to stop using legacy IP (IPv4) only
services. In 2020 we have already seen quite a rise in IPv6
connectivity, as well as more and more services emerging IPv6 only.&lt;/p&gt;
&lt;h2&gt;The IPv6 community is very active&lt;/h2&gt;
&lt;p&gt;The IPv6 community has reported many bugs to products like
&lt;a href="https://github.com/ValveSoftware/steam-for-linux/issues/3372"&gt;Steam from
Valve&lt;/a&gt;,
&lt;a href="https://github.com/docker/roadmap/issues/89"&gt;Dockerhub&lt;/a&gt; and so many
more that it was not possible for me to list them all in this article.&lt;/p&gt;
&lt;p&gt;As a matter of fact, websites or services that have degraded or
non-existing IPv6 connectivity &lt;a href="https://twitter.com/search?q=%23ipv6"&gt;are reported daily on
Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Time to move on&lt;/h2&gt;
&lt;p&gt;As I can see it from the work at ungleich, 2020 was a very active year
when it comes to IPv6. But at some point, services that don't work
with IPv6 are simply not worth caring about anymore.&lt;/p&gt;
&lt;p&gt;While IPv6 &lt;a href="https://tools.ietf.org/html/rfc2460"&gt;has been defined in
1998&lt;/a&gt;, it is clear that vendors
and providers need some time to adapt. But 23 years should have been
more than enough to migrate.&lt;/p&gt;
&lt;p&gt;For this reason we want to encourage everyone in 2021 to move on, to
cut off the old legacy IP applications, services or hardware.&lt;/p&gt;
&lt;h2&gt;How to move on?&lt;/h2&gt;
&lt;p&gt;There are a variety of things everyone of us can do and we have
collected some easy to take steps.&lt;/p&gt;
&lt;h3&gt;Setup networks IPv6 only&lt;/h3&gt;
&lt;p&gt;For every new network you setup, set it up with IPv6 only. All current
mobile phones, tablets and operating systems work in IPv6 only
networks.&lt;/p&gt;
&lt;h3&gt;Setup services and applications IPv6 only&lt;/h3&gt;
&lt;p&gt;If you are an application developer, I suggest to develop your
application with IPv6 first. And if you setup a new service, configure
IPv6 first and maybe only.&lt;/p&gt;
&lt;p&gt;It's important to understand that setting up something IPv6 only, does
not mean it will be unreachable from the legacy IP Internet. NAT64 is
one easy to use technology to solve this problem.&lt;/p&gt;
&lt;h3&gt;Abandon legacy only&lt;/h3&gt;
&lt;p&gt;Whether it's network hardware, applications, Internet providers,
hosting providers - stop using them if they don't work in IPv6 only
environments. And let the everyone know that you did so.&lt;/p&gt;
&lt;p&gt;While I am not a fan of shaming anyone, it is still important to let
vendors know that you have moved on because of the lack of
IPv6. Otherwise the vendor does not know why they are losing
customers. When you communicate that you abandon a product or service
because of lacking proper IPv6 support, I recommend to doing so in a
clear, but respectful way.&lt;/p&gt;
&lt;h3&gt;Advocate IPv6 only&lt;/h3&gt;
&lt;p&gt;To be able to spot bugs and to make life for network operators easier,
I strongly recommend going IPv6 only. Not dualstack, but simply IPv6
only. If you deploy NAT64 in IPv6 only networks, you can even create
reachability in both directions.&lt;/p&gt;
&lt;p&gt;Many of us network operators, developers and sysadmins are very good
in implementing things. However, it is important to share the word.&lt;/p&gt;
&lt;h3&gt;Help each other&lt;/h3&gt;
&lt;p&gt;For about 2 years there is an open, community driven &lt;a href="https://ipv6.chat"&gt;IPv6
Chat&lt;/a&gt;. In this chat you can ask others for help,
ask which alternative products or services to use. Or how to migrate
to IPv6 only networks. There is also an &lt;a href="https://www.reddit.com/r/ipv6/"&gt;IPv6
reddit&lt;/a&gt; and an &lt;a href="https://www.facebook.com/groups/2234775539"&gt;IPv6 group on
Facebook&lt;/a&gt;. Many of the
RIRs (RIPE, APNIC, Afrinic, LACNIC and ARIN) also offer IPv6 training
resources.&lt;/p&gt;
&lt;p&gt;Migrating to IPv6 is not difficult and there is a community to help
you with it.&lt;/p&gt;
&lt;p&gt;Let's do it, together.&lt;/p&gt;
</content></entry><entry><title>Managing IPv4 islands with Jool and OpenWrt</title><link href="https://ungleich.ch/u/blog/managing-ipv4-islands-with-jool-and-openwrt/" rel="alternate"/><updated>2020-12-15T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:f25cd65d-9f55-323f-9974-f418a389edcf</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At ungleich we are using &lt;a href="https://www.jool.mx/"&gt;Jool&lt;/a&gt; in a variety of
scenarios with NAT64 or SIIT. The main use of jool in our
infrastructure is to enable IPv6 only hosts to communicate with the
IPv4 Internet.&lt;/p&gt;
&lt;p&gt;However today we want to show you a different use case of jool:
Enabling IPv4 islands to communicate with the IPv6 Internet.&lt;/p&gt;
&lt;p&gt;For this we will focus on using Jool on
&lt;a href="https://openwrt.org"&gt;OpenWrt&lt;/a&gt;, because this is a platform that you
can also easily use in your networks or even at home.&lt;/p&gt;
&lt;h2&gt;The general problem to solve&lt;/h2&gt;
&lt;p&gt;The literally biggest problem to solve when connecting the two
different worlds is that the IPv6 space is significantly bigger. This
is a problem, because we cannot achieve a 1:1 mapping from the IPv4
world, but we can do a 1:1 mapping from the IPv6 world:&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ipv4-ipv6-nat-asymmetric.png" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Installing jool&lt;/h2&gt;
&lt;p&gt;Installing jool on OpenWrt is very easy, it is just a matter of
installing the kernel module and the tools for managing jool:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;opkg update
opkg install kmod-jool jool-tools
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Making IPv4 islands reachable&lt;/h2&gt;
&lt;p&gt;Assume that you are mostly running IPv6 only networks. And you happen
to have some hosts, which, for whatever reason, cannot be switched to
IPv6. We can use a stateful NAT64 to map "the whole IPv6 Internet" to
192.0.2.1 as follows:&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ipv4-only-island-ipv6-reachable.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;This works pretty similar to regular NAT that you are used from
home. If we compare it visually, it is even more clear:&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ipv4-nat.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Let's have a look at this in an OpenWrt context:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The LAN network is usually 192.168.1.0/24&lt;/li&gt;
&lt;li&gt;The router's IPv4 address is usually 192.168.1.1&lt;/li&gt;
&lt;li&gt;In this example we routed 2a0a:e5c1:18f::/48 to the router&lt;/li&gt;
&lt;li&gt;192.168.1.0/24 has 8 bits for the hosts (32-24=8)&lt;/li&gt;
&lt;li&gt;We choose 2a0a:e5c1:18f:b00::/120 to map the IPv4 island (128-120=8)&lt;/li&gt;
&lt;li&gt;We use the OpenWrt's standard address to masquerade/squash the IPv6 Internet&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First we will create an "IPv4 pool":&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@vigir2:~# jool -4 -a 192.168.1.1
root@vigir2:~# jool -4
+------------+-------+--------------------+-----------------+-------------+
|       Mark | Proto |     Max iterations |         Address |       Ports |
+------------+-------+--------------------+-----------------+-------------+
|          0 |   TCP |       1024 ( auto) |     192.168.1.1 |     1-65535 |
+------------+-------+--------------------+-----------------+-------------+
|          0 |   UDP |       1024 ( auto) |     192.168.1.1 |     1-65535 |
+------------+-------+--------------------+-----------------+-------------+
|          0 |  ICMP |       1024 ( auto) |     192.168.1.1 |     0-65535 |
+------------+-------+--------------------+-----------------+-------------+
  (Fetched 3 samples.)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows jool to map IPv6 addresses stateful to 192.168.1.1 and
basically allows incoming IPv6 traffic. What is left now is to
configure the mapping from IPv6 to IPv4. For this we use the pool6
argument of jool:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jool -6 2a0a:e5c1:18f:b00::/96
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we cheated here. We did not only map
2a0a:e5c1:18f:b00::/120, but we did actually map the whole IPv4
range. The advantage of this is that we do not need to care which
networks are used on the IPv4 island. Any IPv4 address inside the LAN
segment is now reachable. If you want to reach the IP address
192.168.1.42, you can ping as &lt;strong&gt;2a0a:e5c1:18f:b00::192.168.1.42&lt;/strong&gt;. As
a matter of fact, while writing this article, the sample network is up and
running and you should be able to &lt;strong&gt;ping
2a0a:e5c1:18f:b00::192.168.1.1&lt;/strong&gt; from the IPv6 Internet.&lt;/p&gt;
&lt;h2&gt;More of this?&lt;/h2&gt;
&lt;p&gt;If you are interested in IPv6 or network, feel free to join us on the
&lt;a href="https://IPv6.chat"&gt;IPv6.chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>An alternative to annoying phone hotlines</title><link href="https://ungleich.ch/u/blog/an-alternative-to-annoying-phone-hotlines/" rel="alternate"/><updated>2020-11-29T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:111f81fc-ad3c-387a-bd69-a214e28a2ec6</id><content type="html">&lt;h2&gt;The phone hotline&lt;/h2&gt;
&lt;p&gt;If you have a problem with your contract, if you want to have some
information about your product or you just want to change some
detail. By default, many companies nowadays offer something that we
call "hotline". Or in other words: a voice based communication that
allows to easily queue people.&lt;/p&gt;
&lt;p&gt;The motivation and how it works is rather clear: there are a finite
number of employees, each of which can only talk to one person at a
time.  So if the number of requests is more than number of employees,
then you are stuck in the queue. However this post is not about the
annoyance of waiting in a queue and enduring little quality, down
sampled classic music pieces.&lt;/p&gt;
&lt;p&gt;No, in this post I want to address a different fundamental problem:
every time you call, you start a fresh conversation. You are likely to
talk to a different person with a different background and probably
not much knowledge of your situation. From a customer perspective you
usually don't have any trail of previous communication. Actually, the
company you are calling might record (and correctly announce it
before) the call. However as a customer, you cannot easily record as
well. Often it is also impossible to correspond with the company by
email, so all written communication has to be sent in letters. In
2020!&lt;/p&gt;
&lt;p&gt;Looking at it this way clearly shows how much power imbalance the
innovation of the phone hotline is causing. But it could easily be
different.&lt;/p&gt;
&lt;h2&gt;The classic way&lt;/h2&gt;
&lt;p&gt;You might or might not remember when companies used to be smaller and
you would request a service with the counterpart in person. Both of
you know each other and are fully aware of each other responsibilities
("I give you money, you give me a product or service") and also of the
support process (A: "It did not work" - B: "I'll fix it!).
Often the service provider was not far away, might even have been my
neighbour. And it's really not good for our relationship if my
neighbour does do what he promised to do.&lt;/p&gt;
&lt;p&gt;As you can easily imagine this does not scale nor work easily in big
companies where staff is rotated or fluctuating. The old value system
of being responsible on a personal basis cannot easily be
transferred. This also means that the classic way is much more
expensive in terms of time and resources, but the responsibilities are
enforced by social relationships.&lt;/p&gt;
&lt;h2&gt;Mixing the two?&lt;/h2&gt;
&lt;p&gt;So we could say that they are two extremes: one very personal, high
quality, expensive and the other - well, you get the picture. Is it
possible to improve the current situation and how can we get the best
of the two worlds? Before answering this question, let me give you a
short background of where we, ungleich, are and how we work, to show
you how these approaches can naturally merge.&lt;/p&gt;
&lt;h2&gt;ungleich @ Digital Glarus&lt;/h2&gt;
&lt;p&gt;ungleich is based in &lt;a href="../../projects/digital-glarus/"&gt;Digital Glarus&lt;/a&gt;,
a really old mountain valley in Switzerland. Majority of its buildings
are very old (I'd guess most are built prior to 1900, many even much
older), major businesses are industry, farming and also tourism. Many
people here get up before 6 and start working latest by 8.&lt;/p&gt;
&lt;p&gt;We from ungleich on the other hand are working in IPv6 only
networks connected by our own fiber or with long range wifi links. Our
working hours are very flexible, can be morning, day, night, week,
weekend - we are free to choose. Our topics are very technical by
nature.&lt;/p&gt;
&lt;p&gt;These two approaches can contradict, but they can also work together
very well. Like the two ways of communication.&lt;/p&gt;
&lt;p&gt;Interestingly our experience here is that they can easily be combined:
many people living in Digital Glarus have what we call an "old value
system". If you offer a service towards people in Digital Glarus, you
need to take responsibility and be trustworthy. Otherwise the word
will get out within a few days and social enforcement will result in
no more work for you.
While this might sound cruel, you could actually call this "social
quality assurance". Actually a bit similar to what we see in social
media, just lower scale.&lt;/p&gt;
&lt;p&gt;And how does this look like in reality? People here want and need to
be convinced that you are trustworthy. You are having in
person meetings (before corona), one person will make a protocol and then later send
it for verification back to the other party. If something is noted
incorrectly, the protocol will be amended and again verified.&lt;/p&gt;
&lt;p&gt;This ensures that trust is built and also that both parties, the
delivering company as well as the customer are playing on eye level.&lt;/p&gt;
&lt;h2&gt;Combining old values and new communication&lt;/h2&gt;
&lt;p&gt;Let's come back to the original problem: we shifted from high quality,
individual services to mass produced in-transparent
communication. Technically and organisational, it is not necessary to
provide a worse product or service if it is mass produced. It just
happens to be the case due to technical limitations in the beginning.&lt;/p&gt;
&lt;p&gt;So let's go back to the hotline problem: we advocate a simple change
that costs little for companies to implement but restores trust and
quality in communication:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every support hotline should be, by default, accompanied by a text based
ticketing system that sends users a protocol and let's them interact
with you on a text basis.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So how does this work? The agent in the call center will make notes of
the phone call - they are already done nowadays, but unavailable for
you. Some of these notes might be internal ("The customer does not
know the difference between the power button and the reset button -
always advise to push the button on the right") and are not for
sharing. However, &lt;strong&gt;the key points of the conversation must be sent to
the customer&lt;/strong&gt;. This way, as a customer I can easily react and correct
statements that have been incorrectly recorded. With a trail.&lt;/p&gt;
&lt;p&gt;Furthermore in a later stage, as a customer, I also have a trail and
the ability to respond to the previous conversation by text, giving me
the opportunity to add to the trail. And to built trust on the way.&lt;/p&gt;
&lt;p&gt;Obviously, our suggestion here is not rocket science. In fact, it is a
very easy, natural and cost effective measure to be more transparent
and to built mutual trust.&lt;/p&gt;
&lt;p&gt;Some companies might try to argue that it is too complex or too
expensive to implement such a system. To prevent that argument from
being true, we have added a &lt;a href="../../products/hosted-support-system/"&gt;Hosted Support
System&lt;/a&gt; to our product
list. Nobody needs to get it from us, but anybody can. And thus there
is no excuse, not to have it implemented. It is a very similar
&lt;a href="../../products/ipv6-vpn/"&gt;approach to not have an excuse for not having
IPv6&lt;/a&gt;, but that is a story for
another day...&lt;/p&gt;
</content></entry><entry><title>The new EU draft endangers everyone's security</title><link href="https://ungleich.ch/u/blog/the-dangerous-eu-draft/" rel="alternate"/><updated>2020-11-09T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:29117f73-2458-3953-879f-65f660e8071c</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;The EU is trying to disable encryption for everyone.
However, this approach is fundamentally flawed, as the bad guys don't
follow the law.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The Council of the European Union &lt;a href="https://www.heise.de/downloads/18/2/9/9/8/5/2/0/eu-council-draft-declaration-against-encryption-12143-20.pdf"&gt;has published a
draft&lt;/a&gt;
which requires everyone who is offering secure communication channels
to allow authorities to read the communication.&lt;/p&gt;
&lt;p&gt;The motivation is clear: terrorist attacks and unlawful behaviour
should be prevented by wiretapping. No crime is better for everyone.
So far, so good. In theory.&lt;/p&gt;
&lt;h2&gt;First problem: reducing security affects everybody&lt;/h2&gt;
&lt;p&gt;The first problem is that modern encryption is not easy to break, or
let's put it clearly: it is almost impossible to break. Thus passing
this law requires decades of work to be undone. To make systems that
have been mathematically proven to be secure, more insecure.&lt;/p&gt;
&lt;p&gt;This reduces security for any communication by default. And this does
not only affect terrorists, but also government agencies and the
general public.&lt;/p&gt;
&lt;p&gt;Thus it also reduces the freedom of speech. There are activists out there
(f.i. in the area of climate change) that fear their life, if their
communication is revealed, because some governments do not allow free
speech.&lt;/p&gt;
&lt;h2&gt;Second problem: the bad guys don't comply&lt;/h2&gt;
&lt;p&gt;One of the strangest problems with the EU proposal is that the idea is
to make this into a law that everyone has to follow. Or, more precisely: the
idea is that companies like Whatsapp or Signal have to provide keys or
backdoors into their systems that authorities can use for wiretapping.&lt;/p&gt;
&lt;p&gt;Now, this is a crucial problem. Because companies like us, ungleich,
also provide &lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;secure communication using
Matrix&lt;/a&gt;. And we
are not in the EU (fact check: Switzerland is not in the EU).&lt;/p&gt;
&lt;p&gt;See the problem? No? Well, let's say you are the bad guys and you plan
to coordinate some attack. What do you do?&lt;/p&gt;
&lt;p&gt;You run your own chat system. It is very easy to do. It cannot be
technically prevented. It might be against the law in the EU to run a
chat system that does not allow backdoor access, ok. But then again - you
are going to do something that is against the law anyway. So this is
the least of your problems.&lt;/p&gt;
&lt;p&gt;So the proposed law is actually doing the opposite of its intention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It reduces security for everyone who is behaving according to law&lt;/li&gt;
&lt;li&gt;It does not prevent unlawful parties from communicating securely&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Third problem: criminalizing science&lt;/h2&gt;
&lt;p&gt;Apart from the obvious two really strong problems, the law might
actually lead to research and science being prohibited. The underlying
algorithms are usually based on mathematically hard-to-solve
problems.&lt;/p&gt;
&lt;p&gt;The problems are carefully researched and in the end used to provide
security, confidentiality and integrity.&lt;/p&gt;
&lt;p&gt;Researchers can be hindered by legal questions whether or not they
are able to solve mathematical problems. Which then again can and will stop the progress in other areas of science as well. This all sounds terribly wrong, doesn't it?&lt;/p&gt;
&lt;h2&gt;Fourth problem: a new attack vector&lt;/h2&gt;
&lt;p&gt;Let's assume for a moment that none of the above problems is already
crucial enough to stop the whole motion. There is one more big and
crucial problem: if authorities have a backdoor into your
communication, this backdoor needs to be submitted to the
authorities. It needs to be securely stored by authorities.&lt;/p&gt;
&lt;p&gt;It means that this law will make authorities a very interesting target for hacking into. You do
not need to attack a technically very secure system. You can just hack
the authorities server and you gain access to everyone's
communication.&lt;/p&gt;
&lt;p&gt;This enables much easier access for terrorists, foreign (enemy) governments and
everyone else who is interested in getting access to your
communication.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The proposed draft is dangerous for everyone except the criminals. It is dangerous for civilians,
governments, journalists, whistle-blowers and even the science and medical
sectors.&lt;/p&gt;
&lt;p&gt;The whole approach is fundamentally flawed and if passed as-is reduces
security for everyone, but the bad guys.&lt;/p&gt;
&lt;p&gt;We urge everyone reading this article to do whatever is in their power
to stop this law passing, before it is too late. And too late might
unfortunately already be on the 19th of November 2020.&lt;/p&gt;
&lt;h2&gt;Related websites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.heise.de/hintergrund/EU-Regierungen-planen-Verbot-sicherer-Verschluesselung-4951415.html"&gt;Report from heise (DE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fm4.orf.at/stories/3008930/"&gt;Report from ORF (Austria, DE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/cybersecurity/comments/jqp84o/eu_encryption_ban_proposed_following_terrorist/"&gt;Reddit discussion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.politico.eu/wp-content/uploads/2020/09/SKM_C45820090717470-1_new.pdf"&gt;Technical details on politico&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.heise.de/downloads/18/2/9/9/8/5/2/0/eu-council-draft-declaration-against-encryption-12143-20.pdf"&gt;The EU draft document (on
heise.de)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://files.orf.at/vietnam2/files/fm4/202045/783284_fh_st12143-re01en20_783284.pdf"&gt;The EU draft document (on orf.at)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://matrix.org/blog/2020/10/19/combating-abuse-in-matrix-without-backdoors"&gt;Matrix.org about the current backdoor requests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content></entry><entry><title>The IPv6-eye: a proper IPv6 camera</title><link href="https://ungleich.ch/u/blog/the-ipv6-eye-a-proper-ipv6-camera/" rel="alternate"/><updated>2020-11-04T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:e2f8a62d-925f-373f-b078-10747de2fb0a</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;At ungleich we have created an IPv6 camera that brings its own IPv6
connectivity. And a world wide reachable name. We are
currently
&lt;a href="https://swiss-crowdfunder.com/campaigns/the-1000-eyes-project/"&gt;crowdfunding&lt;/a&gt;
the production of the first 100 cameras.&lt;/p&gt;
&lt;h2&gt;A real IPv6 camera?&lt;/h2&gt;
&lt;p&gt;What is the advantage of IPv6 again? Exactly, world wide reachability
without any hacks or quirks.&lt;/p&gt;
&lt;p&gt;To support this, we have not only created a camera &lt;strong&gt;that works within
all types of networks&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv6 only&lt;/li&gt;
&lt;li&gt;IPv4 only&lt;/li&gt;
&lt;li&gt;Dual Stack (IPv6+IPv4)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We took it one step further: The
&lt;strong&gt;IPv6-eye&lt;/strong&gt; is an IPv6 camera that &lt;strong&gt;brings its own IPv6
connectivity&lt;/strong&gt;. This way it works independently of whether your network
actually supports IPv6 or not.&lt;/p&gt;
&lt;p&gt;On top of all of this, we created the &lt;a href="https://1000ey.es"&gt;1000ey.es&lt;/a&gt;
project that even &lt;strong&gt;gives a cool name&lt;/strong&gt; to every IPv6 camera in the world.&lt;/p&gt;
&lt;h2&gt;How to use the IPv6-eye&lt;/h2&gt;
&lt;p&gt;It is very simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;plugin a network cable with Internet uplink&lt;/li&gt;
&lt;li&gt;connect it to power&lt;/li&gt;
&lt;li&gt;It works!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After that you can ...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Point the camera to what you want to show&lt;/li&gt;
&lt;li&gt;Visit &lt;em&gt;yourname&lt;/em&gt;.1000ey.es:8081 (you can find an example on
&lt;a href="http://mountains-diesbach.1000ey.es:8081/"&gt;mountains-diesbach.1000ey.es&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Optionally configure it to connect to your existing wifi network&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How does the IPv6-eye work?&lt;/h2&gt;
&lt;p&gt;But what happens under the hood? The IPv6-eye is based on a similar
concept as the &lt;a href="../../products/viirb-ipv6-box"&gt;VIIRB&lt;/a&gt;. The IPv6-eye
uses the &lt;a href="https://IPv6VPN.ch"&gt;IPv6VPN&lt;/a&gt; to acquire IPv6
connectivity. This works in IPv4 only, IPv6 only and dual stack networks.&lt;/p&gt;
&lt;p&gt;From that moment on, the camera is world wide reachable.&lt;/p&gt;
&lt;h2&gt;A name for every IPv6 camera out there&lt;/h2&gt;
&lt;p&gt;However, people do not like to type IP addresses. Not IPv4, not
IPv6. For this reason you can choose a name below the domain
&lt;strong&gt;1000ey.es&lt;/strong&gt; for your camera. This offer is for free on top of the
actual hardware.&lt;/p&gt;
&lt;h2&gt;Fully Open Source&lt;/h2&gt;
&lt;p&gt;Like the VIIRB, the whole stack is fully Open Source. The
operating system is OpenWRT. The VPN software is wireguard. And the
video streaming server is based on mjpg-streamer or motion (still has
to be decided for the final shipment). All files that are required to
configure the IPv6-eye can be found in the &lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-tools"&gt;ungleich-tools
repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Crowdfunding the production&lt;/h2&gt;
&lt;p&gt;As it is usual for the production process to start at a minimum size,
we aim to crowdfund the first 100 units. If we exceed the minimum goal
of 100 IPv6 eyes, we have added some extra goodies as an option.&lt;/p&gt;
&lt;p&gt;Checkout the &lt;a href="https://swiss-crowdfunder.com/campaigns/the-1000-eyes-project/"&gt;crowdfunding
campaign&lt;/a&gt;
for more details.&lt;/p&gt;
</content></entry><entry><title>Encrypted rootfs with Alpine Linux</title><link href="https://ungleich.ch/u/blog/encrypted-rootfs-with-alpine-linux/" rel="alternate"/><updated>2020-10-08T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:e4036462-5a59-3196-8883-f704b7609e52</id><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is a short guide on how to encrypt your root filesystem on Alpine
Linux. This article assumes an EFI based system.&lt;/p&gt;
&lt;h2&gt;Booting Alpine Linux&lt;/h2&gt;
&lt;p&gt;Use the standard Alpine Linux installer to boot. Prepare networking
and and apkrepos:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setup-interfaces
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are in an IPv6 only network, setup a nameserver. At the moment
Alpine Linux does not start rdnssd by default. The following works for
VMs on &lt;a href="https://datacenterlight.ch"&gt;Data Center Light&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo nameserver 2a0a:e5c0:2:a::a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then setup the repos:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setup-apkrepos
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optional, if you want to continue the installation remotely from
another computer via ssh:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setup-sshd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then add your ssh key to /root/.ssh/authorized keys. We are using
the key.wf service for staff at ungleich:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir -p /root/.ssh/
wget -O ~/.ssh/authorized_keys  key.wf/nico
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Create partitions&lt;/h2&gt;
&lt;p&gt;In this guide we assume you create 3 partitions, based on gpt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/boot: a vfat partition usable for EFI boot (usually ~500MB)&lt;/li&gt;
&lt;li&gt;swap: the swap partition (usually ~half RAM)&lt;/li&gt;
&lt;li&gt;root: the partition containing the root filesystem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the the following sections we assume your disk is &lt;strong&gt;/dev/sda&lt;/strong&gt;. If you
are using NVMe, your disk might also be &lt;strong&gt;/dev/nvme0n1&lt;/strong&gt; or similar.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apk add gptfdisk
gdisk /dev/sda
# create new partition table if it does not exist or you want to start clean
# create the partitions
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Format partitions&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mkfs.vfat /dev/sda1
apk add cryptsetup

# Enter YES and your password twice
cryptsetup luksFormat /dev/sda3

# Create DM device
cryptsetup luksOpen /dev/sda3 rootfs

# Create filesystem
apk add e2fsprogs
mkfs.ext4 /dev/mapper/rootfs

# Mount filesytems
mount /dev/mapper/rootfs /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Configure initramfs&lt;/h2&gt;
&lt;p&gt;We need to enable rootfs decryption on boot. For this we need to add
cryptsetup into the feature list of /etc/mkinitfs/mkinitfs.conf:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hike:/etc# cat /etc/mkinitfs/mkinitfs.conf
features="ata base ide scsi usb virtio ext4 cryptsetup"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regenerate the initramfs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkinitfs
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Configure and install the bootloader&lt;/h2&gt;
&lt;p&gt;We will be using grub for booting:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apk add grub-efi efibootmgr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Update the /etc/default/grub to contain the cryptroot kernel
parameter in the GRUB_CMDLINE_LINUX_DEFAULT variable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hike:/# cat /etc/default/grub
GRUB_DISTRIBUTOR="Alpine"
GRUB_TIMEOUT=2
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_RECOVERY=true
GRUB_CMDLINE_LINUX_DEFAULT="cryptroot=/dev/sda3 cryptdm=root"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Regenerate the grub configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grub-mkconfig -o /mnt/boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Verify it has been added correctly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hike:/# grep crypt /boot/grub/grub.cfg
        linux   /vmlinuz-lts root=UUID=fa67b307-e155-47d8-98a6-4930131b5cd3 ro  modules=sd-mod,usb-storage,ext4 nomodeset quiet rootfstype=ext4 cryptroot=/dev/sda3 cryptdm=root
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install grub:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grub-install --efi-directory /mnt/boot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Install to disk&lt;/h2&gt;
&lt;p&gt;All changes so far have been done in RAM. Let's persist them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;setup-disk /mnt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Final step&lt;/h2&gt;
&lt;p&gt;If everything went well so far - it's time to reboot your fully
encrypted system. The usual steps like setting up the root password or
the hostname have been skipped for the sake brevity.&lt;/p&gt;
&lt;p&gt;Enjoy your full encrypted &lt;a href="https://alpinelinux.org/"&gt;Alpine Linux&lt;/a&gt;!&lt;/p&gt;
</content></entry><entry><title>Blocking DHCP servers and router advertisements with nftables</title><link href="https://ungleich.ch/u/blog/nftables-block-dhcp-and-router-advertisements/" rel="alternate"/><updated>2020-08-27T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:4f7673f8-d23b-3ca4-a281-2d8892dabafa</id><content type="html">&lt;h2&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Here at &lt;a href="https://ungleich.ch"&gt;ungleich&lt;/a&gt; we are providing a variety of
hosting services in the &lt;a href="https://datacenterlight.ch"&gt;Data Center
Light&lt;/a&gt;. One of the workloads we offer is
VM hosting and we need to take some security measures to prevent one
customer abusing another customer.&lt;/p&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;The virtual machines in our next generation uncloud hosting will be
using standard DHCP and IPv6 address assignments. Currently
we are still using the
&lt;a href="https://github.com/OpenNebula/addon-context-linux"&gt;OpenNebula&lt;/a&gt;
contextualisation scripts that read the networking information from an
attached ISO.&lt;/p&gt;
&lt;p&gt;While this makes it easier to create VM images and VMs behave even
more like regular computers, this exposes the VMs to attacks where one
customer runs a DHCP server or IPv6 router advertisement daemon and
tricks the other VMs into sending traffic to it.&lt;/p&gt;
&lt;h2&gt;The architecture&lt;/h2&gt;
&lt;p&gt;VMs are connected to a single shared network in which they get
their IP addresses (in uncloud usually only IPv6) and then they can
retrieve more information from a metadata server. So the main
protection that is required is preventing to trick other customers
into using a wrong IP address or route.&lt;/p&gt;
&lt;p&gt;Also, if the network is IPv6 only, another customer should not be able
to trick someone else into using IPv4.&lt;/p&gt;
&lt;h2&gt;Fixing it&lt;/h2&gt;
&lt;p&gt;So the easiest thing to do is to disallow IPv6 router advertisements
and IPv4 DHCP server answers. However as all the interfaces are put
into one bridge, we will need to filter on bridge and not ip level:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;table bridge filter {
    chain prerouting {
        type filter hook prerouting priority 0;
        policy accept;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next we create a chain to drop the packets we dislike:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    chain drop_ra_dhcp {
        # Blocks: router advertisements, dhcpv6, dhcpv4
        icmpv6 type nd-router-advert drop
        ip6 version 6 udp sport 547 drop
        ip  version 4 udp sport 67 drop
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the only thing left is to correctly classify the traffic. For this
lets take some real world assumptions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let's assume the bridge is named &lt;strong&gt;br100&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Let's assume the upstream interface that should allow RA/DHCP is
named &lt;strong&gt;vxlan100&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then we can connect the chains together:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;table bridge filter {
    chain prerouting {
        type filter hook prerouting priority 0;
        policy accept;

        iifname != vxlan100 meta ibrname br100 jump drop_ra_dhcp
    }

    chain drop_ra_dhcp {
        # Blocks: router advertisements, dhcpv6, dhcpv4
        icmpv6 type nd-router-advert drop
        ip6 version 6 udp sport 547 drop
        ip  version 4 udp sport 67 drop
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way we have a very simple filter to prevent router advertisements
or dhcp answers to come from customer VMs.&lt;/p&gt;
&lt;p&gt;We hope you enjoyed reading it, but if something does not make sense,
you can ask on our &lt;a href="../../projects/open-chat/"&gt;open chat&lt;/a&gt; or
&lt;a href="https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Meta"&gt;consult the nftables reference&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>2020 is the year of IPv6</title><link href="https://ungleich.ch/u/blog/2020-the-year-of-ipv6/" rel="alternate"/><updated>2020-08-07T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:439435d8-b8e9-392d-991c-f97f09085929</id><content type="html">&lt;p&gt;When is IPv6 beginning to matter? When is IPv6 taking off? These are
questions that we debate in the IPv6 community at meetings, online and offline.&lt;/p&gt;
&lt;p&gt;For us, 2020 has already become the year of IPv6, even way before it
is ending.&lt;/p&gt;
&lt;h2&gt;IPv6 traffic reached more than 33% (1/3) of traffic to Google&lt;/h2&gt;
&lt;p&gt;According to Google, IPv6 search traffic already exceeds 33%:&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/google-ipv6-2020-08-07.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;The recent growth this year is also attributed to more people working
from home, where IPv6 is already more present than in business
connections.&lt;/p&gt;
&lt;p&gt;33% - this is clearly not yet 100%, however it means that every third
search request is made using IPv6.&lt;/p&gt;
&lt;h2&gt;Some countries passed the 50% IPv6 deployment status&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://stats.labs.apnic.net/ipv6/IN"&gt;India&lt;/a&gt;,
&lt;a href="https://stats.labs.apnic.net/ipv6/BE"&gt;Belgium&lt;/a&gt;,
&lt;a href="https://stats.labs.apnic.net/ipv6/US"&gt;the US&lt;/a&gt; and
&lt;a href="https://stats.labs.apnic.net/ipv6/MY"&gt;Malaysia&lt;/a&gt; - all of them have
passed the 50% IPv6 deployment mark. &lt;strong&gt;India even surpassed the 70%
mark!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And &lt;a href="https://stats.labs.apnic.net/ipv6/GR"&gt;Greece&lt;/a&gt; and
&lt;a href="https://stats.labs.apnic.net/ipv6/DE"&gt;Germany&lt;/a&gt; are not far from
passing the 50% mark (while we in
&lt;a href="https://stats.labs.apnic.net/ipv6/CH"&gt;Switzerland&lt;/a&gt; only passed the
40% mark...).&lt;/p&gt;
&lt;p&gt;In other words: if you are living or travelling to the above countries,
you have a good chance of getting IPv6 - and it's growing.&lt;/p&gt;
&lt;h2&gt;IPv6 community is active and growing&lt;/h2&gt;
&lt;p&gt;At the moment there are so many cool IPv6 projects and communities
around, more active than we have ever seen before.
Let us list some projects/communities we are aware of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://packetpushers.net/series/ipv6-buzz/"&gt;IPv6 Buzz&lt;/a&gt;
by Ed Horley, Scott Hogg, and Tom Coffeen&lt;/li&gt;
&lt;li&gt;&lt;a href="../../projects/ipv6-chat/"&gt;The IPv6 Chat on Matrix and IRC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.apnic.net/"&gt;The APNIC blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://labs.ripe.net/"&gt;RIPE labs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/ipv6/"&gt;IPv6 on Reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.afrinic.net/"&gt;Afrinic is offering education&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ipv6.blog/"&gt;The IPv6 blog&lt;/a&gt; is a community maintained link
collection - add your IPv6 resources there!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/search?q=%23ipv6"&gt;#IPv6 on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;.. and probably many more! Did we miss a community? Just &lt;a href="../../contact/"&gt;let us know about it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/nico-ripe79.jpeg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;IPv6 hardware/software support improving&lt;/h2&gt;
&lt;p&gt;For many years we have been watching IPv6 support in (network)
hardware and open source software. And while not every everything is
fixed, many pain points have been solved.
And the great thing is, even if your network equipment does not work with IPv6 nicely,
a lot of equipment can now be made IPv6 usable just by flashing
&lt;a href="https://openwrt.org/"&gt;OpenWRT&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;IPv6 everywhere&lt;/h2&gt;
&lt;p&gt;You might have heard the claims of our CEO, &lt;a href="https://twitter.com/NicoSchottelius"&gt;Nico
 Schottelius&lt;/a&gt;,
 that &lt;a href="https://twitter.com/RobbieMitch/status/1183731875292037121"&gt;you can have IPv6
 everywhere&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This year at ungleich we released the
&lt;a href="u/products/viirb-ipv6-box/"&gt;VIIRB&lt;/a&gt;, the world's smallest IPv6
router.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/viirb-strawberry.jpeg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;This device is so easy and so small that you really don't have an
excuse for not having IPv6: power it on, plug it into an IPv4 only
network: all devices in your network have IPv6 via autoconfiguration.&lt;/p&gt;
&lt;h2&gt;IPv6 in 2020&lt;/h2&gt;
&lt;p&gt;So in 2020, you can go out, connect yourself anywhere with IPv6, talk
about it with everybody and get your software up and running easily.
Oh, and if you think it is just us, we are not the only ones
who think &lt;a href="https://blog.apnic.net/2020/08/03/ipv4-ipv6-and-a-sudden-change-in-attitude/"&gt;the attitude towards IPv6
changed!&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>South Pole meets ungleich</title><link href="https://ungleich.ch/u/blog/southpole-meets-ungleich/" rel="alternate"/><updated>2020-06-15T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:5a8c5c0f-9134-3882-9efb-e21b6577385f</id><content type="html">&lt;h2&gt;Where penguins meet&lt;/h2&gt;
&lt;p&gt;Do you know where penguins live? Probably all of us assume that they
live at the South Pole. That is correct. And it is &lt;a href="https://en.wikipedia.org/wiki/March_of_the_Penguins"&gt;a really
fascinating story how penguins
meet&lt;/a&gt;. If you
haven't seen the movie, we can highly recommend it!&lt;/p&gt;
&lt;p&gt;But did you know that penguins also live and meet at other places? For
instance &lt;a href="https://en.wikipedia.org/wiki/African_penguin"&gt;in Africa&lt;/a&gt;.
Or in the case of the penguin companies &lt;a href="https://www.southpole.com/"&gt;South
Pole&lt;/a&gt; and &lt;a href="https://ungleich.ch"&gt;ungleich&lt;/a&gt;:
in Switzerland.&lt;/p&gt;
&lt;p&gt;This blog post is about how penguins and ethical values brought South
Pole and ungleich together.&lt;/p&gt;
&lt;h2&gt;Who is South Pole?&lt;/h2&gt;
&lt;p&gt;South Pole is a 350-people team of passionate climate experts with its headquarters in Zürich. It provides global climate solutions and develops projects for companies and organizations embarking on their Climate Journey, which includes assessing their carbon footprint and climate risks, green investments, carbon neutrality, and renewable energy.&lt;/p&gt;
&lt;p&gt;Started as a handful of people with great ideas back in 2006, now their offices are spread over 18 countries, including Singapore, London, Amsterdam, Sydney, Stockholm, and more. And most importantly: their mascot is a penguin, and the team calls themselves the Penguins.&lt;/p&gt;
&lt;p&gt;Sustainability, Switzerland, penguins?! Instant love for us.&lt;/p&gt;
&lt;p&gt;We recommend that you take a look at &lt;a href="https://www.southpole.com/blog"&gt;the South Pole
blog&lt;/a&gt; that covers inspiring
projects such as forest conservation, wild animal protection, clean
water project for local communities, and many more.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/southpole-projects.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Sustainability at ungleich&lt;/h2&gt;
&lt;p&gt;A few years ago ungleich started building data centers in
&lt;a href="https://en.wikipedia.org/wiki/Canton_of_Glarus"&gt;the Canton of Glarus in Switzerland&lt;/a&gt;.
This valley does not only offer a gorgeous view, but was the home of
the weaving industry for more than a century. And it's our luck and
privilege to build on top of this heritage.&lt;/p&gt;
&lt;p&gt;Our focus is on re-using and re-modeling buildings from this
time. Many factory halls in Glarus also come with on-site hydropower
plants, which allows us to run servers on 100% renewable, locally
produced power.&lt;/p&gt;
&lt;p&gt;Not only do we re-use old buildings, but with recycled hardware,
we were all in for creating a data center that is
as sustainable as possible.&lt;/p&gt;
&lt;p&gt;When we started this project it was not 100% clear for us what kind of
people would be interested in this kind of hosting.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/datacenter-location.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;More and more we are realising that how we started and continued our
journey has actually brought us the best kind of people. The kind
who shares our visions of sustainable technology and understands the
value of what we do.  So such was the case for team ungleich and team
South Pole. We love that those whom we provide our services to have
the same mission as we do. Enabling and supporting like-minded people
with what we have built has been a really exciting journey for our
team.&lt;/p&gt;
&lt;h2&gt;Continuing our work on sustainability together&lt;/h2&gt;
&lt;p&gt;South Pole is offering a variety of
&lt;a href="https://www.southpole.com/sustainability-solutions"&gt;Sustainability
Solutions&lt;/a&gt; in all
kinds of areas. At ungleich we focus on sustainable hosting in the
&lt;a href="https://datacenterlight.ch/"&gt;Data Center Light&lt;/a&gt;, the renewable
energy-powered data center in the Alps. And we are proud to say that
South Pole hosts data in the Data Center Light.&lt;/p&gt;
&lt;p&gt;Together we can make a change for a better world.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/southpole-ungleich-penguin-together.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Join the discussion&lt;/h2&gt;
&lt;p&gt;If you like to discuss sustainability topics, we invite you to get in
touch with us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.southpole.com/contacts"&gt;Get in touch with South Pole&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../../contact/"&gt;Get in touch with ungleich&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chat.with.ungleich.ch"&gt;Join the online chat for sustainability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content></entry><entry><title>ungleich adds a bounty program</title><link href="https://ungleich.ch/u/blog/ungleich-adds-bounty-program/" rel="alternate"/><updated>2020-04-29T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:6bc40b7e-7f49-3345-9561-5ed11fedd6c5</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;At ungleich we love &lt;a href="../../projects/opensource"&gt;FOSS&lt;/a&gt;. If you want to
contribute to selected Free and Open Source Software and even get paid
for it, checkout the &lt;a href="../../projects/jobs-hacks-bounties/"&gt;ungleich bounty
program&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At ungleich we have something like an "infinite task queue". While we
do contribute to Free and Open Source Software on daily basis, there
are a variety of things we can't do during daily work.&lt;/p&gt;
&lt;h2&gt;It's Open Source&lt;/h2&gt;
&lt;p&gt;So because everything we use is Open Source and we live the Open
Source spirit, chances are high that somebody will scratch the itch
that we have found some time in the future. Because it is Open Source,
anyone with the technical skills can actually fix it.&lt;/p&gt;
&lt;h2&gt;It's about values&lt;/h2&gt;
&lt;p&gt;Many bounty items will actually list support for IPv6 or fixing things
that are necessary for having "good" or clean software. With
volunteers contributing to Open Source Software, everyone profits from
the changes that you make.&lt;/p&gt;
&lt;h2&gt;The bounty list&lt;/h2&gt;
&lt;p&gt;The list of bounties can be found on our
&lt;a href="../../projects/jobs-hacks-bounties/"&gt;Jobs, Hacks and Bounties page&lt;/a&gt;. It
will be updated regularly with the progress.&lt;/p&gt;
&lt;p&gt;If you think you have a project that fits very much the ungleich
project, you can also suggest a bounty by writing an email to &lt;strong&gt;support
at ungleich.ch&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You are also invited to join our &lt;a href="../../projects/open-chat/"&gt;open chat&lt;/a&gt;,
to hang out or to discuss the bounty idea.&lt;/p&gt;
</content></entry><entry><title>Free Video Conference Call For All</title><link href="https://ungleich.ch/u/blog/video-conference-for-all/" rel="alternate"/><updated>2020-04-26T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:bd82dc69-92b6-352d-aee2-c8d510120a7b</id><content type="html">&lt;h2&gt;A Sustainable Video Conference System&lt;/h2&gt;
&lt;p&gt;For many people who can work remotely, now is the time to stay home and to move meetings from in person to (video) conference. We have published &lt;a href="https://ungleich.ch/u/blog/remote-working-with-opensource-sustainability/"&gt;our remote working stack&lt;/a&gt; for those who look for a sustainable solution for digitally continuing their work.&lt;/p&gt;
&lt;p&gt;Good news, one more nice thing is added to this list of remote working stack: a free and open source &lt;a href="https://talk.ungleich.ch/"&gt;video conference system.&lt;/a&gt; Powered by &lt;a href="https://datacenterlight.ch/en-us/cms/hydropower/"&gt;100% renewable energy,&lt;/a&gt; running on a VM at our Swiss data center.&lt;/p&gt;
&lt;p&gt;You can try now at 
&lt;a href="https://talk.ungleich.ch/"&gt;talk.ungleich.ch&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Deciding what to use&lt;/h2&gt;
&lt;p&gt;An important note: we’re an open-source, sustainability- focused IT company. We decide which tools to use by these criteria.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;open-source&lt;/li&gt;
&lt;li&gt;sustainablility&lt;/li&gt;
&lt;li&gt;state of the art&lt;/li&gt;
&lt;li&gt;usability for people with all backgrounds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="../../image/jitsi-ungleich.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Cool thing about Jitsi&lt;/h2&gt;
&lt;p&gt;The underlying technology for our free video conference call is Jitsi. We love that Jitsi has a really cool architecture - it does not encode or decode the video streams, but only forwards video streams so the client does the encoding and decoding. This means the virtual machine that runs Jitsi doesn't need to be much powerful and can stay fairly small.&lt;/p&gt;
&lt;h2&gt;Go ahead, use it for free&lt;/h2&gt;
&lt;p&gt;You can have a video call with multiple parties, you can share screen, and you can share video over it. You can use have a conference call with or without video. No signup is needed, you can just use it on the go. We don't track any of your information: we want to enable people to work from home and stay safe, with open source and renewable energy.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/jitsi-ungleich-confcall.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Useful things to know&lt;/h2&gt;
&lt;p&gt;Our free video conference call is rolled out on March 20th and since then we have collected some feedbacks. Here are some useful infos we got from using it first-hand and from the inputs of our users.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Could show mixed result with video call when used on Firefox. We heard that the great developers of Jitsi are working on this right now and the fix is on its way.&lt;/li&gt;
&lt;li&gt;Users have reported that when one call has more than 12 active videos the quality degrades. In such case turning off the video solves the issue.&lt;/li&gt;
&lt;li&gt;The video quality varies greatly depending on the cleint computer. Computers with more graphic capability shows better performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Call as much as you need, and stay home&lt;/h2&gt;
&lt;p&gt;Use our free video conference to call the ones you need to talk to. We hope this helps your communication in this extraordinary time we're living in.&lt;/p&gt;
&lt;p&gt;If you have any thoughts to share, feel free to get in touch with us at our &lt;a href="https://twitter.com/ungleich"&gt;Twitter&lt;/a&gt; or &lt;a href="https://matrix.ungleich.ch"&gt;Matrix.&lt;/a&gt; 
Wherever you are, stay safe.&lt;/p&gt;
</content></entry><entry><title>Emacs server the fun way</title><link href="https://ungleich.ch/u/blog/emacs-server-the-smart-way/" rel="alternate"/><updated>2020-04-23T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:14f8fb96-27ea-3318-84f4-d40d57c5c5de</id><content type="html">&lt;p&gt;Today I want to talk about how amazing emacs is. Not because it is the
most feature complete operating system out there or because
&lt;a href="https://github.com/emacs-evil/evil"&gt;it fully emulates vi/vim&lt;/a&gt;.
No, because emacs has a very nice feature called &lt;strong&gt;emacs server&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;What's an emacs server?&lt;/h2&gt;
&lt;p&gt;If emacs is not an operating system, at least emacs stands for
"&lt;strong&gt;e&lt;/strong&gt;ight &lt;strong&gt;m&lt;/strong&gt;egabytes &lt;strong&gt;a&lt;/strong&gt;nd &lt;strong&gt;c&lt;/strong&gt;onstantly &lt;strong&gt;s&lt;/strong&gt;wapping", doesn't
it? (This is actually from times where 8 megabytes were quite a lot of
memory)&lt;/p&gt;
&lt;p&gt;So why do people make fun of emacs and how is it related to the emacs
server?
Emacs, like any other operating system, loads a lot of things at
startup. In my case this is initialising
&lt;a href="https://orgmode.org/"&gt;org-mode&lt;/a&gt;, starting my mail client, calculating
my agenda view to tell me what to do today.&lt;/p&gt;
&lt;p&gt;An emacs server creates a special emacs process that listens on a
socket for connecting to it. This way the initialisation is already
done before you connect to it and all
configurations are already loaded. This is the actual "slow" part of
emacs. And is a bit similar to starting python, which also needs to
load its libraries at start.&lt;/p&gt;
&lt;p&gt;With the emacs server running, you can connect to it using the
&lt;strong&gt;emacsclient&lt;/strong&gt; program.&lt;/p&gt;
&lt;p&gt;As a matter of fact,
&lt;a href="http://software.schmorp.de/pkg/rxvt-unicode.html"&gt;rxvt-unicode&lt;/a&gt; also
knows about a server mode (checkout the manpage, look for
&lt;strong&gt;urxvtd -q -f -o&lt;/strong&gt;). For rxvt-unicode, you'd use &lt;strong&gt;urxvtc&lt;/strong&gt; to
connect to it. So quite simlar.&lt;/p&gt;
&lt;h2&gt;What is so cool about the emacs server?&lt;/h2&gt;
&lt;p&gt;Saving a lot of response time and making working with emacs &lt;strong&gt;feel&lt;/strong&gt;
much faster is the obvious advantage. However, there is a much bigger
one:&lt;/p&gt;
&lt;p&gt;With the emacs server, you can connect to it from the terminal &lt;strong&gt;and&lt;/strong&gt; X
Window. Because the emacs server also manages the buffers ("open
files" for non-emacs users), you can view the same open file from the
terminal or an x window.&lt;/p&gt;
&lt;h2&gt;Turning the notebook into a server&lt;/h2&gt;
&lt;p&gt;As you might know, we at ungleich are pretty much into IPv6. So all of
our devices are generally speaking world-wide reachable. Our work
notebooks are no exception from that. In fact, most notebooks even
have their own &lt;a href="../../products/ipv6-vpn/"&gt;/48 IPv6 network assigned via
VPN&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So if I am away from my notebook, but need to check my open (and
potentially unsaved) notes or view my emails, I can use any other
computer, ssh to my notebook and type &lt;strong&gt;emacslient -nw&lt;/strong&gt; in the
terminal.&lt;/p&gt;
&lt;p&gt;While my regular emacs is running as an X11 window, I can select,
display and work in all buffers that I have previously opened in the
emacs server. In the terminal, on a remote computer.&lt;/p&gt;
&lt;h2&gt;How to configure your system to use the emacs server&lt;/h2&gt;
&lt;p&gt;In my case I start the emacs server when I start X11 in my .xinitrc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eval $(ssh-agent)
...
urxvtd -q -f -o
emacs --daemon
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of running emacs --daemon, you can also use &lt;strong&gt;M-x
server-start&lt;/strong&gt; in a running emacs process.&lt;/p&gt;
&lt;p&gt;And because I always want to have my mail client open, just after I start
i3, I have i3 launch the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-add &amp;lt;/dev/null &amp;amp;&amp;amp; emacsclient -c -e '(mu4e)'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The connection to my mailserver is tunneled via SSH to prevent
security issues from using SSL/TLS. Thus I need to add all my ssh keys
to the ssh-agent, before starting my mail client.&lt;/p&gt;
&lt;p&gt;To actually open a new emacs windown (aka "frame" in emacs speech), I
use the following configuration in my &lt;strong&gt;~/.i3/config&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bindsym $mod+Tab    exec emacsclient -c
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;How does this look like?&lt;/h2&gt;
&lt;p&gt;Below you find a screenshot of my writing this article. The upper
window is the X11 window, the lower window is a terminal window (they
happen to be configured to have the same nice background colour).&lt;/p&gt;
&lt;p&gt;&lt;img src="emacs.png" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Updates&lt;/h2&gt;
&lt;h3&gt;2020-04-23, 17:23&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/user/MutoShack/"&gt;MutoShack&lt;/a&gt; pointed
out on
&lt;a href="https://www.reddit.com/r/emacs/comments/g6nqwv/emacs_server_the_fun_way/foazghz/"&gt;reddit&lt;/a&gt;
that using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;emacsclient -a "" -c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is actually smarter than just using&lt;/p&gt;
&lt;p&gt;&lt;code&gt;emacsclient -c&lt;/code&gt;,&lt;/p&gt;
&lt;p&gt;because it will start the daemon if it is not already running. No day
that you don't learn something!&lt;/p&gt;
</content></entry><entry><title>Deutschsprachiger Coronavirus (COVID19) Chat</title><link href="https://ungleich.ch/u/blog/deutschsprachiger-coronavirus-chat/" rel="alternate"/><updated>2020-03-22T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:ea9c673e-aac3-37ec-a56f-2349811a339c</id><content type="html">&lt;h2&gt;Wie es funktioniert in Kürze&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Gehe auf &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt; und erzeuge einen neuen Account&lt;/li&gt;
&lt;li&gt;Schaue in Deine Inbox, verifiziere Deine E-Mail&lt;/li&gt;
&lt;li&gt;Gehe auf &lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; und melde Dich mit Deinem
Benutzernamen an&lt;/li&gt;
&lt;li&gt;In dem Textfeld gib &lt;strong&gt;/join #covid-19-de:ungleich.ch&lt;/strong&gt; ein&lt;/li&gt;
&lt;li&gt;Nun kannst Du Dich mit anderen austauschen, auch wenn Du zuhause
oder isoliert bist&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Kontakt trotz sozialer Distanz&lt;/h2&gt;
&lt;p&gt;In Zeiten des Coronavirus ist es wichtig, dass wir Abstand zueinander
halten und uns nicht gegenseitig infizieren, damit unser
Gesundheitssystem nicht überlastet.&lt;/p&gt;
&lt;p&gt;Damit wir in der Isolation trotzdem Kontakt miteinander haben können,
stellen den offenen Kanal &lt;strong&gt;#covid-19-de:ungleich.ch&lt;/strong&gt; zum Austausch
zur Verfügung.&lt;/p&gt;
&lt;h2&gt;Warum nicht Whatsapp, Facebook oder ähnliches?&lt;/h2&gt;
&lt;p&gt;Es gibt 1 grosses Probleme bei Whatsapp, Facebook, Telegram, Signal,
Threema und co.:&lt;/p&gt;
&lt;p&gt;Es sind alles geschlossene Systeme. Jemand der nur auf Whatsapp ist,
kann nicht mit jemanden von Telegram kommunizieren.&lt;/p&gt;
&lt;p&gt;Der Matrix-Chat ist anders: er ist offen und man kann sich mit
Teilnehmern von verschiedenen Matrix-Systemen unterhalten. Und man
kann Gruppen von anderen Systemen wie Telegram oder Whatsapp einbinden.&lt;/p&gt;
&lt;h2&gt;Wie es funktioniert&lt;/h2&gt;
&lt;p&gt;Du kannst Dir einen Account auf &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt;
anlegen. Danach bekommst Du eine E-Mail, die Du bestätigen musst.
Nachdem der Account erstellt ist, kannst Du Dich auf
&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; anmelden. Um dann mit anderen zum Thema
Coronavirus zu sprechen, tippe &lt;strong&gt;/join #covid-19-de:ungleich.ch&lt;/strong&gt;
ein.&lt;/p&gt;
&lt;p&gt;Für Englischsprachige Personen gibt es bereits den internationalen
Chat &lt;strong&gt;#covid-19:ungleich.ch&lt;/strong&gt;, mit einer &lt;a href="../work-from-home-work-remote-with-matrix/"&gt;englischen
Anleitung&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Eigene Chat-Server für Firmen&lt;/h2&gt;
&lt;p&gt;Der Chat ist kostenlos und öffentlich verfügbar. Wenn Du einen eigenen
Chat brauchst für Deine Organisation,
kannst Du diesen auf der &lt;a href="../../products/hosted-matrix-chat/"&gt;Hosted Matrix
Chat&lt;/a&gt; Webseite bestellen. Dies
ermöglicht Dir, selber Deine Benutzer zu verwalten.&lt;/p&gt;
&lt;p&gt;Falls Du jedoch nur mit Deinen Freunden und Familie Dich unterhalten
willst, kannst Du einfach kostenlos den Dienst auf
&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; benutzen.&lt;/p&gt;
&lt;h2&gt;Coronavirus&lt;/h2&gt;
&lt;p&gt;Es liegt an uns allen, die Folgen des Coronavirus zu begrenzen. Dies
passiert nur, wenn wir alle Vorsicht walten lassen und Abstand zu
anderen halten und die Hände häufig waschen.&lt;/p&gt;
&lt;p&gt;Macht mit und helft allen anderen. Danke fürs Lesen!&lt;/p&gt;
</content></entry><entry><title>코로나바이러스 챗 (한국어)</title><link href="https://ungleich.ch/u/blog/coronavirus-chat-korean-hangul/" rel="alternate"/><updated>2020-03-22T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:3db29930-86a9-39f9-a06a-318aa6ed1ed6</id><content type="html">&lt;h2&gt;밖에 안나가고 바깥 세상과 디지털로 연결하기&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt; 에서 계정 만들기 (무료)&lt;/li&gt;
&lt;li&gt;계정 생성 확인 이메일 받기&lt;/li&gt;
&lt;li&gt;&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; 로 가서 새로 만든 계정으로 로그인하기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/join #covid-19-kr:ungleich.ch&lt;/strong&gt; 바이러스와 관련된 얘기하기&lt;/li&gt;
&lt;li&gt;사람들과 소통하세요. 당신은 혼자가 아닙니다.&lt;/li&gt;
&lt;li&gt;원하면 새로운 챗방을 만들수 있습니다&lt;/li&gt;
&lt;li&gt;계속 집에 계세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;코로나바이러스, 재택근무, 정신줄 챙기기&lt;/h2&gt;
&lt;p&gt;코로나는 많은 사람들의 생각과 행동, 근무방식을 바꾸고 있습니다. 자발적으로든 강제적으로든 재택근무하게되신 여러분, 그래도 세상과 소통하고 싶으실거예요. 동료들 또는 다른 나라에서 같은 처치에 처한 분들과요.&lt;/p&gt;
&lt;p&gt;집에 계세요. 하지만 우리는 연결되어 있죠.&lt;/p&gt;
</content></entry><entry><title>Chat Francophone à propos du Coronavirus (COVID-19)</title><link href="https://ungleich.ch/u/blog/coronavirus-chat-francais/" rel="alternate"/><updated>2020-03-22T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:04074efa-8625-3c45-9831-d7bd59ee3030</id><content type="html">&lt;h2&gt;Version courte:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Va à l'adresse &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt; et créé-toi un nouveau compte&lt;/li&gt;
&lt;li&gt;Vérifie ta messagerie (y.c. le spam ;-) et valide ton adresse e-mail&lt;/li&gt;
&lt;li&gt;Va à l'adresse &lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; et connecte-toi avec ton nouveau compte&lt;/li&gt;
&lt;li&gt;Dans le champ texte, copie /join #covid-19-fr:ungleich.ch&lt;/li&gt;
&lt;li&gt;Tu peux désormais échanger avec d'autres francophones depuis chez toi ou en isolement&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Gardons le contact malgré la distanciation sociale&lt;/h2&gt;
&lt;p&gt;En cette période de pandémie, il est important que nous gardions une
certaine distance entre personnes et que nous ne nous infections pas
mutuellement, afin de ne pas surcharger nos systèmes de santé. Afin de
maintenir le contact malgré l'isolement, nous mettons à disposition le
canal ouvert #covid-19-fr:ungleich.ch pour les échanges d'idées,
d'informations et simplement de contact social&lt;/p&gt;
&lt;h2&gt;Pourquoi pas Whatsapp, Facebook ou similaire?&lt;/h2&gt;
&lt;p&gt;Il y a un gros problème avec Whatsapp, Facebook, Telegram, Signal,
Threema, etc.: Ce sont tous des systèmes fermés. Quelqu'un qui n'est
que sur Whatsapp ne peut pas communiquer avec quelqu'un qui n'utilise
que Telegram.  Le chat Matrix est construit différemment: il est
ouvert et accessible à des utilisateurs de différents systèmes
Matrix. Il est aussi possible d'intégrer des groupes d'autres systèmes
comme Telegram ou Whatsapp.&lt;/p&gt;
&lt;h2&gt;Comment ça fonctionne?&lt;/h2&gt;
&lt;p&gt;Tu peux créer ton propre compte sur &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt;. Tu
recevras un email pour vérifier et valider ton compte, que tu devras
approuver. Une fois ceci fait, tu pourras te connecter sur
&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt;. Pour rejoindre le groupe francophone
consacré au nouveau coronavirus, tape simplement
&lt;strong&gt;/join #covid-19-fr:ungleich.ch&lt;/strong&gt; Il y a également un groupe germanophone:
&lt;strong&gt;#covid-19-de:ungleich.ch&lt;/strong&gt; avec son manuel:
&lt;a href="https://ungleich.ch/u/blog/deutschsprachiger-coronavirus-chat/"&gt;https://ungleich.ch/u/blog/deutschsprachiger-coronavirus-chat/&lt;/a&gt;.
Et un anglophone: &lt;strong&gt;#covid-19:ungleich.ch&lt;/strong&gt; et son manuel:
&lt;a href="https://ungleich.ch/u/blog/work-from-home-work-remote-with-matrix/"&gt;https://ungleich.ch/u/blog/work-from-home-work-remote-with-matrix/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Avoir son propre serveur de chat pour une entreprise&lt;/h2&gt;
&lt;p&gt;Ce chat est gratuit et publiquement disponible. Si tu as besoin de ton propre
système pour ton organisation, tu peux le commander à cette address:
&lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;https://ungleich.ch/u/products/hosted-matrix-chat/&lt;/a&gt;.  Ceci te permet de
gérer toi-même tes utilisateurs.  Si tu veux simplement discuter avec
tes amis et ta famille, tu peux simplement utiliser le service gratuit
&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Coronavirus&lt;/h2&gt;
&lt;p&gt;C'est à nous tous de limiter les conséquences du Coronavirus. Ceci ne
se fera que si nous faisons tous attention, que nous gardons nos
distances et que nous nous lavons les mains régulièrement.  Participez
et aidez votre prochain! Merci d'avoir lu jusqu'ici!&lt;/p&gt;
</content></entry><entry><title>List of Coronavirus (COVID19) Chats</title><link href="https://ungleich.ch/u/blog/coronavirus-chats/" rel="alternate"/><updated>2020-03-22T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:6a9426d1-6598-3a4a-86b3-476a5e236bde</id><content type="html">&lt;p&gt;Instead of meeting in person, you can chat with others about your
coronavirus thoughts. It is available in the following languages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="../deutschsprachiger-coronavirus-chat/"&gt;Auf Deutsch&lt;/a&gt; &lt;strong&gt;#covid-19-de:ungleich.ch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../work-from-home-work-remote-with-matrix/"&gt;In English&lt;/a&gt; &lt;strong&gt;#covid-19:ungleich.ch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../coronavirus-chat-francais/"&gt;En Français&lt;/a&gt; &lt;strong&gt;#covid-19-fr:ungleich.ch&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="../coronavirus-chat-korean-hangul/"&gt;한국어&lt;/a&gt; &lt;strong&gt;#covid-19-kr:ungleich.ch&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All channels are available via the open Matrix chat and can be joined
with an account from any Matrix server. Details can be found in the links.&lt;/p&gt;
</content></entry><entry><title>Remote Working with Open Source</title><link href="https://ungleich.ch/u/blog/remote-working-with-opensource-sustainability/" rel="alternate"/><updated>2020-03-16T00:00:00Z</updated><author><name>ungleich</name></author><id>urn:uuid:ccac39d5-cb0d-3af0-bf12-c20f150271cf</id><content type="html">&lt;h2&gt;Working at the time of Covid19&lt;/h2&gt;
&lt;p&gt;So looks like 2020 is the year of remote working for a whole lot of people. Hey, welcome to the club! Our team has been working remotely since 2013, and now we are distributed in 5 different time zones. For us remote working has been a lot of fun, all you need is the right setup that enables everybody to be connected and be productive.&lt;/p&gt;
&lt;p&gt;We obviously couldn't do it without the digital infrastructure. Lately we've been getting a lot of requests for sharing tips for which tool or software to use for remote working, and we thought it'd be a good idea to share a practical list of tech stack we use in our daily business. So, here we go: remote working stack chez ungleich.&lt;/p&gt;
&lt;h2&gt;How we decide what to use&lt;/h2&gt;
&lt;p&gt;Before we continue, an important disclaimer: we’re an open-source, sustainability- focused IT company. So we decide which tools to use by these criteria.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;open-source&lt;/li&gt;
&lt;li&gt;sustainablility&lt;/li&gt;
&lt;li&gt;state of the art&lt;/li&gt;
&lt;li&gt;usability for people with all backgrounds&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1. Chat: Zero carbon chat - Mattermost and Matrix&lt;/h2&gt;
&lt;p&gt;You need a chat system when working remotely with your
team, and you need it to be secure and hassle-free. We used to be on
Slack at the very beginning, but we did not like the fact that Slack
is hosted with AWS: from our point of view AWS datacenters are not
sustainable compared to &lt;a href="https://datacenterlight.ch"&gt;our own renewable energy datacenter in
Switzerland,&lt;/a&gt; so we moved away from Slack into hosting our own chat.&lt;/p&gt;
&lt;p&gt;Now we have two chat systems, &lt;a href="https://ungleich.ch/u/products/zero-carbon-chat/"&gt;Mattermost&lt;/a&gt; and &lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;Matrix.&lt;/a&gt;
Mattermost offers an extremely easy and smooth team communication for
people with all kinds of backgrounds. Most of our team talk happens on
this platform. &lt;a href="https://chat.with.ungleich.ch"&gt;Our chat&lt;/a&gt; is open for the public
and anybody can join with their email and have a conversation with
us.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/zerocarbon-chat-screen.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ungleich.ch/u/products/hosted-matrix-chat/"&gt;Zero Carbon
Matrix&lt;/a&gt;, on the
other hand, offers end-to-end encryption and federation, which makes
it very attractive for people with high sensitivity for privacy and
security. It also allows us to be more open. Matrix works nicely with
video and audio calls as well, suitable for the secure conference call
with different teams.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/penguin-matrix.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;2. Cloud storage - Nextcloud&lt;/h2&gt;
&lt;p&gt;We are using hosted &lt;a href="https://ungleich.ch/u/products/zero-carbon-cloud"&gt;Nextcloud&lt;/a&gt; for data storage and sharing. It supports cloud storage, file sharing between teams and real-time collaboration for document editing. It's pretty easy and we like to save data in Switzerland and not somewhere we don't trust how the authorities operate.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/nextcloud-docediting.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;3. Project management - Redmine&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://ungleich.ch/u/products/project-management/"&gt;Redmine&lt;/a&gt; is our longest standing project management tool since the beginning of our company. It supports calendar, ticket creating, issue tracking, wiki, roadmap and more.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/open-infrastructure.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;Redmine is just very handy for managing multiple projects and subprojects, and giving access to different people can be done on a role basis. Our whole &lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure"&gt;data center infrastructure&lt;/a&gt; is actually in redmine &amp;amp; we open it for the public, so you can take a look to get an impression.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/open-infrastructure-overview.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;4. Code hosting - Gitlab&lt;/h2&gt;
&lt;p&gt;We used GitHub before, but &lt;a href="https://ungleich.ch/en-us/cms/blog/2018/10/18/moving-away-github/"&gt;we decided to move to our own Gitlab in 2018&lt;/a&gt; due to GitHub's lack of #IPv6 support and some other issues. We are very happy with our new home, and that's why we're hosting Gitlab for our customers too.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/github-penguin.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;A decision with sustainability goes a long way&lt;/h2&gt;
&lt;p&gt;As we disclosed at the beginning, sustainability is an important factor for us so we run all of the above on our servers with renewable energy.
Many of you who are new to remote working might have to make decisions in a hurry, but try to remember that decisions with sustainability in mind saves a lot of pain in the long run, and also saves our environment.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/decarbonize-penguin.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2&gt;Questions?&lt;/h2&gt;
&lt;p&gt;It can be overwhelming when you need to decide what to use for a new style of work: you'll have to use it every day and you want to make the right decision. Our approach is that we know where are values stand such as decentralisation, open-source, sustainability, and we try to make our decisions aligned to our values. For us working remotely with open source is fun and exciting, it gives so much freedom to everybody involved.
If you have any questions on the above stack, our remote-working team is around to give you answers. ;) Stay healthy, and happy remote working to you all!&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/zerocarbon_no.jpg" alt=""&gt;&lt;/p&gt;
</content></entry><entry><title>Remote Working with Matrix in covid-19 times</title><link href="https://ungleich.ch/u/blog/work-from-home-work-remote-with-matrix/" rel="alternate"/><updated>2020-03-15T00:00:00Z</updated><author><name>Nico Schottelius</name></author><id>urn:uuid:0b5a94db-184e-3c2d-abf9-445964596eba</id><content type="html">&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Stay isolated in real life, stay connected digitally.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt;, create an account, it's free&lt;/li&gt;
&lt;li&gt;Verify your account by email&lt;/li&gt;
&lt;li&gt;Go to &lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt;, login with your new account&lt;/li&gt;
&lt;li&gt;Type &lt;strong&gt;/join #covid-19:ungleich.ch&lt;/strong&gt; if you want to talk about
topics related to the virus.&lt;/li&gt;
&lt;li&gt;Talk to people. You are not alone.&lt;/li&gt;
&lt;li&gt;Create your own rooms as needed (as in above channel if you need help)&lt;/li&gt;
&lt;li&gt;Stay home&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Coronavirus, remote working and how to not go crazy&lt;/h2&gt;
&lt;p&gt;The covid-19 virus forces a lot of us to think differently, behave
differently and work differently. Whether you have to work from home
or whether you do it voluntarily, you might want to stay in touch with
other people. With your teammates, colleagues or other people.&lt;/p&gt;
&lt;h2&gt;Isolate in real life, stay connected digitally&lt;/h2&gt;
&lt;p&gt;One of the most important things to do at the moment is to not further
spread the virus. Here in Switzerland, we try to reduce the risk by
social distancing. No shaking hands, coughing and sneezing into your
elbow and in general to stay away from other people.&lt;/p&gt;
&lt;p&gt;If you are not used to staying alone or being isolated, this can be a
tricky
thing to do. Luckily, we do have the Internet that allows us to talk
with each other, without causing a danger to each other.&lt;/p&gt;
&lt;p&gt;While there are a variety of tools out there to stay in touch with
each other, we propose to use the &lt;strong&gt;Matrix&lt;/strong&gt; chat for a variety of
reasons:&lt;/p&gt;
&lt;h2&gt;Matrix is federated. Federated = open to talk to others&lt;/h2&gt;
&lt;p&gt;Matrix is federated. As opposed to Whatsapp, Telegram, Hangouts,
Skype or Slack, Matrix is open to connect to others. Let me guide you through
how it differs to other systems:&lt;/p&gt;
&lt;p&gt;If you create an account on &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt; and then go to
&lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt; afterwards, you can talk to anyone in the
world, who is also using Matrix. Not the one from ungleich, but maybe
the one from &lt;a href="https://matrix.org"&gt;https://matrix.org&lt;/a&gt;. Or from somebody completely
different.&lt;/p&gt;
&lt;p&gt;Matrix is not a closed system. If you decide that you want to write to
somebody on a different server, you can do so.&lt;/p&gt;
&lt;p&gt;Matrix also allows you to &lt;strong&gt;call&lt;/strong&gt; other people or have &lt;strong&gt;video
conferences&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;A Matrix channel dedicated to COVID-19&lt;/h2&gt;
&lt;p&gt;So coronavirus. Social distancing. We created a channel dedicated to
the coronavirus to discuss the topic. If you created an account above
and joined &lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt;, you can join the channel by
typing &lt;strong&gt;/join #covid-19:ungleich.ch&lt;/strong&gt; or use the
&lt;a href="https://matrix.to/#/#covid-19:ungleich.ch"&gt;matrix.to&lt;/a&gt; service.&lt;/p&gt;
&lt;p&gt;The covid-19 channel is open for everyone. You can discuss how you
feel, whether you are affected, infected, bored or ask questions about
how to behave. Beware though, we are &lt;strong&gt;not&lt;/strong&gt; a medical team. This is
more the type of alcoholics anonymous style, not a digital hospital.&lt;/p&gt;
&lt;p&gt;There is now also a &lt;a href="../deutschsprachiger-coronavirus-chat/"&gt;German speaking
channel&lt;/a&gt; available.&lt;/p&gt;
&lt;h2&gt;Your own Matrix server&lt;/h2&gt;
&lt;p&gt;If you are newly into remote work and you want or need your
own Matrix server,
this is something that we provide. You can checkout the
&lt;a href="../../products/hosted-matrix-chat/"&gt;Hosted Matrix Chat&lt;/a&gt; for details. It
allows you to manage your own chat rooms and to control whom to invite
to what.&lt;/p&gt;
&lt;p&gt;If you just need a place to talk with your friends, you can
do so freely on &lt;a href="https://matrix.ungleich.ch"&gt;https://matrix.ungleich.ch&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Future of the coronavirus&lt;/h2&gt;
&lt;p&gt;No one of us knows at the moment how things will continue with the
covid-19 virus, but we wish everyone to stay safe. And hopefully above
chat helps some of us to not stay too alone, even if we are alone at
home.&lt;/p&gt;
&lt;p&gt;Stay safe!&lt;/p&gt;
</content></entry><entry><title>What I deployed on IPv6 this week</title><link href="https://ungleich.ch/u/blog/what-i-deployed-on-ipv6-this-week/" rel="alternate"/><updated>2020-02-26T00:00:00Z</updated><author><name>ungleich IPv6 team</name></author><id>urn:uuid:b2a57277-528a-32b2-8d77-d2256f87bf16</id><content type="html">&lt;p&gt;IPv6 is growing and everyone in the IPv6 community contributing to it.
This article is dedicated to show what &lt;strong&gt;you&lt;/strong&gt; have done with IPv6 or
where you have enabled IPv6 this week.&lt;/p&gt;
&lt;h2&gt;Your story here&lt;/h2&gt;
&lt;p&gt;Do you have something interesting to share? Either send your short
story to &lt;strong&gt;ipv6&lt;/strong&gt; at &lt;strong&gt;ungleich.ch&lt;/strong&gt; with the subject
&lt;em&gt;What I deployed on IPv6 this week&lt;/em&gt; or submit a merge request to
&lt;a href="https://code.ungleich.ch/ungleich-public/ungleich-staticcms"&gt;the ungleich-staticcms
repo&lt;/a&gt;
(account can be created on &lt;a href="https://account.ungleich.ch"&gt;https://account.ungleich.ch&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Anything IPv6 related is welcome!&lt;/p&gt;
&lt;h2&gt;2020-02-24 - 2020-03-01&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/tschaeferm"&gt;Thomas Schäfer&lt;/a&gt; installedd a ripe atlas probe with IPv6 only&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/NicoSchottelius"&gt;Nico Schottelius&lt;/a&gt; deployed a prototype of &lt;a href="https://code.ungleich.ch/nico/meow-pay"&gt;uncloud
v2&lt;/a&gt; on the IPv6 only host
&lt;strong&gt;manager.place7.ungleich.ch&lt;/strong&gt; that serves as a test bed for migrating
the OpenNebula based virtualisation to uncloud.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;More of it&lt;/h2&gt;
&lt;p&gt;Feel free to join the discussion on the
&lt;a href="../../projects/ipv6-chat"&gt;IPv6.chat&lt;/a&gt;.&lt;/p&gt;
</content></entry><entry><title>Proying IPv4 traffic via the ungleich VPN</title><link href="https://ungleich.ch/u/blog/2020-02-18-proxying-ipv4-traffic-via-ungleich-vpn/" rel="alternate"/><updated>2020-02-18T00:00:00Z</updated><author><name>Timothée Floure</name></author><id>urn:uuid:7c5fe97c-3ca0-3a46-9399-8f3c60a2cdcd</id><content type="html">&lt;p&gt;We have been offering an &lt;a href="https://ungleich.ch/ipv6/vpn/"&gt;IPv6-capable VPN&lt;/a&gt;
alongside our IPv6-only VPS hosting for a while in order to bring IPv6
connectivity to customers stuck in the IPv4 world. The service also allows you
to reach the IPv6-enabled side of global Internet but was not able to connect
to IPv4-only services (such as &lt;a href="https://github.com/"&gt;github&lt;/a&gt;!), which can be
painful depending on your use-case.&lt;/p&gt;
&lt;p&gt;This shortcoming is no more since we recently deployed two
&lt;a href="https://en.wikipedia.org/wiki/IPv6_transition_mechanism#DNS64"&gt;DNS64&lt;/a&gt;
resolvers available to any VPN user. They will generate a synthetic IPv6
address for domains lacking an &lt;code&gt;AAAA&lt;/code&gt; (i.e. IPv6) DNS record, which will in
turn be routed via our NAT64 gateway. You only have to configure
&lt;code&gt;2a0a:e5c0:2:12:0:f0ff:fea9:c451&lt;/code&gt; and &lt;code&gt;2a0a:e5c0:2:12:0:f0ff:fea9:c45d&lt;/code&gt; as DNS
servers when you are connected to the VPN: all the details and instructions are
available on &lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki/Ungleich_IPv6_wireguard_VPN#Proxy-all-traffic-via-the-VPN"&gt;our
wiki&lt;/a&gt;, although it boils down to two lines in your wireguard configuration.&lt;/p&gt;
&lt;p&gt;The above means that ungleich now provides a &lt;em&gt;fully-fledged&lt;/em&gt; VPN! Note, however, that
direct IPv4 queries (i.e. requests 'bypassing' DNS resolution) won't be routed
though the VPN.  Full isolation can be achieved using network namespaces as
described in the &lt;a href="https://www.wireguard.com/netns/#the-new-namespace-solution"&gt;wireguard
documentation&lt;/a&gt;.
Feel free to &lt;a href="https://redmine.ungleich.ch/projects/open-infrastructure/wiki/CHATting_with_ungleich"&gt;join our
chat&lt;/a&gt;
to discuss such (non-trivial) setup in details!&lt;/p&gt;
</content></entry><entry><title>How to route IPv4 via IPv6</title><link href="https://ungleich.ch/u/blog/how-to-route-ipv4-via-ipv6/" rel="alternate"/><updated>2020-02-10T00:00:00Z</updated><author><name>ungleich network</name></author><id>urn:uuid:f4ac84cc-f883-3714-a60c-a0e89a5ca2a7</id><content type="html">&lt;p&gt;Imagine the following: you are running an IPv6 only network. And now
someone asks you to pass IPv4 traffic through it, without tunneling
it. Was sounds crazy at first, is actually quite feasible.&lt;/p&gt;
&lt;h2&gt;A short routing recap&lt;/h2&gt;
&lt;p&gt;Routers have routing tables. The routing tables basically say
"if you receive a packet for this host, send it to that router".&lt;/p&gt;
&lt;p&gt;&lt;img src="../../image/ip-routing.png" alt="IP routing"&gt;&lt;/p&gt;
&lt;p&gt;The important thing about this process is that the information on
where to send it to, is &lt;strong&gt;not in the packet&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;How to send IPv4 packets via IPv6&lt;/h2&gt;
&lt;p&gt;Because the next hop is not written into the IPv4 packet, the router
is free to forward the packet via any method it thinks is the
best. And if that happens to be IPv6 - well, it will forward the IPv4
packet via an IPv6 neighbour.&lt;/p&gt;
&lt;h2&gt;A practical example!&lt;/h2&gt;
&lt;p&gt;In the IPv6 only coworking network in the &lt;a href="../../projects/digital-chalet/"&gt;Digital
Chalet&lt;/a&gt;, I can add an IPv4 default route
via the IPv6 router:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@diamond ~]# ip route add 0/0 nexthop via inet6 fe80::21b:21ff:febb:6934 dev wlp0s20f3
[root@diamond ~]# ip r
default via inet6 fe80::21b:21ff:febb:6934 dev wlp0s20f3
[root@diamond ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now to be able to actually transmit IPv4 packets, I do need a source
IPv4 address. In the current network I can use an address in the
unused 10.0.8.0/22 network, however I'll add it with a /32 mask to
make it clear that there is no interface local route applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@diamond ~]# ip addr add 10.0.8.42/32 dev wlp0s20f3
[root@diamond ~]# ip r
default via inet6 fe80::21b:21ff:febb:6934 dev wlp0s20f3
[root@diamond ~]# ip a sh dev wlp0s20f3
2: wlp0s20f3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 24:ee:9a:54:c3:bf brd ff:ff:ff:ff:ff:ff
    inet 10.0.8.42/32 scope global wlp0s20f3
       valid_lft forever preferred_lft forever
    inet6 2a0a:e5c0:0:4:c6ea:b1a8:ec14:6f35/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 86400sec preferred_lft 14400sec
    inet6 fe80::3b98:cb58:ed02:c25/64 scope link
       valid_lft forever preferred_lft forever
[root@diamond ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I can indeed ping another IPv4 address, routed via IPv6!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@diamond ~]# ping -4 10.0.8.3
PING 10.0.8.3 (10.0.8.3) 56(84) bytes of data.
64 bytes from 10.0.8.3: icmp_seq=1 ttl=64 time=2.37 ms
^C
--- 10.0.8.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.365/2.365/2.365/0.000 ms
[root@diamond ~]#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;Why would anyone want to do this? It's quite easy: with this you can
route an IPv4 address to an IPv6 only host. This enables IPv6 only
resources to create and send IPv4 packets, even if they don't have
IPv4 routes.&lt;/p&gt;
&lt;h2&gt;Do it yourself&lt;/h2&gt;
&lt;p&gt;If you don't believe us that it is possible, you can test it yourself
on IPv6 only VMs on &lt;a href="https://ipv6onlyhosting.com"&gt;IPv6OnlyHosting.com&lt;/a&gt;.&lt;/p&gt;
</content></entry></feed>