Installation eines Ansible-Orchestrator-Management-Hosts mit Hilfe eines Kickstartfiles für CentOS 8.x (PXE-Server)

Kurz mal einen Rechner zu installieren, wie im Kapitel Installation von CentOS 8.x via PXE beschrieben und anschließend manuell dann anschließend Ansible mit Ansible einzurichten, wie hier beschrieben, mag auch eine Variante darstellen.

Wir wollen aber in folgendem Beispiel automatisiert unseren AOMH1) reproduzierbar vie PXE installieren, so dass wir ohne Umwege direkt mit der Arbeit beginnen und unsere Zielsysteme nach unseren Wünschen automatisiert zu bestücken.

Folgende Voraussetzungen müssen hierzu erfüllt werden:

  1. Der DHCP-Server muss für PXE konfiguriert werden und im Netz erreichbar sein.
  2. Ein TFTP-Server muss zur Verfügung stehen und im Netz erreichbar sein.
  3. Eine Definition des Bootmenüs mit entsprechenden Optionen wurde erfolgreich vorgenommen.
  4. Die Netzwerkkarte im Clientrechner muss PXE unterstützen!

Der Grundgedanke bei dieser Vorhaben ist, im Zweifel immer wieder exakt den gleichen Ansible-Ochestrator-Management-Host reproduzierbar aufzusetzen, werden wir das benötigte SSH-Schlüsselmaterial zu aller erst erzeugen und dann auch entsprechend sicher im physischen Safe weg sperren, so dass wir im Katastrophenfall darauf zurückgreifen zu können.

Im Kapitel Voraussetzung: SSH-Schlüssel haben wir uns bereits ausführlich mit der Thematik SSH-Schlüssel beschäftigt und auch gezeigt, wie dieser erstellt wird.

Wir erstellen uns nun einen ED25519-Schlüssel (-t), mit einer festen Schlüssellänge. Der Parameter (-a) beschreibt dabei die Anzahl der KDF-Schlüsselableitfunktion (siehe manpage von ssh-keygen). Wir verwenden wieder als Beschreibung Ansible Systemuser (-C) und als Ziel-/Speicherort ~/.ssh/id_ed25519_ansible (-f).

  $ ssh-keygen -t ed25519 -a 100 -C 'Ansible Systemuser' -f ~/.ssh/id_ed25519_ansible
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in ~/.ssh/id_ed25519_ansible.
Your public key has been saved in ~/.ssh/id_ed25519_ansible.pub.
The key fingerprint is:
SHA256:jTZQUDbCqZaV648fKVBfx3L4+tBMWL+z+iUCBY3kKMQ Ansible Systemuser
The key's randomart image is:
+--[ED25519 256]--+
|     o+==.oo     |
|     .E+ +.+.    |
|     ++.. = *    |
|    +..+ + O .   |
|   ...  S + o .  |
|     ... o *   . |
|      .oo o + + .|
|      .... o . = |
|       ..   ooo  |
+----[SHA256]-----

Die beiden Key-Files kopieren wir dann auf ein vertrauenswürdiges Medium, auf welches wir jederzeit wieder zurückgreifen können.

 $ ll .ssh/
-r--------. 1 ansible ansible 411 Jun 20 13:08 id_ed25519_ansible
-rw-r--r--. 1 ansible ansible 100 Jun 20 13:08 id_ed25519_ansible.pub

Ob das nun ein sicherer USB-Speicherstick wie der Nitrokey Storage 2, ein Network Attached Storage oder eine vertrauenswürdige (Next)Cloud ist, muss natürlich jeder für sich selbst entscheiden.

Wie Eingangs schon angesprochen, wollen wir unseren Ansible-Orchestrator-Management-Host bei Bedarf immer nach dem gleichen Grundschema aufbauen, konfigurieren und auch härten. Wir werden also diese Aufgaben standardisieren und automatisch abarbeiten lassen.

Folgende Aufgaben wird unser Script für uns reproduzierbar künftig erledigen:

  1. Grundinstallation eines CentOS 8 Hosts (Minimalinstallation)
  2. IP-Adresse und Hostname Durch Angabe des Hostnamens beim Booten des Installationsimages wollen wir diesen setzen und auch die zugehörige IP-Adresse übernehmen lassen. (Der Hostname wir so z.B. auch bei der Definition der VolumeGroup eines LVMs verwendet.)
  3. Installations-Logfile zum Nachvollziehen der erfolgten INstallation unter /root/anaconda-postinstall.log anlegen.
  4. Bootloader Da wir beim Booten der Maschine detailierte Informationen sehen wollen werden wir die Option rhgb in der GRUB-Definition entfernen.
  5. MOTD und ISSUE.NET individualisieren inkl. Hostnamen
  6. SSH-Daemon Den SSH Daemon härten wir und passen die Konfigurationsdatei entsprechend an.
  7. SSH-Publickey Für unseren Admin-Account django hinterlegen wir den zugehörigen öffentlichen SSH-Schlüssel.
  8. Repositories Statt der öffentlichen, sollen nur noch die lokal gesyncten Repositories verwendet werden; daher macht es auch keinen Sinn die Einträge mirrorlist= in den entsprechenden repo-filers stehen zu lassen.
  9. Zusätzlich zum Standard soll auch noch das Repository EPEL eingebunden und genutzt werden.
  10. Update Zum Schluss stellen wir noch sicher dass alle installierten Pakete in der aktuellsten Version vorliegen und lassen dann das System neu starten.
  11. NFS-Client zur Verbindung NAS einrichten, damit später die Playbooks gesichert werden können.
  12. Ansible System-User erstellen und zuvor erstelltes Schlüsselmaterial hinterlegen
  13. Ansible: Directory Layout- Verzeichnisstruktur anlegen

Zur automatischen Installation und Konfiguration unseres Ansible-Orchestrator-Management-Hosts verwenden wir folgende Kickstart-Datei.

 # vim /srv/kickstart/ks_centos_8_x86_64_ansible.cfg
/srv/kickstart/ks_centos_8_x86_64_ansible.cfg
# Django 2020-06-21 Kickstart-Datei zum automatischen Betanken des Ansible-Orchestrator-Management-Hosts (64 Bit)
# Version=CentOS 8 (RHEL 8)
 
# 1) Grundinstallation ##########################################################################################
 
# Tastaturlayout definieren
keyboard --vckeymap=de-nodeadkeys --xlayouts='de (nodeadkeys)'
 
# Systemsprache setzen
lang en_US.UTF-8
 
