Sunday, November 3, 2024

Fork, Knife, TetherFi

Hey there, been a little bit.

A lot has happened in the world of pyamsoft, so lets get right down to business.

First thing's first, TetherFi is currently in version 49 beta on the Play Store. This release is particularly important as it brings new support for a few cool features:

1. Proxy over RNDIS: A long standing GitHub issue has been finally closed with this release - you can share your TetherFi proxy connection over USB Tethering/Ethernet instead of requiring Wi-Fi to be on and using Wi-Fi Direct. Currently this is an "Expert" level setting, so many people will not need to change it, especially if you do not know what it is. But, if this is a use-case you are interested in, the new 49 when it releases will support this.

2. Proxy over Cellular Data: Other past requests have wished that the proxy connection could use only cellular data while still ensuring that the device stays connected to a Wi-Fi network. With changes in 49 you will now be able to request that proxy connections go over cellular data strictly. To implement this, I had to do some interesting code changes in the KTOR library that TetherFi uses - more on that in a bit.

3. There has also been a long-standing crash issue on the Connection screen in the release 47 that I have been unable to pinpoint - it causes about 5% of users to crash sometimes and leads to instability (and reports from Google in the store Vitals). This release should fix the crash or at least lessen the chances of it occurring - but since I can't consistently reproduce it - who knows. I will keep looking.


Regarding forking KTOR - I have a simple fork of KTOR which applies 2 commits over the latest tagged release version and applies a single 1-line change. It is only supported for JVM, specifically for Android, and I will do absolutely zero support regarding the fork. This single line change added the ability for me to grab a socket BEFORE it was connected but AFTER it was built, so that I could then implement support on the Android side for binding a Socket to a Network connection.

If you are curious, see here and here

Future work on TetherFi will hopefully finally bring support for SOCKS connections. Like HTTP, SOCKS is just another way to connect devices together, but one important difference for SOCKS is that it has "generic" network support for just about anything - including UDP connections. A working SOCKS4/SOCKS4a/SOCKS5/SOCKS5H (at least for connect()) is currently on the developer mode branch for 49 and I look to release a version 50 with full production support. Finally after so many years, progress is being made on this issue

Other software of note these past few months have been the following for Linux systems

pstate-frequency gained support for the new amd-pstate driver's core-boost functionality. On supported Linux kernels (6.11+) you will be able to also set the turbo boost state for AMD CPU using amd-pstate as the driver.

I released iptables-geoblock, which is a simple shell script that uses an xtables DKMS module to block connections from IP addresses based on the country. I use this in my homelab/VPS setup to block connections from any countries that I do not reside in currently - because no legitimate users need access from outside of my friendship circle.

I released poke-monitor which I use on Linux to "wake up" my DP connected monitor after suspend. Before, after suspend, my DP monitor would just stay on a lit up black screen. Linux seems to have weird issues with this for whatever reason, but basically "poking" the monitor with something like xrandr to query the EDID seems to fix it. Though I don't run dual monitors anymore (1 large 34"), it was particularly helpful when I did.

I released adjust-pci-latency which is a micro-optimization tool that collects recommendations from the ArchLinux wiki around performance tuning for PCI devices and ships it as a simple script. You can use it to "finetune" your PCI devices for things like gaming (lower latency) or supposedly even realtime pro-audio production (though I lack the hardware for this and cannot actually confirm this).


Lots more changes in the future, and life gets busier and busier still. More to come.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Wednesday, May 1, 2024

TetherFinally

Hey, it's been a little while.

Back in February I started a new full-time day job, so updates both code and blog have obviously been sparse and slower. I did finally manage to get some stuff released though.

For nerds, PYDroid 27 is published which brings support for Material3 UI. The Material2 days are behind us now, but the M3 widgets are basically the same. Material You is supported but optional.

This new M3 support is best reflected in the newly beta released update to TetherFi, version 41. This version brings full Material3 and Material You support, and adds some new features.

The "Stubborn Proxy" optional tweak is being made default, so it will be On unless you explicitly turn it off. In a future TetherFi version, this tweak will be removed completely, since I believe the option works very well. The "Bind to All Interfaces" tweak has been turned off, and will be removed in the next version, as the default configuration is now faster and more reliable than the tweak was.

One significant feature additional is the ability to track and monitor the amount of data used by connected devices. You will be able to monitor how much data the connected device sends to and receives from the Internet. This feature work is done in preparation of a future feature additional requested by a community member on GitHub to implement Bandwidth limits.

Now that this release is out the door I can continue work on my two other apps, which have still not been released public as I am trying to figure out the final few steps to take them from "cool toy" to actual "production product", which is always the most-fun-but-most-time-consuming step of the process. Having new commitments at a new job doesn't do me any favors here - but I digress.

We'll get there when we get there!

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Sunday, February 18, 2024

Split Up Your bashrc

Have you ever found yourself in this situation?

You add a new line to your .bashrc to use some cool new something, you close your terminal, and then the next time you go to open your terminal, it crashes because something was invalid in your bashrc.

Bummer.

I'm here with a hot take today - you should split your bashrc up into individial "drop-in" config style files instead, so that you can:

1. Have cleanly separated responsibilities in each rc dropin file
2. Avoid killing your entire bashrc because of one bad line.

You can see how I use dropin config files as well as the contents of the dropins here.

By setting up my bashrc, bash_profile, and general environment files using the drop-in style, I can easily maintain and change one part of my configuration without worrying about it effecting another section - kind of like code.

More code stuff someday.
Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Wednesday, February 7, 2024

PXE and XYZ

If you are a giant nerd like I am, you may have dabbled with PXE boot to launch systems off of network devices instead of installing an operating system on to a physical drive.

Nerd.

Anyway, if you manage a fleet of devices all via PXE or you have a virtualized cluster or do whatever else in your lab with a random set of machines, you've probably heard of netboot.xyz. If you haven't you may be making life more difficult than it has to be.

You can set the image up in a container on a central machine, host whatever your custom standard image packages are supposed to be, and then deploy image updates centrally through the xyz delivery so that way you don't need to carry and pass around a USB stick, or deal with mass email chains about what the latest PXE should be.

Plus it's fun.

If you like that kind of thing, you nerd.


Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

TetherFi and the Older Devices

TetherFi supports "old" versions of Android, all the way down to Android N which was released in 2016! As far as developer toolchain is concerned, N is still "new enough" that most modern Android features work.

Recently though I was testing TetherFi on an Android N emulator and noticed that some visual differences made the app a little tricky to use on older versions.

For one thing, the bottom Navigation used in old versions of Android was showing as completely transparent in Light mode! White buttons on a white background are very hard to see. This is because TetherFi requests that the Navigation bar itself be completely transparent, and requests that the Navigation bar paint black icons using the new AndroidX compat edgeToEdge method.

What I didn't notice because I failed to read the documentation, or the documentation failed to note, is that while a Transparent Navigation bar works just fine on old Android N, the black-icon change does absolutely nothing! In the code it is intentionally left blank, a no-op. Thanks AndroidX.

A change in a developer version that should become the future version 41 will make the bar semi-transparent on older versions of Android to account for the fact that the dark icons do not show up.

Similarly, light status icons were not taking effect properly on old versions of Android, and various areas on screen which displayed some "fallback" text for unsupported features were very hard to read.

