Semantic Versioning

In my current team (actually the whole company) we end up within the dependency hell day by day. Not only that many teams just don’t do any versioning, if they do there are no clear rules how they should do.

Semantik Versioning specification provides a great introduction of how and when to use (semantic) versioning. Definitely worth a read.

In the world of software management there exists a dreaded place called “dependency hell.” The bigger your system grows and the more packages you integrate into your software, the more likely you are to find yourself, one day, in this pit of despair.

In systems with many dependencies, releasing new package versions can quickly become a nightmare. If the dependency specifications are too tight, you are in danger of version lock (the inability to upgrade a package without having to release new versions of every dependent package). If dependencies are specified too loosely, you will inevitably be bitten by version promiscuity (assuming compatibility with more future versions than is reasonable). Dependency hell is where you are when version lock and/or version promiscuity prevent you from easily and safely moving your project forward.

Link: https://semver.org/

Automatically close GitHub Issues

As you might now, I am currently working on a small Docker project to containerize ttrss.

I am using GitHub and Docker just for the sake of keeping up to date with the the features of both plattforms.

Although this might be an old feature, well known in the Git and/or GitHub community, I “accidentally” wrote a commit message fixed #2: …

Well, GitHub automatically closed this issue during the process of creating the pull request and merging it into the master. What an awesome feature, especially when found this was!

Entrypoint Pitfalls in the Mac-o-Windolinux Docker World

I do some work on my MacBook with macOS, on my Windows laptop with Windows 10 and Ubuntu WSL. I work in Visual Studio Code onWindows while running Ansible scripts in my Ubuntu WSL on the same code base. What could possibly go wrong? While I spent the last few evenings debugging, I completely forgot about the obvious. I should know better, though.

CRLF vs LF

When working on my Windows machine I regular forget about file formats. While in many cases the systems are nowadays very resilient, when creating Docker containers this can end up in a big FUBR. In the likely case, you freshly built container using an entrypoint script tells you during a docker-compose up something like

standard_init_linux.go:xxx: exec user process caused "no such file or directory"

go and check the file format of the entrypoint script and switch to LF. At least Visual Studio Code makes it easy.

To bash or not to bash

In case you see exactly the same error, check the entrypoint script again. Is it using bash as mine?


Go ahead and make sure bash is installed in your image. Use something like the line below. On a very regular base, I completely forget about installing bash but keep trying to use it again and again.


apk add bash

No Permission

In case you encounter another obscure message telling you

standard_init_linux.go:xxx: exec user process caused "permission denied"

check the permissions of the entrypoint script.

chmod +x entrypoint.sh 

should do it on on your host. As I run my deployment using Ansible, I use a task similar to

 
- name: Copy entrypoint.sh file
copy:
src: entrypoint.sh
dest: "{{ install_dir }}/entrypoint.sh"
owner: root
group: root
mode: 0755
force: yes

I am still not sure if setting755 and root are best practices and should be modified.

Cannot connect to SMB shares on Windows 10

I recently set up a new Windows 10 machine. After eight years with only Apple devices, I finally wanted to fetch up with the PC and Windows world again.

For a day or two, I tried to connect my laptop to my NAS at home. I checked firewalls, credentials, server settings, usernames, network. I checked it double, triple, quadrupplewise. I tried almost any permutation. Eventually, I gave up.

The actual problem was, Windows 10 gave no feedback at all when trying to connect to a SMB (aka Sever Message Block Protocol) share on my server. All connection attempts just ended with a silent fail. In terms of user experience this is a violation of Grice’s maxims. Windows 10 simply chooses to opt out of the conversation.

At a very last attempt, I tried the option to map a network drive. After entering user credentials again and again, finally Windows 10 came up the very first time with a useful error message.

Error while connecting SMB1 shares on Windows 10

This shares requires the obsolete SMB1 protocol…” is quite some information one can work with.

Enabling SMB1 turns out to be quite easy. Head to Turn Windows Features on or of and scroll down to SMB 1.0/CIFS File Sharing Support. There check SMA 1.0/CIFS Client to enable SMB1 support.

SMB 1.0/CIFS Support on Windows 10

Once done, connection to servers providing (only) SMB1 will work again on Windows 10.

Getting Exim4 Done the Job

In my current project, moving my home server from a PC Tower running Windows Server 2003 to a more energy as well as space efficient Mac mini, I need to migrate quite a bunch of tools and scripts from Windows to Ubuntu.

Said that, hMailServer served me well for years on my local network. It was easy to install, maintain and run. However, I was now looking for some more lightweight solution for the new server.

The need can be summarized quite easily:

  • arbitrary devices and services on the local network need to be able to deliver mails via SMTP to the server
  • local services on the server need to be able to send out mails as well
  • the server needs to forward the mail to my real server
  • very basic authentication is a must
  • it need to run on my old 1.66 Ghz Mac mini

At all it’s as simple as the following diagram:

Exim4 SetupAfter digging through all the stuff such as Sendmail, Postfix and so on, I ended up with Exim4 as the perfect solution for my needs.

Basically, after installing it via

sudo apt-get install exim4

the only thing is to quickly run through the setup.

sudo dpkg-reconfigure exim4-config

It’s sort of guided and quite easy to do as long as you have some experience with networks. However, there are quite some pitfalls which are quite annoying if you are little experienced with Exim.

Network Interfaces

Assign all network interface IP addresses you want to listen for incoming mails as seen below.

Ecim4 Mail Server configurationHowever, make sure providing only IP addresses from network interfaces, which are actually connected to the network. Otherwise the daemon might fail to start.

