07 Apr

Manage Wireguard users using Ansible

Day 16 of lockdown here in Haryana due to Covid19. Time for some distraction.


Last week it was reported that Wireguard will be added in next version of Linux kernel. I have been using Wireguard from over a year and it has been working great. I replaced OpenVPN with Wireguard for both site to site VPN as well as client-server VPN. If you are looking for a free open source VPN for remote employees or just connecting to your own remote servers Wireguard can be a really good candidate.

Recently I create client-server VPN at home so that I can get inside the home network whenever travelling (which is little uncommon due to Covid19 lockdown!).

Somehow I did not find any good automated script to generate keys. Tried a few projects and either they did not work or they tend to re-write everything inside /etc/wireguard directory. I presently run 5 different VPN daemons on my Raspberry Pi. It does site to site VPNs to two locations over two different uplinks and then OSPF running over FRR takes care of dynamically routing. For 5th one which is client-server VPN, I used Ansible put a playbook. Idea is to run playbook each time I want to add a user, provide it with client-name and client-ip (didn’t automate client IP since it’s just 4-5 devices max) and the playbook will take care of generating keys, config (which can be copy-pasted in Wireguard running on a laptop) and also QR code which can be scanned for importing config along with the keys in iOS devices. Ideally, I should put a more detailed one as Ansible role but then it’s just me being lazy and settling for a playbook instead.

Here’s goes the playbook!

---
  - hosts: ## Put server hostname here ##
    gather_facts: no
    become: yes
    vars: 
      client_name: anurag-phone
      client_ip: 10.0.0.10 
      client_mask: 24
      client_dns: 10.1.0.5
      wgname: wg5
      wgport: 5005
      work_dir: "/home/anurag/config"
      server_ip: ## Put server IP here ##


    tasks: 
      - name: Ensure {{ work_dir }} exists
        file: 
          path: '{{ work_dir }}'
          state: directory

      - name: Generate client keys for {{ client_name }}
        shell:
          cmd: wg genkey | tee privatekey | wg pubkey > publickey
          chdir: "{{ work_dir }}"

      - name: Read client privatekey and register into variable
        shell: cat {{ work_dir }}/privatekey
        register: privatekey    
      
      - name: Read client publickey and register into variable
        shell: cat {{ work_dir }}/publickey
        register: clientpublickey    
  
      - name: Read server publickey of server and register into variable
        shell: cat /etc/wireguard/publickey
        register: serverpublickey    

      - name: Add {{ client_name }} to the server
        blockinfile:
          path: '/etc/wireguard/{{ wgname }}.conf'
          marker: "## Added by Ansible"
          block: |
              # {{ client_name }}
              [Peer]
              PublicKey = {{ clientpublickey.stdout }}
              AllowedIPs = {{ client_ip }}/32

      - name: Stop wireguard for {{ wgname }}
        command: wg-quick down {{ wgname }}
        register: wireguardstop 
        tags: wireguardrestart

      - debug: 
          var: wireguardstop.stderr_lines
        tags: wireguardrestart 

      - name: Start wireguard for {{ wgname }}
        command: wg-quick up {{ wgname }}
        register: wireguardstart
        tags: wireguardrestart

      - debug: 
          var: wireguardstart.stderr_lines
        tags: wireguardrestart  

      - name: Generate client config for {{ client_name }} for full internet access
        blockinfile:
          path: "{{ work_dir }}/{{ client_name }}-full.conf"
          block: |
              [Interface]
              PrivateKey = {{ privatekey.stdout }}
              Address = {{ client_ip }}/{{ client_mask }}
              DNS = {{ client_dns }}
          
              [Peer]
              PublicKey = {{ serverpublickey.stdout }}
              AllowedIPs = 0.0.0.0/0
              Endpoint = {{ server_ip }}:{{ wgport }}       

          state: present    
          create: yes

      - name: Generate QR code for {{ client_name }}
        shell: qrencode -t ansiutf8  < {{ work_dir }}/{{ client_name }}-full.conf  > {{ work_dir }}/{{ client_name }}-qr-full
        tags: qr

Some limitations of this playbook:

  1. Cannot be used to delete users. I don’t do that often and thus I am OK to delete those just manually though one can make it little more smart to do that. Probably define users within vars and have a check to not-re-write keys during each run.
  2. It will keep on adding keys to the server side config and hence if run twice for same user, IP – it will add junk. Again, this was more of a quick written solution and not a extensively written playbook to tackle that.

The key objective here was just to generate keys, insert client public key in server side config and server’s key in client side config. And ofcourse making config available in text and QR code form so that one can use import and delete it.

22 Nov

My home network…

This is a common discussion topic when I tell friends in Indian network operators that I work from home. As soon as I say that, they ask me – “How good is the connectivity at your home?” And of course like all answers in engineering – it depends. 🙂

So I have two links at my home: IAXN and Siti broadband. IAXN is a FTTH connection with 50Mbps down and 25Mbps up, while Siti broadband is a DOCSIS connection with ~60Mbps down and 25Mbps up.

Both have reasonable but not 100% uptime. So to get close to 100% uptime, I use both together. These are consumer grade connections with no BGP. These days many routing platforms support running multiple WAN links for the redundancy reasons. I use Ubnt Edgerouter Lite which my good friend Nat Morris gifted me a while ago. Both links are defined in the “load balancing” where one link acts as primary and other for failover only with multiple routing tables. Next, policy based routing on the LAN VLAN sub-interface takes care of routing packets as needed. This documentation covers the setup in detail. For wifi I use a Asus device which runs purely as a access point in bridged mode with no routing.

