MoreRSS

site iconPeter CaiModify

An Infrastructure Engineer. A Free and Open Source Software enthusiast. Native language is Mandarin.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Peter Cai

Getting called "Paid Actor" by Linus Torvalds

2024-10-24 05:15:27

Update: I am not participating in this whole shitshow anymore. I don't retract any of my comments made, but I also probably don't want your attention. If you want to get anything out of me, you can go away.

To those "don't get political" crowd: I urge you to read again what I said towards Torvalds. Have I ever agreed with some of the obvious troll bots? If telling Linus Torvalds "you shouldn't be making baseless accusations" is somehow a "political" opinion, I don't know what isn't. I sincerely wish you the best going forward, but I am going to try not to be even remotely involved in a community where their leaders can get away with abusing their community members in any manner.

My final involvement in this whole topic is demanding an apology letter towards all those that were accused of being paid actors. Whatever (or not) this ends up getting, I am not responding to the thread any further.

Context

On Oct 22 (or Oct 23 depending on where you are), Greg K-H posted a commit to remove a bunch of kernel maintainers citing "various compliance requirements". The commit was posted right before it was included in a pull request, without time for comments from pretty much anyone else. This has triggered some concerns on transparency in the Linux kernel community -- rather than referring to exact compliance requirements or state that they are under some type of NDA, Greg (and Linus Torvalds) have chosen to use the very vague wording to justify a big change.

Some have (IMHO, rightfully) raised a concern that this type of changes should at least have a better citation on why. They may be required legally to do so, or they are under some NDA, but referring to the existence of said law or NDA itself seems to be the minimum for transparency. Without citation, this sets a very dangerous precedent that Linus, or Greg, or anyone who threatens them with lawsuit, can influence the Linux kernel in unpredictable ways that no one else will be able to have an early eye on.

One of my friends sent a reverse patch for this to the list citing these concerns. This triggered responses from another bunch of people, some of which may rightfully be spam bots. However, instead of addressing the concern publicly, Greg chose to send a private correspondence to one of them seeking to defuse the situation (I assume), which didn't help. On the other hand, Linus Torvalds begun to call out people who raised concerns as Russian state-sponsored spam, and said that reverting this patch is equal to "supporting Russian aggression".

The last email mentioned above was the last straw for me due to the sheer ignorance and arrogance it showed. I wrote an email back trying to point out how absurd his response was, and ended up getting called paid actor.

Shortly after that, the whole https://lore.kernel.org began to 404. It ended up recovering, but I thought this showed that they might want to remove the conversation from public view at any time. So here is a copy of my arguably short email conversation with Linus Torvalds, in case that happens and Linux Foundation decides to stop even pretending they value community participation.

1. Linus calling out "Russian state-sponsored spam"

Subject: Re: [PATCH] Revert "MAINTAINERS: Remove some entries due to various compliance requirements."
Date: Wed, 23 Oct 2024 10:45:47 -0700   [thread overview]
Message-ID: <CAHk-=whNGNVnYHHSXUAsWds_MoZ-iEgRMQMxZZ0z-jY4uHT+Gg@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>

Ok, lots of Russian trolls out and about.

It's entirely clear why the change was done, it's not getting
reverted, and using multiple random anonymous accounts to try to
"grass root" it by Russian troll factories isn't going to change
anything.

And FYI for the actual innocent bystanders who aren't troll farm
accounts - the "various compliance requirements" are not just a US
thing.

If you haven't heard of Russian sanctions yet, you should try to read
the news some day.  And by "news", I don't mean Russian
state-sponsored spam.

As to sending me a revert patch - please use whatever mush you call
brains. I'm Finnish. Did you think I'd be *supporting* Russian
aggression? Apparently it's not just lack of real news, it's lack of
history knowledge too.

                      Linus

2. My response

