Jekyll2026-04-17T12:51:34+00:00https://dancocos.com/feed.xmlDan Cocos - Tech LeadershipAI Generated Code is Like an Offshore Team2026-04-16T07:00:00+00:002026-04-16T07:00:00+00:00https://dancocos.com/2026/04/16/ai-generated-code-is-like-an-offshore-team*Note this isn’t intended to drag on offshore teams. I’ve worked with many of them, with varying levels of quality and success, over my career.

I’ve been reading a lot of well-informed and skeptical posts about AI and where it will play a part in the near and distant future. It’s a long read, but I’ve really enjoyed The Future of Everything is Lies, I Guess. One of the points it makes is that AI essentially is just putting a bunch of tokens together in a way that sounds like it makes sense, and it never actually does any real thinking. This reminded me of a role where I worked with an offshore dev team, and the quality of code we got from them was usually pretty good, but you often had to guide them in the right direction.

I mentioned there were several examples of numbers being used with no real context for what they meant.

for (int i = 1; i <= 5; i++) {
    //Do something
}

if (i < 10) {
    //Do something
    }

I brought up on the call that we shouldn’t have numbers like 5 or 10 just sitting around; it should be a named variable. I was expecting

final int NUMBER_OF_RESULTS_PER_PAGE = 5;
final int MAX_NUMBER_OF_RETRIES = 10;

I looked at the code a few days later and saw this:

final int ONE = 1;
final int TWO = 2;
final int THREE = 3;
final int FOUR = 4;
final int FIVE = 5;
final int SIX = 6;
final int SEVEN = 7;
final int EIGHT = 8;
final int NINE = 9;
final int TEN = 10;

Sigh, this wasn’t a case of malicious compliance, and they did technically do what I’d asked. This result, though, is something that I’d expect from a vibe coding tool.

]]>
Tailscale Service Jellyfin Proxy2026-01-24T07:00:00+00:002026-01-24T07:00:00+00:00https://dancocos.com/2026/01/24/jellyfin-tailscale-service-proxy

If you want to securely watch video content served by Jellyfish over a Tailscale machine read on.

If it isn’t clear already I love Tailscale I setup a Jellyfin server on my home network, read about setting up ssl, the server running Jellyfin has a few other services running as well so Jellyfin is on port 8920 it’s annoying to have add a port to a URL and when serving up “family videos” to friends and family it’s a step beyond what they would think is reasonable. In comes Tailscale services.

First create a tag for this service. I named mine “jellyfin” you can assign a Tag Owner and description if you’d like.

Next define a service. I also named this “jellyfin” this name is what how you’ll access it in your browser https://jellyfin.name-example.ts.net/

Note the port should be 443 this is the port the TS service uses NOT the port you’re serving on your instance. define a service

Add the tag jellyfin as well.

Also add the tag jellyfin to the machine.

Now ssh into the instance running jellyfin sudo -i and run the following tailscale serve --service=svc:jellyfin -https=443 https://myserver.example-name.ts.net:8920

You should see something like this:

root@myserver:~# tailscale serve --service=svc:jellyfin -https=443 https://myserver.example-name.ts.net:8920
Available within your tailnet:

https://jellyfin.example-name.ts.net/
|-- proxy https://myserver.example-name.ts.net:8920

Serve started and running in the background.
To disable the proxy, run: tailscale serve --service=svc:jellyfin --https=443 off
To remove config for the service, run: tailscale serve clear svc:jellyfin

Open a browser and go to https://jellyfin.example-name.ts.net/ all done.

]]>
Browser Profiles for Fun and Profit2025-11-11T07:00:00+00:002025-11-11T07:00:00+00:00https://dancocos.com/2025/11/11/Browser-profiles-for-fun-and-profitThere are a handful of browser extensions that will give you cash back when you make purchases. The trade-off is that the extension follows you around the web all day, tracking your every move, not what I really want. Add into this that I use a Pi-hole that has pretty aggressive ad blocking turned on, and it breaks a lot of things.

What I tried

  • Chrome Profiles didn’t work because while you can have the browser source DNS from a different source, this changes it across all profiles.
  • Safari “Put App in the Dock” (not sure of the official name) didn’t work because you lose the URL bar.

Solution

Firefox profiles allow you to set DNS lookups per profile, so I have one named “Shopping” that has the shopping extensions installed and uses Cloudflare DNS, and when I want to buy something online, I use that browser to get the cashback while avoiding tracking and having to disable add blocking on the Pi-hole. The only problem I’ve noticed so far is that Apple Pay is hit or miss.

