## Wednesday, August 23, 2017

### OpenVPN

This article on Ars Technica inspired me to try and setup a VPN, but it seemed to lack a couple of extra steps that were required to run the server on a Raspberry Pi behind a router. The official OpenVPN documentation was helpful but long-winded, and I resorted to a few askubuntu answers in the end.
1. #### Certificate names

client-no-pass doesn't have to be replaced with the client host name, but can be (pretty much) any identifier for the client. The important thing is to sign all certificates with the same CA key.
2. #### VPN topology

The default topology of net30 is perhaps not as easy to comprehend as subnet, and subnet works with Ubuntu, Windows and iPhone clients.
3. #### Default gateway

On the server, I needed to push redirect-gateway, push "route xxx.xxx.xxx.0 255.255.255.0" and consequently push "dhcp-option DNS xxx.xxx.xxx.1" so that the client would be able to route to the server's local network, and the tun0 device would be able to do DNS lookups.
4. #### Firewall rules

Besides enabling the forwarding of IPv4 so that the Raspberry Pi acted as a router, I need to add three firewall rules in iptables: one for NAT masquerading, and two for accepting new and related established connections.
5. #### DNS setup for clients

The dhcp-options that were pushed to the client were ignored, which resulted in the client being unable to resolve any DNS names to IP addresses. This was only a problem on Ubuntu clients, but the script /etc/openvpn/update-resolv-conf was provided when I installed openvpn; all I had to do was reference it from client-name.config as a pair of lines:
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf


## Sunday, August 13, 2017

### Grub

It's nice when the Grub bootloader remembers your last choice and reuses it as the default value next time your machine boots. Using Linux, put the following in /etc/default/grub:
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

Then run:
sudo update-grub

## Wednesday, March 29, 2017

### SubscribeOn / ObserveOn

Once you have an instance of an IObservable<T> object, Reactive Extensions (Rx) provides at least two points where you can choose an IScheduler which will determine the threading context under which the later operations will run. Those operations can be broken down into two phases: subscription and observation.

Subscription refers to the operations that modify the behaviours of an IObservable<T> (e.g. Throttle, Merge, Concat) The IScheduler for the subscription phase is assigned by the SubscribeOn() method.

Observation refers to the callback operations that are invoked as the result of observing an IObservable<T> (e.g. OnNext, OnCompleted, OnError) The IScheduler for the observation phase is assigned by the ObserveOn() method.

While not the subject of this post, you can also choose an IScheduler implementation to convert any IEnumerable<T> to an IObservable<T> with the ToObservable method. This is relevant when the IEnumerable<T> has the potential to take a long time to be enumerated.

## Saturday, March 04, 2017

### 6 Simple Rules for Async/Await

1. If a method A calls another method B that returns a Task (or Task<T>) then the calling method does not block on the completion of that task, unless it either: