Category Archives: freebsd

FreeBSD 12.1 + Alpine with GPG

Intro:
I decided to install GPG on FreeBSD with alpine. What does this do? It’s the old days, using pgp to encrypt your email before sending. This is a howto so everyone can start encrypting their emails. Why do it? Back in the 90s when I was sitting in computer science class it was common courtesy and etiquette to always provide people with your PGP key when sending emails. So by not providing people with your PGP key, it’s considered disrespectful among the computer professionals. This is a tribute to my old classmates Isaac Eaglestone and Jason Barlow, I wish I could find them again. Especially Isaac who would bitch me out every other day for not using it 🙂 To be fair it was a headache to get anything working back then with an email client, considering all we had to work with was Slackware Linux back then, so I decided let’s go through FreeBSD, pull our hair out fixing any errors that pop up and let’s get a reliable Alpine + GPG setup going!

Can this stop quantum computers?

By now we all know Shor’s algorithm is set to break all asymmetric encryption. So what we will do is use best encryption we can with GPG using symmetric encryption, GPG supports AES256, so we will use that along with using RSA for compatibility. For all said purposes we will use the strongest that makes sense and stay compatible with other people’s keys as well.

Why use alpine?

If you ssh into systems on a regular basis, it makes no sense to download your email to an insecure device at home. If your using openvpn to download over VPN to a client such as Kmail to your Google Pixel Phone, it should be ok. What makes a phone insecure is trusting to many app developers. FaceBook for instance has been known to go behind people’s backs and upload your contacts to their servers. FaceBook also owns whatsapp. If you want to keep your phone secure, don’t put these on your phone.

FreeBSD Prerequisites: PART 1

Firstly I prefer using alpine with Postfix and Maildir support, since the Maildir patch is not available with standard pkg system. Off to the ports we go:

Let’s install alpine from ports, lock it from package manager updating it, install alpine gpg addon from pkg system, and see what directories it used for installing it.

cd /usr/ports/mail/alpine
make config #(Select Maildir patch)
make
make install
pkg lock alpine
pkg install ez-pine-gpg 
pkg list ez-pine-gpg

(Assuming your using bash for your shell and nano for your editor)
Next we want to get rid of any “pinentry” errors that may come up, the first problem I ran into, the following will solve it next login:

alias pico='nano -w'
pico ~/.bash_profile #(add the following next line,save and exit)
export GPG_TTY=$(tty)

At this point at least run alpine once to get your .pinerc created if its not already, then let’s open .pinerc and REPLACE display-filters and sending-filters with the following:

# This variable takes a list of programs that message text is piped into
# after MIME decoding, prior to display.
display-filters=_BEGINNING("-----BEGIN PGP")_ /usr/local/bin/ez-pine-gpg-incoming

# This defines a program that message text is piped into before MIME
# encoding, prior to sending
sending-filters=/usr/local/bin/ez-pine-gpg-sign-and-encrypt _INCLUDEALLHDRS_ _RECIPIENTS_,
        /usr/local/bin/ez-pine-gpg-encrypt _RECIPIENTS_,
        /usr/local/bin/ez-pine-gpg-symmetric _RECIPIENTS_,
        /usr/local/bin/ez-pine-gpg-sign _INCLUDEALLHDRS_

Alright we are getting closer, now we want to actually create our gpg key if you don’t have one already, now we run into the ssh X11 forwarding headache if you have it enabled when you su to another user, so to make sure we have no issues ssh to localhost as that user without X manually so we don’t get any end of file errors creating our brand new key. This generally happens because when you su to another user, the tty is still owned by user who logged in on tty device and permissions are generally 600 on it. You can get around it by chowning the tty device or using tmux, but honestly why go through the trouble, just ssh as user you want to create the key with:

ssh -x localhost #(disable X forwarding for this user)
gpg --full-generate-key

Enable encrypted swap space if you have newer hardware and your CPU supports AES-NI, here is a quick test:

swapoff -a
kldload -n aesni
swapon -a
dmesg #this should show if CPU supports it or not

If above is supported, put aesni_load=”YES” in /boot/loader.conf and append the “.eli” suffix to all swap devices. Enjoy your encrypted swap space.

Ok now let’s create our gpg.conf file, so we can remove unsecure memory errors if you don’t have secure memory space and set some defaults for encryption. You remembered to run gpg at least once so ~/.gnupg directory got created right? Just type in random crap and hit CTRL-D.

pico ~/.gnupg/gpg.conf #add following to the file, save and exit:
no-secmem-warning
cipher-algo AES256
personal-cipher-preferences AES256 AES192 AES CAST5
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
keyid-format 0xlong
with-fingerprint
use-agent
charset utf-8

Now let’s edit our keyserver daemon’s config file, this always goes through tor, so unless you want to be waiting 30 seconds for it to timeout all the time, just install tor! Yes, you could just set option for it not to use tor, but only thing that is going to do is make it start faster, after process forks it will try tor anyways, so trust me save yourself the hours of headache and just install tor so your not always waiting on dirmngr to timeout using tor, unless of course you enjoy sitting there waiting 30+ seconds for a simple command like gpg –search-key <KEYID>. This dirmngr.conf file and daemon is only used when dealing with public internet keyservers.

There is nothing wrong with using Tor, just as long as you aren’t an exit node, if you can run one awesome! Is Tor secure? Absolutely not, NSA pulled 2 people out of DefCon conference when 2 researchers from university found a way to exploit TLS in there, then they have been in talks with source code developers of Tor as well. If that is not enough they are known to run honeypots all over the system. If you want secure, your best to run a VPN, then run that through Tor. Personally I think of having Tor on my system just like enabling IPV6 on it, just another network I can talk to. For our purposes we are going to use it just so dirmngr doesn’t piss us off 🙂 Besides we can just do “service tor stop” anytime we not talking to a keyserver if we like.

pico ~/.gnupg/dirmngr.conf #add following to the file, save and exit:
keyserver hkps://keys.openpgp.org

#now setup Tor if you haven't already
pkg install tor
pico /etc/rc.conf  #add the following, save and exit
tor_enable="YES"

#I am not going through configuring tor in this article, at least go into
#/usr/local/etc/tor and configure torrc and torsocks.conf so port 9050 is #working, just make sure your not running an exit node!

service start tor  #start tor

Now you may be asking why I am using keys.openpgp.org instead of sks key servers. The reason is simple, there is a DOS attack that has been known for decades that still works on all internet key servers. The DOS is quite simple, sign someone’s key 150k+ times and upload it to keyserver effectively destroying their gpg installation once they refresh their keys. The key server I have picked for us today, is only one on internet as of this date that at least attempts to mitigate this attack. So do yourself a favor and use it! As of recent versions of gpg all keyserver lines go in this file now,  not gpg.conf anymore.  As of this date I am using version 2.2.21.

Great now let’s get on with the real stuff, playing with gpg itself. First we want to generate our key. I suggest leaving things at defaults, but you can set RSA key to 4096, there really not much security between 2048, maybe 40 bits, according to gpg website, trade off in performance not really worth it.

I am saying use defaults just to be compatible with other people, in future what we really want to do is just replace RSA with elliptical curve bitcoin uses by selecting secp256k1 in expert mode down the road. (ie: selecting 10 and 9 with next command) Let’s not do that now. We still using AES256, even with quantum computers with 4096 qubits would only knock that down to AES128, by time they have that 1 million qubit computer hopefully the quantum algorithm is out. Pick a good password! With today’s technology they can brute force 2.8 billion tries a day, that is enough to try every lower case character a-z of a 10 character password in one day! Mix it up with upper case, numbers, special characters and use 4 words if you can!

Back in 90s, I used sentences with pgp, then I always forgot what it was cause I wasn’t using it that frequently like a password you would use to login with email or ssh, so keep it to something you can remember!

gpg --full-generate-key --expert #generate our key!

You will notice it put a revocation certificate in: ~/.gnupg/openpgp-revocs.d/
You will need this to revoke your key down the road if you loose it.

