mybonk-wiki

Baby rabbit holes

Ordered list of “basic” skills that need to be acquired to enjoy the ride.

Applies to Linux, whatever the distribution, although we use NixOS ourselves and have a section dedicated to it.

Go through this slowly. It is tempting to speed-read through a book, call it done, and move on to the next book.

To get the most out of this, take your time understanding each section.

For every 5 minutes you spend reading you should spend 15 minutes tinkering around with what you just read. Play around, copy/past, break things, have fun.

A good general cheat sheet page: https://github.com/ruanbekker/cheatsheets#readme

UNIX vs. Linux? What’s the difference?

Good read on how Unix started and influenced Linux: [https://www.redhat.com/sysadmin/unix-linux-history] UNIX in the 70s

First steps with command-line

A shell is a user interface for access to an operating system’s services.

A terminal is a program that opens a graphical window and lets you interact with the shell.

It is common that the keyboard layout the system is configured with is different from the keyboard you actually use (e.g. system keyboard configured US layout but you use a keyboard with a French layout), read this article “https://www.baeldung.com/linux/console-change-keyboard-layout” to fix this.

A CLI (command-line interface) is what deal with when you interact with the shell.

RTFM!

The most important command is man which stands for “manual”. It explains what the command is and how to use it. Don’t spend hours on youtube, read the manuals. e.g.

  $ man git

  NAME
          git - the stupid content tracker

  SYNOPSIS
          git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
              [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
            [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
            [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
            [--config-env=<name>=<envvar>] <command> [<args>]


  DESCRIPTION
          Git is a fast, scalable, distributed revision control system with an unusually rich command set that provides both high-level operations and full access to internals.

  [...]

Most common commands

The importance of Git / GitHub

“If your work is not on Github it does not exist”
-Ben Arc

GitHub (or GitLab or other alternative) is a platform on the Internet used for storing, tracking, and collaborating on projects. It makes it easy to share all sorts of files and collaborate with peers in an asynchronous but coordinated way. GitHub also serves as a social networking site where developers can openly network, collaborate, and pitch their work.

Source Tree screenshot

Make it simpler to deal with the key to connect to git hub?

The interactions with git are now exclusively through “deployment keys”. These “deployment keys” is basically GitHub managing a list of authorized public keys to decide who can do what. So you need one of your public keys copied within in the “deployment key” properties section in your repo on GitHub.

Now to interact with github you’ll need to authenticate using your private key. “juggling” with keys is not ideal. A key can be passed in different ways (by argument, by using ssh-agent) but we recommend is the following effective approach: Define a host named gh in ~/.ssh/ssh.config:

Host gh
  Hostname github.com
  User git
  IdentityFile ~/.ssh/myprivatekey

Test the connection works (-T to disable pseudo-terminal allocation and -v for verbose so you actually see what’s going on at connection time, the last output message should be along the line of You've successfully authenticated, but GitHub does not provide shell access.):

$ ssh -Tv gh

And your command becomes:

$ git clone gh:me/myRepo

No more git@... since the config file includes User git.

How to fork after cloning?

I cloned a git repo to my local machine, played around with it a bit and found it cool.

Now I would like to keep the result as I modified it in my own github space. How can I proceed?

I suppose the regular way would have been to fork the repo on the first place to my space, clone it, modify and then push it to GitHub, but now I cloned the original’s author repo, how can I commit that as a new thing in my personnal?

ANSWER:

First rename the old remote as upstream, in case you want to be able to keep in sync with the original repository.

git remote rename origin upstream

Then add your forked repository as origin:

git remote add origin https://github.com/<your-username>/<your-project>

Or if you’re using ssh:

git remote add origin git@github.com:<your-username>/<your-project>.git

To push to your repository:

git push -u origin master

To pull from the base repository:

git pull upstream

It is recommend you do all of your work in a separate branch, not the master branch. It will be easier to rebase to the upstream/master branch in case you want to make a pull request.

You don’t really have to rename the origin to upstream - the remote names can be arbitrary, but it is recommended to keep up with the naming convention used by GitHub.

Good to know

Git front ends

Using one of the following might saves you time by simplifying your interactions with Git.

GitHub CLI

Command-line tool that brings pull requests, issues, GitHub Actions, and other GitHub features to your terminal, so you can do all your work in one place.

Authenticate with your GitHub account:

$ gh auth login

Text processing

File processing

Processes

File system / Block devices

wget

Cryptography

Remote Access

Spare yourself the pain, learn good habits, save tones time and avoid getting locked out of your system by really understanding how SSH (a.k.a Secure Shell or Secure Socket Shell) works, how it allows you to connect a remote machine, execute commands, upload and download files.

Use ssh auto login (auto login using public and private keys pair to be specific) as it is also significantly more secure than basic password-based login. Bellow is a real time illustration of ssh failed login attempts initiated from the Internet (bots, hackers, you name it) on a machine with password authentication left enabled (instead of using ssh auto login).

For reference:

$ssh root@192.168.0.155
#

IP addresses (here 192.168.0.155) are not “human friendly”. You can associate an IP address to an arbitrary name, easier to remember. This can be configured in your ssh configuration file ~/.ssh/config. Here is an example in its simplest form:

Host console_jay
  HostName 192.168.0.155
  User root

You can now use the following simple syntax instead to connect:

$ ssh console_jay

Tailscale

This is all very nice until you change environment or move your hardware to another network: A new IP address will be assigned to the machine and the shorthand console_jay will no longer work, you now have to figure out what the new IP address of your machine (scan the network or physically connect to serial) which is frustrating and time consuming.

A more effective way to deal with this issue and streamline remote access altogether is to use WireGuard/Tailscale. Tailscale basically hides all the nitty gritty of ssh by managing the VPN for you in the background.

Have a look at this Tailscale Quick tutorial.

To enable Tailscale:

With tailscale on you can now refer to your remote machine anytime anywhere through its Tailscale “Magic DNS” name:

$ tailscale ssh console_jay@dab-dominant.ts.net

Or even just:

$ tailscale ssh console_jay

Note that Tailscale’s “Magic DNS” and ssh commands are transparently wrapped through the Tailscale VPN. So $ ssh console_jay will work as well as $ tailscale ssh console_jay.

Commonly used:

# tailscaled
$ tailscale help
$ tailscale login
$ tailscale up
$ tailscale down
$ tailscale status
$ tailscale netcheck
$ tailscale ssh console_jay

How to SSH to machine A via machine B

This is done using ssh “port forwarding” using netcat (nc). You can ssh to machine A via machine B by adding similar entries in your ~/.ssh/config:

Host machine_B          # Machine B definition
Hostname 12.34.45.56    # Change this IP address to the address of machine b
User operator           # Change the default user accordingly 

Host machine_A          # Machine A definition (the target host)
ProxyCommand ssh -q machine_B nc hostname.or.IP.address.internal.machine 22

Now you can reach Machine A directly having Machine B used in the back-end transparently. You have a single SSH host target name to reach Machine A, you can as well use it in ssh, scp, sftp …

scp somefile user@machine_A:~/

rsync

rsync uses a delta transfer algorithm and a few optimizations to make the operation a lot faster compared to scp. The files that have been copied already won’t be transferred again (unless they changed since). Can be run ad-hoc on the command line or configured to run as a deamon on the systems to keep files in sync.

rsync allows to restart failed transfers - you just reissue the same command and it will pick up where it left off, whereas scp will start again from scratch.

rsync needs to be used over SSH to be secure:

### Tor

### I2P

tmux & tmuxinator

… or alternatives like GNU Screen, Terminator, Byobu, .etc…

tmux for beginners:

tmux source-file ~/.tmux.conf

tmux new -s MY_SESSION

tmux list-keys

tmux list-sessions / $tmux ls

tmux kill-session -t name_of_session_to_kill : Kills a specific session.

tmux kill-session -a : Kills all the sessions apart from the active one.

tmux kill-session : Kills all the sessions.

tmux kill-server : Kills the tmux server.

tmux-resurrect and tmux-continuum: Tmux plugins to persist sessions across restarts.

tmux shortcuts

tmuxinator is a tool that allows you to easily manage tmux sessions by using .yaml files to describe the layout of a tmux session, and open up that session with a single command.

The following command allows to access a remote tmuxinator over ssh. It is very powerful because the sessions are persisted even if you close the ssh connection and reconnect. The remote tmux and tmuxinator are used so they need to be installed on the remote machine. Similarly the configuration files .tmux and .tmuxinator are looked for in the home directory of the user you ssh with on the remote server.

ssh -o TCPKeepAlive=no -t admin@192.168.0.97 "cd '.' ; tmuxinator start console -p .tmuxinator.yml ; sh --login"

processes

certificate

What is the difference between IPtables and UFW Linux firewalls?

UFW is built upon IPtables, IPtables a very flexible tool but it’s more complex as compared to UFW. Also IPtables requires a deeper understanding of TCP/IP, which might not be the case with every Linux user, so UFW is the solution. UFW allows the user to configure firewall rules easily using IPtables under the hood. Hence, for an average Linux user UFW is the best way to get started with setting up different firewall rules.

We discuss and use UFW in our scope.

In NixOS the following commands are replaced by parameters in the configuration file (networking.firewall.allowTCPPorts .etc…) you should not run them manually.

partitions / filesystems

alt text

UEFI vs. Legacy Boot

Privacy tools

Other tools / resources

Using bitcoin’s command line interface bitcoin-cli

bitcoin-cli is the most straightforward way to execute bitcoin RPC commands (full list of RPC commands), here are some of the most commonly used:

Using bitcoin JSON-RPC API calls

The bitcoin JSON-RPC API allows to interact with bitcoin deamon in a varierty of ways: cURL, JavaScript, Python …

First you need to make sure Bitcoin is setup to accept Remote Procedure Calls (RPC):

For instance you could run getnetworkinfo using the following cURL:

curl -u public:2S8PWBZ71wMXdrsAxL21 -d '{"jsonrpc": "1.0", "id": "curltest", "method": "getnetworkinfo", "params": [] }' -H 'content-type: text/plain;' http://mybonk-jay:8332/

Most noticably you need to use the option -u (or --user) to pass valid credentials (here username public and password 2S8PWBZ71wMXdrsAxL21) otherwize you will get an 401 Unauthorized error. Username is either public or priviledged, their password in /etc/nix-bitcoin-secrets/bitcoin-rpcpassword-{public|priviledged}.

Also make sure that the method you call (getnetworkinfo, getpeerinfo, listwallets…) is defined in the RPC whitelist.

You can use curl with the -v (verbose) parameter to see the sent headers: The text after the Basic keyword is the base64 encoded text string of the username:password that were passed with the -u parameter.

Authorization: Basic cHVibGljOjJTOFBXQlo3MXdNWGRyc0F4TDIx

To manually generate this base64 encoded credentials you can simply use:

$ echo -n "username:password" | base64 -w0
cHVibGljOjJTOFBXQlo3MXdNWGRyc0F4TDIx

To test this end to end, you can remove -u username:password and substitute with -H Authorization: Basic cHVibGljOjJTOFBXQlo3MXdNWGRyc0F4TDIx, the authenticate will work too:

$ curl -v -d '{"rpc": "1.0", "id": "curltest", "method": "getnetworkinfo", "params": [] }' -H 'content-type: text/plain;' -H 'Authorization: Basic cHVibGljOjJTOFBXQlo3MXdNWGRyc0F4TDIx' http://mybonk-jay:8332/

In conculsion, you could even run these RPC commands without using cURL: You would just need to base64 encode the username:password combination and set the HTTP Authorization header with the type as Basic along with the base64 encoded string.

This is a nice cheatsheet for https://github.com/grubles/cln-cheatsheet

Another example is sending funds onchain using lightning-cli, which is also possible.

Using clightning JSON-RPC API calls

Similarly to the bitcoin JSON-RPC, the clightning JSON-RPC API allows to interact with clightning deamon in a varierty of ways: cURL, JavaScript, Python …

Corelightning documentation is very well done with clear examples.

Podcasts

Other projects and references

For developers

Books

NixOS/Nix specific

If you are actualy running NixOS operating system (as opposed to just Nix which is the package manager), you can lookup the currently active NixOS configuration. For example:

$ nixos-version
23.05.20230915.360a7d3 (Stoat)

Of course you also use the traditional Linux commands to know more:

Common Nix commands

nix repl

Garbage collection:

Nix debugging

Search NixOS/Nix packages on the command line

You can search for packages using search.nixos.org:

But you can also search for packages straight from the command line, there are 2 methods to do this:

Method 1

Just use nix-shell’s autocomplete feature: Press the < tab > key as you enter the name, you’ll see all Nix package names that begin with the text you entered (takes a second or two to complete):

$ nix-shell -p asciiq
asciiquarium

Note: Nix shell autocomplete applies only on the Nix package names (not its description nor any other metadata).

Method 2

Use the nix terminal app with search:

$ nix search nixpkgs asciiquarium
* legacyPackages.x86_64-linux.asciiquarium (1.1)
  Enjoy the mysteries of the sea from the safety of your own terminal!

* legacyPackages.x86_64-linux.asciiquarium-transparent (2023-02-19)
  An aquarium/sea animation in ASCII art (with option of transparent background)

Notes:

Run a package without having to install it

This is a great feature of NixOS. For example I can open a shell with the asciiquarium package available in it:

$ nix-shell -p asciiquarium

Now get this: that command didn’t actually install anything. When I leave the shell (with exit or ctrl+d), asciiquarium is no longer there, and it doesn’t pollute my user environment.

Alternatively, if you have Flakes enabled you can us the following command (more information here):

$ nix shell nixpkgs#asciiquarium

You can play around with plenty of nifty little programs kids love:

$ nix-shell -p asciiquarium cmatrix fortune cowsay sl figlet toilet oneko

.etc…

Many other little games are bundled in a package. The package bsdgame for instance has cool command-line games.

Various

Others