Finding and Setting the Maximum Transmission Unit (MTU) on a Windows Machine

If you have just changed ISPs or moved house and your internet suddenly starts misbehaving the likelihood is your Maximum Transmission Unit (MTU) is set too high for your ISP. The default internet facing MTU is 1500 bytes, BUT depending on your setup, this often needs to be set much lower.

Step 1:

First check your current MTU across all your ipv4 interfaces using netsh:

netsh interface ipv4 show subinterfaces
   MTU  MediaSenseState   Bytes In  Bytes Out  Interface
------  ---------------  ---------  ---------  -------------
4294967295                1          0          0  Loopback Pseudo-Interface 1
  1492                1        675        523  Local Area Connection

As you can see, the Local Area Connection interface is set to a 1492 bytes MTU. So how do we find out what it should be? We are going to send a fixed size Echo packet out, and tell the network not to fragment this packet. If somewhere along the line this packet is too big then this request will fail.

Next enter (if it fails then you know your MTU is too high):

ping 8.8.8.8 -f -l 1492

Procedure to find optimal MTU:

For PPPoE, your Max MTU should be no more than 1492 to allow space for the 8 byte PPPoE “wrapper”. 1492 + 8 = 1500. The ping test we will be doing does not include the IP/ICMP header of 28 bytes. 1500 – 28 = 1472. Include the 8 byte PPPoE wrapper if your ISP uses PPPoE and you get 1500 – 28 – 8 = 1464.

The best value for MTU is that value just before your packets get fragmented. Add 28 to the largest packet size that does not result in fragmenting the packets (since the ping command specifies the ping packet size, not including the IP/ICMP header of 28 bytes), and this is your Max MTU setting.

The below is an automated ping sweep, that tests various packet sizes until it fails (increasing in 10 bytes per iteration):

C:\Windows\system32>for /l %i in (1360,10,1500) do @ping -n 1 -w 8.8.8.8 -l %i -f

Pinging 8.8.8.8. with 1400 bytes of data:
Reply from 8.8.8.8: bytes=1400 time=6ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 6ms, Maximum = 6ms, Average = 6ms

Pinging 8.8.8.8 with 1401 bytes of data:
Reply from 8.8.8.8: bytes=1401 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

Pinging 8.8.8.8 with 1402 bytes of data:
Reply from 8.8.8.8: bytes=1402 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

Pinging 8.8.8.8 with 1403 bytes of data:
Reply from 8.8.8.8: bytes=1403 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms 

Once you find the MTU, you can set it as per below:

set subinterface “Local Area Connection” mtu=1360 store=persistent

Hacking: Using a Macbook and Nikto to Scan your Local Network

Nikto is becoming one of my favourite tools. I like it because of its wide ranging use cases and its simplicity. So whats an example use case for Nikto? When I am bored right now and so I am going to hunt around my local network and see what I can find…

# First install Nikto
brew install nikto
# Now get my ipaddress range
ifconfig
# Copy my ipaddress into to ipcalculator to get my cidr block
eth0      Link encap:Ethernet  HWaddr 00:0B:CD:1C:18:5A
          inet addr:172.16.25.126  Bcast:172.16.25.63  Mask:255.255.255.224
          inet6 addr: fe80::20b:cdff:fe1c:185a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2341604 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2217673 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:293460932 (279.8 MiB)  TX bytes:1042006549 (993.7 MiB)
          Interrupt:185 Memory:f7fe0000-f7ff0000
# Get my Cidr range (brew install ipcalc)
ipcalc 172.16.25.126
cp363412:~ $ ipcalc 172.16.25.126
Address:   172.16.25.126        10101100.00010000.00011001. 01111110
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   172.16.25.0/24       10101100.00010000.00011001. 00000000
HostMin:   172.16.25.1          10101100.00010000.00011001. 00000001
HostMax:   172.16.25.254        10101100.00010000.00011001. 11111110
Broadcast: 172.16.25.255        10101100.00010000.00011001. 11111111
Hosts/Net: 254                   Class B, Private Internet
# Our NW range is "Network:   172.16.25.0/24"

Now lets pop across to nmap to get a list of active hosts in my network

# Now we run a quick nmap scan for ports 80 and 443 across the entire range looking for any hosts that respond and dump the results into a grepable file
nmap -p 80,433 172.16.25.0/24 -oG webhosts.txt
# View the list of hosts
cat webhosts.txt
$ cat webhosts.txt
# Nmap 7.93 scan initiated Wed Jan 25 20:17:42 2023 as: nmap -p 80,433 -oG webhosts.txt 172.16.25.0/26
Host: 172.16.25.0 ()	Status: Up
Host: 172.16.25.0 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.1 ()	Status: Up
Host: 172.16.25.1 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.2 ()	Status: Up
Host: 172.16.25.2 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.3 ()	Status: Up
Host: 172.16.25.3 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.4 ()	Status: Up
Host: 172.16.25.4 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.5 ()	Status: Up

Next we want to grep this webhost file and send all the hosts that responded to the port probe of to Nikto for scanning. To do this we can use some linux magic. First we cat to read the output stored in our webhosts.txt document. Next we use awk. This is a Linux tool that will help search for the patterns. In the command below we are asking it to look for “Up” (meaning the host is up). Then we tell it to print $2, which means to print out the second word in the line that we found the word “Up” on, i.e. to print the IP address. Finally, we send that data to a new file called niktoscan.txt.

cat webhosts.txt | awk '/Up$/{print $2}' | cat >> niktoscan.txt
cat niktoscan.txt
$ cat niktoscan.txt
172.16.25.0
172.16.25.1
172.16.25.2
172.16.25.3
172.16.25.4
172.16.25.5
172.16.25.6
172.16.25.7
172.16.25.8
172.16.25.9
172.16.25.10
...