Some other things in use at home network:

  • A Raspberry pi 3 stays on a dedicated VLAN & runs multiple site to site Wireguard VPN tunnels (over multiple WAN links) to multiple of my remote locations.
  • It also runs OSPF over FRR to ensure dynamic routing table changes whenever a link is changed. I can switch over traffic by defining the OSPF cost.
  • My server in Munich runs a NGIX proxy & apart from doing various tasks, it also hosts a test URL which does reverse proxy via Raspberry Pi at my home over Siti broadband (only). UptimeRobot monitors that URL for availability and that’s how I monitor my Siti broadband link which is without any public IP and totally behind the CGNAT.
  • Site to site VPNs over multiple links with OSPF taking care of dynamically moving traffic also takes care of things like SNMP monitoring of home devices. I use LibreNMS which is hosted remotely & keeps an eye on home network.
  • Raspberry Pi at home also runs Smokeping where certain predefined targets are moved forcefully out of each WAN link to plot latency. That helps in keeping eye on latency to ISP’s core, as well as upstream telco cores via each link.
  • I also host a node for Galmon project node to keep an eye on (American) GPS satellites, European, Chinese & Russian navigation satellites. The wonderful map here shows the receivers. Lately project is getting good coverage for it’s stats (reference here)
  • I run a DNS resolver at home (again on the raspberry pi)

While there’s auto switching in case of failure or packet loss beyond certain rate on the primary WAN link, I also have a ansible playbook which can be used to tweak the primary/secondary choice & the playbook is available via Semaphone web UI based interface so that my family can switch if they need to.

So the end result is close to 100% uptime (30 seconds outage if primary fails) as well with no irritating wifi switching as well as push notifications on my phone about an outage (via Uptime Robot) for both links. Usually there’s outage once in 30 days not because of WAN links but because I have shut things to clean up the dust.

17 Oct

New rules related to road safety

(A very Indian specific post, International readers feel free to skip this one!)

From last month Motor Vehicles (Amendment) Act, 2019 came to existence. It increases fines for various violations a lot more then what it used to be. I don’t need to cover what has changed since it has been extensively covered in various news articles. One can refer to the Times of India article here which has a nice comparison of old Vs new fine.

This change is a great move and I am little surprised at the stupidity of Indian politicians who even made it an election move to halt it. Due to the federal structure of India, it’s the State Governments who can decide whether or not to apply some parts of it. While there are various sections of society who romanticize with the idea of giving power to states and even more to local city bodies, I found often local folks way more corrupt, idiotic than their National counterparts. The fact that we rank really bad on road safety it’s really needed.

Discussion with a friend

I was once in Muscat for MENOG and I decided to stay for 2 extra after the conference to the roam around but found there was almost no public transport around in a place where I was staying. Plus it was quite expensive to take a taxi. I mentioned this to a good from the UK and he suggested me to rent a car. I promptly replied “no” hinting that it would be hard for me to drive in Oman because there are many “obvious” rules which don’t look obvious to me from the (Indian) system I am used to. He replied back – “If you don’t know the rules, you shouldn’t be driving in India anyway!“. Besides ignoring his amazing level of thinking, I just terminated the discussion. 🙂

My driving has gone from decent to safe over the last few years as a result of looking at how people drive across the world. But I must say from my experience average Indian driving has gone really bad. This is the interesting part – while all other infra like roads, bridges, power infra, telecom has gone much better in say last 10-20 years, average driving has gone from bad to worst. The only place where I have seen driving even worst then ours is in Bangladesh.

Documentation, Digilocker and some thoughts

One of the commonly reported issue with new rules is the fact that it’s very expensive to be driving with a driving license and registration certificate. The new rules have fine of 5,000 INR ($70 USD) for that. That’s actually a real challenge as it beings to dilemma whether to carry driving license regularly at risk of losing it Vs the fine. One thing which comes at the rescue is the Digilocker platform which is a Govt. run platform for pulling the documents from various Central and State Govt. bodies. As per various notifications are given on the Digilocker website (here), it is an accepted valid proof for showing driving license as well as the registration certificate. The traffic policeman checking the documents can anyway validate it from their handheld device using the unique numbers on these. This option is much better than to carry originals since replacement for lost ones is still a bit challenging. The RTO (Regional Transport Office) are often crowded with people applying for new licenses. Though the fact that due to issues in name, missing of surnames, father’s name etc it does breaks sometimes for pulling the document.

Few more things which will help in fixing millions of people to drive better:

  1. Police reforms so that local politicians cannot simply push away a traffic policeman when they fine someone.
  2. Addition of content in the school curriculum for safer driving, showing some scary driving videos & it results to young people will further help.
  3. An overhaul of traffic signal lights across the country. It’s quite poor, doesn’t work many times, doesn’t responds to traffic as it should, designed so poorly that someones a street light pole blocks the visibility of signal etc.
  4. Mandating footpaths across all roads and at least the ones which are built now. This issue results in pedestrians being forced to walk on the road.
  5. Make it mandatory for bicycles riders to use the helmet as well as lights during the night time.