NFD nightly APT repository

Last year, I started building NFD nightly packages in GitHub Actions. So far, installation is a manual procedure: the user must manually download the ZIP files from, decompress them, and figure out the dependency among various .deb packages. Starting today, I'm publishing NFD nightly packages in an APT repository, and you can install them with apt-get command.

Add the NFD nightly APT repository

Add the repository with the command that matches your platform:

# Ubuntu 18.04 (bionic), amd64 (laptops and servers)
echo "deb [trusted=yes] bionic main" \
  | sudo tee /etc/apt/sources.list.d/nfd-nightly.list

# Ubuntu 20.04 (focal), amd64 (laptops and servers)
echo "deb [trusted=yes] focal main" \
  | sudo tee /etc/apt/sources.list.d/nfd-nightly.list

# Debian 10 (buster), amd64 (laptops and servers)
echo "deb [trusted=yes] buster main" \
  | sudo tee /etc/apt/sources.list.d/nfd-nightly.list

# Debian 10 (buster), armv7 (Raspberry Pi 3 or 4)
echo "deb [trusted=yes] buster main" \
  | sudo tee /etc/apt/sources.list.d/nfd-nightly.list

# Debian 10 (buster), armv6 (Raspberry Pi Zero W)
echo "deb [trusted=yes] buster main" \
  | sudo tee /etc/apt/sources.list.d/nfd-nightly.list

If your operating system and CPU architecture combination is not listed, it is not supported by NFD nightly. See the previous post on how to request a new platform.

How to Host a Website in Oracle Cloud Free Tier

Oracle Cloud is a cloud computing service offered by Oracle Corporation. Oracle Cloud has a generous free tier that offers two "always free" virtual machine (VM) instances with the following specification:

  • KVM virtualization
  • 1/8 CPU cores (AMD EPYC 7551)
  • 1GB memory
  • 45GB disk storage
  • 1 IPv4 address, no IPv6
  • 48Mbps Internet bandwidth

I signed up for Oracle Cloud, so that I can have some more free computing resources to play with. The sign-up procedure requires a credit card for identity confirmation purpose, but the credit card will not be charged. During sign-up, there's a choice of home region, which determines the location of VM instances; once selected, it cannot be changed in the future.

A common use case for a virtual machine is to host a website. Due to the firewalls, hosting a website on Oracle Cloud needs a few more steps. Here's exactly how to deploy a website in a Oracle Cloud Free Tier VM instance.

Create a VM Instance

How to Select Default IPv6 Source Address for Outbound Traffic with Netplan

I bought a few Virtual Private Servers (VPS) on Black Friday, and have been busy setting them up. Nowadays, most VPS comes with an IPv6 subnet that contains millions of possible addresses. Initially, only one IPv6 address is assigned to the server, but the user can assign additional addresses as desired. Given that I plan to run multiple services within a server, I added a few more IPv6 addresses so that each service can have a unique IPv6 address.

One of my servers is using KVM virtualization technology, in which I installed Ubuntu 20.04 operating system manually from an ISO image. Unlike a template-based installation, an ISO-installed Ubuntu 20.04 system manages its networks using Netplan, a backend-agnostic network configuration utility that generates network configuration from YAML files. Most VPS control panels, including SolusVM and Virtualizer, are unable to generate the YAML files needed by Netplan. IPv4 works out of box via DHCP, but IPv6 has to be configured manually. To assign two IPv6 addresses to my server, I need to write the following in /etc/netplan/01-netcfg.yaml:

  version: 2
      dhcp4: true
        - 2001:db8:30fa:5877::1/64
        - 2001:db8:30fa:5877::beef/64
        - to: ::/0
          via: 2001:db8:30fa::1
          on-link: true
        - 2001:4860:4860::8888
        - 2606:4700:4700::1111

I intend to host my secret beef recipes on its unique IPv6 address 2001:db8:30fa:5877::beef, and use the other address 2001:db8:30fa:5877::1 for outbound traffic such as pings and traceroutes. However, I noticed that the wrong address is being selected for outgoing packets:

$ ping 2001:db8:57eb:8479::2

$ sudo tcpdump -n icmp6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
00:44:48.704099 IP6 2001:db8:30fa:5877::beef > 2001:db8:57eb:8479::2: ICMP6, echo request, seq 1, length 64
00:44:48.704188 IP6 2001:db8:57eb:8479::2 > 2001:db8:30fa:5877::beef: ICMP6, echo reply, seq 1, length 64
00:44:49.704011 IP6 2001:db8:30fa:5877::beef > 2001:db8:57eb:8479::2: ICMP6, echo request, seq 2, length 64
00:44:49.704099 IP6 2001:db8:57eb:8479::2 > 2001:db8:30fa:5877::beef: ICMP6, echo reply, seq 2, length 64