Now let nikto do its stuff:

nikto -h niktoscan.txt -ssl >> niktoresults.txt
# Lets check what came back
cat niktoresults.txt

Macbook: Exploring DNS using DIG (Domain Information Groper)

DIG is an awesome command line utility to explore DNS. Below is a quick guide to get you started.

Query Specific Name Server

By default, if no name server is specified, dig will use the servers listed in /etc/resolv.conf file. To view the default server use:

% cat /etc/resolv.conf
#
# macOS Notice
#
# This file is not consulted for DNS hostname resolution, address
# resolution, or the DNS query routing mechanism used by most
# processes on this system.
#
# To view the DNS configuration used by this system, use:
#   scutil --dns
#
# SEE ALSO
#   dns-sd(1), scutil(8)
#
# This file is automatically generated.
#
nameserver 100.64.0.1

You can override the name server against which the query will be executed, use the @ (at) symbol followed by the name server IP address or hostname.

For example, to query the Google name server (8.8.8.8) for information about andrewbaker.ninja you would use:

% dig andrewbaker.ninja @8.8.8.8

; <<>> DiG 9.10.6 <<>> andrewbaker.ninja @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33993
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;andrewbaker.ninja.		IN	A

;; ANSWER SECTION:
andrewbaker.ninja.	300	IN	A	13.244.140.33

;; Query time: 1099 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Nov 17 11:26:55 SAST 2022
;; MSG SIZE  rcvd: 62

Get a Short Answer

To get a short answer to your query, use the +short option:

% dig andrewbaker.ninja +short
13.244.140.33

Query a Record Type

Dig allows you to perform any valid DNS query by appending the record type to the end of the query. In the following section, we will show you examples of how to search for the most common records, such as A (the IP address), CNAME (canonical name), TXT (text record), MX (mail exchanger), and NS (name servers).

Querying A records

To get a list of all the address(es) for a domain name, use the a option:

% dig +nocmd andrewbaker.ninja a +noall +answer
andrewbaker.ninja.	156	IN	A	13.244.140.33

Querying CNAME records

To find the alias domain name use the cname option:

dig +nocmd mail.google.com cname +noall +answer
mail.google.com.	553482	IN	CNAME	googlemail.l.google.com.

Querying TXT records

Use the txt option to retrieve all the TXT records for a specific domain:

% dig +nocmd google.com txt +noall +answer
google.com.		3600	IN	TXT	"globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8="
google.com.		3600	IN	TXT	"MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB"
google.com.		3600	IN	TXT	"docusign=1b0a6754-49b1-4db5-8540-d2c12664b289"
google.com.		3600	IN	TXT	"onetrust-domain-verification=de01ed21f2fa4d8781cbc3ffb89cf4ef"
google.com.		3600	IN	TXT	"apple-domain-verification=30afIBcvSuDV2PLX"
google.com.		3600	IN	TXT	"google-site-verification=TV9-DBe4R80X4v0M4U_bd_J9cpOJM0nikft0jAgjmsQ"
google.com.		3600	IN	TXT	"facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
google.com.		3600	IN	TXT	"webexdomainverification.8YX6G=6e6922db-e3e6-4a36-904e-a805c28087fa"
google.com.		3600	IN	TXT	"docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
google.com.		3600	IN	TXT	"v=spf1 include:_spf.google.com ~all"
google.com.		3600	IN	TXT	"atlassian-domain-verification=5YjTmWmjI92ewqkx2oXmBaD60Td9zWon9r6eakvHX6B77zzkFQto8PQ9QsKnbf4I"
google.com.		3600	IN	TXT	"google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o"

Querying MX records

To get a list of all the mail servers for a specific domain using the mx option:

% dig +nocmd google.com mx +noall +answer
google.com.		48	IN	MX	10 smtp.google.com.

Querying All Records

Use the any option to get a list of all DNS records for a specific domain:

dig +nocmd andrewbaker.ninja any +noall +answer
andrewbaker.ninja.	300	IN	A	13.244.140.33
andrewbaker.ninja.	21600	IN	NS	ns-1254.awsdns-28.org.
andrewbaker.ninja.	21600	IN	NS	ns-1514.awsdns-61.org.
andrewbaker.ninja.	21600	IN	NS	ns-1728.awsdns-24.co.uk.
andrewbaker.ninja.	21600	IN	NS	ns-1875.awsdns-42.co.uk.
andrewbaker.ninja.	21600	IN	NS	ns-491.awsdns-61.com.
andrewbaker.ninja.	21600	IN	NS	ns-496.awsdns-62.com.
andrewbaker.ninja.	21600	IN	NS	ns-533.awsdns-02.net.
andrewbaker.ninja.	21600	IN	NS	ns-931.awsdns-52.net.
andrewbaker.ninja.	900	IN	SOA	ns-1363.awsdns-42.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

Tracing DNS Resolution

DNS query resolution follows a simple recursive process outlined below:

  1. You as the DNS client (or stub resolver) query your recursive resolver for www.example.com.
  2. Your recursive resolver queries the root name server for www.example.com.
  3. The root name server refers your recursive resolver to the .com Top-Level Domain (TLD) authoritative server.
  4. Your recursive resolver queries the .com TLD authoritative server for www.example.com.
  5. The .com TLD authoritative server refers your recursive server to the authoritative servers for example.com.
  6. Your recursive resolver queries the authoritative servers for www.example.com, and receives 1.2.3.4 as the answer.
  7. Your recursive resolver caches the answer for the duration of the time to live (TTL) specified on the record, and returns it to you.

Below is an example trace:

