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
=========================