OpenWRT Switches From iptables To nftables!

So after many years of using and learning iptables, one of my favourite firewalls, I had to translate my command line ruleset into a new format/syntax. It wasn’t too bad but with the added power and flexibility of nftables, it can be harder to find the order/priority of the rules for a given filter hook, for example, INPUT. However, I really appreciate how the new firewall incorporates some previous features that I used to have to install via iptables modules like ipset and hashlimit, which provides the rate limiting functionality!

hook="input"
nft list ruleset                               \
  | sed -e 's/counter.*[0-9]//g'               \
  | tr '\t' ' ' | tr '\r\n' '~' | tr '{}' '\n' \
  | grep -i "hook.${hook}"                     \
  | tr '~' '\n'                                \
  | grep -i '[a-z]'                            \
  | sed -e 's/^[ ]*//'
type filter hook input priority filter; policy accept;
iifname "lo"  accept
iifname "lan" udp dport 67  accept
iifname "wan" ct state established,related  accept
drop
OpenWRT Switches From iptables To nftables!

Hacky – Restart Network Interface On OpenWRT

So on OpenWRT for example, a WAN interface can be set get an IP address via DHCP, however, this will launch a separate independent process on Linux to act as the client. On the web interface, there is a button on each network interface which allows you to restart that individual interface (and in addition, it will be smart enough to kill the previous client process and launch a new one as well as re-initialize the firewall and other stuff). I could not find the equivalent command line option to this as a simple ifdown/sleep/ifup would not capture all of these sub-actions as per the extra configurations set on the interface. So I searched and read a helpful hint that can give a similar workaround using the network init startup script. You can modify some small part of the network interface configuration and then call network reload which will be smart enough to pick up the diff/changes only. This helps greatly in case you need to script or schedule a specific interface restart:

#!/bin/sh
r=$(/bin/date | /usr/bin/md5sum | /usr/bin/cut -c 1-8)
/sbin/uci set network.wan.hostname="owrt${r}"
/sbin/uci commit network
/etc/init.d/network reload
Hacky – Restart Network Interface On OpenWRT

Local HTTP Proxy Server – Bypass Host Regex Match – Multi Destination Client Connection

No usage documentation, however, posting this for historical purposes:

#ok:www.google.com:false
python3 proxy.py ~/.proxy.txt host:port
export https_proxy='http://127.0.0.1:9090'
import os, sys, re
import select, socket, socketserver


class proxysrv(socketserver.BaseRequestHandler):
    def init(self):
        self.size = (8 * 1024)
        self.file = sys.argv[1]
        self.info = sys.argv[2].split(":")
        self.host = (self.info[0], int(self.info[1]), True)
        self.sock = self.request

    def config(self, file):
        proxlist = []
        try:
            fobj = open(file, "r")
            for line in fobj.readlines():
                line = line.strip().split(":")
                stat = False
                if ("true" in line[2].lower()):
                    stat = True
                proxlist.append([line[0], line[1], stat])
        except:
            print("error","config")
        return proxlist

    def checks(self, conf, data):
        try:
            proxyreq = data.decode().split("\n")
            hostreqs = proxyreq[0].strip().split(" ")
            hostinfo = hostreqs[1].split(":")
            hostname = hostinfo[0]
            hostport = int(hostinfo[1])
            lasthost = ()
            for item in conf:
                regx = re.match("^.*%s$" % (item[1]), hostname)
                if ((item[0] == "no") and (not regx)):
                    lasthost = (hostname, hostport, item[2])
                if ((item[0] == "ok") and regx):
                    lasthost = (hostname, hostport, item[2])
            if (lasthost and (not lasthost[2])):
                return lasthost
        except:
            print("error","checks")
        return self.host

    def newcon(self, srcs, data, host):
        try:
            senddata = "HTTP/1.1 200 Connection established\r\nProxy-Connection: Keep-Alive\r\n\r\n".encode()
            sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sockobjc.connect((host[0], host[1]))
            if (host[2]):
                sockobjc.sendall(data)
            else:
                srcs.sendall(senddata)
            return sockobjc
        except:
            print("error","newcon")
        return None

    def relays(self, srcs, dsts):
        try:
            while True:
                (readlist, _, _) = select.select([srcs, dsts], [], [])
                for sockitem in readlist:
                    if (sockitem == dsts):
                        data = dsts.recv(self.size)
                        print("dsts",len(data))
                        if (not data):
                            raise
                        srcs.sendall(data)
                    if (sockitem == srcs):
                        data = srcs.recv(self.size)
                        print("srcs",len(data))
                        if (not data):
                            raise
                        dsts.sendall(data)
        except:
            pass

    def handle(self):
        self.init()

        proxlist = self.config(self.file)
        recvdata = self.sock.recv(self.size)
        desthost = self.checks(proxlist, recvdata)
        sockobjc = self.newcon(self.sock, recvdata, desthost)

        print("addr",self.client_address)
        print("data",recvdata)
        print("host",desthost)

        if (sockobjc):
            self.relays(self.sock, sockobjc)