Ok at this point go test it, go into alpine, send an email to yourself, hit CTRL-x like usual to send, but before typing “Y” to send, hit CTRL-p instead to scroll through sending filters, select something like sign and encrypt, then hit “Y” to send.

If all goes well, you should get prompted for your password, gpg-agent will then store this password in shared memory for a set amount of time, which you can actually specify for how long in config file, or until server is rebooted or gpg-agent is killed and restarted. You’ll notice in “ps aux” every time you deal with gpg in anyway, that gpg-agent is running.

This is how gpg works. Try thinking gpg as a key-ring management tool. Everytime we use gpg we are mostly just a client talking to that gpg-agent server process running. We can list keys in there, tell it to remember our password in shared memory for X amount of time, sign things, encrypt and de-crypt files and much more. So now just sending email to our self is not very useful.

At this point I want you to add another user to your system, I want you to repeat all these steps and do it for this second user. Send email to itself, and when you got that working and ready to send to each other, let’s continue… Remember when using su – $USER you cannot create a key if he does not have his own tty, make sure to ssh -x $USER@localhost so he get his own tty so you have no issues!

PART 2 – Actually working with GPG (our key manager)

OK if you made it this far, congratulations! The hard part is done! You completed the setup! Give yourself a pat on the back. Only things we are going to do now is play with gpg command itself, that’s about it and learn what cool things we can do with it.

Let’s start off by continuing where we left off, I told you to create another user on system and setup his .gnupg directory. So at this point let’s send our practice emails to that user back and forth.

First Step: Let’s export our public keys for each of these accounts:

cd /tmp
gpg --armor --output user1@example.com.public-key.gpg --export user1@example.com
#now for other user:
cd /tmp
gpg --armor --output user2@example.com.public-key.gpg --export user2@example.com
#I like to keep copies of these in my .gnupg directory so let's do that
#for each user do following:
cd ~/.gnupg
cp /tmp/user1@example.com.public-key.gpg .
cp /tmp/user2@example.com.public-key.gpg .
#now for user1:
gpg --import user2@example.com.public-key.gpg
gpg --sign-key user2@example.com
#now for user2:
gpg --import user1@example.com.public-key.gpg
gpg --sign-key user1@example.com

Ok great, what we did was import the key, then signed the keys for each user because we trust them. Great now jump in alpine on each user and send emails back and forth with the CTRL-p filters. Play with it for a bit, you will notice gpg-agent daemon starts asking you for your password. Pinentry program runs here to ask for it, which is

sunsaturn:~/.gnupg # ls -al /usr/local/bin/pinentry
lrwxr-xr-x 1 root wheel 12 Oct 11  2019 /usr/local/bin/pinentry -> pinentry-tty
sunsaturn:~/.gnupg # 

gpg-agent keeps your password in shared memory approx 2 hours, unless you change that in config file or you restart gpg-agent. You can kill gpg-agent and dirmngr daemons anytime you want with “gpgconf –kill all”. Or the old school reliable way of “ps aux” “kill -9 <pid1> <pid2>”

Wonderful you have done it! But wait we probably want to submit our key for at least ourselves to the internet keyservers! We don’t have to but it would be nice if we could link our email address to a PGP key on internet so people could find us easily.

Ok what we will do is submit our key to SKS keyservers as well as our default openpgp key server. Then we will add our key to our .signature file in alpine so whole world now knows we have a PGP key. We will even put a copy of our public PGP in our .signature file so people can grab it anytime through a website, sound cool? Great let’s do it…

 

gpg --list-keys #let's start by listing the keys and find our 

pub   rsa2048/0xFF6F49977311C386 2020-07-17 [SC]
      Key fingerprint = A1A7 6E84 FB0B 8994 C3B5  A1BA FF6F 4997 7311 C386
uid                   [ultimate] Dan The Man (Dan @ SunSaturn)

For example above here is my key, my <KEYID> is the numbers/letters after the pub rsa2048/0x string. So here my <KEYID> is FF6F49977311C386. The reason we have 0x in front of it is because in our gpg.conf file we have “keyid-format 0xlong”. It’s just to prevent problems really, had I done just “keyid-format long” then it would not have the “0x” in front of it. Also you can see the fingerprint of my public key. So since we are using 0xlong I can use 0xFF6F49977311C386 as my <KEYID> here.

Alright let’s submit our key to keys.openpgp.org, since that is in our dirmngr.conf file as the keyserver that is what we will default to.

gpg --send-key 0xFF6F49977311C386     #use your KEYID!
gpg --search-key 0xFF6F49977311C386   #use your KEYID!

Great if all went well we submitted our key to keys.opengpg.org and then searched it and got it back. Now wouldn’t it be cool to search by our email address instead? Go in your browser now to : https://keys.openpgp.org follow instructions in your email and this site to verify your email address so people can search for your key by your email address. Once you are done that awesome let’s see if it worked:

gpg --search-key user@domain.com #use your email now!
gpg: data source: https://keys.openpgp.org:443
(1) Dan The Man (Dan @ SunSaturn) 
2048 bit RSA key 0xFF6F49977311C386, created: 2020-07-17

Good job, now let’s submit our key to SKS servers as well:

gpg --send-key --keyserver pool.sks-keyservers.net 0xFF6F49977311C386
gpg --search-key 0xFF6F49977311C386 #use your KEYID for both!
gpg --search-key user@domain.com    #use email to if you like

Now you have to realize pool.sks-keyservers.net is a pool of addresses, it may take time for them all to sync, if you ran command “host -t A pool.sks-keyservers.net”, you can see IP address is going to rotate each time, but if you ran those 2 commands above quickly you may have gotten same IP address twice and it successfully searched the key. Don’t worry about this, check back in in 24 hours. One good thing is we don’t have to do any email verification checks to list our key on SKS servers, so we are done. For a list of pools visit : https://sks-keyservers.net/overview-of-pools.php

Almost there, last thing we want to do is tell the world in our .signature file on alpine we are able to use PGP/GPG if people wish to add our public key to their keyring to encrypt emails/files to us. For that we want our public key on our website somewhere, and we want our fingerprint for the file so we can include that for people so they know it was not tampered with.

gpg --armor --output /path/to/website/root/pgp.txt --export user@example.com
gpg --list-keys

In first command above we exported our public key to directory of our website, or just copy pgp.txt to your website on another server if needed. In the second command we looking for “Key fingerprint” line so in my case:

gpg --list-keys
pub rsa2048/0xFF6F49977311C386 2020-07-17 [SC]
Key fingerprint = A1A7 6E84 FB0B 8994 C3B5 A1BA FF6F 4997 7311 C386

My fingerprint is “A1A7 6E84 FB0B 8994 C3B5 A1BA FF6F 4997 7311 C386”. By putting a link to pgp.txt file and giving them this fingerprint in .signature file this gives people 3 ways now they can find us. Through openpgp keyserver, through SKS keyservers, and also our emails. So let’s edit our .signature:

pico ~/.signature #add something as follows:
PGP Key: https://SunSaturn.com/pgp.txt
A1A7 6E84 FB0B 8994 C3B5 A1BA FF6F 4997 7311 C386

For reference here is my .signature with my email address/phone number removed for this blog, obviously put your pgp.txt and fingerprint ID in it’s place 🙂


Dan The Man
CEO & Founder
Websites, Domains and Everything else
PGP Key: https://SunSaturn.com/pgp.txt
A1A7 6E84 FB0B 8994 C3B5 A1BA FF6F 4997 7311 C386

That’s it we are done! Congratulations for doing the entire setup! For now on all you will ever have to do is remember to hit CTRL-p to send with PGP/GPG and your password. I hope to god you can remember your password. Place a file somewhere giving you hints what it is if needed.

Closing Thoughts:

Keep your private key secure. We all know by now intelligence agencies store encrypted data to save at a later date when technology gets better to decrypt. That being said your emails should be fine until they have quantum computers with millions of qubits. If your really paranoid, create an advanced key with elliptic curves from this setup, it just won’t be compatible with most people at this point for anyone running older versions of gpg. For any important files you need to encrypt, always use the best you can. When quantum algorithms come out, unencrypt your files, then encrypt them again with newest standard. If your key ever becomes compromised revoke the keys on both keyservers we submitted to and go through creating new key again. You can also do a shared password between the both of you using one of the sending filters, cool right?

If you have really sensitive information to send someone, both of you agree to access the file over a vpn/ssh connection to download the PGP file. Gives you a double later of protection. Even better yet, ssh over a VPN connection for a third layer 🙂 Someone storing encrypted data would have to break your VPN key, your SSH key and then your PGP key, you’ll most likely be dead by then, should be good 🙂 For advanced users: create a cronjob that switches your vpn key and ssh secret/public keys at regular intervals, ultimate protection. Store your encrypted files in an encrypted filesystem preferably on an SSD with many layers of 4 or more like QLC with trim support, more layers there are, harder it is for forensics teams to grab deleted data, they will give up. Personally I don’t have any sensitive data, but if I did those are avenues I would use. For me I use VPN’s for what they were made for, accessing internal machines on remote servers like I was there.

Encrypt files: (create files with .gpg ending)

#have a friends public key imported? 
#this method you cannot decrypt .gpg file after
#only his secret key can
gpg --encrypt --recipient myfriend@gmail.com myfile.txt
ls -al myfile.txt* #decide what to do with myfile.txt
#even better way, encrypt with yours and your friends secret keys
#this way you can both decrypt myfile.txt.gpg
gpg --encrypt --recipient myemail@domain.com --recipient myfriend@gmail.com myfile.txt
rm -f myfile.txt #send him myfile.txt.gpg
#or share same password between you both
gpg --symmetric myfile.txt
rm -f myfile.txt #send him myfile.txt.gpg

Decrypt file:

gpg -d myfile.txt.gpg > myfile.txt

Enjoy your new setup!

Dan.

FreeBSD 10 Ports and pkg2ng, how to deal with binaries and ports collection at same time

Intro:
FreeBSD has implemented a new packaging system called pkg2ng. While that is great for a number of reasons, like allowing commercial companies to now have their own remote repositories or even better faster update times, we still have 1 issue. We would like to also keep the most powerful feature of FreeBSD, the custom port build options we like on our custom ports build.

Ideally what we would like to do then, since FreeBSD now stuffs binary installs and ports collection installs in same SQLite database for pkg2ng, is take advantage of updating with binaries first, then update our custom port builds as well. A big danger we face, is if we just do a normal “pkg upgrade”, we could effectively loose all our custom options in certain ports collection builds. So let’s talk about a way that we can have best of both worlds.

Pre-requisites:
I assume you are running at least FreeBSD 10, and using pkg2ng for package management, and portmaster for port upgrades. Also let us take a custom realistic scenario, let say we want to run alpine with custom options for maildir patch support, also we want to install apache22-itk-mpm, with custom modules built into apache, as well we want to use the new mariadb instead of MySQL for database.

So for this scenario we are not going to want to let binaries touch anything building MySQL, as it will install real MySQL. We also do not want binaries upgrading our apache modules as it will try to install regular apache, so let’s begin.

pkg install apache22-itk-mpm mariadb55-client mariadb55-server
cd /usr/ports/mail/alpine; make install; pkg lock alpine
cd /usr/ports/www/mod_auth_mysql_another; make install; pkg lock ap22-mod_auth_mysql_another
cd /usr/ports/www/mod_geoip2; make install; pkg lock ap22-mod_geoip2
cd /usr/ports/www/mod_perl2; make install; pkg lock ap22-mod_perl2
cd /usr/ports/www/mod_rpaf2; make install; pkg lock ap22-mod_rpaf2
(enable apache module in make config below)
cd /usr/ports/lang/php55; make config;make install; pkg lock php55
pkg install php55-extensions
pkg install php55-mysql (this is fine as binary since it uses custom MySQL build)