014-12-25 10:23:46 socket bind() to port 25 for address 192.168.0.205 failed: Cannot assign requested address: daemon abandoned

If the network interfaces are set up correctly, you should find the daemon listening on the network interfaces specified before:

2014-12-25 10:31:06 exim 4.82 daemon started: pid=16276, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25 [192.168.0.206]:25

Monitoring the logs

Whenever you try to figure out what’s going wrong while connecting from any client during the setup, e.g. to check the logging information above, it might help to start tailing the log via

sudo tail -f /var/log/exim4/mainlog

The Paniclog Fail

When messing with the configuration, you might end up from time to time with the following message while starting the daemon.

ALERT: exim paniclog /var/log/exim4/paniclog has non-zero size, mail system possibly broken

Check the file, and just delete the log file after fixing the cause for the log entry.

sudo rm /var/log/exim4/paniclog

The Authentication Test

Once up and running, you might want to check the server. It might be quite convenient to check simply via Telnet by opening to your Exim server and one of the IP addresses provided before.

macbook:~ andreas$ telnet 192.168.0.206 25
 Trying 192.168.0.206...
 Connected to 192.168.0.206.
 Escape character is '^]'.
 220 macmini ESMTP Exim 4.82 Ubuntu Thu, 25 Dec 2014 11:47:43 +0100
 ehlo 192.168.0.203
 250-macmini Hello macbook [192.168.0.80]
 250-SIZE 52428800
 250-8BITMIME
 250-PIPELINING
 250 HELP

Following the SMTP protocol, you can ask the server using

ehlo <someIdentifier>

The ehlo verb provides some computer-readable information about the server’s abilities, though.

Instead of Telnet you could start Exim using

exim -bh 192.168.0.203

This will bring up Exim wit a testing session.

*** SMTP testing session as if from host 192.168.0.203
**** but without any ident (RFC 1413) callback.
**** This is not for real!

>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? yes (matched "*")
>>> looking up host name for 192.168.0.203
>>> IP address lookup yielded localhost
>>> gethostbyname2 looked up these IP addresses:
>>>   name=localhost address=127.0.0.1
>>> checking addresses for localhost
>>>   127.0.0.1
>>> no IP address for localhost matched 192.168.0.203
>>> 192.168.0.203 does not match any IP address for localhost
>>> host in host_reject_connection? no (option unset)
>>> host in sender_unqualified_hosts? no (option unset)
>>> host in recipient_unqualified_hosts? no (option unset)
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
220 macmini ESMTP Exim 4.82 Ubuntu Fri, 26 Dec 2014 11:39:25 +0100

Again ask the server using ehlo.

>>> 192.168.0.203 in helo_lookup_domains? no (end of list)
>>> host in pipelining_advertise_hosts? yes (matched "*")
>>> host in auth_advertise_hosts? yes (matched "*")
>>> host in tls_advertise_hosts? no (option unset)
250-macmini Hello 192.168.0.203 [192.168.0.203]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250 HELP

I figured this out, as one of my devices, an failed to send a status mail.

Dec 25 13:32:07 SMTP[2007]: smtp error (auth failed): 250 HELP^M
Dec 25 13:32:07 SMTP[2007]: SMTP authentication failed

The Missing Plain Auth Advertisement

So far, everything works as a charm. However, for the recent setup, I wanted to have plain authentication for most of my clients. This did cost me half a day to figure out and drove me almost mad while digging through tons of Exim docs.

First of all, activate plain authentication for the server by changing the configuration

sudo vim /etc/exim4/conf.d/auth/30_exim4-config.examples

Here you need to remove the comments from the following section

lain_server:
  driver = plaintext
  public_name = PLAIN
  server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{CONFDIR/passwd}{$value}{*:*}}}}}{1}{0}}"
   server_set_id = $auth2
  server_prompts = :
  .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS
  server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}}
  .endif

Finally  update the configuration

sudo update-exim4.conf

and restart Exim

sudo service exim4 restart

If you now walk through the tests above, the server will still omit the authentication advertisement.

Once that has been done, create (or edit if it already exists)the exim4.conf.localmacros file.

sudo touch /etc/exim4/exim4.conf.localmacros.
sudo vim /etc/exim4/exim4.conf.localmacro

Add the following line and restart the daemon once again.

AUTH_SERVER_ALLOW_NOTLS_PASSWORDS = true

If you now start the tests again, you will see the authentication advertisement of the server, though.

ehlo test
 >>> host in smtp_accept_max_nonmail_hosts? yes (matched "*")
 >>> test in helo_lookup_domains? no (end of list)
 >>> host in pipelining_advertise_hosts? yes (matched "*")
 >>> host in auth_advertise_hosts? yes (matched "*")
 >>> host in tls_advertise_hosts? no (option unset)
 250-macmini Hello test [192.168.0.203]
 250-SIZE 52428800
 250-8BITMIME
 250-PIPELINING
 250-AUTH PLAIN LOGIN
 250 HELP

Once this worked at the very end, the devices where able to send vie my Exim relay.

Test Mail from IC 3115W CameraDealing with Non System Users

When dealing with non system users, you can simply create Exim users via

sudo /usr/share/doc/exim4-base/examples/exim-adduser

That’s quite easy, when dealing with plain authentication. Keep in mind, users and passwords are stored in plain text in the /etc/exim4/passwd file.

Failed to find Host

In case you get some log entries such as

2014-12-25 12:12:31 refused relay (host) to ...; from &...; H=(...) [192.168.0.203] (failed to find host name from IP address)

You need to add some host names for the corresponding IP addresses in /etc/hosts.