# Definition der Netzwerkeinstellungeni - setzen der Netzwerk-Adresse und Hostname
# die aus dem Preinstall-Script beim PXE-Boot übernommen wurden.
%include /tmp/networks.cfg
network  --bootproto=static --device=eth1 --ip 10.20.30.40 --netmask 255.255.255.0 --ipv6=auto --activate
 
# Zeitzone setzen
timezone Europe/Berlin --isUtc --ntpservers=time.dmz.nausch.org
services --enabled="chronyd"
 
# Netzwerkinstallation aus dem eigenen Repository mit den aktuellen Paketen
url --url="http://repo.dmz.nausch.org/centos/8/BaseOS/x86_64/os/"
repo --name="AppStream" --baseurl=http://repo.dmz.nausch.org/centos/8/BaseOS/x86_64/os/../../../AppStream/x86_64/os/
 
# Root-Passwort verschlüsselt vorgeben
rootpw --iscrypted $6$Z46HtZ/aLHbA19p$WVsutOEqe0m0e97lgEreKUzfkAEFzFSR0Hj8RFN8MHqWjPqk7PkJeQ9mIcTGtdutFnFVdFzFSR0KhrdGwUdAn01
 
# Default-Benutzerkonto anlegen
user --name=django --password=$6$2.fGKBeQa18GE6XwDMXG6$QX/j.TfZXk0bBuoJ8GE6XMXRZYz/4pEE6PuwkubaDmteRAAerLVKK69EF30d1K/f1d/sUEqbF9FJBulc/ --iscrypted --gecos="Bastard Operator from Hell"
 
# vorhandene Partitionen löschen
#ignoredisk --only-use=vda
#clearpart --all --initlabel --drives=vda
# autopart --type=lvm
 
# GUI für Installation verwenden
graphical
 
# Kein X Window System konfigurieren, da dieses nicht installiert wird
skipx
 
# Reboot nach der Installation ausführen
reboot
 
# Paketauswahl definieren (Minimalinstallation mit zusätzlichen Paketen
%packages
@^minimal-environment
-iwl*firmware
vim
bash-completion
bind-utils
wget
telnet
net-tools
lsof
tree
%end
 
%addon com_redhat_kdump --disable --reserve-mb='auto'
%end
 
%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end
 
#%end
 
%addon com_redhat_kdump --disable --reserve-mb='auto'
 
%end
#################################################################################################################
 
# 2) Preinstall-Anweisungen: IP-Adresse und Hostname ermitteln und setzen #######################################
%pre
#!/bin/bash
echo "network --device eth0 --bootproto dhcp --hostname vml000XXX.dmz.nausch.org" > /tmp/network.ks
for x in `cat /proc/cmdline`; do
    case $x in SERVERNAME*)
        eval $x
        NULL=${SERVERNAME:6:1}
        if [ "$SERVERNAME" == "" ]; then
            echo "network  --bootproto=static --device=eth0 --gateway=10.0.0.17 --ip 10.0.0.250 --nameserver=10.0.0.27 --netmask 255.255.255.0 --ipv6=auto --activate --hostname vml000250.dmz.nausch.org" > /tmp/networks.cfg
        else
            if [ "$NULL" == "0" ]; then
                OCTET=${SERVERNAME:7:2}
            else
                OCTET=${SERVERNAME:6:3}
            fi
            echo "network  --bootproto=static --device=eth0 --gateway=10.0.0.17 --ip 10.0.0.${OCTET} --nameserver=10.0.0.27 --netmask 255.255.255.0 --ipv6=auto --activate --hostname ${SERVERNAME}.dmz.nausch.org" > /tmp/networks.cfg
        fi
        ;;
        esac;
    done
%end
#################################################################################################################
 
# 3) Postinstall-Anweisungen: Installations-Log erzeugen und VVariablen setzen ##################################
%post --log=/root/anaconda-postinstall.log
#!/bin/bash
DATUM=$(date +"%Y-%m-%d")
for x in `cat /proc/cmdline`; do
case $x in SERVERNAME*)
eval $x
#################################################################################################################
 
# 4) Bootloader anpassen, rhgb bei den Bootoptionen entfernen ###################################################
sed -i 's/rhgb//g' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg
#################################################################################################################
 
# 5) MOTD und ISSUE.NET individualisieren #######################################################################
# /etc/issue.net anlegen
cat <<ISSUE.NET > /etc/issue.net
##############################################################################
#                                                                            #
#                       This is a private home server.                       #
#                                                                            #
#             Unauthorized access to this system is prohibited !             #
#                                                                            #
#    This system is actively monitored and all connections may be logged.    #
#         By accessing this system, you consent to this monitoring.          #
#                                                                            #
##############################################################################
ISSUE.NET
 
chown root: /etc/issue.net
chmod 644 /etc/issue.net
 
# /etc/motd anlegen
cat <<MOTD > /etc/motd
##############################################################################
#                                                                            #
#                 This is the home server of Michael Nausch.                 #
#                                                                            #
#                            $SERVERNAME.nausch.org                            #
#                                                                            #
#             Unauthorized access to this system is prohibited !             #
#                                                                            #
#    This system is actively monitored and all connections may be logged.    #
#         By accessing this system, you consent to this monitoring.          #
#                                                                            #
##############################################################################
MOTD
 
chown root: /etc/motd
chmod 644 /etc/motd
#################################################################################################################
 
# 6) SSH-Daemon konfigurieren ###################################################################################
cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
cat <<SSHD_CONFIG > /etc/ssh/sshd_config
#	$OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
 
# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.
 
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
 
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.
 
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
# Specifies which address family should be used by sshd(8). Valid arguments
# are ''any'', ''inet'' (use IPv4 only), or ''inet6'' (use IPv6 only).
#AddressFamily any
 
# Specifies the local addresses sshd(8) should listen on. The following 
# forms may be used:
#                   ListenAddress host|IPv4_addr|IPv6_addr
#                   ListenAddress host|IPv4_addr:port
#                   ListenAddress [host|IPv6_addr]:port
# If port is not specified, sshd will listen on the address and all prior 
# Port options specified. The default is to listen on all local addresses. 
# Multiple ListenAddress options are permitted. Additionally, any Port 
# options must precede this option for non-port qualified addresses.
#Port 22
#ListenAddress 0.0.0.0
#ListenAddress ::
 
# Specifies a file containing a private host key used by SSH. The default 
# is /etc/ssh/ssh_host_key for protocol version 1, and 
# /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for protocol 
# version 2. Note that sshd(8) will refuse to use a file if it is 
# group/world-accessible. It is possible to have multiple host key files.
# ''rsa1'' keys are used for version 1 and ''dsa'' or ''rsa'' are used for
# version 2 of the SSH protocol. 
HostKey /etc/ssh/ssh_host_ed25519_key
 