To set it up in Firefox put about:preferences#privacy in the URL bar. Scroll down to DNS over HTTPS, select “Increased Protection” and chose a provider.

Firefox DNS over HTTPS settings

]]>
GL.iNet Repeater Expander Nonsense2025-08-16T07:00:00+00:002025-08-16T07:00:00+00:00https://dancocos.com/2025/08/16/glinet-repeater-expander-confusionI added an update at the end

I recently picked up the Flint 3 router, and a Slate 7 to replace my aging Asus networking gear.

One thing I find incredibly frustrating is the lack of clear documentation of how to configure the Flint 3 as the primary and the Slate 7 as the secondary.

Intially set it up as a WDS node but that seemed to break pretty often and it appeared that you lost access to the admin interface on the Slate 7.

Based on a comment from GL.iNet employee I went with repeater mode. The keys to getting this off the ground.

On the Slate 7 change all of the network names to match the SSID of your Flint 3 and connect to repeater mode.

Things that broke the configuration and required me to have to connect with an ethernet cable or reset the Slate 7.

  • Do NOT enable MLO Wi-Fi on the Slate 7 this seems to break the repeater mode
  • Do NOT enable IPv6 on the Slate 7 this also seems to break things

Other things to note I set the IP of the Flint 3 router to 192.168.50.1. I left the default 192.168.8.1 config on the Slate 3 this is the address it answers on even when in repeater mode, it is given a 192.168.50.x address from the Flint 3 but it won’t answer on it. To make all of this a bit easier I have Tailscale installed on both routers and end up just using the hostnames to save me a lot of headache.

It does make me appreciate the simplicity of setting up the Asus routers in “mesh mode” where you simply made a few click in the app or web interface to add new nodes.

I’m still not sure if this is the best config but it seems to work for now. There are a few videos provided by GL.iNet but seem to be lacking in a few critical details like setting the SSIDs to all be the same.

update:

I went back to WDS mode mostly because I want everything on same subnet and I want the Flint 3 to handle all of heavy lifting, such as DNS and DHCP. I followed a suggestion on an openwrt forum and have a crontab that bounces the wifi if it goes down.

*/10 * * * * /bin/ping -c 1 192.168.50.1 || (/sbin/wifi down && /sbin/wifi up)

The only downside I’ve seen so far is that I can’t connect via ssh or https over Tailscale despite the fact that it is running on the Slate and I can see in the console. 🤷‍♂️ If anyone knows how to make that work it would be much appreciated. Update I can get there via local IP.

]]>
GL.iNet Tailscale Config2025-08-16T05:00:00+00:002025-08-16T05:00:00+00:00https://dancocos.com/2025/08/16/gl-inet-tailscale-setupI recently picked up the Flint 3 router, running OpenWrt, to replace my aging home networking gear.

The version of Tailscale supported by GL Inet/Openwrt isn’t very current. Thanks to Admonistrator Tailscale Update Script for GL.iNet Routers exists

BEFORE YOU RUN THE SCRIPT DO THE FOLLOWING

Go to Applications –> Click to Enable Tailscale Bind your account, it will process for a few minutes and should give you a link. Click on the link THEN run the script above.

Tailscale config menu

Now you can use a more up to date version of Tailscale, keep the scripts around because you’ll want to run them peridocially to keep up to date.

]]>
Basic Flint 3 Router Security2025-08-01T05:00:00+00:002025-08-01T05:00:00+00:00https://dancocos.com/2025/08/01/GL-Inet-Flint3-Router-ConfigI recently picked up the Flint 3 router, to replace my aging home networking gear. I didn’t find a complete guide to basic configuration I’d deem manditory out of the box.

The GL Inet “basic” interface is on ports 80/443 and the LuCI UI on 8080/8443. They seem to configue the same things just with different interfaces and different levels of details. On to enabling ssh with keys.

Using the LuCI interface you can add keys via the System –> Administraion menu. On the SSH Access tab, I suggest turning OFF

  • Password authentication
  • Allow root logins with password
  • Allow the root user to log in with password

On the SSH Keys tab you can, unsuprisingly add ssh keys.

On the HTTP(S) Access tab I suggest you enable “Redirect to HTTPS”

Save and apply everything, you should now be able to ssh in with root@hostname

Next up Tailscale and SSL Certs.

Follow the instructions in my post GL.iNet Tailscale Config before doing anyhing else with Tailscale.

For the basic GL Inet web interface and the Luci interface I run the following commands, of course change gl-be9300.EXAMPLE.ts.net to your host name.

/usr/sbin/tailscale cert gl-be9300.EXAMPLE.ts.net
cp gl-be9300.EXAMPLE.ts.net.crt /etc/nginx/nginx.cer
cp gl-be9300.EXAMPLE.ts.net.key /etc/nginx/nginx.key
service nginx restart
cp gl-be9300.EXAMPLE.ts.net.crt /etc/uhttpd.crt
cp gl-be9300.EXAMPLE.ts.net.key /etc/uhttpd.key
service uhttpd restart
]]>
Moving to Mint Mobile from Verizon2025-05-23T05:00:00+00:002025-05-23T05:00:00+00:00https://dancocos.com/2025/05/23/Mint-Mobile-from-VerizonA combo of my wife and I giving up our Apple Watches, a horrible experience with Verizon, where I was straight up lied to by several people while trying to get a carrier-subsidized phone, and a friend making fun of me for paying too much. I took the plunge and switched to Mint Mobile, note this is a referral link.

Everything from setup, to number porting to transfer was pretty easy, and my bill went from ~$200 a month to ~$45. At the max, it could be $60, but I looked at our usage, and I never hit over 15GB and wife 20GB. It includes the two things that are important to me as well: tethering and an option for seamless international travel.

Sure, I can’t get the carrier to subsidize my phone but’s not a big deal as I’ve always just bought my phones outright. It doesn’t take much math to figure out that $2500 a year vs $550 a year leaves a couple grand on the table to put towards a new phone.

]]>
Jellyfin SSL Tailscale2025-02-02T05:00:00+00:002025-02-02T05:00:00+00:00https://dancocos.com/2025/02/02/jellyfin-ssl-tailscaleI recently setup Jellyfin on an Ubuntu box at home. I wanted to use SSL certs and Tailscale for the web interface.

You’ll need to create a cert in pfx/pkcs12 format

Replace the servername with yours I put mine in a script

#!/bin/bash
cd /root
/usr/bin/tailscale cert server.example-example.ts.net
openssl pkcs12 -export -inkey /root/server.example-example.ts.net.key  -in /root/server.example-example.ts.net.crt  -out /etc/jellyfin/server.example-example.ts.net.pfx  -passout pass:
chmod 755 /etc/jellyfin/server.example-example.ts.net.pfx
service jellyfin restart

Then enable https Enable https

Once you’ve verirfied everything works you can force https Require https

]]>
Avoid Tracking - Best Bang for Your Buck2025-02-02T05:00:00+00:002025-02-02T05:00:00+00:00https://dancocos.com/2025/02/02/Best-Bang-for-Your-Avoiding-Tracking-BuckWith all of the changes, aka the 💩 show going on in the US right now, a few people have reached out asking how to be more secure online and avoid tracking. They usually start off with “What VPN should I use?”

The money spent by VPN companies on marketing appears to have worked, people think that using a VPN will protect their privacy online and that obscuring their IP address will somehow make them secure. They also seem to imply that doing so will block cookies as evidenced by an ad I saw on the Metro.

Cookies online are not blocked by a VPN

This is not to say that the VPNs don’t serve a purpose and that they aren’t good, hell I pay for a Mullvad subscription. These are broad generalizations but close enough for the general public to understand what VPNs do.

Work

Workplaces will often have your computer connect via a VPN. This covers four things.

  • Puts all of your traffic through a secure tunnel to a server controlled by your job.

  • Helps to insure that if you use an insecure protocol someone at the cafe can’t snoop on your traffic.

  • Usually has the benefit of forcing you to use their DNS which will let you find internal servers.

  • Lastly it allows them to control and see where you go online. This isn’t really bad per se it’s their computer they control it.

Home

Using a VPN at home (or from a cafe) does the following. This makes a few assumptions again but is generally true.

  • Funnels all of your traffic via a tunnel to the VPN sever, this hides where you are going from the cafe.

  • Usually you can chose the VPN exit location. This means you can use an IP address in another location. A common example is saying you’re in the US to watch localized Hulu.

  • Make you appear to the sites you are visiting that you are coming from a different location.

The tl;dr for VPNs it that you can appear to be calling from another place and share resources with other devices on your VPN but it doesn’t really block tracking.

How I Block Ads at the DNS Level

The VPN doesn’t really stop companies from tracking you, you’re basically spoofing the caller id but when someone picks up the line on the other side you’re still saying “Hi, I’m Dan how are you doing?” If you want to stop this type of tracking, usually done through cookies, you can mitigate a LOT of this via ad blockers. There are several browser plugins that can block ads and those work pretty well, but I prefer to nip to the problem in the bud by blocking ads at the DNS level.