Subject: Re: [PATCH] Revert "MAINTAINERS: Remove some entries due to various compliance requirements."
Date: Wed, 23 Oct 2024 15:15:17 -0400   [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAHk-=whNGNVnYHHSXUAsWds_MoZ-iEgRMQMxZZ0z-jY4uHT+Gg@mail.gmail.com>

Hi there,

Not a maintainer, but I have made several bug reports using this email 
address. At least 1 reasonably-sized patch is also currently under 
review in the networking mailing list, along with people from several 
American corporations, so hopefully you won't automatically assume this 
email came from a "Russian troll" account.

Ok. With that out of the way, if you still want to bother reading, 
here's why, in the most un-provocative tone possible, why your comments 
_completely_ miss the point why people are upset:

On 10/23/24 1:45 PM, Linus Torvalds wrote:
> Ok, lots of Russian trolls out and about. >
> It's entirely clear why the change was done, it's not getting
> reverted, and using multiple random anonymous accounts to try to
> "grass root" it by Russian troll factories isn't going to change
> anything.

Yes. Everybody who has more than 1 brain cell knows, in general, "why". 
The point was never to ask for the obvious response.

People are upset because no reference to _exactly which compliance 
requirement_ resulted in the removal of these maintainers. No 
open-source project can live outside of a political entity, but that is 
not the reason why "obviously" can be used to write off such a change.

Even just stating "we were contacted by <...> but details are under NDA" 
is a **much** better response than "due to various compliance 
requirements". No one is saying the LF or the Linux kernel should be 
outside of politics. That's impossible. But it _is_ possible to run the 
project based on _transparency_ and _honesty_ instead of "why can't you 
see the obvious".

> And FYI for the actual innocent bystanders who aren't troll farm
> accounts - the "various compliance requirements" are not just a US
> thing.

Again -- are you under any sort of NDA not to even refer to a list of 
these countries?

> If you haven't heard of Russian sanctions yet, you should try to read
> the news some day.  And by "news", I don't mean Russian
> state-sponsored spam.

Before calling out community members who raised legit concerns about 
procedural transparency, maybe it is worth doing a quick fact-check. 
There are a lot of suspicious looking `.ru` emails in this thread, but 
they are not who first raised the concern. The revert patch was sent out 
by someone at aosc.io. Look up who they actually are -- and before you 
assume "state-sponsored spam" just because of the language of the 
website, maybe you can also spend more than 1 second to check where the 
website is even actually located.

> As to sending me a revert patch - please use whatever mush you call
> brains. I'm Finnish. Did you think I'd be *supporting* Russian
> aggression? Apparently it's not just lack of real news, it's lack of
> history knowledge too.

I hope that either this comment wasn't written by the real Linus 
Torvalds, or that Linus was not under his best judgement when this email 
was sent. Because just like anyone who reads the news would know about 
Russian aggression, anyone who knows anything about politics should also 
be able to understand that individuals and their states are different 
concepts.

If these maintainers are associated with the Russian state, this should 
be cited as the reason for their removal. And you know what? Most people 
wouldn't have any problem with it. And then you can say "we are not 
supporting Russian aggression" with confidence. But this is **not** what 
was done.

I seriously hope that Linus Torvalds would have known better.

Thanks,
Peter.

3. Linus calling me "paid actor"

Subject: Re: [PATCH] Revert "MAINTAINERS: Remove some entries due to various compliance requirements."
Date: Wed, 23 Oct 2024 12:19:37 -0700   [thread overview]
Message-ID: <CAHk-=wjw0i-95S_3Wgk+rGu0TUs8r1jVyBv0L8qfsz+TJR8XTQ@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>

On Wed, 23 Oct 2024 at 12:15, Peter Cai <[email protected]> wrote:
>
> Again -- are you under any sort of NDA not to even refer to a list of
> these countries?

No, but I'm not a lawyer, so I'm not going to go into the details that
I - and other maintainers - were told by lawyers.

I'm also not going to start discussing legal issues with random
internet people who I seriously suspect are paid actors and/or have
been riled up by them.

              Linus

4. My last response

Subject: Re: [PATCH] Revert "MAINTAINERS: Remove some entries due to various compliance requirements."
Date: Wed, 23 Oct 2024 15:28:35 -0400   [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAHk-=wjw0i-95S_3Wgk+rGu0TUs8r1jVyBv0L8qfsz+TJR8XTQ@mail.gmail.com>

> I'm also not going to start discussing legal issues with random
> internet people who I seriously suspect are paid actors and/or have
> been riled up by them.
> 
>                Linus

This has never been a legal discussion, but a procedural transparency 
discussion. You could simply say "our lawyer didn't ok this", and that's 
perfectly fine. No one is going to argue against that.

Your action up until now is also exactly what a hypothetical paid actor 
would have wanted to see happening -- it's not helping **understanding** 
but rather only extending argument on what would have been a quick response.

Calling everyone "paid actors" don't help. If you have more than 1 
minute to waste, I am under my most regularly-used internet handle to 
respond to you. So has the person who sent the original "revert" patch.

Running a quick grep on the other mailing lists and their commits may 
also have helped answer that.

Thanks,
Peter.

Conclusion?

I'm not sure this whole conversation needs anything added on top. My opinion has been made clear, so do all of the rest of community members, but I guess it is hard to talk to someone who refuses to listen.

I am not an active Linux kernel contributor, but I have had various bug reports and patches posted to the list. There is also a bigger-sized one with my initial contribution in it (not with my name in the author list, though). But being called a "paid actor" just for pointing out how absurd Linus's response was will certainly make me MUCH less willing to work on the Linux kernel in the future. Thanks, Linus.

And, if you still couldn't get it by this point: This whole conversation was never about "we should have random Russians as maintainers". It is about how an open-source community should be run. No one lives outside of political influence, everyone has political opinions, and that's fine. What is not fine is making decisions without even citing the reason why, or the reason why an exact citation is impossible. That is the whole point. Not "we should support Russian aggression" -- and I'm sure nobody who raised the concern, save for real spam bots, really thinks like what Linus assumed.

As I have already said it out loud in one of the emails, I really hoped Linus Torvalds would have known better. BUT I'll take this as an achievement -- I assume it's pretty hard to get Linus Torvalds to behave this way.

Spam Filters: Stop Silently Rejecting Emails

2024-03-04 06:39:00

This is probably more rambling than opinion, but seriously, can automatic email spam filters stop pretending to be clever and just stop rejecting emails?

By that, I do not mean disabling spam filters entirely. What I mean is to remove one of their most extreme anti-spam measures: rejecting the email outright. Instead, I think the only acceptable strategies are: either placing them in the Junk folder, or saving them in some sort of quarantine area1.

I of course am aware the prevalence of email spam and condemn anyone who runs stupid email campaigns or outright scams. They deserve whatever consequences they get -- being rejected or getting their IP blacklisted. The problem comes when the spam filter "thinks" a email is almost certain to be spam, but it is in fact not -- i.e. false positives with a high certainty.

This might be rare to a lot of people, but I have run into this more often than I am willing to put up with. I think one of the issues is that many open-source spam filters are only designed / trained for Romance languages, or worse, just English. For example, in the default Rspamd configuration of Mailcow, there is a rule that assigns a high spam score for any email where all letters are upper case. However, this rule is fatally flawed if the email is not even written in the Latin alphabet -- it is pretty common for emails written in Japanese to spell English words only in upper case letters because they fit with Kanji and Kana better aesthetically. This has caused important emails I need to see to be rejected multiple times.

And I can assert that this has not been an isolated incidence. In my experience with using Rspamd, it has become increasingly clear that non-English emails tend to receive a higher spam score, and thus be rejected way more often. On the other hand, I am fully aware that sometimes it is simply hard to design and/or pre-train traditional email filters on all languages possible, especially for open-source ones. There are just so many languages and the spam patters are so different.

But there is one simple solution here, one that is not perfect but at least alleviates the problem -- simply do not reject any email! A silent rejection is the worst a spam filter can do, because there is no remedy once done -- since you don't receive the email anywhere, you can't even tell the spam filter the fact that it is not supposed to be spam. In many cases, if you move an email from Junk to Inbox, this will inform the spam filter that it has made a mistake and should readjust itself. This is simply not possible if the email does not even appear inside of Junk.

This problem does not seem to be limited to just Rspamd or non-English emails. I have seen cases where Gmail and Outlook silently reject emails as well, especially from lesser-known or self-hosted mailboxes. Recently, there has also been a wave of people who fail to receive emails from IRCC2 to which they must reply3 to have their newly-approved permanent residency processed. Although it is entirely possible that this is an issue of the internal mail server of IRCC itself, I also would not be surprised if many of these cases are due to Gmail or Outlook etc. rejecting them silently, and in fact they already seem to have a tendency of putting them in spam for those who are able to receive these emails.

Personally, I honestly do not even see the problem if all supposedly spam emails just go into the Junk folder. Most email clients won't download the Junk folder proactively, and it gives you a way to retrain the spam filter to fit your specific needs. If one really insists on not seeing any spam mail whatsoever, then a quarantine1 mechanism like that of Mailcow can be implemented -- an almost-silent rejection that can be reversed by request if the user logs into a separate web page. On the other hand, if one has to constantly check this separate system, I feel that it is not different from just using the Junk folder after all.

As of me, I have already increased the threshold for rejection on my mail server to 5000, effectively disabling the silent rejection strategy. I would simply not trust a piece of algorithm to make the decision that I just do not need to see some piece of email at all, and I do not want to even have the slightest chance of losing an important email due to a false positive. Self-hosting my mail server gives me this level of control, but for those who use Gmail or Outlook, I could only wish that Google or Microsoft eventually stop using the silent reject strategy as well.


  1. A junk folder-like area but it may be invisible in email clients, and get cleared after a certain duration of time. 

  2. Immigration, Refugees and Citizenship Canada 

  3. Confirming your permanent residence online 

pass-gocrypt: Yet Another Metadata Encryption Extension for Pass

2022-11-08 11:24:52

I have switched to pass, the password manager that conforms to the Unix philosophy, since a few months ago. It stores passwords as a bunch of .gpg files laid out in a file system directory, optionally being a git repository, and provides a bunch of shorthand commands for password generation and management. Compared to other fancy password managers with intricate UI / UX, pass feels very refreshing due to its simplicity and portability. You can use it basically anywhere where you have coreutil commands and gpg -- and even on platforms without standard UNIX tools, it is pretty straightforward to create a platform-specific UI for it, such as the Password Store app on Android.

There is one big issue with pass, however, and that is metadata leakage. Because of its use of simple Unix directories and files, even though your passwords themselves are encrypted, metadata such as sites and apps you use is leaked in plaintext as the file and directory names. Depending on the specific directory structure you adopt, it could also leak the account IDs that you use on each service. This may or may not be a problem -- for most services, your online presence there is probably already public knowledge. This applies to email, social networks, Git hosting, forums, and pretty much everything with user-generated content. But there is a substantial subset of services, at least for me, where my presence is not and shall not be public knowledge. For example, the exact hostnames of my personal servers, the services I host on them and my credentials for those services should preferably be kept private.

Another issue with pass is the use of asymmetric cryptography only -- it is convenient when the asymmetric key can be stored on a hardware token like YubiKey, and to be frank, it may be more secure than a symmetric passphrase (when the private key is stored on a hardware token only). However, no asymmetric cryptography in use today is quantum-resistant, and depending on your exact threat model, this could be an issue. It is certainly not an issue for me at this point, but I would not mind if the password store can be protected by another layer of symmetric cryptography, just in case generic quantum computing becomes a reality way faster than anybody thinks it would -- although it does not seem to be likely anytime soon.

Existing Solutions

Now, of course, since pass has existed for more than just a few days, and the fact that pass, being just a shell script, is very extensible, there have been a lot of solutions to these issues:

  • pass-tomb, which stores the entire .password-store directory inside a Tomb, a wrapper script built upon LUKS. This, however, requires root permissions, since the use of device mapper is limited to the superuser. The use of DM also limits its potential usage to Linux only, with little to no hope for cross-platform compatibility (unless someone digs into the undocumented internals of DM and re-implements everything bug-for-bug on another platform).
  • pass-grave, storing the entire password store inside a .tar.gz file encrypted with GPG. This does not require root privileges like Tomb does, and tar is a portable format, unlike LUKS. However, this does mean that every time we need to decrypt the password store, all files must be extracted from the tar and physically written to the underlying filesystem, and vice-versa when closing the password store. Not only is this not very elegant, it also creates a potential leakage if the underlying filesystem does not truly erase deleted data (which is the case for most filesystems).
  • pass-coffin, another extension very similar to pass-grave. It also puts the entire password store inside a tarball wrapped within a layer of GPG encryption. As far as I can tell, pass-coffin is essentially the same as pass-grave, with the only difference being the exposed command line interface. It also aims for better code quality than other extensions, but this is beyond the scope here.

As you may see, all of these have at least one deal-breaker for me, be it the dependence on root privileges and LUKS, or the fact that every open / close operation generates a huge bunch of actual filesystem I/O that may even leak the metadata we are trying to protect in the first place. That is not even considering at least three common issues of these solutions:

  • They break pass git functionalities. Although all three of the solutions mentioned above do still technically allow the usage of pass git, it only works with the decrypted form of the password store. Even though some of the authors (such as the author of pass-coffin) urge users to back up their password stores using git, the repository that is pushed to a remote is decrypted, in its original form, defeating what I see as one of the main goals of adding another layer of metadata encryption. I am personally more worried about a remote git repository leaking metadata of my password store than an unencrypted directory on my disk would do.
  • They still fully rely on the security of GPG only. As mentioned earlier, this may or may not be an issue for you, but I would not mind if there was an option to add a standalone symmetric passphrase to the encrypted password store, such that accessing it requires both the gpg private key and the symmetric passphrase.
  • They operate under a "all-or-nothing" model. Because none of the solutions work on mobile platforms like Android as of now (also partly due to the reliance on LUKS in the pass-tomb case), it means that metadata encryption and mobile support is mutually exclusive. Ideally, the user should be able to choose which entries to encrypt under the metadata encryption scheme, while leaving the rest as-is -- as mentioned before, you probably do not need all of the entries to be hidden behind metadata encryption. These entries without metadata encryption would be accessible on all platforms and devices. This, combined with the extra symmetric passphrase, also allows one to set up an effective "trust hierarchy" within one single password store, where devices holding the repository would not necessarily be able to read the metadata of the full password store -- at least without the extra passphrase.

Design Goals

I love the simplicity of pass, but I also love to not have to worry about metadata leakage. Since none of the existing solutions really meet my needs, I set out to design and implement one myself, just like how most OSS projects are created. Specifically, I want something that:

  • Provides a reasonable level of metadata encryption within a single password store, such that it would play nicely with scripts and browser plugins based on pass
  • Must play nicely with pass git, i.e. content after encryption must be possible to synchronize using Git just like without metadata encryption
  • Must be able to encrypt only a user-selected subset of entries
  • Must not generate an excess of filesystem I/O during normal operation
  • Must support adding a symmetric passphrase for extra protection

But, as I am far from a cryptographer or security engineer, I would not trust myself to roll a encryption scheme like this. That would be essentially equivalent to (or even harder than) inventing a full password manager all over again. Instead, just like what the author of pass-tomb did, I started searching around for something that I can build upon to implement these features.

Gocryptfs

Enter gocryptfs. Unlike LUKS, used by Tomb, gocryptfs is a userspace implementation of file-based encryption. It operates on a directory tree with a bunch of sub-directories and files, instead of on fixed-size block devices like LUKS does. Being implemented on top of FUSE, it also eliminates the need for root privileges, at least when unprivileged FUSE is allowed.

The nice thing about gocryptfs is that you can use it to set up an encrypted subtree anywhere on the filesystem, and of course this includes inside a pass password store. With the passphrase, an unprivileged FUSE mount would immediately provide a decrypted view into the encrypted subtree, without any actual I/O (other than gocryptfs metadata reads) being done. This is immediately way better than Tomb, and a LOT better than the very, very excessive I/O that pass-coffin and pass-grave do to the password store.

Because gocryptfs operates on files, not blocks on a block device, it would play very nicely with git by simply setting up the encrypted subtree somewhere inside the original pass repository. Of course, git will not be able to track changes inside encrypted files as diffs, but it could not do so to begin with inside a pass tree, so this is not really a disadvantage. gocryptfs itself works on Linux and macOS using libfuse, while a port to Windows also exists as cppcryptfs thanks to the simple and documented encryption scheme designed by the authors of gocryptfs. Even an Android port for gocryptfs exists as DroidFS, although it is not clear at this point how one could integrate this with the Password Store app.

gocryptfs relies on proven symmetric cryptography only. For our purposes, we could easily store the symmetric key inside a GPG-encrypted file for seamless operation with the rest of pass, or we can also add another passphrase to use along with the GPG encrypted one for extra protection. To put it simply, gocryptfs seems like the perfect choice to implement metadata encryption for pass.

Integration with Pass

I then set out to write an extension for pass, pass-gocrypt, that integrates gocryptfs with pass with a convenient command-line interface.

As both pass itself and its extensions are just shell scripts, pass-gocrypt is also pretty simple to implement. What I needed to do is basically a command to initialize the subtree encrypted by gocryptfs, a command to mount (open) it and another command to close it and return to an encrypted state. A few more shorthand commands would be nice, but these three are more than enough.

The gocryptfs subtree will always be located inside the .gocrypt subdirectory in the password store, and the decrypted version will be mounted at gocrypt (without the leading dot), also directly inside the directory of the password store. To initialize the .gocrypt directory, the extension simply invokes the existing pass generate command (albeit internally) to produce a random password, with a length of 32, named gocrypt-passwd inside the store. This password, optionally concatenated with another user-provided static passphrase, will be passed along to gocryptfs as the symmetric password for encryption.

Originally, I was to use some sort of key derivation to combine the user-provided passphrase with the randomly generated password protected by GPG. However, it was a pain to use any sort of proper KDF in bash, and I was reluctant to depend on Perl or Python for that. In addition, I realized that gocryptfs already uses scrypt (a type of KDF) internally before using the passphrase as any sort of encryption key, so a simple concatenation outside of gocryptfs should already be enough. As there is no real limit on the input length of scrypt, the concatenated password should already have all the properties we need.

After creating the gocrypt subtree with pass gocrypt init, you can then simply mount the encrypted subtree with pass gocrypt open, and after a while, unmount it with pass gocrypt close. This style of command line interface closely mimics those provided by pass-tomb and pass-coffin, and should be pretty straightforward to most users. When an extra symmetric passphrase is needed, the user will be prompted when running pass gocrypt open.

When the encrypted subtree is opened, all entries will appear under the gocrypt/ subdirectory inside the password store. This makes it compatible to all tools expecting the standard pass store format, albeit with a gocrypt/ prefix. All pass commands will work transparently inside the gocrypt/ prefix. However, for convenience, and for git compatibility (as will be mentioned later), you can (and should) operate inside the subtree using pass gocrypt <pass-command>. For example, instead of pass edit gocrypt/My/Password, you can use pass gocrypt edit My/Password. Notice how the second command does not include the gocrypt/ prefix, but has to be invoked under the gocrypt subcommand. All known pass commands have an equivalent one under the gocrypt subcommand, which will operate inside the subtree encrypted by gocrypt only.

git compatibility is a little bit tricky still, unfortunately. Don't get me wrong, git itself works perfectly fine with the encrypted subtree. The problem is that when you use the pass commands to generate or edit passwords, a corresponding git commit will be generated with the name of the file in its description (and, the generated commit may not have the correct files staged inside the encrypted directory). This defeats the purpose of implementing metadata encryption. As there is no way for pass extensions to hook into the generation of commits, the only way to work around this is to require the use of the wrapper commands (as mentioned earlier, the pass gocrypt <pass-command> family). These commands suppress the generation of the default commits, and instead creates git commits on their own with a generic commit message.

As an added bonus, these wrapper commands also enable nested repositories for us -- the encrypted subtree itself can be its own standalone git repository! By simply running pass gocrypt git init, you can create an entirely separate git repository just for the encrypted subtree. This repository would not need to be pushed / synchronized on its own, because all of its state (.git) will be automatically included in the outer repository in the encrypted form. Doing so allows the history of the subtree to be tracked separately inside the encrypted directory, without leaking it to the history of the outer repository. After a nested repository is created, all pass gocrypt <pass-command> commands will generate two git commits: one inner commit that includes the detailed file names and changes, stored in the encrypted subdirectory; and another one generic outer commit that includes all the changes inside the encrypted subtree, along with its corresponding (encrypted) .git history changes.

By this point, all of the features I needed (as laid out earlier) have been implemented. The rest is just a few quality-of-life improvements, such as the ability to close itself after a given timeout using systemd-run, and a shorthand to move passwords between the encrypted / unencrypted subtrees. Please refer to the git repository for the latest list of features.

Using pass-gocrypt

To install pass-gocrypt, you simply need to copy gocrypt.bash to the correct path. This can be the .extensions subdirectory in your password store, or one of the supported system-wide extension paths. Please refer to the documentation of pass for details.

Here is a sequence of commands that demonstrate the usage of pass-gocrypt. What is laid out below is basically an excerpt from the project README.

To initialize:

pass gocrypt init
# With extra passphrase:
# pass gocrypt init -p

To generate a password inside the encrypted subdirectory:

pass gocrypt generate "My/Password"

To view a password from inside the encrypted subdirectory:

pass gocrypt show "My/Password"
# or simply: pass show "gocrypt/My/Password"
# or from any other pass-compatible GUI, when the subdirectory is opened

To move a password from outside of the encrypted subdirectory to inside:

pass gocrypt crypt "My/Insecure Password"

To close (unmount) the encrypted subdirectory:

pass gocrypt close

To re-open (mount) the encrypted subdirectory:

pass gocrypt open

To make the encrypted subtree a git repository of its own:

pass gocrypt git init

Conclusion

pass-gocrypt is a simple yet powerful tool to improve the security of pass, the standard password store for Unix. Although it is currently only tested on Linux, it should work with minimal changes on macOS and Windows (patches welcome). As gocryptfs is available on Android, it should be possible to extend Android Password Store with pass-gocrypt support, too, although this has not yet been done. Nevertheless, since we only rely on proven and documented cryptography, I expect it to be pretty straightforward to port and extend on any platform -- just like the original pass tool.

Being towards Death

2022-07-03 10:49:39

When I was a kid, there was a phase where I was extremely afraid of, I kid you not, sleeping. I am not sure how common this is among children, but for me it is a somewhat embarrassing piece of memory. The reasons for my fear of sleeping are a little bit complicated, but one of the major causes is the fear of "not waking up", or sometimes, "not waking up as the same person". To me, it seemed like participating in a Russian roulette game every time I fell asleep: how would I even know whether I, this exact "me", am going to wake up again a few hours later? The loss of consciousness when sleeping seemed to be exactly the same as dying, save for dreams, and the fact that we generally do actually wake up the next morning. For one thing, one could simply just die in a sleep and not even knowing anything. That, for some reason, probably of little rationality, sounded very feasible to the past me, especially after learning about my great-grandma's passing in this exact manner. But beyond that, how would I even know that the person waking up in my body the next morning is the same person as when I fell asleep the night before? It could very well be the case that this consciousness experience that I call "me" is actually different every single day. In that sense, I am only a being who lives for as long as the day lasts, and when I go to bed, that is the end of this current incarnation of "me".

For quite a long time, actually, I had a bit of insomnia for this exact reason. I would lie on my bed, pondering about all of this, and eventually pondering about very generic philosophical topics like life and death, only falling asleep when I cannot keep myself awake anymore. A kid worrying about all of this might seem cute and funny to adults, but I genuinely had a lot of deep thoughts during these sleepless nights. Well, at least they were deep to a kid that I was -- and I am sure they would be somewhat laughable if I said it out loud today. As time went on, the fear of sleeping slowly faded away, but that was not due to some sort of revelation as a result of my pondering. Rather, it was because of me learning how to suppress my inner fear of death -- something I think we all do as we grow up. After all, not sleeping well every single night sounds like a quicker way to die early, in a rational sense. Or shall I say, the practical and rational side of me eventually won against the somewhat emotional, fearful and irrational side of me.

But were those fears so irrational after all? The same thoughts still come back to me sporadically even after my adulthood, despite the fact that I try to suppress them as hard as I could. Of course, I eventually concluded that talking about whether the consciousness that wakes up every day is the same person is meaningless, because there seems to be no physical way to define one specific consciousness without relying solely on memories and experiences. However, this does not really rule out the fear that I, in the sense of a mental experience, would not be the same the next time I wake up. It could very well be the case that there is simply no consistent way of tracking one single stream of conscious experience through time, that my experience in every single unit of Plank time is different from that in the previous one. The illusion of a consistent "me" only exists as a result of the continuous transition from one Plank time slice to the next. The act of sleeping, or anything that involves the loss of consciousness, means the breaking of such an illusion, and thus the breaking of oneself as a mental existence. On the other hand, as we grow older, the chance of actually dying does also increase in a very real way. I could suppress my own fear as hard as I can, yet all of these thoughts still dread me from the deepest part of my mind.

Stepping back for a moment, why do we fear death, or "not waking up as the same person", which is basically the same thing, anyway? It once occurred to me that I did not actually know the reason for me. What does it change for me, if, say, there is not actually a consistent existence of myself? Would I do anything different? If not, what is the point of having this fear to the point that it prevents me from having a good night's sleep? Even if I knew I am going to die in my sleep tonight, what would I be able to do? And what is the difference between dying tomorrow and, say, 50 years later? It seems that to a person, once they cease existing in this world, then nothing would ever matter again, and whatever one did or did not do makes absolutely no difference. Disappearing without pain in one's sleep seems to be the best way of passing under this interpretation. The dread is very real, except that I could not explain where it came from, let alone finding myself a way out.

About one year ago, someone who I had a fair amount of connection with online passed away in her sleep due to something as simple as hypotension. May this year marked the first anniversary of being on the internet without her. For this reason, I and a few friends of her (who are also friends of mine) became a bit emotional around that time this year. A lot of us were talking about how great a person she was, and how much she meant to all of us. I also posted a somewhat emotional article on my second blog remembering her, and my thoughts at that time on the meaning of life. The general idea of what I wrote is that, because we never know whether and when the same sort of things would happen to ourselves, trying to assign a meaning to our lives is ultimately futile. If we define the meaning of life as realizing some sort of dreams or accomplishments, what would we say about her? Would I be cold-hearted enough to say that her life is meaningless because of her early death, or is it not meaningless because she tried to live her best life until the final moments?

While I was writing that article, it struck me that trying to assign a meaning to our lives is also a main reason of my constant dread for death. By that, I do not mean that death itself is not something dreadful -- but the fact that I might live a meaningless life is more dreadful than the fact that all of us will eventually die. Life is fair in the sense that everyone has limited time in this world, but I have always been taught that the meaning of every single person's life is different. It is somehow despisable not to achieve something "meaningful", and we often mourn for people who passed away at a young age for their lost potential of achieving something later in their lives, not for the actual loss of a life.

In the article, I concluded that life does not, ultimately, have any particular meaning. Humans assign meaning to life, just like they assign meaning to everything else. But we should not forget that all of this is just a figment of the human mind -- nature, the universe, or whatever higher being you believe in, does not care even the tiniest bit of what we mere humans think of our lives. Compared to the age of the universe, even the longest-living humans are nothing more than a blip in the never-ending flow of time. If the universe had its own mind, what would it think of our tendency to judge our lives based on what we assign to them as "meaning"? Probably the same way how we see kids, just like me, who worry about life and death -- "cute".

Dreading for death before achieving some particular goal, in this sense, is as meaningless as life itself is. This does not mean, however, that all of us should just do nothing and wait for, or even accelerate our inevitable demise, at least not in my books. Think about it this way -- what do you do after you achieve your goal, if you think that the meaning of your life depends on that goal? I believe most people would not just say that they may as well die the moment they achieve their goals. It is the same case when you do not believe an inherent goal or meaning of life. There are many, many things to experience on this world -- way more than just achieving one or a few goals. Being born on this world is an opportunity, or, if you prefer, a blessing, to experience all that this world has to offer. Because of the lack of an inherent meaning to life, we get to decide what we want to do with our own lives. This of course including the decision to achieve something beneficial for the entire race of humanity -- but there are so much more. From this point of view, obsessing over an arbitrary "meaning of life" and not trying to experience life itself in its fullest form is a waste of a great opportunity.

The YouTube channel Kurzgesagt had a great video on Optimistic Nihilism, which generally matches what I described. It is classified as nihilism due to its rejection of the idea that life has to be inherently meaningful, but optimistic because it does not urge people to give up on life for the reason that makes it nihilistic. The logic goes the exact opposite way -- because life is inherently meaningless, and because how unimportant every single one of us is, it is us who should make the most out of our own short existence. There is no need to worry too much about whether I will wake up the same tomorrow, because it does not make a difference -- whether I live for one day, or 100 years, what I will do is exactly the same. As one of my friends hinted, extrapolating from the same topic: all that matters are the experiences and memories we collect along the way.

We will all eventually die. Is that dreadful? Of course, because what lies ahead is unknown. But before that moment eventually comes, we have all the opportunity to define our very own lives. Make friends, try new things, create art, do what you love, experience everything you can with your limited time. At the very least, when our final moments come, when our lives flash before our eyes, we could then smile and say, "that was a good life".

Cryptocurrency Ramblings

2022-05-14 11:00:29

I used to be a cryptocurrency enthusiast, though not of the type who became billionaires by mining bitcoins on a single CPU for 30 minutes in the early 2010s. The story began in 2016, the year when I graduated from high school and finally became an undergraduate student. Naturally, I had a bit more financial freedom than I did in high school, which led me thinking about, well, "investment". Around that time, Bitcoin and blockchain in general was gaining unprecedented popularity, with a lot of money pouring in and new exchanges being founded almost every single day. Mining farms were being build everywhere in China. There were a few close friends of mine who started playing with blockchain, some of whom invested a considerable amount into Bitcoin. As someone who loves new technologies, I could not resist the trend but to also set up my own Bitcoin wallet and start to play around in the Bitcoin market.

Lucky for me, there was a serious uproar in the Bitcoin market nearing the end of 2016, right after my first ever investment made in Bitcoin. I vividly remember it was in a Monday morning, when I was on my way to the university, that I saw the unbelievable exchange rate on my phone. My heart started pounding like crazy. Even though I had next to zero experience in any sort of trading before, I still knew that such a ridiculous sudden climb in prices will not, on itself, hold for very long. As the seconds passed, I stared at my phone screen, with my hands sweating uncontrollably, hovering over the "sell" button. As the price reached around CN¥8000 (~US$1500), I made up my mind and clicked on the button.

That was the first time I earned anything through investment. I was thrilled, and even more thrilled later after learning that the Bitcoin market crashed a while after that peak. I was relieved that I made the right call, and also quite a bit complacent for my "ability" to make the right call at the right point. However, I did not really make a lot more investment into Bitcoin after that, simply due to the fact that I was worried I ran out of luck and will be tremendously disappointed the next time. Despite that, the first-time earning definitely sparked my interest in the technology as a whole. Following that year, I started to learn a lot about blockchains, including Bitcoins and other cryptocurrencies. I started mining CPU-based coins using a server I have idling. A lot of other decentralized software, not limited to just blockchains, entered my field of view as well. Some notable ones include ZeroNet and IPFS, and a plethora of content distribution systems, based on blockchains or not.

Though I did not continue investing a lot in Bitcoin or other cryptocurrencies themselves, I was nevertheless a firm believer of the entire blockchain ecosystem. The fact that these systems can work without a central authority, at least not technically, fascinated the young me who just started my CS program. To me, this was the future -- the decentralized future, where all centers of power are dissolved and a censorship-less, privacy-first internet, and, beyond that, such a society, would arise -- a pretty naïve technological anarchist, I know, but that was what I believed in. Despite not making direct investments into any cryptocurrency out of fear of volatility, I held onto a small but significant amount of Monero from my mining machines. For a brief moment, I even attempted to run a full Monero node. I tried to use cryptos for payment of everything, including my VPS, my dedicated servers, and donations to various foundations.

All good and dandy until I eventually started to realize the countless downsides of blockchain. Aside from the obvious fact that proof-of-work is extremely wasteful (which I did not realize at that point), the inconvenience of Bitcoin-based payments definitely bugged me a lot during those years. I held on to Monero, but I still had to use Bitcoin for payment quite a bit due to its popularity. Every time I try to do so, I had to sit in front of a screen waiting eagerly for the transaction to go through. Five minutes, ten minutes, one hour, until a confirmed check mark is finally shown on the transaction. This is simply excruciatingly painful. Although this is quite specific to Bitcoin due to its popularity and, well, inefficiency as a first-comer, and they did make the effort to improve the situation, it is nevertheless way more annoying to use than everything else.

This was far from the major deal-breaker for me with blockchain-based cryptocurrency, though. That turning point came way later, when I realized how 90% of new cryptocurrencies were simply money grabs, or worse, pretty much frauds. This realization was from my participation in a (at that time) new cryptocurrency which shall not be named. It promised great returns on investment. It promised great earnings from mining -- which is why a few friends and I all thought about mining and trading some of it. What I could not help but notice though, is that even though they mentioned all of these great investment prospects, they failed to present any technical innovation, not even the tiniest bit. They just forked the code of Monero, changed the name and the genesis block, and started a campaign. Did they believe in decentralization, free software, or even privacy? I fear not, as if so, they would have at least mentioned it in their whitepaper and homepage. At the very least, someone who really cares would not, in my opinion, do something like this without any substance.

After that, I went and checked a bunch of newly-launched cryptocurrencies. To my surprise (but probably to nobody else's), most of them fell into the exact same category -- loads of buzzwords about financial gains, but little or no technical substance whatsoever. My later experience with a few professors in my university who work on blockchains certainly did no help in improving my plunging impression about them. One of them, who shall not be named, allegedly might have mined cryptocurrencies in the university. The course he taught, which is supposed to be about foundational operating system concepts, ended up being nothing about what you expect from an OS course. Instead, the coursework literally asked students to write papers about blockchains or other related areas. He even ran one of his own conference-style thing about cryptocurrency for these substance-less papers. Another one was better than the previous one by a million light years, and I thank him sincerely for his appreciation of my skills and help in my academic life while I was working in his lab, but this still did not give me a better impression on the entire cryptocurrency community. His work, and work I have done with him, definitely had some substance in them instead of being money-grabbing bullshit like the others, or at least I believe so. However, at the end of the day, I still had no idea what our work meant, if cryptocurrencies were to be the future of economy. Did I work on something that make them better? I often ask myself. And the answer, to me, is a no.

Do I hate my professors? Other than the first one, no, not at all. On the contrary, I am extremely grateful for all that they have done for me as an undergraduate student. But the experience doing research in the field simply makes me realize the cold fact about the area -- most people are too profit-driven and few are really working in the field for what Satoshi Nakamoto originally believed in. And I don't even blame them personally -- were there an easy opportunity to become a millionaire, I would do it as well. This does show, however, that true decentralization cannot work purely based on what Nakamoto laid out as the blockchain technology. It creates a self-fulfilling market and the entire community built around such a market. Whatever Nakamoto envisioned for his brave new world, the truth is that everyone is working not for decentralization, but re-playing what has already happened -- centralization of wealth -- just on a different medium.

Nowadays, the sentiment against blockchain-based coins / technology is growing like wild fire. I should be happy, right? Maybe not. For all my hatred towards people who claim to be enthusiasts of cryptocurrency while chasing only profit, I cannot say the same to the technology itself. Don't get me wrong, the blockchain technology as it is today can never be something I will actively advocate for due to its countless pitfalls and shortcomings, not to mention the extreme centralization of computing power and the privacy issues in current popular implementations. But it is not like the non-blockchain financial system is much better in any of these aspects -- centralization of power, tick; privacy issues, tick; the only advantage of it is the power consumption because it does not involve any proof-of-work. Blockchains currently do not solve these problems per-se, but it is so far the only one that looks promising in any capacity at all. At the very, very least, trying to "freeze" accounts or "block" / "reverse" transactions on blockchains with proof-of-work is way harder than in your traditional banks, who have made the headline multiple times in the past year.

I could argue for days why this exact property of blockchains is a good thing or a bad thing, but at the end of the day, just like many things in society, what we need is a balance. The existence of an alternative to traditional banking systems, to me, is not to replace everything, because that would be impractical. Of course, something better than proof-of-work may be able to finally push blockchains towards practicality in general, but at this point it just does not seem likely without another few Satoshi Nakamoto. We have potential ideas for improvement, but they are delayed and delayed and the date of deployment seems pretty far away, not to mention that these ideas generally trade some of the advantages of a PoW blockchain for better performance. Not to mention that the ability to block accounts or reverse transactions can be desirable sometimes. Rather, in my imagined future, these systems, when they (potentially) become mature enough, should act as a check on the old systems, such that abuse of power in the old ones carries an additional risk from people fleeing into the other system.

Where does this put me now? I am not actively holding any number of cryptocurrencies at the moment, and I personally do not want to invest into them in the near future. Nor do I want to be involved in the current cryptocurrency community, academic or not, in any capacity. But I do hope that the technology will come to fruition one day, even though this day may be far, far in the future.

Writing Challenge

2022-04-19 05:25:32

I have been thinking about taking the 100 days writing challenge for a while. Not just for a little while, but for at least a few years by now. Within these few years my blog have been destroyed and restored multiple times, I graduated and I moved -- basically, everything has changed. Yet I have never really made the decision to attempt to write every single day.

Not surprisingly, the main reason I have not done so is due to the big commitment I have to make in order to complete it. Writing everyday is not something very easy -- it's certainly not hard, but it still takes a non-negligible amount of time and energy out of every single day. Like any "beneficial" habit, it is simply hard to make up one's mind to make the initial commitment, just like many have not made up their minds to lose weight, or to try a different kind of diet.

To me, though, there is something more about this unwillingness to commit to writing as a habit. One of them is the idea that all writing has to present a well-supported argument with eloquent words and beautifully organized structure. If I am writing stories, then they have to at least be interesting to someone other than myself. They need to have an eye-grabbing beginning, a twisted plot, and a satisfying ending. Moreover, they have to try to show readers some takeaway through the story-telling. And of course, as English is my second language, I was basically trained to be extremely careful about grammatical errors by all the tests and exams I have been through. The result is simple -- every time I try to write, this pressing anxiety begins to creep into every single nerve of my brain, and, well, it makes writing, at least in English, a somewhat exhausting process. Every time I publish a blog article, I have to go through a time-consuming process of trying to organize the article in a bunch of different ways, figuring out what exactly to say in each paragraph or even each sentence, and so on. As you might be able to see, this means that I was really only willing to write about things I consider "important" for more people to know about, for example, technical challenges not solved by Google-fu.

I could simply not write in English, then, if the problems come from my training of English as a second language. Except I can't. First of all, the idea that writing has to be formal is not limited to just English. I did not get this from my English training, but rather, from the fact that all writing training I received is under an academic setting. Obviously, for something academic, one would want to be as formal and structured as possible, because you would not get too far in the academic world without some nice, cough, papers. Secondly, although my mother tongue is Mandarin, I, somehow, feel even more pressure when I try to write in Chinese. It might be from all the Chinese exams I had to take during my high school years, which forces me to come up with something nice for the writing task, taking up almost half of the total marks for those exams. What's the result of scratching my head over and over again for more than 3 years in high school? Every single Chinese exam, every single one of them, gave me just the passing mark for all my effort. I might write another blog post just about my current inability to write in my own native language. The takeaway here is that if I were to try the writing challenge in Chinese, it would be even harder.

I am trying to work my way out of this mindset, for both English and my native language Chinese. I need to stop thinking about what others would think of my writing. I of course write for others to read, but what I write needs to reflect me, not what I expect others to expect from me -- that, is too many levels of "indirection" to make sense. When I have something well-supported to argue about, fantastic, and I should definitely write a nice long article for it. But when I don't, it is no shame to simply admit that I am not sure. It is okay to not be that most knowledgeable guy. It is okay to make mistakes. Because these are all part of me -- and through writing, I'd like the readers to know me.

Will I ever take the 100 days writing challenge? I am not sure. Even if all the problems above are resolved, I might still not want to write publicly every single day. When you write that much, it is inevitable that aspects of your daily life will eventually be leaked into what you write, either directly through your own words when you have nothing else to write about, or through the patterns visible from your posts. I, coming from a background where everything can be used against you, probably will never be comfortable with such a possibility. I want to record my thoughts, and I want my readers to know me as a person, but not the entirety of me -- and I feel that taking on a challenge like that is the perfect opportunity not to do so.

What I will do, though, is to write more. Like, more than how much I did before. When I have blog ideas, I will try to force myself to get something out of them, even if the resulting product is not well-organized to my satisfaction. I am also going to start a private diary that I will, at least attempt to, update every day. It will not be public, but hopefully some great writing ideas can come out of it. It would also be a nice archive of who I am now and how I am changing over time, which is always nice to have. To be honest, I hope I have had a diary way earlier. When I was younger, I never thought that I could change so much one day, but here I am, almost a completely different person from who I was 10 years ago. It would be nice to be able to see how I changed, which could also serve as a guide for myself, or even others, in the future. Hopefully, this time, I will have such an archive.