My thoughts on Slackware, life and everything

Category: Me (Page 2 of 26)

I am hiring (ASML Veldhoven Netherlands)

As you may know, I am working at ASML since 2016, first in a technical IT role but nowadays as an IT Group Leader focusing on providing services and solutions in Virtual Product Development (VPD) and Engineering Simulation (simulation driven design) toward our internal customers (mechanical and optical engineering, and research).

ASML is an exciting company to work for, and the amount of work we do is rapidly expanding as a result of the pandemic and the resulting increase in demand for consumer electronics and computer chips. As a company we are at the forefront of lithography innovation with our EUV machines (Extreme Ultra Violet laser powered).
See this one-minute intro video for instance:

To keep up the pace with the ever increasing demands from our ASML Research and Engineering colleagues, I have been growing the IT teams that report to me. I hired quite a lot of people during the past two years that I have been in the manager seat, and I am now hiring again!
I am also posting here on my blog because it is becoming more challenging every year to find the right people within a reasonable time.

Specifically: I have a job opening for an “IT Infra Automation & Integration Expert“. This job is located at ASML HQ, Veldhoven, The Netherlands. Note that you’d have to move to the Netherlands if you are interested and want to apply.
We are looking for a new colleague in the “SIMS” team of our IT Agile Release Train “Engineering Simulation Services”. This IT ART delivers a Simulation Workplace to our internal customers who are in Mechanical and Optical Engineering as well as Research departments.
See the online profile for all the job details. Feel free to ask below in the comments section about further background info.

Hope this is of interest to someone!
Eric

Remember Joe Mann

A story of remembrance and gratefulness towards Joe Mann.

Today 76 years ago, on September 19th 1944, a young US soldier called Joe Mann gave his life to save that of his comrades. He jumped on a grenade thrown by a German soldier and died a hero. This was the day after Eindhoven was liberated from the Nazis.

No one knew at the time, but the war in the Netherlands would not end until 8 months later, causing countless civilian deaths during the “hunger winter” of 44/45.

A monument was erected for Joe Mann a few years back, and my wife and I walk the surrounding area a lot, so yesterday we stopped at the monument to contemplate the bravery and fate of this young man. This is a picture of the place:

The inscription reads: “On 19 September 1944, Joe E. Mann as soldier at this place gave his young life to save the lives of his comrades.

Remote access to your VNC server via modern browsers

I think I am not the only one who runs a graphical Linux desktop environment somewhere on a server 24/7.
I hear you ask: why would anyone want that?

For me the answer is simple: I work for a company that runs Linux in its datacenters but offers only Windows 10 on its user desktops and workstations. Sometimes you need to test work related stuff on an Internet-connected Linux box. But even more importantly: when I travel, I may need access to my tools – for instance to fix issues with my repositories, my blog, my build server, or build a new package for you guys.

This article documents how I created and run such a 24/7 graphical desktop session and how I made it easily accessible from any location, without being restricted by firewalls or operating systems not under my control. For instance, my company’s firewall/proxy only allows access to HTTP(S) Internet locations; for me a browser-based access to my remote desktop is a must-have.

How to run & access a graphical Linux desktop 24/7 ?

Here’s how: we will use Apache, VNC and noVNC.

VNC or Virtual Network Computing is a way to remotely access another computer using the RFB (Remote Frame Buffer) protocol. The original VNC implementation is open source. In due time, lots of cross-platform clients and servers have been developed for most if not all operating systems. Slackware ships with an optimized implementation which makes it possible to work in a remote desktop even over low-bandwidth connections.

There’s  one thing you should know about VNC. It is a full-blown display server. Many people configure a VNC server to share their primary, physical desktop (your Linux Xserver based desktop or a MS Windows desktop) with remote VNC clients.
VNC is also how IT Help Desks sometimes offer remote assistance by taking control over your mouse, keyboard and screen.
But I want to run a VNC server ‘headless‘. This means, that my VNC server will not connect to a physical keyboard, mouse and monitor. Instead, it will offer virtual access to these peripherals. Quite similar to X.Org, which also provides what is essentially a network protocol for transmitting key-presses, mouse movements and graphics updates. VNC builds on top of X.Org and thus inherits these network protocol qualities.

Start your engines

Get a computer (or two)

First, you will have to have a spare desktop computer which does not consume too much power and which you can keep running all day without bothering the other members of your family (the cooling fans of a desktop computer in your bedroom will keep people awake).

Next, install Slackware Linux on it (any Linux distro will do; but I am biased of course). You can omit all of the KDE packages if you want. We will be running XFCE. Also install ‘tigervnc’ and ‘fltk’ packages from Slackware’s ‘extra’ directory. The tigervnc package installs both a VNC client and a VNC server.

Note that  the version of  TigerVNC server which ships in Slackware 15.0 and onwards behaves differently than described in this article (which focuses more on the NoVNC part).
I recommend reading my follow-up article “Challenges with TigerVNC in Slackware 15.0” before continuing with the remainder of this page, and follow the VNC server instructions as shown in that other article.

You can store this server somewhere in a cupboard or in the attic, or in the basement: you will not have a need to access the machine locally. It does not even have to have a keyboard/mouse/monitor attached after you have finished implementing all the instructions in this article.

You may of course want to use a second computer – this one would then act as the client computer from which you will access the server.

In my LAN, the server will be configured with the hostname “darkstar.example.net”. This hostname will be used a lot in the examples and instructions below. You can of course pick and choose any hostname you like when creating your own server.
I also use the Internet domain “lalalalala.org” in the example at the end where I show how to connect to your XFCE desktop from anywhere on the Internet. I do not own that domain, it’s used for demonstrative purposes only, so be gentle with it.

Run the XFCE desktop

Let’s start a VNC server and prepare to run a XFCE graphical desktop inside.

alien@darkstar:~$ vncserver -noxstartup

You will require a password to access your desktops.

Password:
Verify:
Would you like to enter a view-only password (y/n)? n

New 'darkstar.example.net:1 (alien)' desktop is darkstar.example.net:1

Creating default config /home/alien/.vnc/config
Log file is /home/alien/.vnc/darkstar.example.net:1.log

What we did here was to allow the VNC server to create the necessary directories and files but I prevented its default behavior to start a “Twm” graphical desktop. I do not want that pre-historic desktop, I want to run XFCE.

You can check that there’s a VNC server running now on “darkstar.example.net:1”, but still without a graphical desktop environment inside. Start a VNC client and connect it to the VNC server address (highlighted in red above):

alien@darkstar:~$ vncviewer darkstar.example.net:1 

TigerVNC Viewer 64-bit v1.10.1 
Built on: 2019-12-20 22:09 
Copyright (C) 1999-2019 TigerVNC Team and many others (see README.rst) 
See https://www.tigervnc.org for information on TigerVNC.
...

The connection of the VNC client to the server was successful, but all you will see is a black screen – nothing is running inside as expected. You can exit the VNC viewer application and then kill the VNC server like this:

alien@darkstar:~$ vncserver -kill :1

The value I passed to the parameter “-kill” is “:1”. This “:1” is a pointer to your active VNC session. It’s that same “:1” which you saw in the red highlighted “darkstar.example.net:1” above. It also corresponds to a socket file in ” /tmp/.X11-unix/”. For my VNC server instance with designation “:1” the corresponding socket file is “X1”. The “kill” command above will communicate with the VNC server through that socket file.

Some more background on VNC networking follows, because it will help you understand how to configure noVNC and Apache later on.
The “:1” number does not only correspond to a socket; it translates directly to a TCP port: just add 5900 to the value behind the colon and you get the TCP port number where your VNC server is listening for client connections.
In our case, “5900 + 1” means TCP port 5901. We will use this port number later on.

If you had configured VNC server to share your physical X.Org based desktop (using the ‘x11vnc’ extension), then a VNC server would be running on “:0” meaning TCP port 5900.
And if multiple users want to run a VNC server on your computer, that is entirely possible! Every new VNC server session will get a new TCP port assigned (by default the first un-assigned TCP port above 5900).
It’s also good to know that the VNC server binds to all network interfaces, including the loop-back address. So the commands “vncviewer darkstar.example.net:1” and “vncviewer localhost:1” give identical result when you start a VNC client on the machine which is also running the VNC server.

Enough with the theory, we need that XFCE session to run! When a VNC server starts, it looks for a script file called “~/.vnc/xstartup” and executes that. This script should start your graphical desktop.

So let’s create a ‘xstartup’ script for VNC, based on Slackware’s default XFCE init script:

alien@darkstar:~$ cp /etc/X11/xinit/xinitrc.xfce ~/.vnc/xstartup
alien@darkstar:~$ vi ~/.vnc/xstartup

Edit that ‘xstartup’ script and add the following lines. They should be the first lines to be executed, so add them directly before the section “Merge in defaults and keymaps“:

vncconfig -iconic &
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

Add the following lines immediately before the section “Start xfce Desktop Environment” to ensure that your desktop is locked from the start and no-one can hi-jack your unprotected VNC session before you have a chance to connect to it:

# Ensure that we start with a locked session:
xscreensaver -no-splash &
xscreensaver-command -lock &

In order for these commands to actually work, you may have to run “xscreensaver-demo” once, the first time you login to your desktop in VNC, and configure the screensaver properly.

Into the future

This ends the preparations. From now on, you will start your VNC server (hopefully once per reboot) with the following simple command without any parameters:

alien@darkstar:~$ vncserver

That’s it. You have a XFCE desktop running 24/7 or until you kill the VNC server. You can connect to that VNC server with a VNC client (on Slackware that’s the vncviewer program) just like I showed before, and configure your XFCE desktop to your heart’s content. You can close your VNC client at any time and reconnect to the VNC server at a later time – and in the meantime your XFCE desktop will happily keep on running undisturbed.
You can  connect to your VNC server from any computer as long as that computer has a VNC client installed and there’s a network connection between server and client.

How to make that graphical desktop available remotely ?

So now we have a VNC server running with a XFCE desktop environment inside it. You can connect to it from within the LAN using your distro’s VNC viewer application. And now we will take it to the next level: make this Linux XFCE desktop available remotely using a browser based VNC client.

We will require NoVNC software and a correctly configured Apache httpd server. Apache is part of Slackware, all we need to do is give it the proper config, but NoVNC is something we need to download and configure first.

noVNC

The noVNC software is a JavaScript based VNC client application which uses HTML5 WebSockets and Canvas elements. It requires a fairly modern browser like Chromium, Firefox, and also mobile browsers (Android and i/OS based) will work just fine.
With your browser, you connect to the noVNC client URL. Apache’s reverse proxy connects the noVNC client to a WebSocket and that WebSocket in turn connects to your VNC server port.

Some VNC servers like x11vnc and libvncserver contain the WebSockets support that noVNC needs, but our TigerVNC based server does not have WebSocket support. Therefore we will have to add a WebSockets-to-TCP proxy to our noVNC installation. Luckily, the noVNC site offers such an add-on.

Installing

Get the most recent noVNC ‘tar.gz’ archive (at the moment that is version 1.4.0) from here: https://github.com/novnc/noVNC/releases .
As root, extract the archive somewhere to your server’s hard disk, I suggest /usr/local/ :

# tar -C /usr/local -xvf noVNC-1.4.0.tar.gz
# ln -s noVNC-1.4.0 /usr/local/novnc

The symlink “/usr/local/novnc” allows you to create an Apache configuration which does not contain a version number, so that you can upgrade noVNC in future without having to reconfigure your Apache. See below for that Apache configuration.
We also need to download the WebSockets proxy implementation for noVNC:

# cd /usr/local/novnc/utils/
# git clone https://github.com/novnc/websockify websockify

Running

You will have to start the WebSockets software for noVNC as a non-root local account. That account can be your own user or a local account which you specifically use for noVNC. My suggestion is to start noVNC as your own user. That way, multiple users of your server would be able to start their own VNC session and noVNC acccess port.
I start the noVNC script in a ‘screen‘ session (the ‘screen’ application is a console analog of VNC) so that noVNC keeps running after I logoff.
Whether or not you use ‘screen‘, or ‘tmux‘, the actual commands to start noVNC are as follows (I added the output of these commands as well):

$ cd /usr/local/novnc/
$  ./utils/novnc_proxy --vnc localhost:5901

Warning: could not find self.pem
Using local websockify at /usr/local/novnc/utils/websockify/run
Starting webserver and WebSockets proxy on port 6080
websockify/websocket.py:30: UserWarning: no 'numpy' module, HyBi protocol will be slower
 warnings.warn("no 'numpy' module, HyBi protocol will be slower")
WebSocket server settings:
 - Listen on :6080
 - Web server. Web root: /usr/local/novnc
 - No SSL/TLS support (no cert file)
 - proxying from :6080 to localhost:5901

Navigate to this URL: 
   http://baxter.dyn.barrier.lan:6080/vnc.html?host=baxter.dyn.barrier.lan&port=6080
Press Ctrl-C to exit

I highlighted some of the output in red. It shows that I instruct noVNC (via the commandline argument “–vnc”) to connect to your VNC server which is running on localhost’s TCP port 5901 (remember that port number from earlier in the article when we started vncserver?) and the noVNC WebSockets proxy starts listening on port 6080 for client connection requests. We will use that port 6080 later on, in the Apache configuration.

From this moment on, you can already access your VNC session in a browser, using the URL provided in the command output. But this only works inside your LAN, and the connection is un-encrypted (using HTTP instead of HTTPS) and not secured (no way to control or limit access to the URL).
The next step is to configure Apache and provide the missing pieces.

Apache

Making your Apache work securely using HTTPS protocol (port 443) means you will have to get a SSL certificate for your server and configure ‘httpd’ to use that certificate. I wrote an article on this blog recently which explains how to obtain and configure a free SSL certificate for your Apache webserver. Go check that out first!

Once you have a local webserver running securely over HTTPS, let’s add a block to create a reverse proxy in Apache. If you are already running Apache and have VirtualHosts configured, then you should add the below block to any of your VirtualHost definitions. Otherwise, just add it to /etc/httpd/httpd.conf .

Alias /aliensdesktop /usr/local/novnc

# Route all HTTP traffic at /aliensdesktop to port 6080
ProxyRequests Off
ProxyVia on
ProxyAddHeaders On
ProxyPreserveHost On

<Proxy *>
    Require all granted
</Proxy>

# This will not work when you use encrypted web connections (https):
#<Location /websockify>
#     Require all granted
#     ProxyPass ws://localhost:6080/websockify
#     ProxyPassReverse ws://localhost:6080/websockify
#</Location>
# But this will:

# Enable the rewrite engine
# Requires modules: proxy rewrite proxy_http proxy_wstunnel
# In the rules/conditions, we use the following flags:
# [NC] == case-insensitve, [P] == proxy, [L] == stop rewriting
RewriteEngine On

# When websocket wants to initiate a WebSocket connection, it sends an
# "upgrade: websocket" request that should be transferred to ws://
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:6080/$1 [P,L]

<Location /aliensdesktop/>
    Require all granted
    # Delivery of the web files
    ProxyPass http://localhost:6080/
    ProxyPassReverse http://localhost:6080/
</Location>

Again, I highlighted the bits in red which you can change to fit your local needs.

The “Alias” statement in the first line is needed to make our noVNC directory visible to web clients, since it is not inside the Apache DocumentRoot (which is “/srv/httpd/htdocs/” by default). I do not like having actual content inside the DocumentRoot directory tree (you never know when you accidentally create a hole and allow the bad guys access to your data) so using an Alias is a nice alternative approach.

You will probably already have noticed that Apache’s reverse proxy will connect to “localhost”. This means you can run a local firewall on the server which only exposes ports 80 and 443 for http(s) access. There is no need for direct remote access to port 6080 (novnc’s websocket) or 5901 (your vncserver).

Check your Apache configuration for syntax errors and restart the httpd if all is well:

# apachectl configtest
# /etc/rc.d/rc.httpd restart

Now if you connect a browser to https://darkstar.example.net/aliensdesktop/vnc.html and enter the following data into the connection box:

  • Host: darkstar.example.net
  • Port: 443
  • Password: the password string you defined for the VNC server
  • Token: leave empty

Then press “Connect”. You will get forwarded to your XFCE session running inside the VNC server. Probably the XFCE screen lock will be greeting you and if you enter your local account credentials, the desktop will unlock.

You can expand this Apache configuration with additional protection mechanisms. That is the power of hiding a simple application behind an Apache reverse proxy: the simple application does what it does best, and Apache takes care of all the rest, including data encryption and access control.
You could think of limiting access to the noVNC URL to certain IP addresses or domain names. or you can add a login dialog in front of the noVNC web page. Be creative.

Configure your ISP’s router

My assumption is that your LAN server is behind a DSL, fiber or other connection provided by a local Internet Service Provider (ISP). The ISP will have installed a modem/router in your home which connects your home’s internal network to the Internet.

So the final step is to ensure that the HTPS port (443) of your LAN server is accessible from the internet. For this, you will have to enable ‘port-forwarding’ on your Internet modem/router. The exact configuration will depend on your brand of router, but essentially you will have to forward port 443 on the router to port 443 on your LAN server’s IP address.

If you have been reading this far, I expect that you are serious about implementing noVNC. You should have control over an Internet domain and the Internet-facing interface of your ISP’s modem/router should be associated with a hostname in your domain. Let’s say, you own the domain “lalalalala.org” and the hostname “alien.lalalalala.org” points to the public IP address of your ISP’s modem. Then anyone outside of your home (and you too inside your home if the router is modern enough) can connect to: https://alien.lalalalala.org/aliensdesktop/vnc.html and enter the following data into the connection box in order to connect to your VNC session:

  • Host: alien.lalalalala.org
  • Port: 443
  • Password: the password string you defined for the VNC server
  • Token: leave empty

That’s it! I hope it was all clear. I love to hear your feedback. Also, if certain parts need clarification or are just not working for you, let me know in the comments section below.

Cheers, happy holidays, Eric

Using Let’s Encrypt to Secure your Slackware webserver with HTTPS

In the ‘good old days‘ where everyone was a hippy and everyone trusted the other person to do the right thing, encryption was not on the table. We used telnet to login to remote servers, we transferred files from and to FTP servers in the clear, we surfed the nascent WWW using http:// links; there were no pay-walls; and user credentials, well who’d ever heard of those, right.
Now we live in a time where every government spies on you, fake news is the new news, presidents lead their country as if it were a mobster organisation and you’ll go to jail – or worse – if your opinion does not agree with the ruling class or the verbal minority.
So naturally everybody wants – no, needs – to encrypt their communication on the public Internet nowadays.

Lucky for us, Linux is a good platform for the security minded person. All the tools you can wish for are available, for free, with ample documentation and support on how to use them. SSH secure logins, PGP encrypted emails, SSL-encrypted instant messaging, TOR clients for the darkweb, HTTPS connections to remote servers, nothing new. Bob’s your uncle. If you are a consumer.

It’s just that until not too long ago, if you wanted to provide content on a web-server and wanted to make your users’ communications secure with HTTPS, you’d have to pay a lot of money for a SSL certificate that would be accepted by all browsers. Companies like VeriSign, DigiCert, Komodo, Symantec, GeoTrust are Certificate Authorities whose root certificates ended up in all certificate bundles of Operating Systems, browsers and other tools, but these big boys want you to pay them a lot of money for their services.
You can of course use free tools (openssl) to generate SSL vertificates yourself, but these self-signed certificates are difficult to understand and accept for your users if they are primarily non-technical (“hello supportline, my browser tells me that my connection is insecure and your certificate is not trusted“).

SSL certificates for the masses

Since long I have been a supporter of CACert, an organization whose goal is to democratize the use of SSL certificates. Similar to the PGP web-of-trust, the CACert organization has created a group of ‘assurers‘ – these are the people who can create free SSL certificates. These ‘assurers’ are trusted because their identities are being verified face-to-face by showing passports and faces. Getting your assurer status means that your credentials need to be signed by people who agree that you are who you say you are. CACert organizes regular events where you can connect with assurers, and/or become one yourself.
Unfortunately, this grass-roots approach is something the big players (think Google, Mozilla) can not accept, since they do not have control over who becomes an assurer and who is able to issue certificates. Their browsers are therefore still not accepting the CACert root certificate. This is why my web site still needs to display a link to “fix the certificate warning“.
This is not manageable in the long term, even though I still hope the CACert root certificate will ultimately end up being trusted by all browsers.

So I looked at Let’s Encrypt again.
Let’s Encrypt is an organization which has been founded in 2016 by a group of institutions (Electronic Frontier Foundation, Mozilla Foundation, Michigan University, Akamai Technologies and Cisco Systems) who wanted to promote the use of encrypted web traffic by allowing everyone to create the required SSL certificates in an automated way, for free. These institutions have worked with web-browser providers to get them to accept and trust the Let’s Encrypt root certificates. And that was successful.
The result is that nowadays, Let’s Encrypt acts as a free, automated, and open Certificate Authority. You can download and use one of many client programs that are able to create and renew the necessary SSL certificates for your web servers. And all modern browsers accept and trust these certificates.

Let’s Encrypt SSL certificates have a expiration of 3 months after creation, which makes it mandatory to use some mechanism that does regular expiration checks on your server and renews the certificate in time.

I will dedicate the rest of this article to explain how you can use ‘dehydrated‘, a 3rd-party and free Let’s Encrypt client which is fully compatible with the official ‘CertBot’ client of Let’s Encrypt.
Why a 3rd-party tool and not the official client? Well, dehydrated is a simple Bash shell script, easy to read and yet fully functional. On the other hand, please have a look at the list of dependencies you’ll have to install before you can use CertBot on Slackware! That’s 17 other packages! The choice was easily made, and dehydrated is actively developed and supported.

I will show you how to download, install and configure dehydrated, how to configure your Apache web server to use a Let’s Encrypt certificate, and how to automate the renewal of your certificates. After reading the below instructions, you should be able to let people connect to your web-server using HTTPS.


Install dehydrated

The easiest way to install  dehydrated is to use the SlackBuilds.org script for it. It will install the script, create a default configuration, install a man-page and documentation.

# wget https://slackbuilds.org/slackbuilds/14.2/system/dehydrated.tar.gz
# tar xvf dehydrated.tar.gz
# cd dehydrated
# . dehydrated.info && wget $DOWNLOAD
# chmod +x dehydrated.SlackBuild
# ./dehydrated.SlackBuild
# installpkg /tmp/dehydrated-0.6.5-noarch-1_SBo.tgz

Installing the package will also create a cron job “/etc/cron.d/dehydrated” which makes dehydrated run once a day at midnight. I want that file to have some comments about what it does and I do not want to run it at midnight, so I overwrite it with a line that makes it run once a week at 21:00 instead. It will also log its activity to a logfile, “/var/log/dehydrated” in the example below:

cat <<EOT > /etc/cron.d/dehydrated
# Check for renewal of Let's Encrypt certificates once per week on Monday:
0 21 * * Mon /usr/bin/dehydrated -c >> /var/log/dehydrated 2>&1
EOT

Dehydrated uses a directory structure below “/etc/dehydrated/”.
The main configuration file you’ll find there is called “config”.
The file “domains.txt” contains the host- and domain names you want to manage SSL certificates for.
The directory “accounts” will contain your Let’s Encrypt user account and private key, once you’ve registered with them.
And a new directory “certs” will be created to store the SSL certificates you are going to create and maintain.

How to deal with these files is going to be addressed in the next paragraphs.

The dehydrated configuration files

config

The main configuration file “/etc/dehydrated/config” is well-commented, so I just show the lines that I used:

DEHYDRATED_USER=alien
DEHYDRATED_GROUP=wheel
CA="https://acme-staging-v02.api.letsencrypt.org/directory"
#CA="https://acme-v02.api.letsencrypt.org/directory"
CHALLENGETYPE="http-01"
WELLKNOWN="/usr/local/dehydrated"
PRIVATE_KEY_RENEW="no"
CONTACT_EMAIL=eric.hameleers@gmail.com
LOCKFILE="${BASEDIR}/var/lock"
HOOK=/etc/dehydrated/hook.sh