# Specifies the ciphers allowed for protocol version 2. Multiple ciphers 
# must be comma-separated. The supported ciphers are ''3des-cbc'', 
# ''aes128-cbc'', ''aes192-cbc'', ''aes256-cbc'', ''aes128-ctr'', 
# ''aes192-ctr'', ''aes256-ctr'', ''arcfour128'', ''arcfour256'', 
# ''arcfour'', ''blowfish-cbc'', and ''cast128-cbc''.
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
 
# MACs' Specifies the available MAC (message authentication code) 
# algorithms. The MAC algorithm is used in protocol version 2 for data 
# integrity protection. Multiple algorithms must be comma-separated.
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
 
# Specifies the available KEX (Key Exchange) algorithms. Multiple 
# algorithms must be comma-separated. For ineroperability with Eclipse 
# and WinSCP): 
# KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
# If needed, open /etc/ssh/moduli if exists, and delete lines where the 
# 5th column is less than 2000.
#   awk '$5 > 2000' /etc/ssh/moduli > "${HOME}/moduli"
#   wc -l "${HOME}/moduli"
# make sure there is something left
#   mv "${HOME}/moduli" /etc/ssh/moduli
#
KexAlgorithms curve25519-sha256@libssh.org
 
# Ciphers and keying
#RekeyLimit default none
 
# System-wide Crypto policy:
# This system is following system-wide crypto policy. The changes to
# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any
# effect here. They will be overridden by command-line options passed on
# the server start up.
# To opt out, uncomment a line with redefinition of  CRYPTO_POLICY=
# variable in  /etc/sysconfig/sshd  to overwrite the policy.
# For more information, see manual page for update-crypto-policies(8).
 
# Logging
# Gives the facility code that is used when logging messages from sshd(8). 
# The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, 
# LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. 
SyslogFacility AUTHPRIV
 
# Gives the verbosity level that is used when logging messages from sshd(8).
# The possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, 
# DEBUG1, DEBUG2, and DEBUG3. The default is INFO. DEBUG and DEBUG1 are 
# equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging 
# output. Logging with a DEBUG level violates the privacy of users and is 
# not recommended.
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a 
# clear audit track of which key was using to log in.
LogLevel VERBOSE
 
# Authentication:
# The server disconnects after this time if the user has not successfully 
# logged in. If the value is 0, there is no time limit.
LoginGraceTime 0
 
# Specifies whether root can log in using ssh(1). The argument must be 
# ''yes'', ''without-password'', ''forced-commands-only'', or ''no''. 
# The default is ''yes''. If this option is set to ''without-password'', 
# password authentication is disabled for root. If this option is set to
# ''forced-commands-only'', root login with public key authentication will 
# be allowed, but only if the command option has been specified (which 
# may be useful for taking remote backups even if root login is normally 
# not allowed). All other authentication methods are disabled for root.
# If this option is set to ''no'', root is not allowed to log in.  
PermitRootLogin no
 
# This keyword can be followed by a list of user name patterns, separated 
# by spaces. If specified, login is allowed only for user names that match 
# one of the patterns. Only user names are valid; a numerical user ID is 
# not recognized. By default, login is allowed for all users. If the pattern
# takes the form USER@HOST then USER and HOST are separately checked, 
# restricting logins to particular users from particular hosts. The 
# allow/deny directives are processed in the following order: 
# DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups. 
AllowUsers django ansible
 
# Specifies whether sshd(8) should check file modes and ownership of the 
# user's files and home directory before accepting login. This is normally 
# desirable because novices sometimes accidentally leave their directory 
# or files world-writable.
StrictModes yes
 
# Specifies the maximum number of authentication attempts permitted per 
# connection. Once the number of failures reaches half this value, 
# additional failures are logged.
MaxAuthTries 10
 
# Specifies the maximum number of open sessions permitted per network 
# connection.
MaxSessions 10
 
# Specifies the file that contains the public keys that can be used for 
# user authentication. AuthorizedKeysFile may contain tokens of the form
# %T which are substituted during connection setup. The following tokens
# are defined: %% is replaced by a literal '%', %h is replaced by the 
# home directory of the user being authenticated, and %u is replaced by
# the username of that user. After expansion, AuthorizedKeysFile is
# taken to be an absolute path or one relative to the user's home directory.
AuthorizedKeysFile      .ssh/authorized_keys
 
# Specifies whether public key authentication is allowed. The default is 
# ''yes''. Note that this option applies to protocol version 2 only.
PubkeyAuthentication yes
 
 
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
 
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
 
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
 
# Specifies whether password authentication is allowed. To disable tunneled 
# clear text passwords, change to no here!
PasswordAuthentication no
 
# Specifies whether challenge-response authentication is allowed 
# (e.g. via PAM or though authentication styles supported in login.conf(5))
# Change to no to disable s/key passwords
ChallengeResponseAuthentication no
 
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
 
# Specifies whether user authentication based on GSSAPI is allowed.
GSSAPIAuthentication yes
 
# Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key 
# exchange doesn't rely on ssh keys to verify host identity. 
#GSSAPIKeyExchange no
 
# Specifies whether to automatically destroy the user's credentials cache 
# on logout.
GSSAPICleanupCredentials no
 
# Determines whether to be strict about the identity of the GSSAPI acceptor 
# a client authenticates against. If ''yes'' then the client must authenticate
# against the host service on the current hostname. If ''no'' then the client 
# may authenticate against any service key stored in the machine's default
# store. This facility is provided to assist with operation on multi homed 
# machines. The default is ''yes''. Note that this option applies only to 
# protocol version 2 GSSAPI connections, and setting it to ''no'' may only 
# work with recent Kerberos GSSAPI libraries.
#GSSAPIStrictAcceptorCheck yes
 
#GSSAPIEnablek5users no
 
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
# problems.
UsePAM yes
 
# Specifies whether X11 forwarding is permitted. The argument must be 
# ''yes'' or ''no''. The default is ''no''.
# When X11 forwarding is enabled, there may be additional exposure to the
# server and to client displays if the sshd(8) proxy display is configured
# to listen on the wildcard address (see X11UseLocalhost below), though this
# is not the default. Additionally, the authentication spoofing and 
# authentication data verification and substitution occur on the client side.
# The security risk of using X11 forwarding is that the client's X11 display
# server may be exposed to attack when the SSH client requests forwarding 
# (see the warnings for ForwardX11 in ssh_config(5)). A system administrator
# may have a stance in which they want to protect clients that may expose
# themselves to attack by unwittingly requesting X11 forwarding, which can 
# warrant a ''no'' setting. Note that disabling X11 forwarding does not 
# prevent users from forwarding X11 traffic, as users can always install 
# their own forwarders. X11 forwarding is automatically disabled if UseLogin
# is enabled. 
X11Forwarding yes
 
# Specifies the first display number available for sshd(8)'s X11 forwarding.
# This prevents sshd from interfering with real X11 servers. 
# The default is 10.
#X11DisplayOffset 10
 
# Specifies whether sshd(8) should bind the X11 forwarding server to the 
# loopback address or to the wildcard address. By default, sshd binds the
# forwarding server to the loopback address and sets the hostname part of
# the DISPLAY environment variable to ''localhost''. This prevents remote
# hosts from connecting to the proxy display. However, some older X11 clients
# may not function with this configuration. X11UseLocalhost may be set to 
# ''no'' to specify that the forwarding server should be bound to the 
# wildcard address. The argument must be ''yes'' or ''no''. The default is 
# ''yes''.
#X11UseLocalhost yes
 
# Specifies whether ssh-agent(1) forwarding is permitted. The default is 
# ''yes''. Note that disabling agent forwarding does not improve security 
# unless users are also denied shell access, as they can always install 
# their own forwarders.
#AllowAgentForwarding yes
 
# Specifies whether TCP forwarding is permitted. The default is ''yes''. 
# Note that disabling TCP forwarding does not improve security unless users
# are also denied shell access, as they can always install their own 
# forwarders. 
#AllowTcpForwarding yes
 
# Specifies whether remote hosts are allowed to connect to ports forwarded
# for the client. By default, sshd(8) binds remote port forwardings to the
# loopback address. This prevents other remote hosts from connecting to 
# forwarded ports. GatewayPorts can be used to specify that sshd should 
# allow remote port forwardings to bind to non-loopback addresses, thus 
# allowing other hosts to connect. The argument may be ''no'' to force 
# remote port forwardings to be available to the local host only, ''yes''
# to force remote port forwardings to bind to the wildcard address, or 
# ''clientspecified'' to allow the client to select the address to which 
# the forwarding is bound. The default is ''no''. 
#GatewayPorts no
 
#PermitTTY yes
 
# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
# as it is more configurable and versatile than the built-in version.
PrintMotd no
 
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
 
# The contents of the specified file are sent to the remote user before 
# authentication is allowed. 
Banner /etc/issue.net
 
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
 
# Configures an external subsystem (e.g. file transfer daemon). Arguments 
# should be a subsystem name and a command (with optional arguments) to 
# execute upon subsystem request. Log sftp level file access 
# (read/write/etc.) that would not be easily logged otherwise.
Subsystem	sftp	/usr/libexec/openssh/sftp-server
 
# Example of overriding settings on a per-user basis
#Match User anoncvs
#	X11Forwarding no
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server
SSHD_CONFIG
chown root: /etc/ssh/sshd_config
chmod 600 /etc/ssh/sshd_config
#################################################################################################################
 
# 7) SSH-Publickey des Admin-Accounts hinterlegen ###############################################################
mkdir /home/django/.ssh
chmod 700 /home/django/.ssh
chown django: /home/django/.ssh
cat <<AUTHORIZED_KEYS >/home/django/.ssh/authorized_keys
ssh-ed25519 AAAAC3OkhsMagNI1NTE5AAAAIDYjDCtBTfrpbHHkRrqHrrD5d+IbkzaC1lZDU6ddoBSp django@nausch.org
AUTHORIZED_KEYS
chmod 644 /home/django/.ssh/authorized_keys
chown django: /home/django/.ssh/authorized_keys
#################################################################################################################
 
# 8) lokal gespiegeltes CentOS-Repository benutzen ##############################################################
cp -a /etc/yum.repos.d/CentOS-AppStream.repo /etc/yum.repos.d/CentOS-AppStream.repo.orig
cat <<CENTOS-APPSTREAM > /etc/yum.repos.d/epel-modular.repo
# CentOS-AppStream.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
 
[AppStream]
name=CentOS-\$releasever - AppStream
baseurl=http://repo.dmz.nausch.org/centos/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
CENTOS-APPSTREAM
chown root: /etc/yum.repos.d/CentOS-AppStream.repo
chmod 644 /etc/yum.repos.d/CentOS-AppStream.repo
 
cp -a /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.orig
cat <<CENTOS-BASE > /etc/yum.repos.d/CentOS-Base.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
 
[BaseOS]
name=CentOS-\$releasever - Base
baseurl=http://repo.dmz.nausch.org/centos/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
CENTOS-BASE
chown root: /etc/yum.repos.d/CentOS-AppStream.repo
chmod 644 /etc/yum.repos.d/CentOS-AppStream.repo
 
cp -a /etc/yum.repos.d/CentOS-Extras.repo /etc/yum.repos.d/CentOS-Extras.repo.orig
cat <<CENTOS-EXTRAS > /etc/yum.repos.d/CentOS-Extras.repo
# CentOS-Extras.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
 
#additional packages that may be useful
[extras]
name=CentOS-\$releasever - Extras
baseurl=http://repo.dmz.nausch.org/centos/\$releasever/extras/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
CENTOS-EXTRAS
chown root: /etc/yum.repos.d/CentOS-Extras.repo
chmod 644 /etc/yum.repos.d/CentOS-Extras.repo
#################################################################################################################
 
# 9) EPEL installieren und lokales gespiegeltes EPEL-Repository benutzen ########################################
dnf install epel-release -y
rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-
 
cp -a /etc/yum.repos.d/epel-modular.repo /etc/yum.repos.d/epel-modular.repo.orig
cat <<EPEL-MODULAR > /etc/yum.repos.d/epel-modular.repo
[epel-modular]
name=Extra Packages for Enterprise Linux Modular \$releasever - \$basearch
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Modular/\$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
 
[epel-modular-debuginfo]
name=Extra Packages for Enterprise Linux Modular \$releasever - \$basearch - Debug
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Modular/\$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
 
[epel-modular-source]
name=Extra Packages for Enterprise Linux Modular \$releasever - \$basearch - Source
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Modular/\$basearch/SRPMS
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
 
EPEL-MODULAR
chown root: /etc/yum.repos.d/epel-modular.repo
chmod 644 /etc/yum.repos.d/epel-modular.repo
 
cp -a /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.orig
cat <<EPEL > /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Everything/\$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
 
[epel-debuginfo]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch - Debug
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Everything/\$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
 
[epel-source]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch - Source
baseurl=http://repo.dmz.nausch.org/epel/\$releasever/Everything/SRPMS
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
EPEL
chown root: /etc/yum.repos.d/epel.repo
chmod 644 /etc/yum.repos.d/epel.repo
#################################################################################################################
 
# 10) System Updaten ############################################################################################
dnf update -y
#################################################################################################################
 
# 11) NFS-Client zur Verbindung NAS einrichten ##################################################################
dnf install nfs-utils -y
mkdir /srv/repository
cp -a /etc/fstab /etc/fstab.orig
cat <<FSTAB >> /etc/fstab
10.20.30.10:/volume1/backup	/srv/repository	nfs rw,rsize=8192,wsize=8192,soft,bg,nolock	0 0
FSTAB
mount /srv/repository
#################################################################################################################
 
# 12) Ansible installieren ######################################################################################
dnf install ansible-doc ansible -y
#################################################################################################################
 
# 13) Ansible System-User erstellen und zuvor erstelltes Schlüsselmaterial hinterlegen ##########################
groupadd --gid 65533 ansible && useradd ansible --create-home --home-dir /home/ansible --comment "Ansible System-User" --gid 65533 --uid 65533 --password '$6$7d6OVSAcprhrUHrX$YJUg2rUQwRfJ4UdvQjSOR3cmS0xwoRRkMNCjLNsjAuleUzKCHvOh9ZXWPze.1CQ9Y2uwAS59SsMIwYKJ1lgBr.'
mkdir /home/ansible/.ssh
chmod 700 /home/ansible/.ssh
chown ansible: /home/ansible/.ssh
cat <<KEY > /home/ansible/.ssh/id_ed25519_ansible
-----BEGIN OPENSSH PRIVATE KEY-----
QyNTUxOQAAACC7YuO2mTknrX7zRcVVapCQH0il48r3pgd5EWREOav5HwAAAJhJEdo0SRHa
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
AAAEBTt8W5ylj51xHums6dfdjpPM5qpgCVHIGJV8W5leF5Brti47aZOSetfvNFxVVqkJAf
SKXjyvemB3kRZEQ5q/kfAAAAEkFuc2libGUgU3lzdGVtdXNlcgECAw==
-----END OPENSSH PRIVATE KEY-----
KEY
chmod 400 /home/ansible/.ssh/id_ed25519_ansible
chown ansible:  /home/ansible/.ssh/id_ed25519_ansible
cat <<KEY_PUB > /home/ansible/.ssh/id_ed25519_ansible.pub
ssh-ed25519 AAAAC3NzaC1lZDemB3kRZEQI1NTE5A7aZOSetfvNFxVVqkJAfSKXjAAAILti4yv5q/kf Ansible Systemuser
KEY_PUB
chmod 644 /home/ansible/.ssh/id_ed25519_ansible.pub
chown ansible:  /home/ansible/.ssh/id_ed25519_ansible.pub
cp /home/ansible/.ssh/id_ed25519_ansible.pub /home/ansible/.ssh/authorized_keys
chmod 644 /home/ansible/.ssh/authorized_keys
chown ansible:  /home/ansible/.ssh/authorized_keys
usermod -aG wheel ansible
#################################################################################################################
 
# 14) Ansible: Directory Layout - Verzeichnisstruktur anlegen ####################################################
mkdir -p /home/ansible/ansible/inventories/{production,staging}/{group_vars,host_vars}
mkdir -p /home/ansible/ansible/{library,module_utils,filter_plugins}
touch /home/ansible/ansible/inventories/{production,staging}/hosts.yml
mkdir -p /home/ansible/ansible/roles/common/{tasks,handlers,templates,files,vars,defaults,meta,library,module_utils,lookup_plugin}
touch /home/ansible/ansible/site.yml /home/ansible/ansible/roles/common/{tasks,handlers,templates,files,vars,defaults,meta}/main.yml
chown -R ansible: /home/ansible/ansible/
cat <<HOSTS > /home/ansible/ansible/inventories/production/hosts
--- #YAML start syntax (optional) 
centos8:
  hosts:
    ansible:
      ansible_ssh_host: 10.0.0.40
    #demo:
    #  ansible_ssh_host: 10.0.0.190
    #  ansible_ssh_port: 22
... #YAML ende syntax (optional)
HOSTS
chmod 644 /home/ansible/ansible/inventories/production/hosts.yml
chown ansible: /home/ansible/ansible/inventories/production/hosts.yml
#################################################################################################################
 
# 15) Ansible konfigurieren #####################################################################################
cat <<ANSIBLE_CFG > /home/ansible/.ansible.cfg
# config file for ansible -- https://ansible.com/
# ===============================================
 
# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first
 
[defaults]
 
# some basic default values...
 
# Django : 2020-06-19
# default: #inventory      = /etc/ansible/hosts
inventory = /home/ansible/ansible/inventories/production/hosts.yml
#library        = /usr/share/my_modules/
#module_utils   = /usr/share/my_module_utils/
#remote_tmp     = ~/.ansible/tmp
#local_tmp      = ~/.ansible/tmp
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks          = 5
#poll_interval  = 15
#sudo_user      = root
#ask_sudo_pass = True
#ask_pass      = True
#transport      = smart
#remote_port    = 22
#module_lang    = C
#module_set_locale = False
 
# plays will gather facts by default, which contain information about
# the remote system.
#
# smart - gather by default, but don't regather if already gathered
# implicit - gather by default, turn off with gather_facts: False
# explicit - do not gather by default, must say gather_facts: True
#gathering = implicit
 
# This only affects the gathering done by a play's gather_facts directive,
# by default gathering retrieves all facts subsets
# all - gather all subsets
# network - gather min and network facts
# hardware - gather hardware facts (longest facts to retrieve)
# virtual - gather min and virtual facts
# facter - import facts from facter
# ohai - import facts from ohai
# You can combine them using comma (ex: network,virtual)
# You can negate them using ! (ex: !hardware,!facter,!ohai)
# A minimal set of facts is always gathered.
#gather_subset = all
 
# some hardware related facts are collected
# with a maximum timeout of 10 seconds. This
# option lets you increase or decrease that
# timeout to something more suitable for the
# environment.
# gather_timeout = 10
 
# Ansible facts are available inside the ansible_facts.* dictionary
# namespace. This setting maintains the behaviour which was the default prior
# to 2.5, duplicating these variables into the main namespace, each with a
# prefix of 'ansible_'.
# This variable is set to True by default for backwards compatibility. It
# will be changed to a default of 'False' in a future release.
# ansible_facts.
# inject_facts_as_vars = True
 
# additional paths to search for roles in, colon separated
#roles_path    = /etc/ansible/roles
 
# uncomment this to disable SSH key host checking
#host_key_checking = False
 
# change the default callback, you can only have one 'stdout' type  enabled at a time.
#stdout_callback = skippy
 
 
## Ansible ships with some plugins that require whitelisting,
## this is done to avoid running all of a type by default.
## These setting lists those that you want enabled for your system.
## Custom plugins should not need this unless plugin author specifies it.
 
# enable callback plugins, they can output to stdout but cannot be 'stdout' type.
#callback_whitelist = timer, mail
 
# Determine whether includes in tasks and handlers are "static" by
# default. As of 2.0, includes are dynamic by default. Setting these
# values to True will make includes behave more like they did in the
# 1.x versions.
#task_includes_static = False
#handler_includes_static = False
 
# Controls if a missing handler for a notification event is an error or a warning
#error_on_missing_handler = True
 
# change this for alternative sudo implementations
#sudo_exe = sudo
 
# What flags to pass to sudo
# WARNING: leaving out the defaults might create unexpected behaviours
#sudo_flags = -H -S -n
 
# SSH timeout
#timeout = 10
 
# default user to use for playbooks if user is not specified
# (/usr/bin/ansible will use current user as default)
#remote_user = root
# Django : 2020-06-19
# default: unset
remote_user = ansible
 
# logging is off by default unless this path is defined
# if so defined, consider logrotate
#log_path = /var/log/ansible.log
 
# default module name for /usr/bin/ansible
#module_name = command
 
# use this shell for commands executed under sudo
# you may need to change this to bin/bash in rare instances
# if sudo is constrained
#executable = /bin/sh
 
# if inventory variables overlap, does the higher precedence one win
# or are hash values merged together?  The default is 'replace' but
# this can also be set to 'merge'.
#hash_behaviour = replace
 
# by default, variables from roles will be visible in the global variable
# scope. To prevent this, the following option can be enabled, and only
# tasks and handlers within the role will see the variables there
#private_role_vars = yes
 
# list any Jinja2 extensions to enable here:
#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n
 
# if set, always use this private key file for authentication, same as
# if passing --private-key to ansible or ansible-playbook
#private_key_file = /path/to/file
# Django : 2020-06-19
# default: unset
private_key_file = /home/ansible/.ssh/id_ed25519_ansible
 
# If set, configures the path to the Vault password file as an alternative to
# specifying --vault-password-file on the command line.
#vault_password_file = /path/to/vault_password_file
 
# format of string {{ ansible_managed }} available within Jinja2
# templates indicates to users editing templates files will be replaced.
# replacing {file}, {host} and {uid} and strftime codes with proper values.
#ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
# {file}, {host}, {uid}, and the timestamp can all interfere with idempotence
# in some situations so the default is a static string:
#ansible_managed = Ansible managed
 
# by default, ansible-playbook will display "Skipping [host]" if it determines a task
# should not be run on a host.  Set this to "False" if you don't want to see these "Skipping"
# messages. NOTE: the task header will still be shown regardless of whether or not the
# task is skipped.
#display_skipped_hosts = True
 
# by default, if a task in a playbook does not include a name: field then
# ansible-playbook will construct a header that includes the task's action but
# not the task's args.  This is a security feature because ansible cannot know
# if the *module* considers an argument to be no_log at the time that the
# header is printed.  If your environment doesn't have a problem securing
# stdout from ansible-playbook (or you have manually specified no_log in your
# playbook on all of the tasks where you have secret information) then you can
# safely set this to True to get more informative messages.
#display_args_to_stdout = False
 
# by default (as of 1.3), Ansible will raise errors when attempting to dereference
# Jinja2 variables that are not set in templates or action lines. Uncomment this line
# to revert the behavior to pre-1.3.
#error_on_undefined_vars = False
 
# by default (as of 1.6), Ansible may display warnings based on the configuration of the
# system running ansible itself. This may include warnings about 3rd party packages or
# other conditions that should be resolved if possible.
# to disable these warnings, set the following value to False:
#system_warnings = True
 
# by default (as of 1.4), Ansible may display deprecation warnings for language
# features that should no longer be used and will be removed in future versions.
# to disable these warnings, set the following value to False:
#deprecation_warnings = True
 
# (as of 1.8), Ansible can optionally warn when usage of the shell and
# command module appear to be simplified by using a default Ansible module
# instead.  These warnings can be silenced by adjusting the following
# setting or adding warn=yes or warn=no to the end of the command line
# parameter string.  This will for example suggest using the git module
# instead of shelling out to the git command.
# command_warnings = False
 
 
# set plugin path directories here, separate with colons
#action_plugins     = /usr/share/ansible/plugins/action
#become_plugins     = /usr/share/ansible/plugins/become
#cache_plugins      = /usr/share/ansible/plugins/cache
#callback_plugins   = /usr/share/ansible/plugins/callback
#connection_plugins = /usr/share/ansible/plugins/connection
#lookup_plugins     = /usr/share/ansible/plugins/lookup
#inventory_plugins  = /usr/share/ansible/plugins/inventory
#vars_plugins       = /usr/share/ansible/plugins/vars
#filter_plugins     = /usr/share/ansible/plugins/filter
#test_plugins       = /usr/share/ansible/plugins/test
#terminal_plugins   = /usr/share/ansible/plugins/terminal
#strategy_plugins   = /usr/share/ansible/plugins/strategy
 
 
# by default, ansible will use the 'linear' strategy but you may want to try
# another one
#strategy = free
 
# by default callbacks are not loaded for /bin/ansible, enable this if you
# want, for example, a notification or logging callback to also apply to
# /bin/ansible runs
#bin_ansible_callbacks = False
 
 
# don't like cows?  that's unfortunate.
# set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
#nocows = 1
 
# set which cowsay stencil you'd like to use by default. When set to 'random',
# a random stencil will be selected for each task. The selection will be filtered
# against the  option below.
#cow_selection = default
#cow_selection = random
 
# when using the 'random' option for cowsay, stencils will be restricted to this list.
# it should be formatted as a comma-separated list with no spaces between names.
# NOTE: line continuations here are for formatting purposes only, as the INI parser
#       in python does not support them.
#cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,#              hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,#              stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www
 
# don't like colors either?
# set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1
#nocolor = 1
 
# if set to a persistent type (not 'memory', for example 'redis') fact values
# from previous runs in Ansible will be stored.  This may be useful when
# wanting to use, for example, IP information from one group of servers
# without having to talk to them in the same playbook run to get their
# current IP information.
#fact_caching = memory
 
#This option tells Ansible where to cache facts. The value is plugin dependent.
#For the jsonfile plugin, it should be a path to a local directory.
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
 
#fact_caching_connection=/tmp
 
 
 
# retry files
# When a playbook fails a .retry file can be created that will be placed in ~/
# You can enable this feature by setting retry_files_enabled to True
# and you can change the location of the files by setting retry_files_save_path
 
#retry_files_enabled = False
#retry_files_save_path = ~/.ansible-retry
 
# squash actions
# Ansible can optimise actions that call modules with list parameters
# when looping. Instead of calling the module once per with_ item, the
# module is called once with all items at once. Currently this only works
# under limited circumstances, and only with parameters named 'name'.
#squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper
 
# prevents logging of task data, off by default
#no_log = False
 
# prevents logging of tasks, but only on the targets, data is still logged on the master/controller
#no_target_syslog = False
 
# controls whether Ansible will raise an error or warning if a task has no
# choice but to create world readable temporary files to execute a module on
# the remote machine.  This option is False by default for security.  Users may
# turn this on to have behaviour more like Ansible prior to 2.1.x.  See
# https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user
# for more secure ways to fix this than enabling this option.
#allow_world_readable_tmpfiles = False
 
# controls the compression level of variables sent to
# worker processes. At the default of 0, no compression
# is used. This value must be an integer from 0 to 9.
#var_compression_level = 9
 
# controls what compression method is used for new-style ansible modules when
# they are sent to the remote system.  The compression types depend on having
# support compiled into both the controller's python and the client's python.
# The names should match with the python Zipfile compression types:
# * ZIP_STORED (no compression. available everywhere)
# * ZIP_DEFLATED (uses zlib, the default)
# These values may be set per host via the ansible_module_compression inventory
# variable
#module_compression = 'ZIP_DEFLATED'
 
# This controls the cutoff point (in bytes) on --diff for files
# set to 0 for unlimited (RAM may suffer!).
#max_diff_size = 1048576
 
# This controls how ansible handles multiple --tags and --skip-tags arguments
# on the CLI.  If this is True then multiple arguments are merged together.  If
# it is False, then the last specified argument is used and the others are ignored.
# This option will be removed in 2.8.
#merge_multiple_cli_flags = True
 
# Controls showing custom stats at the end, off by default
#show_custom_stats = True
 
# Controls which files to ignore when using a directory as inventory with
# possibly multiple sources (both static and dynamic)
#inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
 
# This family of modules use an alternative execution path optimized for network appliances
# only update this setting if you know how this works, otherwise it can break module execution
#network_group_modules=eos, nxos, ios, iosxr, junos, vyos
 
# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
# a loop with ) to return data that is not marked "unsafe". This means the data may contain
# jinja2 templating language which will be run through the templating engine.
# ENABLING THIS COULD BE A SECURITY RISK
#allow_unsafe_lookups = False
 
# set default errors for all plays
#any_errors_fatal = False
 
[inventory]
# enable inventory plugins, default: 'host_list', 'script', 'auto', 'yaml', 'ini', 'toml'
#enable_plugins = host_list, virtualbox, yaml, constructed
 
# ignore these extensions when parsing a directory as inventory source
#ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini, .cfg, .retry
 
# ignore files matching these patterns when parsing a directory as inventory source
#ignore_patterns=
 
# If 'true' unparsed inventory sources become fatal errors, they are warnings otherwise.
#unparsed_is_failed=False
 
[privilege_escalation]
# Django : 2020-06-19
# default: #become=True
#          #become_method=sudo
#          #become_user=root
#          #become_ask_pass=False
become=True
become_method=sudo
become_user=root
become_ask_pass=True
 
[paramiko_connection]
 
# uncomment this line to cause the paramiko connection plugin to not record new host
# keys encountered.  Increases performance on new host additions.  Setting works independently of the
# host key checking setting above.
#record_host_keys=False
 
# by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this
# line to disable this behaviour.
#pty=False
 
# paramiko will default to looking for SSH keys initially when trying to
# authenticate to remote devices.  This is a problem for some network devices
# that close the connection after a key failure.  Uncomment this line to
# disable the Paramiko look for keys function
#look_for_keys = False
 
# When using persistent connections with Paramiko, the connection runs in a
# background process.  If the host doesn't already have a valid SSH key, by
# default Ansible will prompt to add the host key.  This will cause connections
# running in background processes to fail.  Uncomment this line to have
# Paramiko automatically add host keys.
#host_key_auto_add = True
 
[ssh_connection]
 
# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it, -C controls compression use
#ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
 
# The base directory for the ControlPath sockets.
# This is the "%(directory)s" in the control_path option
#
# Example:
# control_path_dir = /tmp/.ansible/cp
#control_path_dir = ~/.ansible/cp
 
# The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname,
# port and username (empty string in the config). The hash mitigates a common problem users
# found with long hostnames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format.
# In those cases, a "too long for Unix domain socket" ssh error would occur.
#
# Example:
# control_path = %(directory)s/%%h-%%r
#control_path =
 
# Enabling pipelining reduces the number of SSH operations required to
# execute a module on the remote server. This can result in a significant
# performance improvement when enabled, however when using "sudo:" you must
# first disable 'requiretty' in /etc/sudoers
#
# By default, this option is disabled to preserve compatibility with
# sudoers configurations that have requiretty (the default on many distros).
#
#pipelining = False
 
# Control the mechanism for transferring files (old)
#   * smart = try sftp and then try scp [default]
#   * True = use scp only
#   * False = use sftp only
#scp_if_ssh = smart
 
# Control the mechanism for transferring files (new)
# If set, this will override the scp_if_ssh option
#   * sftp  = use sftp to transfer files
#   * scp   = use scp to transfer files
#   * piped = use 'dd' over SSH to transfer files
#   * smart = try sftp, scp, and piped, in that order [default]
#transfer_method = smart
 
# if False, sftp will not use batch mode to transfer files. This may cause some
# types of file transfer failures impossible to catch however, and should
# only be disabled if your sftp version has problems with batch mode
#sftp_batch_mode = False
 
# The -tt argument is passed to ssh when pipelining is not enabled because sudo 
# requires a tty by default. 
#usetty = True
 
# Number of times to retry an SSH connection to a host, in case of UNREACHABLE.
# For each retry attempt, there is an exponential backoff,
# so after the first attempt there is 1s wait, then 2s, 4s etc. up to 30s (max).
#retries = 3
 
[persistent_connection]
 
# Configures the persistent connection timeout value in seconds.  This value is
# how long the persistent connection will remain idle before it is destroyed.
# If the connection doesn't receive a request before the timeout value
# expires, the connection is shutdown. The default value is 30 seconds.
#connect_timeout = 30
 
# The command timeout value defines the amount of time to wait for a command
# or RPC call before timing out. The value for the command timeout must
# be less than the value of the persistent connection idle timeout (connect_timeout)
# The default value is 30 second.
#command_timeout = 30
 
