Posts Tagged 'Linux'

Setting KVM hostname per DHCP

The Problem

One problem with virtual machines is, when you clone one you also copy the complete configuration including hostname, static IPs, etc. To fix this you need to boot the cloned VM, edit the config and reboot it. The problem is that you will have at least temporary hostname and/or IP conflicts.

Use DHCP

The better approach is to obtain hostnames and IPs via DHCP.
Then when you clone a machine (e.g. using virt-manager) for testing software updates or other changes, you simply remove the external NIC from the cloned VM, and the internal NIC gets a new MAC assigned automatically.
Then you update the DHCP server configuration (e.g. /etc/dnsmasq.conf) and add the new MAC, assigned IP and hostname there. Then when booting the new VM it automatically gets the correct hostname and new IP, without the need of changing the VM’s configuration files.

Example:

dhcp-host=52:54:00:B9:C5:06,redmine,192.168.0.14,30m
dhcp-host=52:54:00:BF:70:1C,redmine-test,192.168.0.19,30m

After the changes have been tested successfully you can apply the changes to the real system (you still should have a backup).
Don’t remove the cloned ‘test-vm’. Just shut it down and keep it for the next time.

When you need to test again some new changes on the machine you have already the complete clone configuration and MAC address DHCP setup. So you simply need to replace the clone’s disk file (e.g. redmine-clone.qcow) with the latest version of your VM’s disk file (e.g. redmine.qcow). Then you can start the test machine and everything should work just fine without any conflicts.

Example SSH Session:

# log into the VM's host system
ssh -l root blade7
cd /var/lib/libvirt/images
# shutdown the VM before copying the file
virsh shutdown Redmine
cp redmine.qcow redmine-test.qcow
# Restart VM
virsh start Redmine
# Start Clone-VM
virsh start Redmine-test
exit

Configuring the DHCP-Client on Debian (VM Guest)

On Debian you simply need to set the hostname in /etc/hostname to “localhost” to enable receiving the hostname via DHCP.
The DHCP client itself is already configured to request “host-name” info via DHCP. See /etc/dhcp/dhclient.conf. There you should find the option “host-name” in the list of requested DHCP options.

About DNSmasq

As a side note I should mention that using DNSmasq is a great solution. It is a DHCP server and DNS server in one application.
This means no matter if you are adding hostnames manually to the DHCP configuration or getting hostnames via DHCP from any DHCP client, these names can be also resolved via DNS automatically, without any further configuration.

Using Let’s encrypt for non-web servers

I think I don’t need to explain Let’s encrypt anymore. But what many people are struggling with is to use Let’s encrypt certificates for other services like SMTP, IMAP, IRC, etc.