NFD nightly packages

NDN Forwarding Daemon (NFD) is the reference implementation of Named Data Networking (NDN) forwarding plane. The software is continuously developed, but binary releases happen rather infrequently. Recently, I made a workflow to build NFD and related software automatically.

Download page:


Which platform should I choose?

  • The platform identifier has two parts: Linux distribution and CPU architecture. Both parts must match your machine.
  • Linux distribution:
    • bionic is Ubuntu 18.04.
    • buster is Debian 10. This includes Raspberry Pi OS.
  • CPU architecture:

Ubuntu 16.04 NFD Development Machine

I shared how I setup my NFD development machine in 2017. Back then, NFD's minimum system requirement is Ubuntu 14.04 so my virtual machine is 14.04 as well. In May 2018, ndn-cxx started requiring Ubuntu 16.04, so it's time for a rebuild.

Vagrantfile for NFD Development in Ubuntu 16.04

Here's my new Vagrantfile:

$vmname = "devbox"
$sshhostport = 2222

$deps = <<SCRIPT
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get dist-upgrade -yq
apt-get install -yq git build-essential gdb valgrind libssl-dev libsqlite3-dev libboost-all-dev pkg-config libpcap-dev doxygen graphviz python-sphinx python-pip
pip install sphinxcontrib-doxylink sphinxcontrib-googleanalytics

Vagrant.configure(2) do |config| = "bento/ubuntu-16.04" :forwarded_port, guest: 22, host: $sshhostport, id: "ssh"
  config.vm.provider "virtualbox" do |vb| = $vmname
    vb.memory = 6144
    vb.cpus = 8
  config.vm.provision "deps", type: "shell", inline: $deps
  config.vm.provision "hostname", type: "shell", inline: "echo " + $vmname + " > /etc/hostname; hostname " + $vmname
  config.vm.provision "sshpvtkey", type: "file", source: "~/.ssh/id_rsa", destination: ".ssh/id_rsa"
  config.vm.provision "sshpubkey", type: "file", source: "~/.ssh/", destination: ".ssh/"
  config.vm.provision "sshauth", type: "shell", inline: "cd .ssh; cat >> authorized_keys"
  config.vm.provision "gitconfig", type: "file", source: "~/.gitconfig", destination: ".gitconfig"

Differences from 2017

NFD on Windows 10 WSL

The NDN Forwarding Daemon (NFD) connects every Ubuntu and Mac OS machine to the Named Data Networking (NDN) testbed network. While it's awesome to get your NFD connected from a Linux server or a Macbook, 82.56% of the desktop users running Windows are out of luck. Compiling NFD for Windows is possible, but the amount of patches needed is astonishing.

Then the good news came: Microsoft announced Windows Subsystem for Linux (WSL), which lets developers run Linux environments directly on Windows, unmodified, without the overhead of a virtual machine. Ubuntu is the first Linux distribution supported by WSL. This means, we can now run NFD natively on Windows!

How to Install NFD on WSL

This section outlines how to install NDN Forwarding Daemon (NFD) on Windows Subsystem for Linux (WSL). As of this writing, I have Windows 10 version 1709 (Fall Creators Update), and the latest NFD release is version 0.6.1.

The steps to install NFD on Windows are:

How I Setup my NFD Development Machine

I'm the lead developer of NDN Forwarding Daemon (NFD). In this article, I want to share how my development machine is setup.

Everything in Virtual Machines

I do all NFD development work in virtual machines. There are many benefits in using VMs: I can have a clean operating system, I can test out different OS versions if necessary, and I can work on a different change on another VM when "my code's compiling".

My VM was setup using Vagrant, using the following Vagrantfile:

$vmname = "devbox"
$sshhostport = 2222

$deps = <<SCRIPT
apt-get update
apt-get dist-upgrade -y -qq
apt-get install -y -qq build-essential doxygen gdb git graphviz libboost-all-dev libcrypto++-dev libpcap-dev libsqlite3-dev libssl-dev pkg-config python-pip python-sphinx valgrind
pip install sphinxcontrib-doxylink sphinxcontrib-googleanalytics