While modern Android feels like it is now at least Android 9 and above, all pyamsoft Android applications (currently only 1 public one :( ) will continue to support down to Android 7 (N) as long as it is feasibly possible.


The new TetherFi update will hopefully be arriving "soon TM".

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Tuesday, February 6, 2024

Running an OpenRCT2 multiplayer server from a jumphost

So, you want to run an OpenRCT2 server ey?
And you have a cheap remote VPS with a public IP, but you run all your server stuff selfhosted at home with a more powerful machine because VPS costs are bullshit ey?
Well, come take a looksie, here's how I got things to "kind-of-work".

I say "kind of" because there are still some issues, namely:
1. Effectively zero security :(
2. Manual park setup and pause/unpause :(
3. Unusable IP logs because all IPs connect as the VPS from the proxy :(

What I had to start:
1. A public domain name and IP address (I use an AWS Lightsail VPS)
2. Your selfhosting machine (I use a second computer at home)
3. A third, "client" machine to play the game with
4. Patience and some shell scripting ability

What I did to get things working:
1. Purchase Roller Coaster Tycoon 2 on Steam
2. Build a local podman container of OpenRCT 0.4.8 on your selfhosting machine
3. Launch the OpenRCT server using the container on your selfhosting machine
4. Setup a reverse proxy on the VPS and connect it with the selfhosting machine

Let's dive in!


1. A public domain name and an IP address

First you'll need a public IP address and preferably, a world-resolvable domain name. I use AWS Lightsail because they cost 5 dollars a month for Amazon backed unmanaged-hosting (soon to be 7.50 because of IPv4 migration costs). Not an advertisement, but just letting you know what I work with. Debian 12 running on a weak little VPS. I bought a domain name from the Cloudflare Registry, turned off the Cloudflare proxy (because non HTTP traffic through the Cloudflare proxy is against their TOS), and we are off to the races!

2. A selfhosting machine at home
My selfhosting machine is a server box running at home. I run as AsRock DeskMini X300 that I've wired into the wall with Cat 5, and swapped the Wifi card out for an Intel AX210. Running on a Ryzen 5600G that I've TDP limited to 35W. Again, not too important - you are hosting a multiplayer server for a 30 year old game.

3. Buy the game. You'll need Roller Coaster Tycoon 2, which I bought on Steam. Download the OpenRCT2 client as well (the latest at this time is 0.4.8). Make sure the game runs on your machine.

4. Launching the game as a dedicated server.
Ok finally.

So, we are going to spin up a container for the dedicated server, and run the container on our selfhosting machine. To do this, we will first need to build the OpenRCT2 server container, because while OpenRCT2 publishes the image on Docker Hub, it hasn't been updated since 0.4.4 (the latest at the time of writing is 0.4.8)

4a. First you'll need to build the OpenRCT2 container on your selfhosting machine. To do this easily for myself, I've written a small dockerize script, though you can roll your own - whatever gets 0.4.8 in a container on your machine.

4b. Next you'll first need to create a new save. First you'll need to launch the client and start any scenario you want. Immediately save the game. Find the OpenRCT2 game folder on your machine (for me it was in $HOME/.config/OpenRCT2), and copy the saved .park file out of the save directory.

4c. Volume mount the save file to the OpenRCT2 container, and launch the container as a dedicated server, providing it the file to your park. For this, I use a runner script.

4d. At this point your dedicated server should be running. You can test it by launching the game client, and clicking the "Add Server" button, providing localhost as the server address.

4e. You might notice when you connect that your game is paused. In order to unpause the game, you'll need to type into the openrct2> console in the container that is running (you allocated a PTY and attached stdio didn't you?), and issue the command context.executeAction("pausetoggle", {});

4f. You may also notice your connected player joins as a "Spectator", unable to do anything. To fix this, you need to grant your player admin level access to the Scenario, by running network.players[1].group = 0 in the openrct2 container console.

5. Opening the server to the world for others to join you
What's multiplayer without other players? This is the "port-forwarding" step, but a bit more complex.
You'll need a way to proxy raw TCP traffic from your VPS machine to your selfhosted machine. This was a little tricky for me, as I run Caddy for HTTP related proxy stuff, but Caddy doesn't speak raw TCP (it's a layer thing), so I needed something else. I decided to use frp.

5a. Run frps on the VPS

5b. Run frpc on the selfhosted machine

5c. Open the OpenRCT2 port on the firewalls for both the VPS and the selfhosted machine.

5d. At this point, you should be all done! Go into the OpenRCT2 client, and this time add a server using your VPS domain name. You should be able to connect!

--
To recap, here is what I run when starting my OpenRCT2 server

On the VPS
$ systemctl --user start frps@openrct2

On the selfhosted machine
$ systemctl --user start openrct2-server@my_save_file.park
$ systemctl --user start frpc@openrct2-server
$ podman attach openrct2-server
openrct2> context.executeAction("pausetoggle", {});
openrct2> network.players[1].group = 0


Some shortcomings are:
1. Zero security. Any person in the world can connect to your VPS now at the OpenRCT2 port and get access to your multiplayer game if they know/guess the password. Security at this point is left up to OpenRCT2, and being as it's a video game, security is not a first priority per-se.

2. No way to know the IP of the client connecting to your server. All player IPs in the openrct2 logs will come over as your network interface IP, since connections are being proxied through fprs and frpc, and OpenRCT2 itself does not have support for the PROXY TCP protocol. No way to know which IP is doing what because of this.

3. Despite using the "pause when empty" config option, your server always seems to start permanently paused, and does not pause the game when you leave. You'll need to manage pause/unpause state yourself, so it's not a "fully set and forget" style setup just yet.



Get out there and put people on Mr. Bones Wild Ride.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Saturday, February 3, 2024

Hardening Tailscale on a Modern System

Tailscale is cool, and it provides a guide to harden a modern system with some additional security practices here. One tiny problem, its for Ubuntu.

As superior Archlinux users, we need updated instructions for hardening stuff - so here it is.

1. Create a tailscale user
# useradd --no-create-home --user-group --shell /bin/nologin tailscale

2. Add the polkit rule to allow the tailscale user to change DNS settings
// Polkit rules are written in Javascript. LOL. Assume ES5
polkit.addRule(function(action, subject) {
  var isValidGroup = subject.isInGroup("tailscale") || subject.isInGroup("wheel");
  var isValidAction = action.id.lastIndexOf("org.freedesktop.resolve1.", 0) === 0;
  if (isValidGroup && isValidAction) {
    return polkit.Result.YES;
  }
});

3. Apply systemctl override to tailscaled.service
# https://tailscale.com/kb/1279/security-node-hardening
[Service]
User=tailscale
Group=tailscale

DeviceAllow=/dev/net/tun
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_MODULE
ProtectKernelModules=no
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
NoNewPrivileges=yes
PrivateTmp=yes
PrivateMounts=yes
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
MemoryDenyWriteExecute=yes
LockPersonality=yes
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelLogs=yes
ProtectSystem=full
ProtectProc=noaccess
SystemCallArchitectures=native
SystemCallFilter=@known
SystemCallFilter=~@clock @cpu-emulation @raw-io @reboot @mount @obsolete @swap @debug @keyring @mount @pkey


That should give you a "more secure" daemon running as it's own user that drops root and severely restricts access and privs. I also lock down my zerotier-one.service as well, at least with the systemctl override file (not sure about whether zerotier can run under a non-root user, so steps 1 and 2 don't apply yet.)

Stay safe.

Stay tuned!

 ========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Friday, February 2, 2024

amd-pstate and pstate-frequency

pstate-frequency recently released version 3.14.0 which brought support for the new amd-pstate CPU driver, but only in "passive" mode. amd-pstate also supports and "active EPP" mode, which a new testing release for what will become pstate-frequency 3.15.0 supports as of today!

Changes were made to support the new active driver, and brought out support for the new --epp option which lets you change the Energy Performance Preference independent of CPU driver as long as the option is exposed by sysfs.

While the official release of 3.15.0 will not be for a while, if you have a recent (Zen 2 or Intel 11 Gen+) CPU that has support for EPP via ACPI CPPC (most modern processors do), then the latest git development version of amd-pstate will support your CPU with better, more specific options! Support is also added for EPP controls into the power-profiles for pstate-frequency, and it should gracefully fallback if you have an old CPU without any exposed EPP support.

Test today by pulling the latest script off of the Github or by using the -git AUR package. I'll update again when I have a release date in mind, but please be aware that it will not be for a little bit.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Sunday, January 28, 2024

The importance of a network namespace

Docker/Podman/Containers have the ability to put your network interfaces into a "network namespace" that hides them from the outside world, so instead of a container user seeing you have a wlan0 and an enp5s0, they'd see a loopback and a single eth0 fake device that routes to something like 10.0.2.3, which routes to a real gateway interface via a containerized network bridge. Very cool stuff, and generally recommended.

EXCEPT when you are running Caddy, or another webserver, on, oh let's say

A public AWS Lightsail instance...

Why do you ask? Oh, nothing, it's not like I had, for example, a public AWS Lightsail instance taken offline by a bot DDOS attempt or anything - no. Of course not...

When you use the network namespace in this case, all the IP addresses in your logs look like 10.0.2.3, instead of the correct X.Y.Z.A that you would generally want them to be. The reason this is of chief importance, is because nice tools like crowdsec and fail2ban rely on these client_ip addresses being valid to block repeat offenders. By using the network namespace that comes by default in a container, you are missing this information, and thus your important network security is effectively bypassed!

Keep all your other containers in a network namespace, but remember to run your reverse proxy entry point container on the host stack so that it can preserve IP address information for logging and reporting! And remember to test your security by using a VPN to make yourself appear as an attacker. Attempt to break into your own services!

Stay tuned

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Flatpak and You

Flatpak is cool. It seems to be positioning itself as the future of packaging on desktop Linux. But, as with all cool things, there are a few top-of-mind points that you should be aware of, even if nobody actively talks about them.

Your decision tree, when installing a flatpak should be as follows, where failing to answer any step with an emphatic "YES" would stop you from continuing down the chain of application installation.

1. Is this a verified flatpak?
2. Is this verified flatpak published by the developer or a trusted developing community member?
3. Is the project still alive, does the flatpak run on the latest runtime, or have a very good reason for why it's not?
4. Does the flatpak ship with a minimal number of extra libraries outside of the runtime?

If you've answered yes to all the above, then it's safe to install the flatpak via the flathub-verified subset, life is good! This is generally the hardest step, as a poorly maintained flatpak can lack security updates or be too open by default. Generally you'll want to pick projects which official publish builds under flatpak, ideally as the "only" distribution channel, to ensure that they are always maintained to the best of the developer's ability.


If you've answered no, then your decision tree splits under the following:

1. Is the package in my distro's official repositories?
2. Is the package maintained by a reliable third party in the AUR, can I vouch for their ability to script a build and maintain it with reasonable turnaround time?

If you've answered yes, then great, install the package. As far as getting the "flatpak sandbox" style experience, you need to remember that flatpak is not a SECURITY sandbox, it's chiefly a "hide my user-homedir from other apps" kind of sandbox. This kind of low-security/high-convenience sandbox can easily be replicated using "raw" bwrap or things like distrobox if you are so inclined. This option is always second to installing an official flatpak, as flatpak handles all of the security and seperation bits for us and we just need to much around in little override files, as opposed to understanding the intricacies of bwrap itself. Nevertheless, bwrap jailing is better than not jailing at all.


Finally, if bwrap is not a viable solution for your program, you can prevent as much "user-homedir" access as possible by running the app as a second user and setting up a kind of "user-jumphost" script.

--

For general reference, I run almost all of my "daily" applications via verified flatpaks with restrictive overrides

For apps that have no officially verified flatpak, like Android Studio and Webstorm, I run them as bwrap restricted jails via packages from either the distro repositories, or the AUR, which at least allow me to namespace UTS, PID, USERNS, and shadow directories like /var/, /proc, /run, and /tmp. I use my own jail script, that gives me access to X11, Wayland, and Pipewire by default, so that "general desktop usage" is seamless. Sharing files in and out of the jail just requires me to copy or move a file into the jail-home first, which is minimal effort.

And finally, for apps like Steam, which I like to run using gamescope which requires root access to the /tmp/.X11-unix socket location and thus cannot be jailed, I run as a delegated user that has minimal privileges, no sudo access, and is only able to be interacted with to run that specific command. Generally this delegated user is reserved only for very special apps, like gamescope, which create their own nested display servers. Basically every other "normal" app can be bwrap jailed with some configuration.

With a bit of extra configuration and some files in the right places, you can have a system which is nicely compartmentalized! If I need to uninstall or reset a flatpak, I delete it's folder in ~/.var/app. If I need to uninstall or reset a bwrap jailed program, I delete it's folder in ~/.local/etc/jails. And if I need to reset a delegated user style application, I delete it's user and all their related home files. Keeps things nicely separated and running with minimal permission where possible.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================