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

Lazy admins using the shell (third one)

Another thing i always use, is a separate file for my aliases, functions etc. I always call this file .bash_common. To use it just source it in your .bashrc:

...
. ~/.bash_common
...

This is my .bash_common: show

Older Posts:

Lazy admins… the second one
Lazy admins using the shell

Hacken in der Warpzone oder Wie finde ich meinen Pi?

Letztes WE war ich mal wieder seit langem in der Warpzone. Mit im Gepäck hatte ich meinen Raspberry Pi und wie jedes mal stellte sich dann die Frage: “Welche IP hat er denn nun bekommen?”
Um diese herauszufinden gibt es natürlich mehrere Möglichkeiten, wobei keine wirklich komfortabel ist. Damit ich nicht jedes mal Ewigkeiten damit verbringe die IP meinese Pi’s rauszubekommen habe ich mir ein kleines Tool geschrieben:

show

Diese Tool speichern, ausführbar machen (chmod +x …) und anschliessen in die /etc/rc.local eingetragen:

...
/usr/bin/ipmailer.py

 

Nach jedem Boot wird eine Mail versendet mit den IP Adressen der angegebenen Interfaces und zusätzlich auch noch die extern IP. Nun kann man ganz einfach per ssh und den IP Adressen aus der E-Mail auf seinen Raspberry Pi zugreifen.

UDATE:
Gerade habe ich per Twitter eine “einfache” Lösung bekommen (Danke an Fenk):

ifconfig eth0|sendxmpp user@host.de


Eine gute Anleitung zum einrichten von sendxmpp findet man sendxmpp.

Delete specific line from a file

After a remote installation through ssh the fingerprint of a system changed. This happend, because a new RSA key during the setup process was generated. Now you want connect to the system and you get the following error:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
f1:9d:1f:fg:7c:ad:ad:43:6e:8f:c9:fd:86:d0:78:ce.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/user/.ssh/known_hosts:371
RSA host key for 127.0.0.1 has changed and you have requested strict checking.
Host key verification failed.

So you have to delete line 371 from your known_hosts file. You can do this with your fravorite editor, or just run the following command:

sed -i ‘371d’ /home/user/.ssh/known_hosts

How to identify the harddisks filesystem

I had an harddisk with an unknown filesystem. The mount command without any option didn’t work, so i had to find out the filesystem.

There is one simpel command to do this:

hellmann linux # file -s /dev/sdb1
/dev/sdb1: x86 boot sector, code offset 0x3c, OEM-ID "TSD FAT ", sectors/cluster 64, sectors 976771120 (volumes > 32 MB) , FAT (32 bit), sectors/FAT 119221, serial number 0x4d1d59b, unlabeled

Now i can use the mount command with the -t option to simply mount this partition (don’t know why it doesn’t detect the filesystem automatically):

mount -t vfat /dev/sdb1 /mnt/usb

Netzwerk testen mit ping

Viele kennen das Problem:

Man will mal eben schnell überprüfen, ob der Server / Client / Netzwerkdevice Netzwerkprobleme hat und ping ihn. So weit so gut, soll der ping dann doch länger laufen weiß man bei Probleme oftmals nie wann genau sie aufgetreten sind.

Ein normaler ping sieht wie folgt aus und lässt keinen Rückschluss zu, wann er ausgeführt wurde.

user@computer:~ $ ping pcspinnt.de
PING pcspinnt.de (81.28.232.70) 56(84) bytes of data.
64 bytes from 81.28.232.70: icmp_req=1 ttl=54 time=55.3 ms
64 bytes from 81.28.232.70: icmp_req=2 ttl=54 time=53.5 ms
64 bytes from 81.28.232.70: icmp_req=3 ttl=54 time=52.4 ms
64 bytes from 81.28.232.70: icmp_req=4 ttl=54 time=55.4 ms
64 bytes from 81.28.232.70: icmp_req=5 ttl=54 time=54.4 ms
64 bytes from 81.28.232.70: icmp_req=6 ttl=54 time=53.3 ms

Um nun auch die Uhrzeit zu bekommen, kann man folgendes machen:

user@computer:~ $ ping pcspinnt.de|while read ping; do echo "$(date +%d.%m.%Y %H:%M:%S) => $ping"; done
18.11.2011 13:41:58 => PING pcspinnt.de (81.28.232.70) 56(84) bytes of data.
18.11.2011 13:41:58 => 64 bytes from 81.28.232.70: icmp_req=1 ttl=54 time=52.9 ms
18.11.2011 13:41:59 => 64 bytes from 81.28.232.70: icmp_req=2 ttl=54 time=55.3 ms
18.11.2011 13:42:00 => 64 bytes from 81.28.232.70: icmp_req=3 ttl=54 time=54.2 ms
18.11.2011 13:42:01 => 64 bytes from 81.28.232.70: icmp_req=4 ttl=54 time=53.2 ms

Sollte es dann zu einem Ausfall kommen, weiß man genau, wann er stattgefunden hat. Hier nun noch einmal der eigentliche Befehl:

ping pcspinnt.de|while read ping; do echo "$(date +%d.%m.%Y %H:%M:%S) => $ping"; done

Gefunden habe ich das ganze auf hak5.org

Nikon D70s und ufraw

Um die Fotos meiner Kamera in jpg’s zu verwandeln nutze ich immer ufraw und das dann bevorzugt im batch Mode (ufraw-batch). Die Parameter habe ich bisher immer von Hand mit übergeben. Da wir aber in letzer Zeit sehr viele Fotos gemacht haben, war das irgend wann zu nervig und ich habe mir eine config gebaut. Man benötigt dafür zuerst einmal das Kamera Profil, was man hier runterladen kann.

Danach legt man sich die Config Datei an z.B. .ufrawrc

Anschließend kann man ufraw-batch mit dem Paramter –conf=/path/to/conf/.ufrawrc aufrufen. Die Bilder werden dann automatisch mit den passenden Einstellungen umgewandelt.