Monday 18 April 2022

Configuring DNS for a (non-GoDaddy) domain with Microsoft 365 Family

Microsoft Office 365 Family - DNS Setup

As a benefit of a Microsoft 365 Family or Personal subscription, you can create a personalized email address that's associated with your Outlook.com mailbox. For example, yourname@yourdomain.com. The official process is described on this Microsoft support article.

Unfortunately M$ announced that they will be removing the ability to use a custom domain with a 365 family/personal subscription from Nov 2023.
You can still configure and modify a domain until that date, after then no further changes will be possible.

It might be the case that you have a domain name already registered elsewhere which you don't want to move (losing already-paid-for registration time), or that you prefer not to be tied-in to GoDaddy (their sales process is notorious for upselling extras).

These instructions are essentially lifted and consolidated from the advice given in a microsoft community support thread I have M365 Family and a domain name not on GoDaddy.   Thanks to all who contributed.

1. If you have no reason to NOT use GoDaddy, then use GoDaddy; it is just easier.  Continuing with a different registrar is probably only for advanced computer users who will understand how to correct the settings if something goes wrong.

2. If you do prefer to use another registrar, then it is possible; Here's how:

2a. Go to Outlook.com and sign in.

2b. Click on the "Manage Premium" diamond and tell it you want a personalized email address.  Click the link at the bottom, "I already own a godaddy domain" to use an existing domain (even though it's registered elsewhere).

2c. A Godaddy "domain connect" sign-in browser window will pop up.  You need the mxRecordValue parameter from it.
Note that the URL might be url-encoded, where '%3F -> ?', '%3D -> =', '%26 -> &':

  • normal example: https://domainconnect.godaddy.com/v2/domainTemplates/providers/outlook.com/services/personalizedoutlookemail/apply?mxRecordValue=123456789&state=abcdef123456789abcdef123456789ab&redirect_url=https%3A%2F%2Foutlook.live.com/mail/LaunchDomainConnectNextStep.html
  • encoded example: https://sso.godaddy.com/login?realm=idp&app=dcc&path=%2Fmanage%2Fv2%2FdomainTemplates%2Fproviders%2Foutlook.com%2Fservices%2Fpersonalizedoutlookemail%2Fapply%3FmxRecordValue%3D987654321%26state%3Dabcdef123456789abcdef123456789ab%26domain%3Dyourdromain.com%26redirect_url%3Dhttps%253A%252F%252Foutlook.live.com%2Fmail%2FLaunchDomainConnectNextStep.html&auth_reason=1

Look for the text: ...?mxRecordValue=987654321&... or ...%3FmxRecordValue%3D987654321%26... - the "987654321" is your MX record value.

2d. Sign in to your registrar and enter the domain records, substituting your own MX record value for 987654321:

TypeNamePriorityValueTTL
CNAMEautodiscoverautodiscover.outlook.com1 Hour
CNAME_domainconnect _domainconnect.gd.domaincontrol.com1 Hour
MX@0987654321.pamx1.hotmail.com1 Hour
TXT@"v=spf1 include:outlook.com ~all"1 Hour
TXT_outlook"987654321"1 Hour
TXT_dmarc"v=DMARC1; p=none;"1 Hour

Notes:

  • CNAME "_domainconnect" entry enables Outlook to see your non-GoDaddy domain as one managed by GoDaddy. DomainConnect(.org) is an 'industry standard' for automating setup of email/web provider settings. It's not something that is used exclusively by Microsoft and GoDaddy. Obviously, in this instance the DomainConnect process is not going to be utilized at all as you will be entering all of the required information manually into your domain provider's DNS record.
  • MX entry - You will likely have an existing entry that you should modify rather than creating a competing entry.
  • MX entry - priority "0" (the highest) appears to be required for O365 to recognise the domain.  Otherwise you will see the message "Your domain yourdomain.com is still being configured. This can take up to 24hrs".
  • TTL may be "Automatic" eg. on Namecheap, some registrars may specify a number in seconds. Around an hour is typical but it's not critical.

2e. Check your DNS records independently
You can confirm that your records are configured properly using nslookup on the CMD-Prompt or an online tool such as mxtoolbox.com.

PrefHostnameIP AddressTTLCheckTest
0987654321.pamx1.hotmail.com104.47.73.16130 minBlacklist CheckSMTP Test

2f. Now go back to outlook.com and Premium > Personalized email address.
Close the window which prompted to Sign-in to GoDaddy, you've just setup all necessary DNS record entries with your own registrar.

2g. After an interval (probably at most the TTL), Outlook "Personalised email address" should display a message similar to:
"We've connected your domain yourdomain.com to Outlook, but you still need to create your personalised email address"
Learn more
Simply click the button and enter the username@yourdomain.com which you prefer.

References:

Sunday 8 December 2019

TP-Link Archer C2300 - custom firewall rules


Background

My home router is a TP-Link Archer C2300 (European flavour). I needed to block external VPN access which my family were using to bypass parental control settings. Unfortunately the router does not provide direct access to do this out-of-the-box.

Resources used:

  1. "Untangle" firewall forum thread: 'Blocking Betternet, potential solution'
  2. Github project: acc-/tplink-archer-c2300
  3. OpenWrt forum thread: 'Firewall egress filtering'

Resource (1) suggests that blocking all outbound traffic to UDP port 500 solves this. Unfortunately the AC2300 and other routers with similar UI no longer have specific port-blocking capability in the parental controls. I reasoned that perhaps it's possible via direct shell access to the unit.

Resource (2) contains in-depth information about how to decode and modify the config-file backups from the unit and obtain varying levels of direct shell access.

Resource (3) gives some great help with firewall blocking rule examples in the context of OpenWrt configurations.

Approach

To successfully set custom firewall rules on the AC2300, all that is needed is to take a backup of the router configuration, modify it adding the additional rules, and restore it back to the router.

Follow the page https://github.com/acc-/tplink-archer-c2300/wiki/Backup-Restore-config-files.

Preparation

Tools "bin2xml.sh" and "xml2bin.sh" from the github project scripts/ dir are required, and a Unix-like environment to run them in. I used "Cygwin" on Windows. I installed the 64-bit setup-x86_64 version. I let it install the basic defaults and added packages:
  • bash shell
  • openssl (version 1.1.1, which turned out to be already compiled with the zlib option needed by the scripts)
  • openssh
  • xxd (hex dump tool)
    The two scripts contain a hard-coded path to OPENSSL which needs to be changed for Cygwin, I just edited as follows in both:

        #OPENSSL=/usr/local/bin/openssl
        OPENSSL=openssl
    

    Config Conversion and Upload

    Follow the instructions in the wiki to download a backup of your router config, convert it to XML, and enable ssh shell access. Restore the modified config to your router and you should be able to access it from a cygwin terminal like:

    $ ssh root@192.168.0.1 (adjust this if you changed your router's IP address)
    
    root@192.168.0.1's password: (your normal router admin password)  
    
    BusyBox v1.19.4 (2018-08-10 16:43:00 CST) built-in shell (ash)
    Enter 'help' for a list of built-in commands.
    
         MM           NM                    MMMMMMM          M       M
       $MMMMM        MMMMM                MMMMMMMMMMM      MMM     MMM
      MMMMMMMM     MM MMMMM.              MMMMM:MMMMMM:   MMMM   MMMMM
    MMMM= MMMMMM  MMM   MMMM       MMMMM   MMMM  MMMMMM   MMMM  MMMMM'
    MMMM=  MMMMM MMMM    MM       MMMMM    MMMM    MMMM   MMMMNMMMMM
    MMMM=   MMMM  MMMMM          MMMMM     MMMM    MMMM   MMMMMMMM
    MMMM=   MMMM   MMMMMM       MMMMM      MMMM    MMMM   MMMMMMMMM
    MMMM=   MMMM     MMMMM,    NMMMMMMMM   MMMM    MMMM   MMMMMMMMMMM
    MMMM=   MMMM      MMMMMM   MMMMMMMM    MMMM    MMMM   MMMM  MMMMMM
    MMMM=   MMMM   MM    MMMM    MMMM      MMMM    MMMM   MMMM    MMMM
    MMMM$ ,MMMMM  MMMMM  MMMM    MMM       MMMM   MMMMM   MMMM    MMMM
      MMMMMMM:      MMMMMMM     M         MMMMMMMMMMMM  MMMMMMM MMMMMMM
        MMMMMM       MMMMN     M           MMMMMMMMM      MMMM    MMMM
         MMMM          M                    MMMMMMM        M       M
           M
     ---------------------------------------------------------------
       For those about to rock... (Attitude Adjustment, unknown)
     ---------------------------------------------------------------
    admin@AC2300:/root$
    

    Note

    The first time you connect, ssh will issue a warning, enter "yes":
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '192.168.1.1' (RSA) to the list of known hosts.
     
    After each reboot, the router will have changed its ssh host key and you will receive a different warning about man-in-the-middle attack.  Do not panic, you just need to remove the old host key from the file:
        ~/.ssh/known_hosts
    You may use the following on the cygwin command-lineto do this:
        $ ssh-keygen -R 192.168.0.1
    
    

    View the Firewall Config

    Now you can inspect the existing firewall config on the router:

    admin@AC2300:/root$ cat /etc/config/firewall
    
    config defaults 'firewall_default'
        option syn_flood '1'
        option output 'ACCEPT'
        option disable_ipv6 '0'
        option input 'ACCEPT'
        option forward 'DROP'
    ... etc ...
    config forwarding 'lan_to_wan'
        option dest 'wan'
        option src 'lan'
    
    config rule 'allow_dhcp'
        option dest_port '68'
        option name 'Allow-DHCP-Renew'
        option target 'ACCEPT'
        option family 'ipv4'
        option proto 'udp'
        option src 'wan'
    ... etc ...
    

    Adding a New Rule

    At this point you have proved that you can successfully modify a router config backup and restore it. All you need to do is insert the new firewall rule(s) into the .xml backup file. Resource (3) has some discussion around the firewall configs and you just need to change these into XML form. I located the section in the XML which matched firewall rules listed and added a rule to block UDP port 500 as highlighted :


    ...
    <forwarding name="lan_to_wan">
    <dest>wan</dest>
    <src>lan</src>
    </forwarding>
    <rule name="allow_dhcp">
    <dest_port>68</dest_port>
    <name>Allow-DHCP-Renew</name>
    <src>wan</src>
    <family>ipv4</family>
    <proto>udp</proto>
    <target>ACCEPT</target>
    </rule>
    <rule name="block_udp_500">
    <name>Block-Outbound-UDP-500-VPN</name>
    <enabled>1</enabled>
    <src>lan</src>
    <dest>wan</dest>
    <dest_port>500</dest_port>
    <proto>udp</proto>
    <family>any</family>
    <target>REJECT</target>
    </rule>
    <include name="include_usr">
    <path>/etc/firewall.user</path>
    </include>
    ...

    Save the file (under a new name, preferably!) and run xml2bin.sh to convert it back to tplink .bin format. Restore this config to your router, and you should find traffic directed to UDP port 500 cannot pass. This should block some VPNs. I have not yet tested it vs my son's mobile so cannot guarantee that this will block all VPNs but at least it's a start to be able to add custom firewall rules. It doesn't block access to my work VPN, incidentally.

    I tested my rule-writing first by blocking a known website address (using dest_ip=the address, with port=443 and proto=tcp).

    An older version of the OpenWrt firewall manual, is here: https://oldwiki.archive.openwrt.org/doc/uci/firewall#rules - this is more likely to be applicable to the old software on the AC2300


    It is entirely possible that you could brick your router if you mess this up. It's not difficult though - just follow the Github project instructions very carefully!

    Saturday 29 June 2019

    Search WhatsApp Messages on iPhone

    I recently had urgent need to search for a snippet of information in my WhatsApp message history.

    How to do this was not obvious and I ended up off on a tangent, searching google for how to search WhatsApp. Unfortunately the results were long-winded articles beginning with an introduction to WhatsApp, why one would want to use it and so on, riddled with adverts and clickbait. When I finally scrolled down to the part containing the information I needed, it was incorrect - perhaps written for an old version of the app.

    How to search through WhatsApp messages on iOS - concise version

    1. Go to the chat or group containing the messages that you want to search
    2. Tap the contact or group name at the top
    3. The "Group Info" or "Contact Info" screen opens. Third down is Chat Search, tap this link
    4. Enter the search text.
    5. The search is case-insensitive. You can move up/down through the matches using ^ v buttons to the left of the match counter

    I hope this helps someone needing a quick answer to a simple problem.

    Monday 6 May 2019

    BA Heritage Liveries

    On August 25, 1919, British Airways’ forerunner company, Aircraft Transport and Travel Limited (AT&T), launched the world's first daily international scheduled air service between London and Paris.


    To mark the centenary year, four aircraft have been repainted in heritage livery:


    Ref. BA press release



    Monday 24 September 2018

    Containerisation cheat-sheet

    A list of useful Docker, Kubernetes and Helm commands

    Basic Docker container management

    • $ docker images - list locally cached images
    • $ docker container ls - list running containers
    • $ docker container stop containername - stop a running container
    • $ docker container rm containername - remove a running container

    Local Docker Registry

    • $ docker run --detach --publish 5000:5000 --restart=always --name=registry registry:2 - run a local registry in the background
      The first port number refers to the local host, the second is the port within the container.
    • $ docker tag imagename localhost:5000/myimagename - To push to a particular registry, first tag the image with the first part as hostname:port.
    • $ docker push localhost:5000/myimagename - push myimagename from the local docker cache to the local registry
    • $ docker pull localhost:5000/myimagename - pull myimagename from the local registry to the local docker cache

    Kubernetes

    The official cheat-sheet is pretty detailed, the shortlist below are my "beginners basics":
    • $ kubectl version
    • $ kubectl get nodes
    • $ kubectl config get-contexts
    • $ kubectl config current-context
    • $ kubectl config use-context
    • $ kubectl config view
    • $ kubectl get deployments
    • $ kubectl delete deployment name
    • $ kubectl get pods [-o wide|yaml|json|go-template=] - list deployed pod names
    • $ kubectl get pod --watch pod-name - follow pod status changes
    • $ kubectl describe pod/pod-name - print detailed pod status and event transitions - useful for start-up diagnostics
    • $ kubectl delete pod/pod-name
    • $ kubectl get services
    • $ kubectl describe service name
    • $ kubectl delete service -l run=name
    • $ kubectl logs pod-name - print pod application logs
    • $ kubectl exec -ti pod-name -- bash
    • $ kubectl exec -ti pod-name -- curl localhost:8080

    Helm

    Helm is an 'orchestration' service. It co-ordinates all of those separate Kubernetes configurations that are required to set up your application. Essentially it allows you to write Kubernetes config files as templates, extracting the variables to a top-level 'values.yaml' file, supporting a level of re-use and abstracting away some of Kubernetes' complexity. You must still learn the Kubernetes API though, and now also some {{ Go }} syntax too...
    • $ helm list - list deployments
    • $ helm install [--debug] [--dry-run] chartdir - deploy the given chart to the cluster
    • $ helm delete ... - opposite of install
    • $ helm status ... - print deployment status

    YAML

    Of course, you also need to learn YAML syntax. This cheat-sheet is the most helpful I've found so far. Scroll down to the Examples section.
    The YAML spec website is a daunting place to start for something essentially so simple, but it does include a short refcard which may become useful once you know what it all means.

    Saturday 20 January 2018

    Model Aircraft Navigation Light Controller

    Brian asked whether I could build him a circuit to flash the navigation lights on a model aircraft in a realistic manner.  He had previously provided me with an Arduino Nano which would easily be capable of the task, actually it seems like overkill, but software does make this kind of thing very easy.

    Searching the Internet yielded a diagram explaining the actual light flash timings for an Airbus, which seems like a fair starting point.

    (Source: UTC Aerospace Systems)

    Programming the Arduino to emulate the timings behind this behaviour required a simple state machine.
    The way I've coded it here isn't going to be very power-efficient though, since it's spinning around the loop all the time. It would be better to add some sleep logic and make it interrupt driven. Maybe later.

    const int pinWingL =  2;
    const int pinWingR =  3;
    const int pinTail =  4;
    const int pinBeacon =  LED_BUILTIN;
    
    // Start time of state machine
    unsigned long startTime = 0;
    
    // Current state
    int state = 0;
    
    void setup() {
      // set the digital pins as output:
      pinMode(pinWingL, OUTPUT);
      pinMode(pinWingR, OUTPUT);
      pinMode(pinTail, OUTPUT);
      pinMode(pinBeacon, OUTPUT);
    }
    
    
    void loop() {
    
      unsigned long currentTime = millis();
      long deltaTime = currentTime - startTime;
      
      switch (state) {
        case (0): 
        default:
          startTime = currentTime;
          setBeacon(LOW);
          setWing(HIGH);
          setTail(HIGH);
          state = 1;
          break;
    
        case (1):
          if (deltaTime > 50) {
            setWing(LOW);
            state = 2;
          }
          break;
    
        case (2): 
          if (deltaTime > 100) {
            setWing(HIGH);
            setTail(LOW);
            state = 3;
          }
          break;
    
        case (3):
          if (deltaTime > 150) {
            setWing(LOW);
            state = 4;
          }
          break;
    
        case (4):
          if (deltaTime > 500) {
            setBeacon(HIGH);
            state = 5;
          }
          break;
    
        case (5):
          if (deltaTime > 600) {
            setBeacon(LOW);
            state = 6;
          }
          break;
    
        case (6):
          if (deltaTime > 999) {
            startTime = currentTime;
            state = 0;
          }
          break;
      }         
    }
    
    void setWing(int state) {
      digitalWrite(pinWingL, state);
      digitalWrite(pinWingR, state);
    }
    
    void setTail(int state) {
      digitalWrite(pinTail, state);
    }
    
    void setBeacon(int state) {
      digitalWrite(pinBeacon, state);
    }
    
    

    Saturday 15 July 2017

    Running Light Controller

    My friend Brian Boot is a modeller.  He's not just any old modeller who assembles a few Airfix kits in his spare time though, he's absolutely dedicated to model making at the highest level, adding additional details and working features wherever possible.  If you visit his house, you have to be careful moving around, because almost all horizontal space has been taken over by models and work-in-progress building more models.  His work has won medals at competitions and some are displayed in museums, I believe you can see some at the Shoreham aircraft museum. He also has galleries on the Farnborough and West Middlesex club websites.

    One thing that sets Brian apart from many other model makers is his desire to add lights and motors where possible.  One of his works-in-progress is a Bandai 1/16 scale Showman's Engine (link shows another finished example) but it had reached a state of impasse due to his desire to illuminate the canopy with some chasing lights and motorise the mechanism.  I set about designing a circuit for the lights, so he could get on and finish it.

    There are a lot of circuits for this type of thing using a microcontroller, but really that isn't necessary, the basic circuit is almost a classic from the 1980s, a 555 timer driving a 4017 decade counter.  The hard part (as far as I was concerned) was to find a good way of driving the LEDs properly using constant-current source.

    If the LEDs were simply wired in parallel, each with its own resistor, the overall current required would be multiplied by the number of LEDs, the wiring would become more of a mess with the resistors needing to be embedded up in the roof of the model, it wasn't going to be ideal.  I needed to connect the LEDs in series so that the current for each set of lights could be set correctly,  this would equalise the brightness, avoid over-driving them, and keep the circuit simpler with reduced wiring.

    The constant-current driver design was taken from an excellent Instructable "High Power LED Driver Circuits" using the final circuit at step 8 with the zener diode.  Each LED requires a forward voltage of between 2 and 3 volts (depending on colour) so a DC-DC boost converter (from ebay) provides the 30v necessary for 10 LEDs in series.

    Circuit diagram:
     Stripboard layout:
    Prototype: