From ce018d219373b675fe1e63c323eaf06e65713f75 Mon Sep 17 00:00:00 2001 From: davidovski Date: Fri, 21 Jul 2023 11:05:15 +0200 Subject: move non-executables to site subdir --- site/entries/entries.sh | 5 + site/entries/git_compile.html | 15 +++ site/entries/librex.html | 9 ++ site/entries/pci_passthrough.html | 274 ++++++++++++++++++++++++++++++++++++++ site/entries/ssh_forwarding.html | 94 +++++++++++++ site/entries/welcome.html | 11 ++ 6 files changed, 408 insertions(+) create mode 100755 site/entries/entries.sh create mode 100755 site/entries/git_compile.html create mode 100755 site/entries/librex.html create mode 100755 site/entries/pci_passthrough.html create mode 100755 site/entries/ssh_forwarding.html create mode 100755 site/entries/welcome.html (limited to 'site/entries') diff --git a/site/entries/entries.sh b/site/entries/entries.sh new file mode 100755 index 0000000..e85c454 --- /dev/null +++ b/site/entries/entries.sh @@ -0,0 +1,5 @@ +#!../page.sh + +[ -z "$1" ] || { + md2html $1 +} diff --git a/site/entries/git_compile.html b/site/entries/git_compile.html new file mode 100755 index 0000000..48619f6 --- /dev/null +++ b/site/entries/git_compile.html @@ -0,0 +1,15 @@ +#!./entries.sh + +# Compiling files in a git repo + +So I decided to improve the way that that you can access some of the repos that I am hosting on this server, including the code that I use to compile the site itself. I quickly hacked together a bit of code in my existing [build.py](https://davidovski.xyz/git/davidovski/build.py.html) to clone a list of repos and go through and generate a html pages for each of the files in the repo. + +Although this means that this is only a static view of the repo at any time (needing me to rebuild the site for it to update) I can easily add any git repo to be built into my site, so as you may see, I have added a few repos from my github as well. + +I tried using cgit, but it just didn't provide exactly what I wanted and I wasn't in the mood to try configuring it to my liking, so I opted for this approach instead. + +A way that I can improve it is to serve a http server that dynamically updates the repositories when new commits are added, which would probably be a better solution; but this works.. for now. + +If you want to view all of the repos that I've listed so far, click the link at the top of the page. (sorry that the index is still the default nginx autoindex, I will change that at some point), and feel free to check out how I did it in [build.py](https://davidovski.xyz/git/davidovski/build.py.html), though Im warning you, its probably some of the hackiest code i've put together. + +Tutorial on how to host your own git repos on your server and allow people to clone them with https may be coming soon diff --git a/site/entries/librex.html b/site/entries/librex.html new file mode 100755 index 0000000..c78c2cd --- /dev/null +++ b/site/entries/librex.html @@ -0,0 +1,9 @@ +#!./entries.sh + +# LibreX - a metasearch engine + +My instance: [search.davidovski.xyz](https://search.davidovski.xyz/) + +For a while now I have been using [SearX](https://github.com/searx/searx) as my search engine, a meta search engine that cumulates search results from multiple different sites. While this is a great idea in theory, making the best of all search engines through one *privacy respecting* interface, in reality it ends up meaning that search results are quite slow. Couple this with the fact that most SearX instances are hosted by volunteers, and often have downtime, I was in the situation where I was hopping between various instances to try and find ones that worked. I always wanted to self host one myself, but the whole system seemed very bloated and complicated, and honestly I just couldn't be bothered to mess around with it. + +That's where [LibreX](https://github.com/hnhx/librex) comes in, a very small and simple meta search engine. Its still in development, but currently it has just enough functionality to actually be somewhat useful. Currently it only really supports google searches, but it still is a good layer for privacy, since all of your queries are anonymised, with google only seeing that they came from LibreX. I am curious to see how well it will handle larger amounts of search queries and if Google will limit them or something. If you want to support development, feel free to use it, find bugs and request features: [View the github repo](https://github.com/hnhx/librex) diff --git a/site/entries/pci_passthrough.html b/site/entries/pci_passthrough.html new file mode 100755 index 0000000..942c2b4 --- /dev/null +++ b/site/entries/pci_passthrough.html @@ -0,0 +1,274 @@ +#!./entries.sh + +# PCI passthrough with qemu + +QEMU is a powerful free and open source emulator which when paired with kvm can be used to create almost bare-metal performance virtual machines. In this guide I will be detailing some tips and tricks to configuring a setup on your linux system to allow a PCI device (typically a graphics card) to be passed through to a virtual machine. + +Countless guides already exist on this topic but they all rely on using virt-manager and other Redhat software, which, depending on your use case, may be completely overkill. This guide assumes that you will not be using the target GPU as a video output on your host machine from boot, so will only work in configurations where you are able to remote connect or where you have **multiple graphics cards**. However the process is mostly similar for single GPU passthrough, with extra steps if you want to bind and unbind display drivers from the host. + +This is a generic guide written to support any semi-standard Linux distributions, so adapt any instructions as you see fit to your current system. + +If you do not trust this guide or need any clarification, feel free to follow steps from other guides, or just skip to the tips at the bottom of this guide. + + +## Prerequisites + +Make sure that your motherboard is: +- supports hardware virtualisation +- supports IOMMU + +These options can be enabled within the motherboard's BIOS settings usually. + +You may also want a spare monitor or a monitor with multiple inputs so that you can switch between GPU outputs. + +Once you have enabled IOMMU, you will need to ensure that your PCI slot can actually be passed through. This is only possible if the GPU appears in its own single IOMMU group, with no other devices in that group. + +To list IOMMU groups, you may use this script from the [archwiki](https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Ensuring_that_the_groups_are_valid) + + #!/bin/bash + shopt -s nullglob + for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do + echo "IOMMU Group ${g##*/}:" + for d in $g/devices/*; do + echo -e "\t$(lspci -nns ${d##*/})" + done; + done; + +If you see that there PCI devices other than ones that correspond to your graphics card, then try using a different PCI slot. Unfortunately some motherboards don't have any isolated PCI slots, in this case you are out of luck; PCI passthrough will not be possible in this method. + + +## Setting up VFIO + +The core principle behind PCI passthrough is that you don't want the kernel from having any control over the device in the PCI slot. To do this, we tell the kernel to bind a *dummy driver* to the gpu so that when we want to pass it through to the VM, it is not in use. + +To do this, you want to find out the Device IDs of your PCI device, you can do this using the following command: + + lspci -nn + +Make sure take notes of all of the devices that appeared within the isolated IOMMU group from the previous stage. If you miss out any PCI devices, this will not work. IDs often look like this: `10de:13c2` + +Next add the following to your kernel's cmdline arguments. This can usually be found somewhere in your bootloaders settings, for example for GRUB, you can add it to `GRUB_CMDLINE_LINUX_DEFAULT=""` in `/etc/default/grub` + + vfio-pci.ids=*id1*,*id2* + +where *id1* and *id2* represent the ids that you collected in the previous step. + +Next you need to tell your initramfs (if applicable) to load the vfio modules. This is done to make sure that the vfio module is loaded and assigned to these pci devices *before* your video drivers. The process of doing this depends on your initramfs system: + +### Dracut + +in `/etc/dracut.conf.d/10-vfio.conf` + + force_drivers+=" vfio_pci vfio vfio_iommu_type1 vfio_virqfd " + +then rebuild your initramfs + + +### mkinitpcio + +in `/etc/mkinitcpio.conf` + + MODULES=(... vfio_pci vfio vfio_iommu_type1 vfio_virqfd ...) + +then rebuild your initramfs + +### booster + +in `/etc/booster.yaml` + + modules_force_load: vfio_pci,vfio,vfio_iommu_type1,vfio_virqfd + +then rebuild your initramfs + +## QEMU arguments and set-up + +In this guide I will be using qemu from the command line. I feel as if this is the easiest way to create virtual machines without any overhead, but you can use libvirt if you wish. + +Here is a script that use a to run a linux virtual machine, if you want to copy it blindly and not understand it, then thats alright, but I will include a description for each argument and why its used. + + #!/bin/sh + + ISO="/path/to/your/installer/iso" + ROOT="/path/to/your/virtual/disk" + OVMF_VARS="/path/to/your/ovmf/vars/image" + + + qemu-system-x86_64 \ + -enable-kvm \ + -m 8G \ + -smp 2 \ + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF.fd \ + -drive if=pflash,format=raw,file="$OVMF_VARS" \ + -drive if=virtio,file="$ROOT",format=qcow2 \ + -vga none \ + -nographic \ + -monitor stdio \ + -serial none \ + -device vfio-pci,host="06:00.0" \ + -device vfio-pci,host="06:00.1" \ + -device vfio-pci,host="06:00.2" \ + -device vfio-pci,host="06:00.3" \ + -net nic,model=virtio -net user \ + -device ich9-intel-hda,addr=0x1b \ + -device hda-micro,audiodev=hda \ + -device ich9-intel-hda,addr=0x1b \ + -device hda-micro,audiodev=hda \ + -audiodev pa,id=hda,server=unix:$(pactl info | sed -rn 's/Server String: (.*)/\1/p') + +### Basic Parameters + + -enable-kvm + +This enables [KVM](https://www.linux-kvm.org/page/Main_Page) which improves performance and allows for *almost bare-metal* CPU performance. + + -m 8G + +Allocate 8 Gigabytes of memory to the virtual machine + + -smp 2 + +Allocate 2 CPU cores to the virtual machine + +### OVMF firmware + + -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF.fd \ + -drive if=pflash,format=raw,file="$OVMF_VARS" \ + +Most PCI cards require UEFI firmware to function properly. For this reason we will be using the OVMF firmware. You may need to install this on your system, typically the package is called ovmf, edk2-ovmf or something similar. Learn to use your package manager's search functionality to find it. + +Make a copy of the OVMF variables file, typically located at `/usr/share/OVMF/OVMF_VARS.fd` and place it somewhere with the rest of your virtual machine's files. You should keep these separate and unique for each virtual machine you wish to create. + +In my example script, make sure you replace `/path/to/your/ovmf/vars/image` to the path to your copy of `OVMF_VARS.fd` + +### Storage + + -drive if=virtio,file="$ROOT",format=qcow2 \ + +Next you need to create a virtual disk for your virtual machine. You can create this using the following command, replacing `32G` with the desired size of this disk. + + qemu-img create -f qcow2 myVirtualDisk.qcow2 32G + +In this example I use `if=virtio,` which provides better performance than the default drive type, however this will only work with linux guests which have the virtio module. **Remove this if you are using windows in your virtual machine** + +For your first boot, you may want to add the following before your primary virtual disk: + + -drive file="$ISO",media=cdrom + +Ensure that you have set the `ISO` and `ROOT` variables appropriately with the paths to the corresponding images. + +### Disabling virtual video output + +This next step is to ensure that qemu doesn't create a virtual VGA output for your virtual machine, nor opens a window, allowing this to be run from outside an X11 session + + -vga none + -nographic + -monitor stdio + -serial none + +### VFIO passthrough + +Next you need to find the pci ids for your device. Make sure you include all the relevant ones in your IOMMU group: + + -device vfio-pci,host="06:00.0" \ + -device vfio-pci,host="06:00.1" \ + -device vfio-pci,host="06:00.2" \ + -device vfio-pci,host="06:00.3" \ + +In this example, my PCI ids start with `06:00`, **make sure you change this for your setup.** + +### Network + +Next you want network for your virtual machine: + + -net nic,model=virtio -net user + +I use the virtio network card, which only works for Linux guests. **If you have a windows guest, do not include this line** this will use the default network card for qemu. + +### Audio + + -device ich9-intel-hda,addr=0x1b \ + -device hda-micro,audiodev=hda \ + -audiodev pa,id=hda,server=unix:$(pactl info | sed -rn 's/Server String: (.*)/\1/p') \ + +This creates a audio device for the virtual machine which connects to the currently running pulseaudio session of your client. + +You can omit this section if you wish to output audio through your PCI device. + +## Other tips and tricks + +### evdev mouse and keyboard passthrough + +Out of all of the methods of passthrough a keyboard and mouse, evdev is probably one of the best and most easiest. + +First you need to identify the input devices that linux creates for your keyboard and mouse. You can list them all using: + + ls /dev/input/by-id/ + +Identify the devices that you want to passthrough and find the ones containing `-event`. + +Then add the follow for each one as an argument to your qemu command. + + -object input-linux,id=*UNIQUE_ID*,evdev=/dev/input/by-id/*YOUR-DEVICE*,grab_all=on,repeat=on + +Then when your virtual machine is running, you will be able to switch to and from the host's control by pressing both left and right ctrl keys at the same time on your keyboard. + +### Running as an ordinary user + +To do this, I would recommend creating a group named `kvm` and adding your user to it. + + groupadd kvm + + usermod -a -G kvm *username* + +Next you will want to ensure that vfio devices have the correct permissions for the kvm group to use. In `/etc/udev/rules.d/10-vfio.rules`: + + SUBSYSTEM=="vfio", GROUP="kvm" + +Next you will probably want to increase memory limits for users of the kvm group, to allow them to allocate potentially GB for the virtual machine. To make things easier, you might want to just set this to the maximum number of megabytes available in the system. You can find this out using `free`, for example for a system with 8GB ram, its: `8100452` + +In `/etc/security/limits.d/99-memlock.conf` write: + + @kvm hard memlock 8100452 + @kvm soft memlock 8100452 + +You may need to reboot for these changes to take effect, especially ones relating to udev rules. + +### Using ddcutil to switch between monitor inputs + +Most monitors, other than laptop displays, have a Virtual Control Panel which can be controlled through i2c as per the Display Data Channel/ Command Interface Standard... DDC/CI + +Setting up ddcutil to work on your monitor will depend on a case to case basis depending on your monitor and video card. + +Depending on your monitor, you may need to enable DDC/CI in its settings. + +Make sure you have installed ddcutil and i2c-dev, again exact package names may vary. + +To detect the montors available, use `ddcutil detect`. If this doesn't work, ensure that the i2c-dev module is loaded. + +To enable the i2c module on load, you may need to add the following to `/etc/modules-load.d/i2c-dev.conf` + + i2c-dev + +To allow users of the i2c group to control i2c devices add the following to `/etc/udev/rules.d/10-i2c-group.rules`. Make sure you create this group and add your user to it. + + KERNEL=="i2c-[0-9]*", GROUP="i2c" + +Find out the Display number of your monitor using `ddcutil detect` +Next find the available inputs on this monitor: + + ddcutil -d $display_number capabilities + +Here you should be able to see `Feature: 60 (input source)`. Take note of hexadecimal values. + +You will be able to switch monitors using: + + ddcutil -d $display_number setvcp 60 0x$monitor_input_hex_value + +I have this bound to a hotkey using `sxhkd` so I can easily switch between inputs without having to reach over to buttons on my monitor.However you can configure this whichever way you want: for example, you can switch to the display output of your passthrough GPU when the virtual machine starts, and back when it shuts down. + +## Conclusion + +Hopefully, this guide has helped you set up a virtual machine with PCI passthrough. All thats left now is to install the software you want in your virtual machine and have fun. + +If there is anything that isn't clear in this guide, please contact me, or look at other guides if you need any help. The archwiki is a pretty good place to look if you are, *or aren't* using archlinux. + diff --git a/site/entries/ssh_forwarding.html b/site/entries/ssh_forwarding.html new file mode 100755 index 0000000..d068f54 --- /dev/null +++ b/site/entries/ssh_forwarding.html @@ -0,0 +1,94 @@ +#!./entries.sh + +# Permanent SSH Forwarding (Tutorial) + +Take this situation: you have a cheap (or even free), low-powered remote server and a considerably better homeserver with more storage and power. For certain services that require more power, you'd obviously want to run them on that homeserver. + +However, what if you don't want to, *or can't*, directly open ports onto your home network, or you if you simply want to keep all of your site to one IP? This is where SSH port forwarding comes in handy: using ssh to forward the open port from a service from your local server to the remote one, where it can be exposed to the rest of the internet. + +## SSH Remote Port Forwarding + +SSH remote port forwarding is built right into ssh itself, and is quite simple: + +``` +ssh -R 5505:localhost:4404 user@remote.host +``` + +When this command is run on the local server, it will: ++ create an ssh connection to the remote server, as per usual ++ open the port 5505 on the remote server, ++ all traffic on this port will be forwarded to port 4404 on the local server. + +This command by itself is already everything you'd need to forward most ports easily to your remote server, of course, remember to open the port on your remote server's firewall, if applicable. + +However to ensure that that port is exposed properly on the remote server, you'd want to make sure that it is listening to all external traffic. + +You can fix this by setting `GatewayPorts yes` in `/etc/ssh/sshd_config` on the remote server. (don't forget to restart sshd after editing the config) + +## Persistent ssh forwarding + +The above is all well and good, but you'd need to keep an interactive ssh connection up at all times, so the above isn't the most ideal solution. + +To get around this, you can create a service to run on the local server to forward requested ports from the remote server. + +To begin, I'd recommend creating two users, one on each server. For sake of example, lets all them `bridge`. I'd recommend to avoid giving these users passwords, that way they can only be accessed through key based authentication. Of course you will still be able to log into them as root using `su - bridge` + +Next you should create an ssh keypair on the local server (`ssh-keygen`) and place the contents of your public key into `.ssh/authorized_keys` on the remote. This will make sure only the local server can ssh into the remote using that key. + +Then, create a script for your ssh port forwarding. I placed mine directly in the home folder on my local server, though it only matters that the bridge user can execute it. In your script you *must* use the `-nT` flag on your ssh command. These will allow you to run this script as a service, by preventing a virtual terminal being allocated. (read `man ssh` for more info) + +Here is my example of a script that you could use: + + #!/bin/sh + + PORTS="8080 25565" + DEST="bridge@remote.host" + SSH_PORT="22" + IDENTITY_FILE="~/.ssh" + + /usr/bin/ssh -nNT $(echo $PORTS | awk -v host=$LOCALHOST '{for (i = 1; i <= NF; i++){ printf "-R %d:%s:%d ",$i,host,$i}}') -p $SSH_PORT -i $IDENTITY_FILE $DEST + +Next you'd want to run this script as a service. Check your distro's service system how to do this if you have any trouble. + +### Systemd service + +Say that the script you made was `/home/bridge/tunnel.sh`, you should create a user service with systemd for the bridge user. + +To do this create the following file in `/home/bridge/.config/systemd/user/tunnel.service`: + + [Unit] + Description=SSH tunnel + + [Service] + ExecStart=/home/bridge/tunnel.sh + RestartSec=5 + Restart=always + KillMode=mixed + + [Install] + WantedBy=default.target + +Then enable and start the service with: `systemd --user enable tunnel.service` and `system --user start tunnel.service`. Ensure that it is running with `systemd --user status tunnel` + +## Forwarding ports smaller than 1024 + +As you may know, TCP/IP port numbers below 1024 are special in that normal users are not able to open, and hence forward from on the remote server. + +One solution to this is run a server on the remote that will proxy requests from port 80 to a different port (say port 8080). + +This can be achieved using `socat`. + +Say you forwarded traffic from port 8080 on remote to port 80 on local, you could then, on the remote server, run `sudo socat TCP-LISTEN:80,fork TCP:localhost:8080` to listen to traffic on port 80 and forward it to 8080, which will forward back to the local server. + +Here is an example of this in practice, forwarding port 80 and 443, by forwarding ports 8080 and 8443: + + /usr/bin/ssh -nT -R 8443:localhost:443 -R 8080:localhost:80 -i $IDENTITY_FILE -p $SSH_PORT $DEST "(sudo socat TCP-LISTEN:80,fork TCP:localhost:8080) & sudo socat TCP-LISTEN:443,fork TCP:localhost:8443" + +However this command assumes that the remote user has access to sudo with **NO PASSWORD**. Alternatively you could create a similar service (this time as a system service) on the remote server running the socat commands. + +## Video Tutorial + +Here is an example of how you can use this to host a webserver (or any other service) from anywhere: even a hotel room. + + +Credit: DenshiVideo diff --git a/site/entries/welcome.html b/site/entries/welcome.html new file mode 100755 index 0000000..5d34602 --- /dev/null +++ b/site/entries/welcome.html @@ -0,0 +1,11 @@ +#!./entries.sh + +# welcome + +welcome. i decided to turn this webpage into blog-style site... i havent got a topic or anything, so expect either: quality tutorials and very interesting techy things; or just random shitposts or rambles about things. + +originally i was going to make this blog on [b.davidovski.xyz](https://b.davidovski.xyz) using [nanoblogger](http://nanoblogger.sourceforge.net/) (you might be able to still see the start of that) but nb itself seemed quite dead, and i couldn't really be asked to customise it all myself. So i made my own script to generate this static site: [kblg](https://github.com/davidovski/kblg/). Right now its probably just the bare minimum needed for this, but I am planning to add more things to it as I go along (including rss, if anyone would be interested?) + +anyway thats all for now, cya + +~davidovski -- cgit v1.2.1