Vagrant.configure(2) do |config| = "ubuntu/trusty64" :forwarded_port, guest: 22, host: $sshhostport, id: "ssh"
  config.vm.provider "virtualbox" do |vb| = $vmname
    vb.memory = 4096
    vb.cpus = 4
  config.vm.provision "deps", type: "shell", inline: $deps
  config.vm.provision "hostname", type: "shell", inline: "echo " + $vmname + " > /etc/hostname; hostname " + $vmname
  config.vm.provision "sshpvtkey", type: "file", source: "~/.ssh/id_rsa", destination: ".ssh/id_rsa"
  config.vm.provision "sshpubkey", type: "file", source: "~/.ssh/", destination: ".ssh/"
  config.vm.provision "sshauth", type: "shell", inline: "cd .ssh; cat >> authorized_keys"
  config.vm.provision "gitconfig", type: "file", source: "~/.gitconfig", destination: ".gitconfig"

Install OpenConnect VPN Server with Trusted Certificate from Let's Encrypt

OpenConnect VPN server, or ocserv, is an SSL VPN server compatible with Cisco AnyConnect. It can easily be installed in a cheap OpenVZ Virtual Private Server (VPS) with TUN capability. However, most online tutorials for installing OpenConnect VPN server rely on certtool to generate a self-signed certificate via OpenSSL. Afterwards, since the self-signed certificate is not trusted by operating systems, either the VPN client must be configured to skip certificate checking, or the self-signed certificate must be imported as a trusted certificate on the VPN client machine. Both practices are insecure. Bypassing certificate checking would allow an attacker to impose as the VPN server. Importing a trusted certificate does not seem wrong at first, but in case the private key is compromised, an attacker would be able to impose as any server to the client, including online shopping and bank websites, using a certificate signed by that private key. Remember that the self-signed certificate's private key is stored on the VPS filesystem, it is much less secure than Hardware Security Modules used at real CAs to store private keys, and therefore it is a bad idea to trust such certificates in client machines.

Let's Encrypt is a free, automated, and open Certificate Authority (CA). It allows anyone to obtain a domain-verified certificate within minutes, and without paying anything. Certificates from Let's Encrypt are trusted by most modern operating systems. They are ideal for securing an OpenConnect VPN server.

This article explains how to request a proper trusted certificate from Let's Encrypt for use with ocserv, how to install OpenConnect VPN Server and use the Let's Encrypt certificate, and how to configure Cisco AnyConnect client to connect to ocserv. These steps are verified with an OpenVZ Ubuntu 16.04 64bit VPS provided by SecureDragon. It is required to enable TUN devices for the VPS, typically through a button in SolusVM or other control panel provided by the hosting company.

Request Let's Encrypt Certificate for OpenConnect VPN Server

Before requesting a certificate from Let's Encrypt, you must have a Virtual Private Server with an IPv4 address, and have a domain name (could be subdomain) resolved to the server so that you are able to ping the server via the domain name. run commands in parallel with bash

Recently I'm doing some heavy research work. One part of my work involves invoking a simulation script with different inputs and parameters and then an analysis script to analyze the simulation output.

At first, this is an easy bash loop:

  echo 3 11
  echo 3 11
  echo 5 19
  echo 5 19
) | while read -r -a L; do
  python2 --x=$X --y=$Y < input.tsv > $X-$Y.simulation.log
  gawk -f analysis.awk $X-$Y.simulation.log > $X-$Y.analysis.tsv

The loop works fine, but it takes too long time when the input gets larger, because scripts are running sequentially. Since we have a big server with 32 CPU cores, can I run the scripts in parallel?

So I wrote this nifty little script,

Share Dropbox between VirtualBox Host and Guest

My laptop comes with Windows, like most other laptops in the market. But as a computer science student, I need to use Linux from time to time. The laptop manufacturer advised me not to install Linux directly on this laptop. Although this would not void my warranty, they would not provide technical support or supply device drivers if I install Linux. Therefore, I turned into VirtualBox, a hypervisor that allows me to run Linux in a virtual machine, alongside the Windows installation.

I'm also a heavy user of Dropbox, a file hosting service that can synchronize my documents among all my device. I have Dropbox clients installed everywhere, including the Windows of this laptop, and the Linux virtual machine. When I edit a file, the Dropbox client uploads this file to the cloud, and then the Dropbox clients on all other devices download the file from the cloud.

One day, there's a congestion on my apartment's WiFi hotspot, and I notice that the Dropbox synchronization between Windows and the Linux virtual machine is having significant delay: every update travels a long way to the cloud, and then comes back. I also realize that, in my setup, the entire Dropbox contents are duplicated twice: it has one copy in Windows, and another copy in Linux virtual machine. Although having multiple copies is usually a good thing because you have more redundancy, having multiple copies on the same hard drive is not useful. Can I eliminate the synchronization delay and the redundant copy?

VirtualBox Shared Folder

VirtualBox has a nifty feature, shared folders, which allows files of the host system to be accessed within a guest system. In my setup, I could use this feature to access the Dropbox on Windows within the Linux virtual machine.