[accelerate]
#accelerate_port = 5099
#accelerate_timeout = 30
#accelerate_connect_timeout = 5.0
 
# The daemon timeout is measured in minutes. This time is measured
# from the last activity to the accelerate daemon.
#accelerate_daemon_timeout = 30
 
# If set to yes, accelerate_multi_key will allow multiple
# private keys to be uploaded to it, though each user must
# have access to the system via SSH to add a new key. The default
# is "no".
#accelerate_multi_key = yes
 
[selinux]
# file systems that require special treatment when dealing with security context
# the default behaviour that copies the existing context or uses the user default
# needs to be changed to use the file system dependent context.
#special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p,vfat
 
# Set this to yes to allow libvirt_lxc connections to work without SELinux.
#libvirt_lxc_noseclabel = yes
 
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
 
 
[diff]
# Always print diff when running ( same as always running with -D/--diff )
# always = no
 
# Set how many context lines to show in diff
# context = 3
ANSIBLE_CFG
chown ansible: /home/ansible/.ansible.cfg
#################################################################################################################
 
;;
esac;
done
%end

Damit nun beim Laden der Menüdatei bei PXE-Boot die überarbeitete Kickstart-Datei geladen werden kann, erweitern wir nun die Menü-Datei /var/lib/tftpboot/pxelinux.cfg/dmz-64 unseres PXE-Bootservers.

 # vim /var/lib/tftpboot/pxelinux.cfg/dmz-64

Dort tragen wir beim betreffenden LABEL die Optionen ks, net.ifnames und biosdevname sowie am Ende der Zeile SERVERNAME=vml000040 ein.

LABEL 3
   MENU LABEL ^3) Installation der CentOS 8 (64 Bit) Ansible-Startup
   KERNEL images/centos/8/x86_64/vmlinuz
   APPEND ks=http://10.0.0.57/kickstart/ks_centos_8_x86_64_ansible.cfg initrd=images/centos/8/x86_64/initrd.img ksdevice=eth0 ip=dhcp --hostname=vml000250.dmz.nausch.org method=http://10.0.0.57/centos/8/BaseOS/x86_64/os/ net.ifnames=0 biosdevname=0 SERVERNAME=vml000040

Anschliessend starten wir wie gewohnt unsere virtuelle Maschine via PXE-Boot.

Bild: Bildschirmhardcopy des PXE Bootmenüs

Da schon alle relevanten Konfigurationsoptionen brauchen wir hier nur noch den entsprechenden Menünkt auswählen und die Installation beginnt vollautomatisch. Am Ende des Installationsvorganges werden wir informiert, dass das postinstall-script, welches wir per PXE-Boot bzw. genauer gesagt mit dem Kickstartfile mitgegeben hatten, ausgeführt wird.

Bild: Bildschirmhardcopy des Installationsvorgangs

Ist die Installation abgeschlossen startet unser neuer Host.

Bild: Bildschirmhardcopy des Bootvorgangs unseres AOMH

Nach kurzer Wartezeit haben wir ein neues, vorkonfiguriertes und vor allem aktuelles System, bei dem wir uns direkt per ssh verbinden können.

 $ ssh 10.0.0.40
The authenticity of host '10.0.0.40 (10.0.0.40)' can't be established.
ED25519 key fingerprint is SHA256:ayqTv8KN1YeMpTudnHRuC3jxSzc4Z92TX3wjRcFavsY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.40' (ED25519) to the list of known hosts.
##############################################################################
#                                                                            #
#                       This is a private home server.                       #
#                                                                            #
#             Unauthorized access to this system is prohibited !             #
#                                                                            #
#    This system is actively monitored and all connections may be logged.    #
#         By accessing this system, you consent to this monitoring.          #
#                                                                            #
##############################################################################
##############################################################################
#                                                                            #
#                 This is the home server of Michael Nausch.                 #
#                                                                            #
#                            vml000040.nausch.org                            #
#                                                                            #
#             Unauthorized access to this system is prohibited !             #
#                                                                            #
#    This system is actively monitored and all connections may be logged.    #
#         By accessing this system, you consent to this monitoring.          #
#                                                                            #
##############################################################################

Wir können dann natürlich auch sofort zu unserem Ansible-Administrationsaccount ansible wechseln.

 $ su - ansible

Nach eingabe des zugehörigen Passwortes befinden wir uns im Homeverzeichnis des Ansible-Administrationsaccounts

Password: 
[ansible@vml000040 ~]$

Dot können wir uns z.B. vergewissern dass das Ansible: Directory Layout wie gewünscht angelegt ist.

 $ tree ansible/
ansible/
├── filter_plugins
├── inventories
│   ├── production
│   │   ├── group_vars
│   │   ├── hosts.yml
│   │   └── host_vars
│   └── staging
│       ├── group_vars
│       ├── hosts.yml
│       └── host_vars
├── library
├── module_utils
├── roles
│   └── common
│       ├── defaults
│       │   └── main.yml
│       ├── files
│       │   └── main.yml
│       ├── handlers
│       │   └── main.yml
│       ├── library
│       ├── lookup_plugin
│       ├── meta
│       │   └── main.yml
│       ├── module_utils
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       │   └── main.yml
│       └── vars
│           └── main.yml
└── site.yml

22 directories, 10 files

Zum Schluss lassen wir uns mit Hilfe des Befehls die aktuell installierte CentOS-Version anzeigen.

 $ ansible centos8 -m shell -a "/usr/bin/cat /etc/redhat-release"

Da wir uns das erste mal mit dem Host ansible verbinden werden wir nach der Eingabe des Passwortes gefragt, ob der Fingerprint des ED25519 Schlüssel stimmt. Nachdem wir das gewissenhaft überprüft habenbestätigen wir diese Frage mit einem yes

BECOME password: 
The authenticity of host '10.0.0.40 (10.0.0.40)' can't be established.
ED25519 key fingerprint is SHA256:ayqTv8KN1YeMp4Z92TX3TudnHRuC3jxSzcwjRcFavsY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
ansible | CHANGED | rc=0 >>
CentOS Linux release 8.2.2004 (Core)

Wir haben also nunmehr die Möglichkeit stets bei Bedarf immer eine gleiche Installation unseres
Ansible-Orchestrator-Management-Host from the scratch zu Installieren.
Letztendlich brauchen wir dann nur noch unsere individuellen playbooks-, inventory- und role-Definitionen
in die zugehörigen Verzeichnisse zurück sichern!

Links


1)
Ansible-Orchestrator-Management-Hosts
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • centos/pxe_c8/pxe_4.txt
  • Zuletzt geändert: 14.09.2022 16:51.
  • von django