if (__name__ == "__main__"):
    for e in ["http_proxy", "https_proxy", "no_proxy"]:
        for v in [e.upper(), e.lower()]:
            print("envr",v)
            os.environ[v] = ""

    sockobjc = socketserver.TCPServer(("127.0.0.1", 9090), proxysrv)
    sockobjc.serve_forever()
Local HTTP Proxy Server – Bypass Host Regex Match – Multi Destination Client Connection

Bored on Reddit and submitting funny coding comments

So there was a Reddit thread today that was diverging into bad coding tests plus grade evaluation puns (C++) – so I tried to make a purposefully confusing C program behave in a way that a coder or programmer wouldn’t exactly expect. After I wrote it, I had to put in some for-loop-printf-debug statements just to confirm and demonstrate how the right-to-left side value-lookup to delayed-increase to index-assignment works in C, it’s pretty neat to try and analyze how and why this is “working” lol!

#include <stdio.h>
int main()
{
    char A = 'A', B = 'B', C = 'C', D = 'D', E = 'E', F = 'F';
    char grades[256];
    grades[A++] = A++;
    grades[B++] = B++;
    grades[C++] = C++;
    grades[D++] = D++;
    grades[E++] = E++;
    grades[F++] = F++;
    printf("My grade is %c!\n",grades[C++]);
}

And basically this will print out “My grade is D!” – but it’s fun to trace through how each line will process the value statement first and then the assignment index is processed afterwards. In addition, each line will affect the next statement below because of the increases that take place in between processing sides, so the future lookup index values are being changed along the way! 🙂

Bored on Reddit and submitting funny coding comments

Another Helper App – BrowserBot

So, there was one more app I needed to complete my personal trilogy, and it’s named BrowserBot! It’s an app that will help “curl” the web for any page you’d like to monitor for changes, and you can feed it custom commands (similar to ClippyCommand) so it will parse out any field/value you specify. I had scripts running in a crontab to do this but I wanted a more centralized and official place to quickly view the latest and refreshed web data that I was interested in tracking for security reasons!

Source Code: github.com/stoops/BrowserBot

Another Helper App – BrowserBot

A new MacOS app – ClippyCommand!

So as a Mac/Linux/BSD fan, I’ve posted a few different Microsoft related creations/customizations that I use as a daily reminder of the good old days! Even though I wasn’t the biggest fan of Windows and Explorer, I still tried to make some dock icons to appreciate and represent both of them in the future. I was just missing one last memory of mine, which was, Clippy! I created a new MacOS app that allows you to pipe the copy-paste buffer into a set of your own customized bash shell command line programs and it will rewrite the paste buffer so you are ready to go! This is the second custom app in my dock, along side my DynaDock application.

Source Code: github.com/stoops/ClippyCommand

Some of my more useful and commonly used editing/formatting commands!

A new MacOS app – ClippyCommand!

A World Of Different Switches

So I recently ordered a Drop Alt keyboard with Halo True switches as it offered the ability to hot-swap them out. The case and frame is much more stable and solid compared to the Ducky Mini and it produces a much more clunky-analogue, type-writer kind of sound. I put in some Holy Panda switches and they have a greater feeling tactile bump at the start of the key travel along with a slightly lighter spring force for an easier press downwards. Both are great switches to type on overall!

Edit: For comparison, the Cherry Brown switch has a tactile resistance during the key travel, but the bump in the beginning is not as noticeable or pronounced as to what some of the other switches offer and the spring force is much lighter.

