SSL-Certificates with Let’s Encrypt

I followed the guide from https://github.com/diafygi/letsencrypt-nosudo
so that I don’t have to trust the letsencrypt script that requires root access.
One caveat is that you need to read through the script from diafygi, or trust it 🙂

Then, I transferred the signed certificate, and the domain private key to the server, and configured my site like this:



ServerName www.hestben.se
ServerAlias hestben.se
ServerAdmin address@to.webmaster
DocumentRoot /var/www/website/
SSLEngine on
SSLCertificateFile "/path/to/signed.crt"
SSLCertificateKeyFile "/path/to/domain.key"

Find out if TLS is used when sending mail

So, I have an old installation of Debian, with postfix, and I don’t remember how I set it up. I should check that it is using sane settings and really using encryption for the transport of mails. This is on my Debian Jessie 8.7 server.
First, I wanted to see what version of postfix I am using.
Issuing postcond -d | grep mail_version yields the version 2.11.3..
So, according to the answers in this question, I should use the newer configuration options smtp_tls_security_level.
In the configuration that existed on the server, I didn’t have anything about smtp, only for smtpd (incoming mail). From logs obtained when running smtp with the options -v -v (Change the settings in /etc/postfix/master.cf and restart postfix):
Mar 2 16:30:17 galerkin postfix/smtp[15196]: > mail.tele2.se[212.247.156.1]:587: EHLO galerkin.hestben.dyndns-ip.com
Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-mailfe09.swip.net host name is unknown galerkin.hestben.dyndns-ip.com Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-DSN Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-SIZE 314572800 Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-STARTTLS Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-AUTH LOGIN PLAIN Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-ETRN Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-TURN Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-ATRN Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-NO-SOLICITING Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-8BITMIME Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-HELP Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250-PIPELINING Mar 2 16:30:17 galerkin postfix/smtp[15196]: < mail.tele2.se[212.247.156.1]:587: 250 EHLO

Then, it looks like it creates a TCP buffer with the login credentials, and then issues AUTH LOGIN:
Mar 2 16:30:17 galerkin postfix/smtp[15196]: smtp_sasl_authenticate: mail.tele2.se[212.247.156.1]:587: SASL mechanisms LOGIN PLAIN
Mar 2 16:30:17 galerkin postfix/smtp[15196]: > mail.tele2.se[212.247.156.1]:587: AUTH LOGIN

I.e. no encryption used, so I added smtp_tls_security_level=may to main.cf (you can also use postconf -e "smtp_tls_security_level=may")
Then reloaded postfix with
postfix reload
You can then verify that the setting is set with
postconf | grep smtp_tls_security_level.
Now the mail.log looks like:
Mar 3 15:11:41 galerkin postfix/pickup[22696]: 98D91232032: uid=0 from=
Mar 3 15:11:41 galerkin postfix/cleanup[22702]: 98D91232032: message-id=<20170303141141.98D91232032@galerkin.hestben.dyndns-ip.com>
Mar 3 15:11:41 galerkin postfix/qmgr[22697]: 98D91232032: from=, size=359, nrcpt=1 (queue active)
Mar 3 15:11:42 galerkin postfix/smtp[22704]: Untrusted TLS connection established to mail.tele2.se[212.247.156.1]:587: TLSv1 with cipher AES256-SHA (256/256 bits)
Mar 3 15:11:43 galerkin postfix/smtp[22704]: 98D91232032: to=, relay=mail.tele2.se[212.247.156.1]:587, delay=2.2, delays=0.31/0.3/0.5/1.1, dsn=2.0.0, status=sent (250 549908680 mailfe03 Message accepted for delivery)
Mar 3 15:11:43 galerkin postfix/qmgr[22697]: 98D91232032: removed

So, now you could hope tele2 would change to a better cipher with perfect forward secrecy (such as ECDHE-RSA-AES256-GCM-SHA384). Reading through the reference below about postfix forward secrecy, it also looks like the server does not support anonymous cipher suites =(.

Now, check incoming mail. The setting for the incoming mail which is called smtpd_tls_security_level. I had previously used smtpd_use_tls=yes so I changed to the newer setting. I sent a mail to my server (there is only a dyndns-ip configured for it, I use an external email provider for my hestben.se-domain).
The log from that looks like this:
Mar 3 15:29:33 galerkin postfix/smtpd[22788]: connect from mx.kolabnow.com[95.128.36.1]
Mar 3 15:29:33 galerkin postfix/smtpd[22788]: Anonymous TLS connection established from mx.kolabnow.com[95.128.36.1]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Mar 3 15:29:33 galerkin postfix/smtpd[22788]: A0EC523202F: client=mx.kolabnow.com[95.128.36.1]
Mar 3 15:29:33 galerkin postfix/cleanup[22793]: A0EC523202F: message-id=<20170303142924.GB4898@debian.hestben.dyndns-ip.com>

Super, it is even using a good cipher.

References : postfix forward secrecy, postfix tls readme, postfix main.cf format.

Encrypting automatic mail from a linux server with GPG

So, recently, I have been reviewing my systems, to harden them against attack. When I look back at it, I really think I have had quite naive in what security measures I employ.
One thing I have started doing, is have logwatch send a mail to my mail address every day. That way, I am more forced to look into what is happening with the servers each day. This information could be interesting to an attacker, though, so it is important to secure that information. In part, I have been looking into if my MUA uses TLS to send the mail to the outgoing mail server (I will cover this in a different post). Then, you should ensure that connection is secure when downloading and viewing the mail is secure as well (also covered in a different post).
But, in the end, you don’t know how the outgoing mail server sends the mail to the receiving server. Best is then to encrypt the mail. I did some duckduckgoing (the duckduckgo.com equivalent of googling) and found this post:GnuPG-encrypted mail forwarding

Using the steps from that post, I first imported my public gpg-key for the root user with
gpg --import <path/to/public/key>
gpg --edit-key <The key>
And trust the imported key ultimately (gpg will complain otherwise, and you don’t have any way to handle that interaction in an automated script). Thus, in the gpg-promt do:
trust
5
And lastly, quit
quit

Then, I created the mailgate user with
adduser mailgate

On one of my systems, I use Maildir format instead of mbox-format, so I was changing my script to handle this. One con with the script in that post above, is that the mail is not a Content-Type: multipart/encrypted;, instead, the body of the mail, is an encrypted text, that you manually need to decrypt with gpg.

I asked around on the channels #gnupg and #mutt (you can use mutt to send an encrypted mail, that has the correct format, but piping the message into mutt didn’t make it a Content-Type: multipart/encrypted; mail) on freenode, and was tipped by dtw in #gnupg about mime-construct (example usage)

So, I ended up with a script looking like this (beware that wordpress line breaks badly):

#!/bin/bash
#backup this script to /home/robert/scripts
rsync /root/scripts/relay_mailgate_mail_encrypted /home/robert/scripts/
chown robert:robert /home/robert/scripts/relay_mailgate_mail_encrypted
MAILGATE_NEW_MAIL_DIR=/home/mailgate/Maildir/new
MAILGATE_CUR_MAIL_DIR=/home/mailgate/Maildir/cur
if [ ! -z "$(ls -A $MAILGATE_NEW_MAIL_DIR)" ]
then
BACKUP_DIR=/home/mailgate/mailbackup/`date +%y%m%d-%H%M`
mkdir $BACKUP_DIR
echo $BACKUP_DIR
rsync -a $MAILGATE_NEW_MAIL_DIR $BACKUP_DIR
for mail in $MAILGATE_NEW_MAIL_DIR/*
do
echo $mail
cat $mail | mime-construct --subpart \
--type 'text/plain; charset=UTF-8' \
--encoding quoted-printable \
--file - \
| gpg --batch --yes \
--armor --textmode --openpgp \
--recipient "mailaddr@domain.com" \
--encrypt \
| mime-construct --output \
--header "From: root" \
--to "mailaddr@domain.com" \
--subject "Relayed mail" \
--header "Date: $(date --rfc-2822)" \
--multipart 'multipart/encrypted; protocol="application/pgp-encrypted"' \
--type application/pgp-encrypted \
--encoding 7bit \
--string $'Version: 1\n' \
--type application/octet-stream \
--file - | sendmail -i mailaddr@domain.com
mv $mail $MAILGATE_CUR_MAIL_DIR
done
fi

I called this script in a script in /etc/cron.hourly/00mailencrypt.
Lastly, I edited the /etc/cron.daily/00logwatch and /etc/apt/apt.conf.d/50unattended-upgrades scripts to mail to mailgate@localhost instead of to an external address directly.

What does it mean to be a Senior Developer?

So, I have been looking for a job for quite a while now, and have had some interviews. Thus far, I have not been successful, though.

I just had an interview, where I was asked to solve some things during the interview. Here are some of the questions that I didn’t have an answer to, from the top of my head.

“In Bash, change mode of all jpg-files in the current directory, and sub directories”.
Here, I was first thinking about how to setup the for-loop in bash. There is the do, and done, and somewhere, you need a semicolon.
I also started to think about using find, but was not sure if I needed the flag in xargs to limit the output to one entry per line. While I was contemplating, the interviewer asked how much I had done in Bash, and I said, I mostly did small build scripts. And then he asked about Makefile, so we skipped the first question.

I later checked the solution I was starting to form in my head:
find . -iname *.jpg | xargs chmod 600
That would have worked.

“What does .PHONY in a Makefile mean?”
I have seen it often, but never looked it up.
Now, I have found that it is a directive you put in a Makefile, that is always dirty, thus is always built. This is mostly used for clean and all. A Makefile always has a target, and clean and all are used for cleaning up the build (remove all built binaries and libraries), and to make all projects. If you then have a file in the directory that is called clean or all, it becomes ambiguous for make, if you want to build the file clean or if you want to clean up the build. That’s why you setup a .PHONY directive.

“How do you combine two lists in Javascript or Python”.
This, I should have known. But I guess it is something that I missed by not doing a proper course in Python, or I have simply forgot it. I hate it when I forget the elementary things. I don’t know how often I have to lookup “Hello world” in languages I have used before, because I have forgotten how to start a simple project, or how to output text to command line.
The more detailed question:
“You have:
a=[1,2,3]
b=[4,5,6]

How do you create
c=[1,2,3,4,5,6]?”
I quick-and-dirty-solved it in Python like this:
c=[]
for x in a:
c.append(x)
for x in b:
c.append(x)

This was not an acceptable solution, and we broke off the interview at this point.

When did some searches. I saw, I should have simply tried the +-operator:
c=a+b
In other languages:
In Javascript, you can use concat.
c=a.concat(b);
In C/C++, first C-arrays:
//How do you concatenate c arrays?
int a[3]={1,2,3};
int b[3]={4,5,6};
int c[6];
// You actually don't need to specify the size of the
// array,
// if it is initialized with the {} notation,
// the compiler can infer it:
int d[]={1,2};
//Need to loop through a and b to fill c, and for this,
// need to
// specifically know the sizes of the arrays
const int size1=3;
const int size2=3;
for(int i=0; i < size1; i++) { c[i] = a[i]; } for(int i=0; i < size2; i++) { c[i+size1]=b[i]; }

In C++:
// In C++, you should use std::vector
std::vector a_vec;
a_vec.push_back(1);
a_vec.push_back(2);
a_vec.push_back(3);
// In C++ 11, you can use the array initialization as
// well:
std::vector b_vec = { 4, 5, 6};
std::vector c_vec;
c_vec.insert(c_vec.end(), a_vec.begin(), a_vec.end());
c_vec.insert(c_vec.end(), b_vec.begin(), b_vec.end());

It is worrisome, that my memories of some of the basic things are so sketchy, I need to shape up, to call myself senior in any language. Maybe I should stop looking at more different languages (I am currently working my way through SICP - Structure and Interpretation of Computer Programs), and focus on some languages that I would like to work in.
Other resources that deal with what it means to be "Senior Developer": The programmer competence matrix.

Gentoo msmtp and local mail

I have installed msmtp to handle mail I send from mutt using my accounts. But, I would like to get mail from local users, such as cron-jobs and smartmontools as well.
I have researched it, and have found that Gentoo blocks use of more than one Mail Transfer Agent (MTA). This, I found from this forum answer
msmtp is counted as an MTA, and thus, I cannot install sendmail or exim, which my Debian system uses.
So, my alternatives seem to be to either

  1. configure the msmtp sendmail symlink to use one account by default, and use a sane “from” address.
  2. Manually install msmtp after emerging another MTA.

The drawback with 1. is that I will get cron mail to one of my accounts, rather than having it local to the computer. And I need to be careful when setting it up, so that I don’t run into the problem in this question.

The drawback with 2. is that it is more of a hack to enable use of two MTAs. I wonder why Gentoo forbids use of two MTAs while Debian accepts it.

To be continued

Gentoo ZFS

So, background: I wanted to try out a BSD, specifically TrueOS (link).
I installed it and chose the bsd-bootloader. This was a bad choice, though, because that didn’t work on my GPT partitioned EFI-boot hard drive.
I figured, I could try to boot it with grub, but, my manual configuration tests didn’t work out, so maybe I should try to make grub detect it automatically. For this, the file system needs to be able to be read, and it is using ZFS; thus, I need to be able to read ZFS in gentoo. I found this.

During the install, I got the error that CONFIG_ZLIB_DEFLATE was not set in the kernel. I searched and found this thread. From it, I figured out, I should enable the option
Cryptographic API ---->
Deflate compression algorithm

as a module.
Now, I could emerge zfs and modprobe zfs

Gentoo – connect android device with jmtpfs

I have an android device, that I transfer files to and from with jmtpfs in my Debian system.
I searched and found the package sys-fs/jmtpfs, which I unmasked and emerged.
When the installation has finished it complained:* CONFIG_FUSE_FS: is not set when it should be. so I figured, that is probably a Kernel configuration I have not made.
I found it here:
File systems --->
FUSE (Filesystem in Userspace) support

I enabled it as a module.
Now I could modprobe fuse, and then run tmtpfs /path/to/mount/it

Gentoo – enabling sound

So, I installed vlc, only to find I had no sound. So I looked in the hand book configuring ALSA.
I had the sound device:
00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family High Definition Audio Controller (rev 05)
I changed the kernel configuration and added
Device Drivers --->
<*> Sound card support
<*> Advanced Linux Sound Architecture --->
[*] PCI sound devices --->
Intel/SiS/nVidia/AMD/ALi AC97 Controller
Intel/SiS/nVidia/AMD MC97 Modem

as modules.
And I added the following into the kernel:
Device Drivers --->
<*> Sound card support
<*> Advanced Linux Sound Architecture --->
[*] PCI sound devices --->
Select the driver for your audio controller, e.g.:
<*> Intel HD Audio ---> (snd-hda-intel)
-*- Allow dynamic codec reconfiguration
[*] Support digital beep via input layer
(1) Digital beep registration mode (0=off, 1=on)
[*] Support initialization patch loading for HD-audio
<*> Build Realtek HD-audio codec support
...
<*> Build HDMI/DisplayPort HD-audio codec support
...
-*- Enable generic HD-audio codec parser

Then, I followed the guide, and rebooted. Now I have sound.

Ssh login fails with debug1: SSH2_MSG_KEXINIT sent\n Connection closed by XX

I was playing around with my apache settings yesterday, and decided to ditch what I had and checkout what was in master in etckeeper with etckeeper vcs checkout HEAD.
After that, I couldn’t log in to my server again with ssh:
debug3: load_hostkeys: loaded 1 keys
debug3: order_hostkeyalgs: prefer hostkeyalgs: ssh-rsa-cert-v01@openssh.com,ssh-rsa-cert-v00@openssh.com,ssh-rsa
debug1: SSH2_MSG_KEXINIT sent
Connection closed by IP-ADDRESS

I thought it was strange.
After getting the logwatch mail, I got these error messages in the log:
error: key_load_private: bad permissions : 58 time(s)
error: Could not load host key: /etc/ssh/ssh_host_rsa_key : 29 time(s)
error: Permissions 0644 for '/etc/ssh/ssh_host_dsa_key' are too open. : 29 time(s)
error: It is recommended that your private key files are NOT accessible by others. : 58 time(s)
error: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ : 116 time(s)
fatal: No supported key exchange algorithms [preauth] : 29 time(s)
error: This private key will be ignored. : 58 time(s)
error: Permissions 0644 for '/etc/ssh/ssh_host_rsa_key' are too open. : 29 time(s)
error: @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ : 58 time(s)
error: Could not load host key: /etc/ssh/ssh_host_dsa_key : 29 time(s)

So, something had changed the permissions to /etc/ssh/ssh_host_dsa_key. First I though: “Damn, have I been rooted now? That is just fair with my previous bad password policy”.
Then I gave it more thought, and remembered my restoring with etckeeper. I searched and found this question.
Looks like you need to run etckeeper init after checking out.
The problem now, because the server is far away from me, is to get somebody technical to connect a screen and keyboard to the computer and follow my instructions.
EDIT: etckeeper init was not enough. It didn’t restore the file permissions. I wonder how many other files have wrecked file permissions now :/