% dig +trace andrewbaker.ninja

; <<>> DiG 9.10.6 <<>> +trace andrewbaker.ninja
;; global options: +cmd
.			62163	IN	NS	g.root-servers.net.
.			62163	IN	NS	j.root-servers.net.
.			62163	IN	NS	e.root-servers.net.
.			62163	IN	NS	l.root-servers.net.
.			62163	IN	NS	d.root-servers.net.
.			62163	IN	NS	a.root-servers.net.
.			62163	IN	NS	b.root-servers.net.
.			62163	IN	NS	i.root-servers.net.
.			62163	IN	NS	m.root-servers.net.
.			62163	IN	NS	h.root-servers.net.
.			62163	IN	NS	c.root-servers.net.
.			62163	IN	NS	k.root-servers.net.
.			62163	IN	NS	f.root-servers.net.
.			62163	IN	RRSIG	NS 8 0 518400 20221129170000 20221116160000 18733 . MbE0OpdxRbInDK0olZm8n585L4oPq3q8iVbn/O0S7bfelS9wauhHQnnY Ifuj3D6Owp6R7H2Om6utfeB2kjrocJG9ZQPy0UQhWvgcFp9I4KnWRr1L H/yvmSM2EejR7kQHp4OBrb55RBsX4tojvr1UU+fWRuy988prwBVBdKj6 EElNwteQCosJHxVzqP0z6UpP9i5rUkRNGOD7OvdwF8ynBV93F4FpOI9r yuKzz0hdE3YAQJztOY84VuLkXM2DPs51LR6ftibxswUwoeUg04QUS7py gzn1z9en99oUgX+Lic6fLKc5Q0LpeZGhW0qBCY2CB9KEaRth+ZCD6WEU tjOBCw==
;; Received 525 bytes from 8.8.8.8#53(8.8.8.8) in 249 ms

ninja.			172800	IN	NS	v0n2.nic.ninja.
ninja.			172800	IN	NS	v2n1.nic.ninja.
ninja.			172800	IN	NS	v0n0.nic.ninja.
ninja.			172800	IN	NS	v0n1.nic.ninja.
ninja.			172800	IN	NS	v2n0.nic.ninja.
ninja.			172800	IN	NS	v0n3.nic.ninja.
ninja.			86400	IN	DS	46082 8 2 C8F816A7A575BDB2F997F682AAB2653BA2CB5EDDB69B036A30742A33 BEFAF141
ninja.			86400	IN	RRSIG	DS 8 1 86400 20221130050000 20221117040000 18733 . xoEolCAm4d+f6LxulPa/lnCwKuwWLPI8LzlgmOVvMNL7z8J/21FqTWBu 4tZT8KZTciAvcTcRo3TDAg0Qr48QvJI30ld4yYa81HGHpVKVuTSoNCtn FnxvCuZmqDY+aFM/zn9jSTdCcT8EhwLJrsHq/zj/iasymLZ/UvanJo8j X/PRSorGfWJjUeDSSjCOpOITjRLqzHeBcY9+Qpf7O5fDguqtkhzc/8pS qKmjUh2B+yJA4QgDSaoxdv9LRQIvdSL1Iwq9eAXnl9azJy3GbVIUVZCw bA8ZsFYhw9sQbk39ZDi3K4pS717uymh4RBlk4r/5EuqdKBpWFYdOW4ZC EGDBcg==
;; Received 763 bytes from 198.41.0.4#53(a.root-servers.net) in 285 ms

andrewbaker.ninja.	3600	IN	NS	ns-1363.awsdns-42.org.
andrewbaker.ninja.	3600	IN	NS	ns-1745.awsdns-26.co.uk.
andrewbaker.ninja.	3600	IN	NS	ns-462.awsdns-57.com.
andrewbaker.ninja.	3600	IN	NS	ns-983.awsdns-58.net.
4vnuq0b3phnjevus6h4meuj446b44iqj.ninja.	3600 IN	NSEC3 1 1 10 332539EE7F95C32A 4VVVNRI7K3EH48N753IKM6TUI5G921J7  NS SOA RRSIG DNSKEY NSEC3PARAM
4vnuq0b3phnjevus6h4meuj446b44iqj.ninja.	3600 IN	RRSIG NSEC3 8 2 3600 20221208121502 20221117111502 22878 ninja. RIuQHRcUrHqMNg1lab6s/oRNmflV4e+8r2553miiZdlGqCl8Q05+e1f5 /AY0enkAaG4DvoXCAlwroL7B7iYgivgrmPXklPTEahnzdeZV76UWimRs 2WjKLI9DSUsSl5yPZBDloqYBxhQlHwY7RPcKxELX2wO7ld8Dk+cSpQIu CQQ=
dg8umbqgrvdemk76n4dtbddckfghtloo.ninja.	3600 IN	NSEC3 1 1 10 332539EE7F95C32A DGG261SH46I7K27S1MPEID8CER0BFH07  NS DS RRSIG
dg8umbqgrvdemk76n4dtbddckfghtloo.ninja.	3600 IN	RRSIG NSEC3 8 2 3600 20221130155636 20221109145636 22878 ninja. b3g1om7FYmaboSk49ZuQC/wiyuZ0zQXOs/HbfrtDP1wUGyvXMAG1ofik //wSTVEvi7bufrbKUCSkBrxiBweSkRIKokaB/5j90Izpb9znaN0MWmOQ gywML7TQ3etOWb9s8L/oUmiBUUUtBtPGAy/e4hsbuYKQt+awJZVhR4G/ GBM=
;; Received 691 bytes from 65.22.21.4#53(v0n1.nic.ninja) in 892 ms