Let’s go through these parameters:

  • We are starting the ‘dehydrated script as root, via a cron job or at the commandline. The values for DEHYDRATED_USER and DEHYDRATED_GROUP are the user and group the script will switch to at startup. All activities will be done as user ‘alien’ and group ‘wheel’ and not as the user ‘root’. This is a safety measure.
  • CA: this contains the Let’s Encrypt URL for dehydrated to connect to. You’ll notice that I actually list two values for “CA” but one is commented out. The idea is that you use the ‘staging’ URL for all your tests and trials, and once you are satisfied with your setup, you switch to the URL for production usage.
    Also note that Let’s Encrypt expects clients to use the ACMEv2 protocol. The older ACMEv1 protocol will still work, but you can not register a new account using the old protocol. Its only use nowadays is to assist in migrating old setups to ACMEv2. The “CA” URL contains the protocol version number, and I highlighted that part in red.
  • CHALLENGETYPE : we will be using HTTP challenge type because that’s easiest to configure. Alternatively if you manage your own DNS domain you could let dehydrate update your DNS zone table to provide the challenge that Let’s Encrypt demands.
    What is this challenge? Let’s Encrypt’s ACME-protocol wants to verify that you are in control of your domain and/or hostname. It will try to access a verification file via a HTTP request to your webserver.
  • WELLKNOWN: this defines the local directory  where dehydrated creates the ‘challenge-tokens’ which are then served by your webserver. The Let’s Encrypt ‘ACME server’ will connect to your server as part of the ‘http-01’ challenge and expects to find a specific file there with specific content (created by dehydrated). In the case of a webserver running on our example domain “foo.net”, that URL would be  http://foo.net/.well-known/acme-challenge/m4g1C-t0k3n . The dehydrate client must provide that “m4g1c-t0k3n” file which it will create during a certificate creation or renewal. Below I will explain how to create this URL location “.well-known/acme-challenge” and make it readable for an external server like Let’s Encrypt.
    If your “domains.txt” file contains more than one hostname or domain, the ACME server will repeat this challenge for every one of them. Usually, multiple hostnames or (sub-)domains means that you have defined multiple VirtualHost in your Apache webserver configuration. For every VirtualHost you need to enable access to this ‘http-01’ challenge location (I will show you how, below).
    Note: The first connect from the ACME server will always be over HTTP on port 80, but if your site does a redirect to HTTPS, that will work.
  • PRIVATE_KEY_RENEW: whether you want the certificate’s private key to be renewed along with the certificate itself. I chose “no” but the default is “yes”.
  • CONTACT_EMAIL: the email address which will be associated with your Let’s Encrypt account. This is where warning emails will be sent if your certificate about to expire but has not been renewed.
  • LOCK: the directory (which must be writable by our non-root user) where dehydrated will place a lock file during operation.
  • HOOK: the path to an optional script that will be invoked at various parts of dehydrate’s activities and which allows you to perform all kinds of related administrative tasks – such as restarting httpd after you have renewed its SSL certificate.
    NOTE: do not enable this “HOOK” line – i.e. put a ‘#” comment character in front of the line – until you actually have created a working and executable shell script with that name! You’ll get errors otherwise about the non-existing script.

domains.txt

The file “/etc/dehydrated/domains.txt” contains the list hosts and domain names you want to associate with your SSL certificates. You need to realize that a SSL certificate contains the hostname(s) or the domain name(s) that it is going to be used for. That is why you will sometimes see a “hostname does not match server certificate” warning if you open a URL in your browser, it means that the remote server’s SSL certificate was originally meant to be used with a different hostname.

In our case, the “domains.txt” file contains just one hostname on a single line:

www.foo.net

… but that line can contain any amount of different space-separated hosts under the same domain. For instance the line could be “foo.net www.foo.net” which would tell Let’s Encrypt that the certificate is going to be used on two separate web servers: one with hostname “foo.net” and the other with the hostname “www.foo.net“. Both names will be incorporated into the certificate.

Your “/etc/dehydrated/domains.txt” file can be used to manage the certificates of multiple domains, each domain on its own line (e.g. domain foo.org on one line, and domain foo.net on another line). Each line corresponds to a different SSL certificate – e.g. for different domains. Every line can contain multiple hosts in a single domain (for instance: foo.org www.foo.org ftp.foo.org).

Directory configuration

Two directories are important for dehydrated, and we need to create and/or configure them properly.

/etc/dehydrated

First, the dehydrated configuration directory. We have configured dehydrated to run as user ‘alien’ instead of user ‘root’ so we need to ensure that the directory is writable by this user. Or better (since we installed this as a Slackware package and a package upgrade would undo an ownership change of /etc/dehydrated) let’s manually create the subdirectories “accounts” “certs”, “chains” and “var” where our user actually needs to write, and make ‘alien’ the owner:

# mkdir -p /etc/dehydrated/accounts
# chown alien:wheel /etc/dehydrated/accounts
# mkdir -p /etc/dehydrated/certs
# chown alien:wheel /etc/dehydrated/certs
# mkdir -p /etc/dehydrated/chains
# chown alien:wheel /etc/dehydrated/chains
# mkdir -p /etc/dehydrated/var
# chown alien:wheel /etc/dehydrated/var

/usr/local/dehydrated

The directory “/usr/local/dehydrated” is the location where dehydrated to will generate the Let’s Encrypt challenge files. These files provide the proof that we actually own the domain(s) we are requesting a certificate for.
So let’s create that directory and allow our non-root user to write there:

# mkdir -p /usr/local/dehydrated
# chown alien:wheel /usr/local/dehydrated

SUDO considerations

We configured the dehydrated script to drop its root privileges at startup and continue as user ‘alien’, group ‘wheel’. Because we also change the group iit is important that the sudo line for root in the file “/etc/sudoers” is changed from the default:

#root ALL=(ALL) ALL

to

root ALL=(ALL:ALL) ALL