Using certbot this is quiet easy (See https://certbot.eff.org for installation instructions).

When certbot is installed you can use it in standalone mode. This means it starts a built-in webserver which is used for the authentication process and gets stopped again a few seconds later.

To make it short here is an example command to create a new certificate for your mail server:

./certbot-auto certonly --standalone -d smtp.yourdomain.com -d imap.yourdomain.com

Of course the standalone webserver must be reachable from the internet, so ensure that no firewall is blocking port 443 (https). In my case I have a firewall running, so I need to temporary enable https. Certbot also supports this by using the options pre-hook and post-hook.

./certbot-auto certonly --standalone --pre-hook /root/enable_https --post-hook /root/disable_https -d smtp.domain.com -d imap.domain.com

The example hook scripts insert a firewall rule for https and remove it again. This again are just examples that you need to adapt to your needs.

enable_https:

#!/bin/bash
IPTABLES=/sbin/iptables
$IPTABLES -I INPUT 8 -i eth0 -p tcp -m conntrack --ctstate NEW -m tcp --dport 443 -j ACCEPT

disable_https:

#!/bin/bash
IPTABLES=/sbin/iptables
$IPTABLES -D INPUT -i eth0 -p tcp -m conntrack --ctstate NEW -m tcp --dport 443 -j ACCEPT

See man(8) iptables for more information on this.

Renewing is also easy. By default the “certbot-auto renew” command will renew all certificates with the same options. Only the hooks must be give again at the command line.

./certbot-auto renew --pre-hook /root/enable_https --post-hook /root/disable_https

It is recommended to call this twice a day. Certbot will only really renew it when the certificate is about to expire. To automate this process you can create a cronjob.

I used the template which gets created when installing certbot using Debian Jessie.

/etc/cron.d/certbot:

# /etc/cron.d/certbot: crontab entries for the certbot package
#
# Upstream recommends attempting renewal twice a day
#
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# twice a day
0 */12 * * * root test -x /root/certbot-auto && perl -e 'sleep int(rand(3600))' && /root/certbot-auto -q renew --pre-hook /root/enable_https --post-hook /root/disable_https

Finally you need to update your mail server configuration to use the new certificates. Let’s encrypt stores the currently active certificate in /etc/letsencrypt/live/<your domain>/. This folder contains only symlinks to /etc/letsencrypt/archive/<your domain>/ with the real certificate files and keys, chains, etc.

In my case I simply edited /etc/postfix/main.cf and /etc/imapd.conf to use these new files.
Cyrus was no able to access the files by default, because the default file permissions prevented it to access the folders of “Let’s Encrypt”.
I fixed this by giving cyrus readonly access using the ssl-cert group.

chgrp -R ssl-cert /etc/letsencrypt/live /etc/letsencrypt/archive
chmod 750 /etc/letsencrypt/live /etc/letsencrypt/archive
usermod -a -G ssl-cert cyrus

Building MinGW Cross-Compilation Toolchain using CrossDev

This is mainly a note to myself. Maybe it’s useful for you too.

Actually building cross-compiler toolchains using crossdev is easy, but there are some pitfalls.

  • Remove any compiler environment variables before building, or the build will fail
  • For building MinGW toolchains the openmp useflag must not be set
  • If you have built already a toolchain partially with wrong settings, remove it completely before trying it again

Simple Build Instructions for building mingw32 and gdb:

# become root
su
# clear env (clearing CXX should not be necessary, but it doesn't hurt)
export CC=
export CXX=
export CFLAGS=
export CXXFLAGS=
export LDFLAGS=
# build using crossdev
crossdev --ex-gdb -t i686-pc-mingw32

For 64bit toolchain use x86_64-w64-mingw32 instead of i686-pc-mingw32.

Uninstall: crossdev -C i686-pc-mingw32

See https://wiki.gentoo.org/wiki/Mingw for more information.

CMake uninstall

CMake is a great tool when building cross-plattform software. It offers also install target so you can build and install software this way:


# create of-of-source build directory
mkdir bld
cd bld
# run CMake to generate a Makefile
ccmake ..
# Build in 4 cores
make -j 4
# Install into CMAKE_INSTALL_PREFIX (default is /usr/local)
sudo make install

However there is no uninstall target.
But this is no problem as long as you have a shell and the xargs command (part of GNU findutils).

CMake creates a file called install_manifest.txt when executing the install target. This contains a list of all installed files. So for removing them you simply need to execute this command:


# uninstall
xargs rm < install_manifest.txt

YCM FixIt Feature

YouCompleteMe (YCM) is really an awsome plugin. But today this blog post is not about completion support, it’s about YCM’s FixIt feature. If you are developer and have seen already compiler errors like this:

expected ';' at end of declaration

then I’m sure you also thought already: “If the compiler knows already the solution for the problem, why it can’t fix it automatically?” Well, at least you might think so when using an IDE like Visual Studio.

As a Vim user it is more obvious that compiler and editor are two separate things and the compiler can’t fix it. But Vim with YCM can do exactly that. The command :YcmCompleter FixIt does exactly what we want. YCM shows the capability of doing so by adding the text (FixIt) to the error message. If you map this command to a keyboard shortcut like the following you can fix those issues with a single keypress:

" Apply YCM FixIt
map <F9> :YcmCompleter FixIt<CR>

Here is a short video to demonstrate the feature (click on the GIF to show in full size): ycm_syntax

New Keystroke GUI with Vim support

I’ve created an updated version of my Keystroke-gui keylogger,
which can be controlled by Vim Hooks.
Keystroke is keylogger and visualizer which can be used for screencasts.
This is especially useful when recording screencasts for Vim, because in Vim’s normal mode you cannot see what is typed, opposed to insert mode. But in normal made most of the “magic” happens 😉
The new version of Keystroke can be controlled over a TCP socket. Actually it
supports the following commands:

  • disable: disable the logger (actually just the visualization)
  • enable: enable the logger again
  • insertEnter: enter Vim’s insert mode
  • insertLeave: leave Vim’s insert mode

This TCP server is used by Vim to tell the Keystroke when vim is started, exited, and when it enters/leaves insertMode. Some helper BASH script which simply do a “echo ‘command’ | nc localhost 9999′ are use to form the client side of the communication. Vim’s autocmd feature is used to execute those scrips.

augroup logger
    autocmd!
    autocmd VimEnter * :call system('$HOME/vim/enable_logger')
    autocmd VimLeave * :call system('$HOME/vim/disable_logger')
    autocmd InsertEnter * :call system('$HOME/vim/insert_enter')
    autocmd InsertLeave * :call system('$HOME/vim/insert_leave')
augroup end

When Keystroke is set to insertMode it only displays control keys like
<C-x><C-l> <tab>, or <enter>. Because the normal keys you see anyway in the buffer.

Of course keystroke is also useful for other types of screencasts, it is not
limited to Vim. But the Vim support is unique afaik.

If you want to give it a try you can clone the git repo
https://github.com/gergap/keystroke.git

This new feature is currently available only on the branch
FEATURE_MORE_CONFIG. I’ll need more testing before I release it, but it works
already.

What would be this post without a short demo? So here it comes (click on the GIF to show in full size):

demo

What is still missing: More config options to adapt to different situations.
E.g. what keys get filtered and what keys are shown.

Have fun 😉

Mk script is now on github

An updated version of my ‘mk’ script is now available on github. This way it is easier to update it. See https://github.com/gergap/mk

I blogged about it before in 2014, see https://gergap.wordpress.com/2014/03/04/mk-script-to-simplify-out-of-source-builds