OK Great, now let’s see how we can upgrade for now on.

pkg version -v (see what ports out of date)
pkg upgrade (upgrade binary ports first)
locked (alias locked='pkg info -ak|grep yes')( check locked ports to unlock for portmaster and update list to unlock/lock below )
(ADD ANY PACKAGES MISSING HERE FROM "locked" COMMAND - unlock ports)
pkg unlock alpine; pkg unlock p5-DBD-mysql; pkg unlock ap22-mod_auth_mysql_another; pkg unlock ap22-mod_geoip2; pkg unlock ap22-mod_perl2; pkg unlock ap22-mod_rpaf2; pkg unlock php55
portmaster -adG (upgrade ports)
(ADD ANY PACKAGES MISSING HERE FROM "locked" COMMAND - lock ports back)
pkg lock alpine; pkg lock p5-DBD-mysql; pkg lock ap22-mod_auth_mysql_another; pkg lock ap22-mod_geoip2; pkg lock ap22-mod_perl2; pkg lock ap22-mod_rpaf2; pkg lock php55
pkg clean

There we have it, now we can get fastest build times as possible, first upgrading binaries, and then our custom ports. Locking packages is what prevents “pkg upgrade” from doing bad things to our custom ports. Of course we need to unlock them after to run portmaster on them. The sad part in this is we have to keep track of what packages to lock and unlock all the time for upgrade purposes. I have opened this issue: https://github.com/freebsd/pkg/issues/744

So if developers get around to adding this new feature to pkg2ng, it could make our life simpler, for now any time you lock a package, just update your upgrade notes, I normally toss it into /etc/motd for easy access.

Till next time, happy FreeBSD 10!

Dan.

KVM – Adding Space To FreeBSD 10 zfs on root guest on a Centos 6.5 LVM host

Intro:
I decided to write this after I could not find any documentation on internet how to easily add space to a FreeBSD 10 guest that had zfs on root install. This should show you how to do it easily and quickly. It is important as we may need to add more space from our LVM to our FreeBSD guest at some point, and we need to know exactly how to do that.

Pre-requisites:
I assume you have a Centos host running KVM guests, as well as gdisk installed.

First thing we want to do is extend size of our guest

lvextend -L +10G /dev/vps/sunsaturn (add 10G to sunsaturn)
gdisk /dev/vps/sunsaturn (we let gdisk fix partition table or we will not be able to add new space)

Command (? for help): w
Warning! Secondary header is placed too early on the disk! Do you want to
correct this problem? (Y/N): Y
Have moved second header and partition table to correct location.”

Just save and exit to fix our partition tables.
Now let us run gdisk again to add the new space, since we have following:

gdisk -l /dev/vps/sunsaturn
Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            1057   512.0 KiB   A501  gptboot0
   2            1058         8389665   4.0 GiB     A502  swap0
   3         8389666       335544286   156.0 GiB   A504  zfs0
virt-filesystems --long --parts --blkdevs -h -a /dev/vps/sunsaturn
Name       Type       MBR  Size  Parent
/dev/sda1  partition  -    512K  /dev/sda
/dev/sda2  partition  -    4.0G  /dev/sda
/dev/sda3  partition  -    156G  /dev/sda
/dev/sda   device     -    160G  -

Our last partition can easily be expanded just deleting last partition and add it back with the new space.

gdisk /dev/vps/sunsaturn (now delete last partition(3) and add it back, set code and name back to A504 and zfs0)

Alright we have expanded our LVM, now we need to restart the guest and enable new space within the guest.

virsh shutdown sunsaturn (actually wait till it is shutdown, till "virsh list" shows it gone)
virsh start sunsaturn

IN THE GUEST:

zpool status (find out device and put it below)
zpool online -e zroot vtbd0p3 (zfs will now grab the additional space)

That’s it, now you know how to add space on the fly to any FreeBSD guest with zfs on root, on the fly.

Dan.

Update: a few months after writing this I came across this article which does a good representation.