A World Of Different Switches

My first real mechanical keyboard!

Intro: So, I know I’m a little late to the game in terms of getting a mechanical keyboard, however, I thought it would be a good investment to have a quality one just in case while WFH. I picked up one of those Ducky One-2-Mini keyboards in a white color and it offers some great built-in-hardware features. There are some random color-matching keys that come with it which can make it look a little bit more vintage / retro / classic. It’s not the lowest-profile one but the PBT keycaps are great quality and hug your fingers!

Pros:

  • Programmable and saveable profiles
  • Swappable key mappings for caps/ctrl/alt/cmd/fn
  • Individually lit and bright RGB color patterns for every key
  • Cherry MX Brown Switches with a serious sound and tactile travel
  • Solid key stabilizers and firm case frame
  • Lays flat plus two levels of height adjustment all with rubber feet
  • USB-C detachable-cable + firmware updates

Mods:

  • Remapped dedicated arrow keys, removed one stab set
  • Added some extra PBT keycap colors
  • Added one O-Ring to the space-bar keycap stem
  • Removed the top case cover piece
  • Replaced the bottom case feet with more medium-sized felt-pads
  • Taped small pieces cut out from the keyboard box inside the bottom case
  • Purchased some M3-Sized self-tapping screws for more secure plate mounting

Cons:

  • Not filled with foam inside the keyboard case
  • Not hot-swappable switches
  • Not screw-in stabs

Mod-Sound(Impact): I placed a single O-Ring on the space-bar and it sounds much less hollow and more gentle, similar to a regular key press. I was able to replace the bottom rubber feet with felt pads and the resulting feel and sound is much softer and warmer. I also taped some thin pieces of cardboard cut out from the keyboard box to the inside of case so that the key presses sound a bit deeper and quieter as they are absorbed and dampened.

Mod-Sound(Airborne): I removed the top cover piece which greatly reduces and lessens the amount of sound wave interference that bounces around down within the inside of the case. From the mounting plate upwards, the top portion of the switch and keycap now sit at the highest point on the keyboard. You can hear a little spring ping if you listen closely along with slightly rougher switch noise, but the sound can now directly travel outwards and away from the keys and case, unobstructed. Each key press has a greater distinction and clarity to it, thus making it a much quieter and smoother typing experience.

Mod-Visual(Keycaps): So after spending some time with this little keyboard, I was able to remap dedicated arrow keys to be on the right side while keeping the main modifier keys on the left side (I also remapped caps lock key to be a backup fn key, as this setup is geared more towards coding on the mac). I purchased some extra keycap colors although it would be nice to find some properly wide arrow keys in the future!


Finale: It’s a pretty good MK overall esp for just a stock unit. I wish I could get one of the ones like Taeha makes as they sound soo super smooth and clean and crisp — mechanical contact points only. He’s able to lube all of the sub-components like springs, switches, stabilizers and basically eliminate or reduce most of the noises, thus creating some purrre asmr — buttery sounding — Holy Pandas! (:

¯\_(ツ)_/¯
My first real mechanical keyboard!

Exploring GIT Commit Hashes & Generating Cryptographic Zeros

So I was trying to research what goes into generating a GIT commit hash and I thought I would try to personalize the cryptographic hash output a little bit. My computer isn’t that powerful but it may be possible to generate more zeros!

import time, hashlib, subprocess

head = subprocess.check_output("git cat-file commit HEAD | sed -e 's/> .*$/> %d %s/'", shell=True)
secs = int(time.time())
rnds = (secs - 99999999)
offs = "-0500"
begs = ("0" * 6)
ghsh = ""

while (not ghsh.startswith(begs)):
    rnds = (rnds + 1)
    comm = (head % (secs, offs, rnds, offs))
    data = ("commit %d\0%s" % (len(comm), comm))
    ghsh = hashlib.sha1(data).hexdigest()

chk = raw_input("Commit hash [%s]?: " % (ghsh)).strip()
if (chk.lower().startswith("y")):
    comd = ("GIT_COMMITTER_DATE='%d %s' git commit -a --amend --no-edit --date='%d %s'" % (rnds, offs, secs, offs))
    subprocess.call(comd, shell=True)
Exploring GIT Commit Hashes & Generating Cryptographic Zeros