Weitere Module- / Manifestbeispiele

Mit folgendem Module kann ein User incl. Gruppe und Gruppenzugehörigkeit angelegt werden. Außerdem wird ihm direkt ein ssh-key hinterlegt:
Zuerst muss der entsprechende Ordner angelegt werden:

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
}

Damit man dem Benutzer z.B. eigene Config Dateien zur Verfügung zu stellen, sollte vorher der Fileserver in Puppet konfiguriert werden.

# This file consists of arbitrarily named sections/modules
# defining where files are served from and to whom

# Define a section 'files'
# Adapt the allow/deny settings to your needs. Order
# for allow/deny does not matter, allow always takes precedence
# over deny
[dotfiles]
        path /mnt/puppet_dotfiles
        allow puppetclient.home

[plugins]
#  allow *.example.com
#  deny *.evil.example.com
#  allow 192.168.0.0/24

Über die allow Direktive kann man den Zugriff reglementieren. Bisher habe ich noch keine Möglichkeit gefunden ganze Netze frei zugeben. Im Netz taucht hier oft allow_ip auf. Dies funktionierte bei meinen Tests aber genau so wenig wie allow.
Die Manifest wird dann wie folgt erweitert:

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
        file {'/home/shellmann/.vimrc':
                ensure => 'file',
                mode => '0660',
                owner => 'shellmann',
                group => 'shellmann',
                source => 'puppet:///dotfiles/user_shellmann/.vimrc',
        }
}

In meiner persönlichen vim config sind ein paar Ordner definiert, die noch nicht existieren. Auch dabei kann uns puppet helfen.