Else you’ll get the error “Sorry, user root is not allowed to execute ‘/usr/bin/dehydrated -c’ as alien:wheel on localhost.“.

Apache configuration

I expect that you have already setup your Apache for un-encrypted connections and already have a web site. If you still need to figure out how to setup a web site using Apache, I suggest you look for a good tutorial before you proceed with my article, like https://docs.slackware.com/howtos:network_services:setup_apache .

Before we register an account with Let’s Encrypt and start generating certificates, let’s first update our existing Apache configuration so that it works with dehydrated. We need to make the ‘http-01’ challenge location (http://foo.net/.well-known/acme-challenge/) accessible to external web clients, else the certificate generation will fail.

Note that the above example mentions the “foo.net” hostname. If your “/etc/dehydrated/domains.txt” contains lines with multiple hosts under a domain, you’ll have to make the URL path component “/.well-known/acme-challenge” accessible through every domain host you configured in Apache. The complete certificate generation process will fail in case any of these challenge URLs cannot be validated.
To make life more simple if you run multiple web servers, we created “/usr/local/dehydrated/” to store the challenge file. It’s a single file location.  With the help of the Apache “Alias” directive we can use that single file location in all our web servers.

Use this snippet of text in the <VirtualHost></VirtualHost> configuration block for every webserver host:

# We store the dehydrated info under /usr/local and use an Apache 'Alias'
# to be able to use it for multiple domains. You'd use this snippet:
Alias /.well-known/acme-challenge /usr/local/dehydrated
<Directory /usr/local/dehydrated>
    Options None
    AllowOverride None
     Require all granted
</Directory>

You can use “lynx” on the command-line to test whether a URL is valid:

$ lynx -dump http://www.foo.net/.well-known/acme-challenge/
Forbidden: You don't have permission to access /.well-known/acme-challenge/ on this server.

Despite that error, this message actually shows that the URL works (otherwise the return message would have been “Not Found: The requested URL /.well-known/acme-challenge was not found on this server.“).

This completes the required Let’s Encrypt modifications to your Apache web server configuration.
Next, and before we restart ‘httpd‘, our Apache server must be enabled to accept SSL connections. This is achieved by un-commenting the following line in “/etc/httpd/httpd.conf”:

# Secure (SSL/TLS) connections
Include /etc/httpd/extra/httpd-ssl.conf

You can now restart Apache httpd to activate our modifications (but always test the syntax of your configuration first:

# apachectl configtest
# /etc/rc.d/rc.httpd restart

To end the Apache configuration instructions, here are the bits that define the SSL parameters for your host. Note that you should not add them yet! You do not have a SSL certificate yet. Only after you have executed “dehydrated -c” and obtained the certificates, you can add the following lines to every <VirtualHost</VirtualHost> block where where you previously added the ‘Alias’ related stuff above:

SSLEngine on
SSLCertificateFile /etc/dehydrated/certs/foo.net/cert.pem
SSLCertificateKeyFile /etc/dehydrated/certs/foo.net/privkey.pem
SSLCertificateChainFile /etc/dehydrated/certs/foo.net/chain.pem
SSLCACertificatePath /etc/ssl/certs
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt

Note the hostname “foo.net” in these SSL lines above? This is an example of course and you need to change that to your own hostname.
What you need to realize is that this name corresponds to the first name of the line in your “/etc/dehydrated/domains.txt” file. Earlier in the article I used an example line for this “domains.txt” file which looks like this: “foo.net www.foo.net“. Even more hosts are possible, they should be space-separated. A single certificate will be generated which is valid for all of these hosts, and the directory where they are stored in is “/etc/dehydrated/certs/” followed by “./foo.net” which the name of that first entry of the line.

Running dehydrated for the first time, using the Let’s Encrypt staging server:

With all the preliminaries taken care of, we can now proceed and run ‘dehydrated’ for the first time. Remember to make it connect to the Let’s Encrypt ‘staging’ server during all your tests, to prevent their production server from getting swamped with bogus test requests!

Examining the manual page (run “man dehydrated“) we find that we need the parameter ‘–cron’, or ‘-c’, to sign/renew non-existent/changed/expiring certificates:

# /usr/bin/dehydrated -c
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as alien/wheel
# INFO: Using main config file /etc/dehydrated/config

To use dehydrated with this certificate authority you have to agree to their terms of service which you can find here: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf

To accept these terms of service run `/usr/bin/dehydrated --register --accept-terms`.

What did we learn here?
In order to use dehydrated, you’ll have to register first. Let’s create your account and generate your private key!

Do not forget to set the “CA” value in /etc/dehydrated/config to a URL supporting ACMEv2. If you use the old staging server URL you’ll see this error: “Account creation on ACMEv1 is disabled. Please upgrade your ACME client to a version that supports ACMEv2 / RFC 8555. See https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430 for details.

With the proper CA value configured (you’ll have to do this both for the staging and for the production server URL) , you’ll see this if you run “/usr/bin/dehydrated –register –accept-terms”:

# /usr/bin/dehydrated --register --accept-terms
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as alien/wheel
# INFO: Using main config file /etc/dehydrated/config
+ Generating account key...
+ Registering account key with ACME server...
+ Fetching account ID...
+ Done!

Generate a test certificate

We’re  ready to roll. As said before, it is proper etiquette to run all your tests against the Let’s Encrypt ‘staging’ server and use their production server only for the real certificates you’re going to deploy.
Let’s run the command which is also being used in our weekly cron job, “/usr/bin/dehydrated -c”:

# /usr/bin/dehydrated -c
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as alien/wheel
# INFO: Using main config file /etc/dehydrated/config
+ Creating chain cache directory /etc/dehydrated/chains
Processing www.foo.net
+ Creating new directory /etc/dehydrated/certs/www.foo.net ...
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting new certificate order from CA...
+ Received 1 authorizations URLs from the CA
+ Handling authorization for www.foo.net
+ Found valid authorization for www.foo.net
+ 0 pending challenge(s)
+ Requesting certificate...
+ Checking certificate...
+ Done!
+ Creating fullchain.pem...
+ Done!

This works! You can check your web site now if you did not forget to add the SSL lines to your VirtualHost block; your browser will complain that it is getting served an un-trusted SSL certificate issued by “Fake LE Intermediate X1“.

Generate a production certificate

First, change the “CA” variable in “/etc/dehydrated/config” to the production CA URL “https://acme-v02.api.letsencrypt.org/directory”.
Remove the fake certificates that were created in the previous testing step so that we can create real certificates next:

# rm -r /etc/dehydrated/certs/www.foo.net

Now that we’ve cleaned out the fake certificates, we’ll generate real ones:

# /usr/bin/dehydrated -c
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as alien/wheel
# INFO: Using main config file /etc/dehydrated/config
Processing www.foo.net
+ Creating new directory /etc/dehydrated/certs/www.foo.net ...
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting new certificate order from CA...
+ Received 1 authorizations URLs from the CA
+ Handling authorization for www.foo.net
+ 1 pending challenge(s)
+ Deploying challenge tokens...
+ Responding to challenge for www.foo.net authorization...
+ Challenge is valid!
+ Cleaning challenge tokens...
+ Requesting certificate...
+ Checking certificate...
+ Done!
+ Creating fullchain.pem...
+ Done!

If you reload the Apache server configuration (using the command “apachectl -k graceful”) you’ll now see that your SSL certificate has been signed by “Let’s Encrypt Authority X3” and it is trusted by your browser. We did it!

Automatically reloading Apache config after cert renewal

When your weekly cron job decides that it is time to renew your certificate, we want the dehydrated script (which runs as a non-root account) to reload the Apache configuration. And of course, only root is allowed to do so.

We’ll need a bit of sudo magic to make it possible for the non-root account to run the “apachectl” program. Instead of editing the main file “/etc/sudoers” with the command “visudo” we create a new file “httpd_reload” especially for this occasion, in sub-directory “/etc/sudoers.d/” as follows:

# cat <<EOT > /etc/sudoers.d/httpd_reload
alien ALL=NOPASSWD: /usr/sbin/apachectl -k graceful
EOT

This sudo configuration allows user ‘alien’ to run the exact command “sudo /usr/sbin/apachectl -k graceful” with root privileges.

Next, we need to instruct the dehydrated  script to automatically run “sudo /usr/bin/apachectl -k graceful” after it has renewed any of our certificates. That is where the “HOOK” parameter in “/etc/dehydrated/config” comes to play.

As the hook script, we are going to use dehydrated’s own sample “hook.sh” script that can be downloaded from https://raw.githubusercontent.com/lukas2511/dehydrated/master/docs/examples/hook.sh or (if you used the SlackBuilds.org script to create a package) use “/usr/doc/dehydrated-*/examples/hook.sh”.

# cp -i /usr/doc/dehydrated-*/examples/hook.sh /etc/dehydrated/
# chmod +x /etc/dehydrated/hook.sh

This shell script contains a number of functions, each is relevant and will be called at a certain stage of the certificate renewal process. The dehydrated script will provide several environment variables to allow a high degree of customization, and all of that is properly documented in the sample script, but we do not need any of that. Just at the end of the “deploy_cert()” function we need to add a few lines:

deploy_cert() {
# ...
# After successfully renewing our Apache certs, the non-root user 'alien'
# uses 'sudo' to reload the Apache configuration:
sudo /usr/sbin/apachectl -k graceful
}

That’s all. Next time dehydrated renews a certificate, the hook script will be called and that will reload the Apache configuration at the appropriate moment, making the new certificate available to visitors of your web site.

Summarizing

I am glad you made it all the way down here! In my usual writing style, the article is quite verbose and gives all kinds of contextual information. Sometimes that makes it difficult for the “don’t bother me with knowledge, just show me the text I should copy/paste ” user but I do not care for that.

I do hope you found this article interesting, and useful. If you spotted any falsehoods,let me know in the comments section below. If some part needs more clarification, just tell me.

Have fun with a secure web!

Eric

Continue reading

« Older posts Newer posts »

© 2024 Alien Pastures

Theme by Anders NorenUp ↑