When you load a web page it make a series of calls to multiple servers. I’m using CNN as an example but this is how most modern web pages work so there isn’t anything particularly nefarious about what CNN is doing.

CNN Loading page

I used HTTP Toolkit to gather all of the requests if you look you can see the initial request, GET, for www.cnn.com with the status 200 which means “OK” Let’s skip down and look at one of the GETs with a 🚫 icon. My snooping tool tells me me this about my request for https://get.s-onetag.com/c15ddde9-ec7d-4a49-b8ca-7a21bc4b943b/tag.min.js

The upstream server hostname could be not found, so HTTP Toolkit did not forward the request. This typically means the host doesn’t exist, although it could be an issue with your DNS or network configuration.

This means that when it tried to look up the server using DNS (what translates names to IPs) that it came back empty. I wouldn’t call this an “issue” with my DNS or network configuration but instead a feature. I use the software tool Pi-hole to lookup my DNS requests. Pi-hole maintains a list of servers that are specifically used for ad-tracking and when requested tells my browser “nope that doens’t exist” This is very effective in cutting down tracking because requests to share your info are not able to phone home.

How pervasive is this you may ask? Of the 60 requests my browser made to request the page 40 of them were to tracking services. (╯°□°)╯︵ ┻━┻)

Why do I prefer DNS blocking vs browser ad blocking you may ask? Well because it not only works in my browser, but in my email, on the devices I use around the house including things you never really think about, like your TV.

What are the downsides blocking ads on the DNS level? It will sometimes break things, you can make exceptions for those sites you want to report back to or in the case of Pi-hole temporarily disable the blocker for a while to see if it is even problem. Some sites can detect that you’re blocking ads and will show you a popup. Sometimes it will let you through trying to guilt you into unblocking their site and other times it won’t. ¯_(ツ)_/¯

Imgur add blocking modal

I realize not everyone has the desire or skills to run a Pi-hole what can they do? There are services that offer similar functionality to a Pi-hole. One of them that a lot of people recommend is NextDNS I’ve not personally used them nor am I getting paid or a referral bonus to recommend them but they have a free tier you can try and the paid tier is $19.90 a year.

Does this mean you can’t be tracked online all together? Not really the EFF’s Cover Your Tracks will give you a better idea of what’s going on.

Have questions or is something I said blatantly wrong shoot me an email.

]]>
DOIO KB 16 aka Megalodon Triple Knob Macropad Setup and Review2024-12-27T05:00:00+00:002024-12-27T05:00:00+00:00https://dancocos.com/2024/12/27/DOIO-kb-16I was lucky enough to receive a Megalodon Triple Knob Macropad for Xmas from my brother in law. I was excited to set it up and start using it but information was more difficult to find than I had hoped and what I did find were mostly product reviews. Here is what I’ve learned from a day or two of using it with macOS. There may be finer points that I missed so feel free to email me or comment on my post to give any advice or correct any errors.

I use Karabiner Elements with my Keychron K6 and I’ve been happy with it so I was hoping to tack on to that and not need to run another app. All roads and the suggestion from the manufacturer lead to VIA.

The Device in question

Using VIA

There are two ways to use VIA to configure your keyboard. You can use it in the browser Use VIA or you can grab the release from Github.

The VIA app doesn’t run in the background like KE. It simply configures your device and going forward you no longer need to run the app, once I had this epiphany I was pleasantly surprised. The app just configures key mappings and macros for your HID profile for the device. This has some advantages, the main one being you can move it from machine to machine and not have to worry about installing the software on each machine and keeping the configs up to date everywhere since the config is on the device. The disadvantage and where this differs from something like the Stream Deck is that you cannot have direct application integration via the background app. For example the Stream Deck can call scripts running locally on my computer or poll the CPU. (You probably could create some very fragile macro but meh) This led to some initial disappointment as one of the things I really wanted to use it for was to launch apps or browsers directly to a URL from the buttons.

So many inputs

Enter macOS Shortcuts

macOS has a feature “Shortcuts” you can pretty easily create shortcuts which can interact with most apps8 running on your computer. For example I wanted to map a key launch a browser that opens my company’s help desk. It’s simple enough to do with shortcuts. The next step is to assign a key mapping to that shortcut. It’s pretty to make a key combo that you’ll never likely use <control>+<option>+<command>+h for example. This is a very basic example as you can create very complex Shortcuts depending on your needs. This combined with Choosy is pretty powerful. *I’ll have to write up something for Choosy later.

]]>