class user_shellmann {
        group { 'shellmann':
                ensure => present,
                gid => 1000
        }
        user { 'shellmann':
                ensure => present,
                require    => Group['shellmann'],
                gid => 'shellmann',
                groups => ['sudo', 'cdrom', 'floppy', 'audio', 'dip', 'video', 'plugdev', 'netdev', 'bluetooth',],
                shell => '/bin/bash',
                home => '/home/shellmann',
                purge_ssh_keys => true,
        }
        ssh_authorized_key { 'private':
                user => 'shellmann',
                type => 'ssh-rsa',
                key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDSNp/edM111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
        }
        file {'/home/shellmann/.vimrc':
                ensure => 'file',
                mode => '0660',
                owner => 'shellmann',
                group => 'shellmann',
                source => 'puppet:///dotfiles/user_shellmann/.vimrc',
        }
        file { '/home/shellmann/.vim':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
        file { '/home/shellmann/.vim/backup':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
        file { '/home/shellmann/.vim/swap':
                ensure => 'directory',
                owner  => 'shellmann',
                group  => 'shellmann',
                mode   => '0660',
        }
}

Konfiguration von puppet (nodes und manifest)

Weiter geht es mit der Konfiguration der einzelnen Nodes.
Zuerst müssen die Nodes eingetragen werden:

node 'puppetclient.home' {
}

node 'puppetserver.home' {
}

Das bewirkt aber erst mal noch garnichts. Die erste Aufgabe, die wir per puppet erledigen wollen, ist z.B. das Installieren von diversen “Admin Tools”. Dazu müssen wir als erstes ein neues Modul anlegen.

mkdir -p /etc/puppet/modules/admintools/manifests

In dem neu angelegten Verzeichnis erstellen wir nun ein Manifest:

class admintools {
        package { 'tmux': ensure => 'installed' }
        package { 'multitail': ensure => 'installed' }
        package { 'htop': ensure => 'installed' }
        package { 'vim': ensure => 'installed' }
        package { 'sudo': ensure => 'installed' }
        package { 'openssh-server': ensure => 'installed' }
        package { 'vim-puppet': ensure => 'installed' }
}

Das neue Module kann danach dann eingebunden werden:

node 'puppetclient.home' {
    include admintools
}

node 'puppetserver.home' {
    include admintools
}

Weiter geht es im 3. Teil

Installation von puppet

Zum Testen und für erste Gehversuche mit Puppet habe ich mir zwei VMS mit Debian Jessie installiert.
Die Installation von Puppet selbst ist dann sehr einfach.
Auf dem Server muss folgender Befehl ausgeführt werden:

root@puppetserver:~# apt-get install puppetmaster puppet

Das Paket puppet installiere ich mit, da der Server selber auch Client sein sollen.
Auf dem Client muss dann folgendes installiert werden:

root@puppetclient:~# apt-get install puppet

Damit der Client dann den Server auch erreicht muss muss die puppet.conf angepasst werden (gleiches gilt für den Server, wenn er gleichzeitig auch Agent sein soll)

[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
server=puppetserver.home

[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

Der Agent muss dann aktiviert werden:

root@puppetclient:~# puppet agent --enable

Um für den Client jetzt einen neuen SSL Key und einen Request zu generieren muss folgender Befehl ausgeführt werden:

root@puppetclient:~# puppet agent -t
Info: Creating a new SSL key for puppetclient.home
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for puppetclient.home
Info: Certificate Request fingerprint (SHA256): 74:FC:D5:F1:1D:94:48:14:8D:44:69:00:F4:F2:08:46:42:3E:25:8F:1A:81:EA:AF:44:98:33:21:0B:AD:AE:18
Exiting; no certificate found and waitforcert is disabled

Zur Erklärung:
Auf dem Puppetserver läuft eine CA. Aus Sicherheitsgründen muss deshalb zuerst am Server ein Zertifikat ausgestellt werden.
Die Wortwahl der Befehle ist im nachfolgenden Beispiel etwas ungüstig.
Mit dem ersten Befehl werden all Request und “Zertifikate” bzw. deren Fingerprint angezeigt. Zertifikate haben ein + als erstes Zeichen
Mit dem zweiten Befehl wird dann ein Request signiert. Befehl drei zeigt dann noch mal alle Zertifikate an.

root@puppetserver:~# puppet cert --list --all
  "puppetclient.home" (SHA256) 74:FC:D5:F1:1D:94:48:14:8D:44:69:00:F4:F2:08:46:42:3E:25:8F:1A:81:EA:AF:44:98:33:21:0B:AD:AE:18
+ "puppetserver.home" (SHA256) A6:17:03:8D:F8:2E:C0:E5:76:49:24:E8:84:4D:EB:91:DB:63:82:45:75:2F:33:60:F6:79:A9:AF:D2:06:1B:E1 (alt names: "DNS:puppet", "DNS:puppet.home", "DNS:puppetserver.home")
root@puppetserver:~# puppet cert sign "puppetclient.home"
Notice: Signed certificate request for puppetclient.home
Notice: Removing file Puppet::SSL::CertificateRequest puppetclient.home at '/var/lib/puppet/ssl/ca/requests/puppetclient.home.pem'
root@puppetserver:~# puppet cert --list --all
+ "puppetclient.home" (SHA256) F2:7A:B7:54:0D:F9:18:EE:0E:17:E5:CF:EB:44:E7:D4:CE:68:75:B9:4D:1E:65:0B:E8:05:A8:5D:97:C8:7D:A8
+ "puppetserver.home" (SHA256) A6:17:03:8D:F8:2E:C0:E5:76:49:24:E8:84:4D:EB:91:DB:63:82:45:75:2F:33:60:F6:79:A9:AF:D2:06:1B:E1 (alt names: "DNS:puppet", "DNS:puppet.home", "DNS:puppetserver.home")

Am Client kann nun das Zertifikat abgeholt werden:

root@puppetclient:~# puppet agent -t
Info: Caching certificate for puppetclient.home
Info: Caching certificate for puppetclient.home
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for puppetclient.home
Info: Applying configuration version '1455277912'
Notice: Finished catalog run in 0.06 seconds

Damit ist die Grundinstallation fertig. Per default meldet sich der Client alle 30 Minuten am Server. Der Client kann von Hand ausgeführt werden, mit entsprechendem Verbose / Debug Output:

root@puppetclient:~# puppet agent --no-daemonize --onetime --verbose --debug

Gleiches kann man natürlich auch mit dem Server / Daemon machen:

root@puppetserver:~# puppet master --no-daemonize --verbose --debug

Um das vim Plugin zu aktivieren, muss es zuerst in den Plugin Ordner des Homesverzeichnisses verlinkt werden:

root@puppetserver:~# mkdir -p /root/.vim/plugin
root@puppetserver:~# ln -s /usr/share/vim/addons/syntax/puppet.vim .vim/plugin/puppet.vim

Außerdem muss die vimrc noch angepasst werden:

syntax on

Weiter gehts im 2. Teil

Arduino Plugin in Eclipse aktivieren

Folgende Programme werden benötigt:

Ich habe beide Pakete (Arduino IDE + Eclipse) in meinem Homesverzeichnis in den Unterordner Tools entpackt.

Damit der User auch Zugriff auf den Arduino hat sollte er den Gruppen tty und uucp hinzugefügt werden:

sudo usermod -a -G tty,uucp shellmann

Danach start man eclipse. Dort muss nun das Plugin installiert werden:

Help => Install New Software

install_pluginHier muss man auf Add klicken.

install_plugin2Die Daten für das Repository wie oben abgebildet eingeben
(URL: http://www.baeyens.it/eclipse/V2)

 install_plugin3Nun kann das Repository über die Drop Down Liste ausgewählt werden.
ACHTUNG: Unten müssen auch die Haken passend gesetzt werden.

Das Plugin kann nun installiert werden. Eclipse muss anschliessend neu gestartet werden. Bei mir kam aber z.B. beim Zugriff auf den “Serial Monitor”  noch eine Fehlermeldung:

java.lang.UnsatisfiedLinkError: Can't load library: /home/user/tools/arduino/lib/librxtxSerial64.so
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854) at java.lang.Runtime.load0(Runtime.java:795)
at java.lang.System.load(System.java:1062) at it.baeyens.arduino.common.Common.LoadRXTX(Common.java:528)
at it.baeyens.arduino.ui.ArduinoPreferencePage$1.widgetSelected(ArduinoPreferencePage.java:248)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
...

Dafür musste ich das Paket dev-java/rxtx nachinstallieren und in den entsprechenden Ordner verlinken.

sudo ln -s /usr/lib64/rxtx-2/librxtxSerial-2.2pre1.so ~/tools/arduino/lib/librxtxSerial64.so

UPDATE:
Alternativ kann man die librxtxSerial auch noch /lib linken:

sudo ln -s /usr/lib64/rxtx-2/librxtxSerial-2.2pre1.so /lib/librxtxSerial64.so

Blog nun auch verschlüsselt erreichbar

Der Blog ist jetzt über ssl erreichbar. Habe mir gerade bei startssl ein Zertifikat geholt.

https://www.pcspinnt.de

In dem Zusammenhang habe ich auch ein an den SSL Einstellungen gedreht. Leider kommt man nun mit dem IE6 nicht mehr auf meine Seite.

Zum Feintuning ist diese Seite hier sehr hilfreich:

https://www.ssllabs.com/ssltest/

Attach / detach disks to running vms under libvirt

You can hot add disks to running vm with virsh with the following command:

virsh attach-disk VMNAME /dev/mapper/VG-testdisk vdb

You can although use the parameter –persistent. This will write the new disk to the VMs config.

If you want remove the disk you can use this command:

virsh attach-disk VMNAME --target vdb

Make your prompt ($PS1) more functional

This is a very simple prompt with only different colors:

PS1="\[\e[0;37m\][\[\e[0;32m\]\u\[\e[0;37m\]@\[\e[0;33m\]\h\[\e[0m] "

snapshot-2014-03-31-23-01-35
Some scripting foo to get a different color for root (for better readability split into multiple lines):

PS1=""
# add user
if [[ ${EUID} == 0 ]]; then
        PS1+="\[\e[0;31m\]\u"
else
        PS1+="\[\e[0;32m\]\u"
fi
# add @ + host
PS1+="\[\e[0;37m\]@\[\e[0;33m\]\h "

snapshot-2014-03-31-23-31-47
Now adding some brackets and the working directory:

# opening brackets
PS1="\[\e[0;37m\]["
# add user
if [[ ${EUID} == 0 ]]; then
        PS1+="\[\e[0;31m\]\u"
else
        PS1+="\[\e[0;32m\]\u"
fi
# add @ + host
PS1+="\[\e[0;37m\]@\[\e[0;33m\]\h"
# add working dir
PS1+="\[\e[0;37m\]:\[\e[01;34m\]\w"
# closing brackets + reset
PS1+="\[\e[0;37m\]]\e[0m "

snapshot-2014-03-31-23-28-33
Now some functionall things.
I’m using the prompt_command to add last exit code to my prompt. Short descriptione from the bash man page:

PROMPT_COMMAND
If set, the value is executed as a command prior to issuing each
primary prompt.

Adding last exit code:

function prompt () {
        exitcode=$?
        # add exit code
        PS1=" "
        if [ $exitcode == 0 ]; then
                PS1+="\[\033[01;32m\]\342\234\223"

        else
                PS1+="\[\033[01;31m\]\342\234\227"
        fi

        PS1+="$exitcode "
        # opening brackets
        PS1+="\[\e[0;37m\]["
        # add user
        if [[ ${EUID} == 0 ]]; then
                PS1+="\[\e[0;31m\]\u"
        else
                PS1+="\[\e[0;32m\]\u"
        fi
        # add @ + host
        PS1+="\[\e[0;37m\]@\[\e[0;33m\]\h"
        # add working dir
        PS1+="\[\e[0;37m\]:\[\e[01;34m\]\w"
        # closing brackets + reset
        PS1+="\[\e[0;37m\]]"
        # reset color
        PS1+="\e[0m "
}
PROMPT_COMMAND='prompt'

snapshot-2014-03-31-23-46-21

Combinig all this stuff with one of my last posts, it could look like this:

function prompt () {
        exitcode=$?
        # add exit code
        PS1=" "
        if [ $exitcode == 0 ]; then
                PS1+="\[\033[01;32m\]\342\234\223"

        else
                PS1+="\[\033[01;31m\]\342\234\227"
        fi

        PS1+="$exitcode "
        # opening brackets
        PS1+="\[\e[0;37m\]["
        # add user
        if [[ ${EUID} == 0 ]]; then
                PS1+="\[\e[0;31m\]\u"
        else
                PS1+="\[\e[0;32m\]\u"
        fi
        # add @ + host
        PS1+="\[\e[0;37m\]@\[\e[0;33m\]\h"
        # add working dir
        PS1+="\[\e[0;37m\]:\[\e[01;34m\]\w"
        # closing brackets + reset
        PS1+="\[\e[0;37m\]]"
        # display git branch
        if [ -f /usr/bin/git ]; then
                branch="$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \(\1\)/')"
                PS1+="$branch"
        fi
        PS1+=" \$"
        # reset color
        PS1+="\e[0m "
}
PROMPT_COMMAND='prompt'

snapshot-2014-04-01-00-05-11

bash history and a lot of terminals

If you are using many terminals you know the problem, that the bash_history is only written after logging out. So if you want to share commands between two terminals you have to copy and paste them.

Reading the bash man page i found the PROMPT_COMMAND:

PROMPT_COMMAND
    If set, the value is executed as a command prior to issuing each primary prompt.

With this little guy it’s easy. Simple write this to your .bashrc and commands will be written directly to your history:

export PROMPT_COMMAND='history -a'

Howto show git branch in bash prompt

This is my normal bash prompt:
prompt
The corresponding variable:

PS1='\[\033[0;36m\][\[\e[0;32m\]\u\[\e[0;37m\]@\[\e[0;33m\]\h:\[\e[0;35m\]\w\[\e[0;36m\]]\[\e[0;40m\]\$\[\e[0;37m\] '

To add the git branch, you have to put these lines in your ~/.bashrc:

function parse_git_branch {
        git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \< \1\> /'
}
PS1='\[\033[0;36m\][\[\e[0;32m\]\u\[\e[0;37m\]@\[\e[0;33m\]\h:\[\e[0;35m\]\w\[\e[0;36m\]]\[\e[0;40m\]\[\033[1;34m\]$(parse_git_branch)\[\033[1;37m\]\$\[\e[0;37m\] '

Now it will show the branch in a git directory:
prompt_branch

Server-"Umzug"

Dieses Wochenende habe ich mich mal wieder ein wenig mit meinem Server beschäftigt. Da der Wartungsaufwand immer mehr und die Zeit immer knapper wurde, habe ich mich entschlossen nun doch Debian zu installieren. Hinzu kam, dass die Jails (7 Stück) zum Schluss eine hohe Last erzeugt haben und der Server damit gut beschäftigt war.

D.h. aber nicht, dass ich FreeBSD nicht weiter im Auge behalten werde. Es ist nach wie vor ein cooles OS mit einer Menge interessanter Ansätzen.

Mit dem Umzug sind auch ein paar neue Features hinzugekommen:

* alle Dienste sind vollständig auch über IPv6 erreichbar
* das Zertifikat wurde erneuert und gegen eins mit mehreren “CN’s” ausgetauscht:

...
X509v3 Subject Alternative Name:
DNS:*.pcspinnt.de, othername:<unsupported>, DNS:*.pc-spinnt.de, othername:<unsupported>, DNS:*.hellmann-it.de, othername:<unsupported>
...

Geplant ist auch noch ein VPN Server, damit ich zu Hause auch echts IPv6 bekomme. Die generellen Arbeiten sollten eigentlich abgeschlossen sein…hoffe ich zumindest.