andrewbaker.ninja.	300	IN	A	13.244.140.33
andrewbaker.ninja.	172800	IN	NS	ns-1254.awsdns-28.org.
andrewbaker.ninja.	172800	IN	NS	ns-1514.awsdns-61.org.
andrewbaker.ninja.	172800	IN	NS	ns-1728.awsdns-24.co.uk.
andrewbaker.ninja.	172800	IN	NS	ns-1875.awsdns-42.co.uk.
andrewbaker.ninja.	172800	IN	NS	ns-491.awsdns-61.com.
andrewbaker.ninja.	172800	IN	NS	ns-496.awsdns-62.com.
andrewbaker.ninja.	172800	IN	NS	ns-533.awsdns-02.net.
andrewbaker.ninja.	172800	IN	NS	ns-931.awsdns-52.net.
;; Received 328 bytes from 205.251.195.215#53(ns-983.awsdns-58.net) in 53 ms

As you can see above, the first set of results are the NS (nameservers) for the root domain (.), followed by the NS for .ninja, then finally the NS for andrewbaker.ninja (hosted in AWS).

Macbook: Show which applications have ports open and to what IP address

Below is a dump of examples of doing pretty much the same thing differently. I mostly use netstat and lsof, coupled with some bash scripts.

You can argue that this is overkill, but below is a simple bash function that you can paste into terminal and call it whenever you want to see which application/process IDs have open ports:

macnst (){ netstat -Watnlv | grep LISTEN | awk '{"ps -o comm= -p " $9 | getline procname;colred="\033[01;31m";colclr="\033[0m"; print colred "proto: " colclr $1 colred " | addr.port: " colclr $4 colred " | pid: " colclr $9 colred " | name: " colclr procname; }' | column -t -s "|" }

## Example: 
proto: tcp46 addr.port: *.8770 pid: 1459 name: /usr/libexec/sharingd proto: tcp4 addr.port: 127.0.0.1.9000 pid: 787 name: /Applications/Zscaler/Zscaler.app/Contents/PlugIns/ZscalerTunnel proto: tcp4 addr.port: 100.64.0.1.9000 pid: 787 name: /Applications/Zscaler/Zscaler.app/Contents/PlugIns/ZscalerTunnel proto: tcp6 addr.port: *.56365 pid: 1080 name: /usr/libexec/rapportd proto: tcp4 addr.port: *.56365 pid: 1080 name: /usr/libexec/rapportd proto: tcp4 addr.port: 100.64.0.1.9010 pid: 787 name: /usr/libexec/rapportd proto: tcp6 addr.port: ::1.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::1%lo0.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::244b:70ff:fe0a:ffaa%anpi2.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::244b:70ff:fe0a:ffa8%anpi0.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::244b:70ff:fe0a:ffa9%anpi1.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::109d:a6ff:fed1:244c%awdl0.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp6 addr.port: fe80::109d:a6ff:fed1:244c%llw0.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq proto: tcp4 addr.port: 127.0.0.1.53 pid: 784 name: /opt/homebrew/opt/dnsmasq/sbin/dnsmasq

Below is an alternative to the above using netstat:

$ netstat -ap tcp | grep ESTABLISHED 
tcp4 0 0 192.168.123.227.57278 52.114.104.174.https ESTABLISHED tcp4 0 0 100.64.0.1.cslistener 52.114.104.174.57277 ESTABLISHED tcp4 0 0 100.64.0.1.57277 52.114.104.174.https ESTABLISHED tcp4 0 0 100.64.0.1.57275 13.89.179.10.https ESTABLISHED tcp4 0 0 100.64.0.1.57262 40.79.141.153.https ESTABLISHED tcp4 0 0 100.64.0.1.57258 52.97.201.226.https ESTABLISHED tcp4 0 0 192.168.123.227.57250 52.113.194.132.https ESTABLISHED tcp4 0 0 100.64.0.1.cslistener 52.113.194.132.57249 ESTABLISHED tcp4 0 0 100.64.0.1.57249 52.113.194.132.https ESTABLISHED tcp4 0 0 100.64.0.1.57240 193.0.160.129.https ESTABLISHED tcp4 0 0 100.64.0.1.57239 jnb02s11-in-f6.1.https ESTABLISHED tcp4 0 0 100.64.0.1.57238 944.bm-nginx-loa.https ESTABLISHED tcp4 0 0 100.64.0.1.57237 159.248.227.35.b.https ESTABLISHED tcp4 0 0 100.64.0.1.57236 ip98.ip-51-75-86.https ESTABLISHED tcp4 0 0 100.64.0.1.57235 185.94.180.126.https ESTABLISHED tcp4 0 0 100.64.0.1.57234 a-0001.a-msedge..https ESTABLISHED tcp4 0 0 100.64.0.1.57233 a-0001.a-msedge..https ESTABLISHED

If you want to find the processes listening on a specific port, use the following:

sudo lsof -nP -i4TCP:9000 | grep LISTEN
ZscalerTu 787 root   49u  IPv4 0xfa4872984902c87f      0t0  TCP 100.64.0.1:9000 (LISTEN)
ZscalerTu 787 root   64u  IPv4 0xfa48729849d9138f      0t0  TCP 127.0.0.1:9000 (LISTEN)
## Then you can kill the process using: sudo kill -9 <PID>
sudo kill 787

Following the theme of creating bash scripts for the sake of it, below is a simple listening script:

listening() {
    if [ $# -eq 0 ]; then
        sudo lsof -iTCP -sTCP:LISTEN -n -P
    elif [ $# -eq 1 ]; then
        sudo lsof -iTCP -sTCP:LISTEN -n -P | grep -i --color $1
    else
        echo "Usage: listening [pattern]"
    fi
}

## Example
% listening 9000
ZscalerTu 38629     root   13u  IPv4 0xfa48729848a2f4bf      0t0  TCP 100.64.0.1:9000 (LISTEN)
ZscalerTu 38629     root   14u  IPv4 0xfa48729849edffcf      0t0  TCP 127.0.0.1:9000 (LISTEN)

Next up, using lsof to view TCP sessions (-i4 : IPV4; -n : prevent conversion to host name):

sudo lsof -i4 -n -P | grep TCP | grep ESTABLISHED
identitys  1205       cp363412   37u  IPv6 0xfa487293786896c7      0t0    TCP [fe80:16::c79c:1b6f:a073:9eca]:1024->[fe80:16::e858:3f4a:1724:69c1]:1024 (ESTABLISHED)
identitys  1205       cp363412   38u  IPv6 0xfa4872937868cb47      0t0    TCP [fe80:16::c79c:1b6f:a073:9eca]:1025->[fe80:16::e858:3f4a:1724:69c1]:1026 (ESTABLISHED)
identitys  1205       cp363412   39u  IPv6 0xfa4872937868cb47      0t0    TCP [fe80:16::c79c:1b6f:a073:9eca]:1025->[fe80:16::e858:3f4a:1724:69c1]:1026 (ESTABLISHED)
Google     2149       cp363412   20u  IPv4 0xfa48729848bee74f      0t0    TCP 100.64.0.1:58416->172.217.170.10:443 (ESTABLISHED)
Google     2149       cp363412   26u  IPv4 0xfa48729848bfb25f      0t0    TCP 100.64.0.1:58600->216.58.223.132:443 (ESTABLISHED)
Google     2149       cp363412   30u  IPv4 0xfa48729848aa938f      0t0    TCP 100.64.0.1:58388->151.101.3.9:443 (ESTABLISHED)
Google     2149       cp363412   33u  IPv4 0xfa4872984590512f      0t0    TCP 100.64.0.1:58601->216.58.223.132:443 (ESTABLISHED)
Google     2149       cp363412   35u  IPv4 0xfa487298489734bf      0t0    TCP 100.64.0.1:58602->172.217.170.170:443 (ESTABLISHED)
Google     2149       cp363412   36u  IPv4 0xfa487298489cf25f      0t0    TCP 100.64.0.1:58470->13.244.140.33:443 (ESTABLISHED)
Google     2149       cp363412   41u  IPv4 0xfa487298458fde9f      0t0    TCP 100.64.0.1:58231->172.217.170.10:443 (ESTABLISHED)
Google     2149       cp363412   42u  IPv4 0xfa48729848b25e9f      0t0    TCP 100.64.0.1:58451->142.250.27.188:443 (ESTABLISHED)
Google     2149       cp363412   45u  IPv4 0xfa48729848a8fd6f      0t0    TCP 100.64.0.1:58452->142.250.27.188:443 (ESTABLISHED)
Google     2149       cp363412   47u  IPv4 0xfa48729848b19c3f      0t0    TCP 100.64.0.1:58473->172.217.170.99:443 (ESTABLISHED)
Google     2149       cp363412   57u  IPv4 0xfa48729849ee1c3f      0t0    TCP 100.64.0.1:57722->192.0.78.23:443 (ESTABLISHED)
Google     2149       cp363412   60u  IPv4 0xfa4872984908325f      0t0    TCP 100.64.0.1:57973->198.252.206.25:443 (ESTABLISHED)
WhatsApp   2225       cp363412   21u  IPv4 0xfa4872984590674f      0t0    TCP 192.168.123.227:58288->102.132.100.60:443 (ESTABLISHED)
UPMServic  2333           root  248u  IPv4 0xfa48729848b1325f      0t0    TCP 192.168.123.227:56364->147.161.204.128:443 (ESTABLISHED)
Microsoft 25966       cp363412   44u  IPv4 0xfa48729849d9dc3f      0t0    TCP 100.64.0.1:58615->52.112.238.155:443 (ESTABLISHED)
Microsoft 37667       cp363412   20u  IPv4 0xfa48729849ef9e9f      0t0    TCP 100.64.0.1:58566->52.113.194.132:443 (ESTABLISHED)
Microsoft 37667       cp363412   22u  IPv4 0xfa4872984901887f      0t0    TCP 100.64.0.1:58378->52.112.120.216:443 (ESTABLISHED)
Microsoft 37667       cp363412   23u  IPv4 0xfa487298489e34bf      0t0    TCP 100.64.0.1:58536->20.42.65.84:443 (ESTABLISHED)
Microsoft 37667       cp363412   24u  IPv4 0xfa4872984591487f      0t0    TCP 100.64.0.1:58613->52.112.238.155:443 (ESTABLISHED)
Microsoft 37667       cp363412   27u  IPv4 0xfa48729848bed12f      0t0    TCP 100.64.0.1:58549->52.114.228.1:443 (ESTABLISHED)
Microsoft 37678       cp363412   51u  IPv4 0xfa487298489ddc3f      0t0    TCP 192.168.123.227:56382->52.112.120.204:443 (ESTABLISHED)
Microsoft 37678       cp363412   59u  IPv4 0xfa4872984902912f      0t0    TCP 100.64.0.1:56147->52.114.224.23:443 (ESTABLISHED)
ZscalerTu 38629           root    8u  IPv4 0xfa48729848bde74f      0t0    TCP 100.64.0.1:9000->52.114.228.1:58549 (ESTABLISHED)
ZscalerTu 38629           root    9u  IPv4 0xfa48729849061c3f      0t0    TCP 192.168.123.227:58330->13.244.131.129:443 (ESTABLISHED)
ZscalerTu 38629           root   10u  IPv4 0xfa48729848a9de9f      0t0    TCP 192.168.123.227:58550->52.114.228.1:443 (ESTABLISHED)
ZscalerTu 38629           root   16u  IPv4 0xfa48729849eea74f      0t0    TCP 100.64.0.1:9000->52.113.194.132:58566 (ESTABLISHED)
ZscalerTu 38629           root   17u  IPv4 0xfa4872984904f25f      0t0    TCP 192.168.123.227:58567->52.113.194.132:443 (ESTABLISHED)
ZscalerTu 38629           root   20u  IPv4 0xfa487298489e725f      0t0    TCP 100.64.0.1:9000->52.112.238.155:58613 (ESTABLISHED)

For analysing what is listening to a port lsof also gives you a short history of the state of the connection:

sudo lsof -i tcp:9000
COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ZscalerTu 53971 root   13u  IPv4 0xfa4872984902f4bf      0t0  TCP 100.64.0.1:cslistener (LISTEN)
ZscalerTu 53971 root   14u  IPv4 0xfa48729848bdf25f      0t0  TCP localhost:cslistener (LISTEN)
ZscalerTu 53971 root   18u  IPv4 0xfa487298489f112f      0t0  TCP 100.64.0.1:cslistener->147.161.204.128:63038 (ESTABLISHED)
ZscalerTu 53971 root   19u  IPv4 0xfa487298489f69af      0t0  TCP 100.64.0.1:cslistener->147.161.204.128:63036 (CLOSE_WAIT)
ZscalerTu 53971 root   24u  IPv4 0xfa4872984897674f      0t0  TCP 100.64.0.1:cslistener->a23-2-112-62.deploy.static.akamaitechnologies.com:63040 (ESTABLISHED)
ZscalerTu 53971 root   28u  IPv4 0xfa487298489d138f      0t0  TCP localhost:63045->localhost:cslistener (CLOSE_WAIT)
ZscalerTu 53971 root   29u  IPv4 0xfa4872984900912f      0t0  TCP localhost:cslistener->localhost:63045 (FIN_WAIT_2)

Above you can see port 9000 (the zscaler port); after I have restarted zscaler. It shows the state transitions of the port.

Macbook: MyTraceRoute an alternative ICMP route tracing which works with Zscaler / Zero Trust architecture

If your on a zero trust network adapter like zscaler or netskope, you will see that traceroute doesn’t work as expected. The article below shows how to install mtr (my trace route) using brew:

## Install xcode
xcode-select --install
## Install mtr
brew install mtr


Next we need to change the owner of the MTR package and it’s permissions (otherwise you will need to run it as root every time):

sudo chown root /opt/homebrew/Cellar/mtr/0.95/sbin/mtr-packet
sudo chmod 4755 /opt/homebrew/Cellar/mtr/0.95/sbin/mtr-packet
## Symlink to the new mtr package instead of the default MAC version
ln -s /opt/homebrew/Cellar/mtr/0.95/sbin/mtr /opt/homebrew/bin/
ln -s /opt/homebrew/Cellar/mtr/0.95/sbin/mtr-packet /opt/homebrew/bin/


To run a rolling traceroute with ICMP echo’s use the following:

mtr andrewbaker.ninja
Keys:  Help   Display mode   Restart statistics   Order of fields   quit
                                       Packets               Pings
 Host                                Loss%   Snt   Last   Avg  Best  Wrst StDev

The issue is that Zscaler will attempt to tunnel this traffic. This can be observed by viewing your current routes:

netstat -rn
Internet:
Destination        Gateway            Flags           Netif Expire
default            192.168.0.1        UGScg             en0
1                  100.64.0.1         UGSc            utun6
2/7                100.64.0.1         UGSc            utun6
4/6                100.64.0.1         UGSc            utun6
8/5                100.64.0.1         UGSc            utun6
10/12              100.64.0.1         UGSc            utun6
10.1.30.3          100.64.0.1         UGHS            utun6
10.1.30.15         100.64.0.1         UGHS            utun6
10.1.31/24         100.64.0.1         UGSc            utun6
10.1.31.3          100.64.0.1         UGHS            utun6
10.1.31.41         100.64.0.1         UGHS            utun6
10.1.31.101        100.64.0.1         UGHS            utun6
10.1.31.103        100.64.0.1         UGHS            utun6
10.10.0.11         100.64.0.1         UGHS            utun6
10.10.0.12         100.64.0.1         UGHS            utun6
10.10.160.86       100.64.0.1         UGHS            utun6

As you can see from the above, it lists the routes that are being sent to the Zscaler tunnel interface “utun6” (this is unique to your machine but will look similar). To get around this you can specify the source interface the MTR should run from with the “-I” flag. Below we instruct mtr to use en0 (the lan cable):

mtr andrewbaker.ninja -I en0
                                                                                                                                                                                                            Packets               Pings
 Host                                                                                                                                                                                                     Loss%   Snt   Last   Avg  Best  Wrst StDev
 1. unfisecuregateway                                                                                                                                                                                      1.8%    56    2.0   2.2   1.5   4.5   0.6
 2. 41.71.48.65                                                                                                                                                                                            0.0%    56    4.2   8.1   3.1  28.3   6.0
 3. 41.74.176.249                                                                                                                                                                                          0.0%    56    4.2   4.5   3.4   8.2   0.9
 4. 196.10.140.105                                                                                                                                                                                         0.0%    55    3.0   4.0   2.6  18.8   2.4
 5. 52.93.57.88                                                                                                                                                                                            0.0%    55    5.1   6.3   3.7  12.4   2.0
 6. 52.93.57.103                                                                                                                                                                                           0.0%    55    4.9   4.1   2.6  12.5   1.5
 7. (waiting for reply)
 8. 150.222.94.230                                                                                                                                                                                         0.0%    55    4.0   4.8   3.1  13.8   1.8
 9. 150.222.94.243                                                                                                                                                                                         0.0%    55    4.3   5.3   2.9  37.6   5.2
10. 150.222.94.242                                                                                                                                                                                         0.0%    55   15.2   4.9   2.9  15.2   2.2
11. 150.222.94.237                                                                                                                                                                                         0.0%    55    3.4   5.7   3.1  18.9   2.9
12. 150.222.93.218                                                                                                                                                                                         0.0%    55    4.6   5.5   3.8  11.4   1.3
13. (waiting for reply)

MTR supports TCP, UDP and SCTP based traceroutes. This is useful when testing path latency and packet loss in external or internal networks where QoS is applied to different protocols and ports. Multiple flags are available (man mtr), but for a TCP based MTR use  -T (indicates TCP should be used) and -P (port to trace to):

mtr andrewbaker.ninja -T -P 443 -I en0

Ping specifying source interface

Ping supports specifying the source interface you would like to initiate the ping from. The “-S” flag indicates that the following IP is the source IP address the ping should be done from. This is useful if you want to ping using an internal resource bypassing a route manipulator tool such as Zscaler.

ping outlook.office.com -S 10.220.64.37

Macbook: View the list of DNS nameservers used for resolution

To view the list of nameservers your mac is using, simply open Terminal and paste the following:

myMac ~ % scutil --dns | grep 'nameserver*'
  nameserver[0] : 100.64.0.1
  nameserver[0] : 9.9.9.9
  nameserver[1] : 1.1.1.1
  nameserver[2] : 8.8.8.8
  nameserver[0] : 9.9.9.9
  nameserver[1] : 1.1.1.1
  nameserver[2] : 8.8.8.8

Alternatively, you can copy the DNS servers to clipboard directly from the command line (using pbcopy):

networksetup -getdnsservers Wi-Fi | pbcopy

How to Backup your MySql database on a bitnami wordpress site

I recently managed to explode my wordpress site (whilst trying to upgrade PHP). Anyway, luckily I had created an AMI a month ago – but I had written a few articles since then and so wanted to avoid rewriting them. So below is a method to create a backup of your wordpress mysql database to S3 and recover it onto a new wordpress server. Note: I actually mounted the corrupt instance as a volume and did this the long way around.

Step 1: Create an S3 bucket to store the backup

$ aws s3api create-bucket \
>     --bucket andrewbakerninjabackupdb \
>     --region af-south-1 \
>     --create-bucket-configuration LocationConstraint=af-south-1
Unable to locate credentials. You can configure credentials by running "aws configure".
$ aws configure
AWS Access Key ID [None]: XXXXX
AWS Secret Access Key [None]: XXXX
Default region name [None]: af-south-1
Default output format [None]: 
$ aws s3api create-bucket     --bucket andrewbakerninjabackupdb     --region af-south-1     --create-bucket-configuration LocationConstraint=af-south-1
{
    "Location": "http://andrewbakerninjabackupdb.s3.amazonaws.com/"
}
$ 

Note: To get your API credentials simply go to IAM, Select the Users tab and then Select Create Access Key

Step 2: Create a backup of your MsSql database and copy it to S3

For full backups follow the below script (note: this wont be restorable across mysql versions as it will include the system “mysql” db)

# Check mysql is install/version (note you cannot restore across versions)
mysql --version
# First get your mysql credentials
sudo cat /home/bitnami/bitnami_credentials
Welcome to the Bitnami WordPress Stack

******************************************************************************
The default username and password is XXXXXXX.
******************************************************************************

You can also use this password to access the databases and any other component the stack includes.

# Now create a backup using this password
$ mysqldump -A -u root -p > backupajb.sql
Enter password: 
$ ls -ltr
total 3560
lrwxrwxrwx 1 bitnami bitnami      17 Jun 15  2020 apps -> /opt/bitnami/apps
lrwxrwxrwx 1 bitnami bitnami      27 Jun 15  2020 htdocs -> /opt/bitnami/apache2/htdocs
lrwxrwxrwx 1 bitnami bitnami      12 Jun 15  2020 stack -> /opt/bitnami
-rw------- 1 bitnami bitnami      13 Nov 18  2020 bitnami_application_password
-r-------- 1 bitnami bitnami     424 Aug 25 14:08 bitnami_credentials
-rw-r--r-- 1 bitnami bitnami 3635504 Aug 26 07:24 backupajb.sql

# Next copy the file to your S3 bucket
$ aws s3 cp backupajb.sql s3://andrewbakerninjabackupdb
upload: ./backupajb.sql to s3://andrewbakerninjabackupdb/backupajb.sql
# Check the file is there
$ aws s3 ls s3://andrewbakerninjabackupdb
2022-08-26 07:27:09    3635504 backupajb.sql

OR for partial backups, follow the below to just backup the bitnami wordpress database:

# Login to database
mysql -u root -p
show databases;
+--------------------+
| Database           |
+--------------------+
| bitnami_wordpress  |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
exit
$ mysqldump -u root -p --databases bitnami_wordpress > backupajblight.sql
Enter password: 
$ ls -ltr
total 3560
lrwxrwxrwx 1 bitnami bitnami      17 Jun 15  2020 apps -> /opt/bitnami/apps
lrwxrwxrwx 1 bitnami bitnami      27 Jun 15  2020 htdocs -> /opt/bitnami/apache2/htdocs
lrwxrwxrwx 1 bitnami bitnami      12 Jun 15  2020 stack -> /opt/bitnami
-rw------- 1 bitnami bitnami      13 Nov 18  2020 bitnami_application_password
-r-------- 1 bitnami bitnami     424 Aug 25 14:08 bitnami_credentials
-rw-r--r-- 1 bitnami bitnami 2635204 Aug 26 07:24 backupajblight.sql
# Next copy the file to your S3 bucket
$ aws s3 cp backupajblight.sql s3://andrewbakerninjabackupdb
upload: ./backupajblight.sql to s3://andrewbakerninjabackupdb/backupajblight.sql
# Check the file is there
$ aws s3 ls s3://andrewbakerninjabackupdb
2022-08-26 07:27:09    2635204 backupajblight.sql

Step 3: Restore the file on your new wordpress server

Note: If you need the password, use the cat command from Step 2.

#Copy the file down from S3
$ aws s3 cp s3://andrewbakerninjabackupdb/backupajbcron.sql restoreajb.sql --region af-south-1
#Restore the db
$ mysql -u root -p < restoreajb.sql

Step 4: Optional – Automate the Backups using Cron and S3 Versioning

This part is unnecessary (and one could credibly argue that AWS Backup is the way to go – but am not a fan of its clunky UI). Below I enable S3 versioning and create a Cron job to backup the database every week. I will also set the S3 lifecycle policy to delete anything older than 90 days.

# Enable bucket versioning
aws s3api put-bucket-versioning --bucket andrewbakerninjabackupdb --versioning-configuration Status=Enabled
# Now set the bucket lifecycle policy
nano lifecycle.json 

Now paste the following policy into nano and save it (as lifecycle.json):

{
    "Rules": [
        {
            "Prefix": "",
            "Status": "Enabled",
            "Expiration": {
                "Days": 90
            },
            "ID": "NinetyDays"
        }
    ]
}

Next add the lifecycle policy to delete anything older than 90 days (as per above policy):

aws s3api put-bucket-lifecycle --bucket andrewbakerninjabackupdb --lifecycle-configuration file://lifecycle.json
## View the policy
aws s3api get-bucket-lifecycle-configuration --bucket andrewbakerninjabackupdb

Now add a CronJob to run every week:

## List the cron jobs
crontab -l
## Edit the cron jobs
crontab -e
## Enter these lines. 
## Backup on weds at 12:00 and copy it to S3 at 1am (cron format: min hour day month weekday (sunday is day zero))
1 0 * * SAT /opt/bitnami/mysql/bin/mysqldump -A -uroot -pPASSWORD > backupajbcron.sql
1 2 * * SAT /opt/bitnami/mysql/bin/mysqldump -u root -pPASSWORD --databases bitnami_wordpress > backupajbcronlight.sql
0 3 * * SAT aws s3 cp backupajbcron.sql s3://andrewbakerninjabackupdb
0 4 * * SAT aws s3 cp backupajbcronlight.sql s3://andrewbakerninjabackupdb

Macbook: How to get your Mac to behave like MS Windows to restore minimised windows when using Command + Tab (Alt + Tab)

For those who like to maximise or minimise their windows on a Mac, you will likely be frustrated by the default behaviour of your Macbook (in that it doesn’t restore/focus minimised or maximised screens). Below are a few steps to make your mac screen restores behave like Microsoft Windows:

Install Homebrew (if you dont have):

## Install homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
## IMPORTANT: Once the install finishes run the two commands displayed in the terminal window
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $HOME/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Install AltTab:

brew install --cask alt-tab

Next run the AltTab application (click the magnify glass/search glass in the top right of your macbook (near the clock) and then type “AltTab”). When it starts up it will ask you to permission it to access the various system accessibility functions (ie window preview). If you don’t adjust the settings you will need to switch from using “Command + Tab” to using “Option + Tab”, or read the note below to adjust the settings…

Note: I recommend the following tweaks…

If you want to use the default windows style for tab keystrokes, you will need to change the “Controls” tab setting called “Hold” from “Option” to “Command” as per below:

Next, go to Appearance tab and change the Theme to “Windows 10” (as its hard to see the focus window on Mac style):

Note: detailed documents on AltTab can be found here: https://alt-tab-macos.netlify.app/

How to Automatically Turn your bluetooth off and on when you open and close your MacBook

If you’re like me, little things bother you. When I turn on my bluetooth headset and it connects to my Macbook when its closed/sleeping, I get very frustrated. So I wrote a simple script to fix this behaviour. After running the script below, when you close the lid on your Macbook it will automatically turn bluetooth off. When you open you Macbook it will automatically re-enable bluetooth. Simple 🤓

If you need to install brew/homebrew on your mac then run this:

## Install homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
## IMPORTANT: Once the install finishes run the two commands displayed in the terminal window
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $HOME/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

Script to automatically enable/disable bluetooth:

## Install the bluetooth util and sleepwatcher
brew install sleepwatcher blueutil
## This creates a file which switches bluetooth off when the macbook lid is closed
echo "$(which blueutil) -p 0" > ~/.sleep
## This creates a file which switches on bluetooth when the lid is open
echo "$(which blueutil) -p 1" > ~/.wakeup
## This makes both the files runable
chmod 755 ~/.sleep ~/.wakeup
## Finally restart the sleepwatcher service (to pickup the new files)
brew services restart sleepwatcher

Tip: Using the Watch command to poll a URL

If you want to quickly test a URL for changes, then the linux Watch command couple with Curl is a really simple way to hit a URL every n seconds (I use this for blue/green deployment testing to make sure there is no downtime when cutting over):

# Install watch command using homebrew
brew install watch
# Poll andrewbaker.ninja every 1 seconds
watch -n 1 curl andrewbaker.ninja