--- - name: Basic Debian Linux Setup hosts: all tasks: #- name: Print all available facts # ansible.builtin.debug: # var: ansible_facts - name: Install Basic Packages apt: name: - dhcpcd5 - hd-idle - psutils - psmisc - procps - htop - iotop - sysstat - jnettop - strace - vim - git - man-db - net-tools - tmux - netcat - ethtool - debconf-utils - iputils-ping - lsof - inotify-tools - rsync - dos2unix - locales - iproute2 - logrotate - cryptsetup - curl - moreutils - ffmpeg - mediainfo - smartmontools - telnet - libstring-approx-perl - postfix - zip - nmap - whois - libfile-readbackwards-perl - libcrypt-cbc-perl - libcrypt-des-perl - at - pwgen - certbot - btrfs-progs - mdadm - ufw - jq - btrfsmaintenance - cifs-utils - apt-transport-https - sudo - golang - make - openssh-server - sshfs - imagemagick - libimage-exiftool-perl - nfs-common - sqlite3 - vlc update_cache: yes install_recommends: no - name: add dhcpcd to startup command: systemctl enable dhcpcd args: creates: /etc/systemd/system/multi-user.target.wants/dhcpcd.service - name: No DHCPcd for internal interfaces ansible.builtin.lineinfile: path: /etc/dhcpcd.conf line: denyinterfaces docker0 virbr0 tornet0 veth* br* - name: Disable all Network-config but source interfaces.d in /etc/network/interfaces because dhcpcd will do the job replace: path: /etc/network/interfaces regexp: '(^iface .*)' replace: '#\1' - name: Disable all Network-config but source interfaces.d in /etc/network/interfaces because dhcpcd will do the job replace: path: /etc/network/interfaces regexp: '(^allow-hotplug .*)' replace: '#\1' - name: Disable all Network-config but source interfaces.d in /etc/network/interfaces because dhcpcd will do the job replace: path: /etc/network/interfaces regexp: '(^auto .*)' replace: '#\1' - name: Set a hostname ansible.builtin.hostname: name: "{{inventory_hostname}}" - name: Set timezone to Europe/Berlin community.general.timezone: name: Europe/Berlin # - name: Create {{ ansible_facts['hostname'] }}adm User # ansible.builtin.user: # name: "{{ ansible_facts['hostname'] }}adm" # comment: "{{ ansible_facts['hostname'] }}-Admin" # uid: 1000 # group: users # password: $6$Zqar9GCRvbVgPlZ/$L2xAMekMjE5PXuWY0WbmUcugJkqD14O6/cgC02O0hT5vOdiDj5Pcp6FU/Zz.rCkWKVSPsmTc2OtXAmQIHLc1V1 - name: Allow the hostnameadm User all sudo commands community.general.sudoers: name: ALL state: present user: "{{ ansible_facts['hostname'] }}adm" commands: ALL - name: Remove root-Password user: name: root password: '*' - name: German keyboard layout ansible.builtin.lineinfile: path: /etc/default/keyboard regexp: '^XKBLAYOUT=".+$' line: 'XKBLAYOUT="de"' backup: yes notify: setupcon - name: nodeadkeys ansible.builtin.lineinfile: path: /etc/default/keyboard regexp: '^XKBVARIANT=".+$' line: 'XKBVARIANT="nodeadkeys"' backup: yes notify: setupcon - name: Prefer ipv4 over ipv6 to avoid problems and waiting times ansible.builtin.lineinfile: path: /etc/gai.conf regexp: '^#precedence ::ffff:0:0/96 100' line: "precedence ::ffff:0:0/96 100 # CHANGED BY ANSIBLE" backup: yes - name: Ensure en_US.UTF-8 locale exists community.general.locale_gen: name: en_US.UTF-8 state: present - name: Ensure en_GB.UTF-8 locale exists community.general.locale_gen: name: en_GB.UTF-8 state: present - name: Ensure de_DE.UTF-8 locale exists community.general.locale_gen: name: de_DE.UTF-8 state: present notify: localectl - name: DigitalCourage encrypted DNS (DoT) via TLS systemd-resolved without censorship blockinfile: path: /etc/systemd/resolved.conf.d/digitalcourage-dot.conf mode: "0444" owner: root group: root create: yes insertbefore: BOF # Beginning of the file marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | [Resolve] DNS=5.9.164.112#dns3.digitalcourage.de 2a01:4f8:251:554::2#dns3.digitalcourage.de DNSOverTLS=opportunistic backup: yes - name: SSHD hardening blockinfile: path: /etc/ssh/sshd_config.d/hardening.conf mode: "0444" owner: root group: root create: yes insertbefore: BOF # Beginning of the file marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | Port 22 Port 33 PermitRootLogin prohibit-password PermitUserRC no PermitUserEnvironment no PubkeyAuthentication yes X11Forwarding no AllowAgentForwarding no AllowTcpForwarding yes Subsystem sftp internal-sftp -f AUTH -l INFO -u 0007 ## Ciphers Check https://sshcheck.com/server/{{inventory_hostname}}/ # nmap -p22 -n -sV --script ssh2-enum-algos localhost KexAlgorithms curve25519-sha256@libssh.org HostKeyAlgorithms ssh-ed25519 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com IgnoreRhosts yes LogLevel VERBOSE AddressFamily any backup: yes validate: /usr/sbin/sshd -T -f %s notify: - Restart sshd - name: Disable external sftp-Subsystem replace: path: /etc/ssh/sshd_config regexp: '(^Subsystem.*sftp.*)' replace: '#\1' validate: /usr/sbin/sshd -T -f %s backup: yes notify: - Restart sshd - name: Create .ssh dir ansible.builtin.file: path: /root/.ssh owner: root group: root state: directory mode: '0550' - name: Generate an OpenSSH keypair ed25519 community.crypto.openssh_keypair: path: /root/.ssh/id_ed25519 type: ed25519 - ansible.posix.sysctl: name: vm.swappiness value: '1' state: present - name: shell profile blockinfile: path: /etc/profile.d/settings-from-ansible.sh create: yes mode: "0444" owner: root group: root marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | if ${use_color} ; then if [[ ${EUID} == 0 ]] ; then PS1='\[\033[01;31m\]\h\[\033[01;34m\] \w \$\[\033[00m\] ' else PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] ' fi export EDITOR="/usr/bin/vim" export HISTSIZE= export HISTFILESIZE= export HISTTIMEFORMAT="[%F %T] " if [ -f /etc/debian_version ] then export DEBIAN_FRONTEND='noninteractive' export LANG="en_US.UTF-8" alias ls='ls --color=auto' alias grep='grep --colour=auto' alias egrep='egrep --colour=auto' alias fgrep='fgrep --colour=auto' fi else # show root@ when we don't have colors PS1+='\u@\h \w \$' fi # execute for linuxmint if [ -d /etc/linuxmint ] then grep -q /etc/profile.d/settings-from-ansible.sh ~/.bashrc || echo '. /etc/profile.d/settings-from-ansible.sh' >> ~/.bashrc export LANG="de_DE.UTF-8" #for rc in ~/.bashrc /etc/skel/.bashrc #do # grep -q /etc/profile.d/settings-from-ansible.sh $rc || echo '. /etc/profile.d/settings-from-ansible.sh' >> $rc #done fi backup: yes validate: /bin/bash -n %s - name: vim settings blockinfile: path: /etc/vim/vimrc.local mode: "0444" owner: root group: root create: yes marker: "\" {mark} ANSIBLE MANAGED BLOCK" block: | :syntax on let g:skip_defaults_vim = 1 set encoding=utf-8 set tabstop=2 softtabstop=0 expandtab shiftwidth=2 smarttab syntax match nonascii "[^[:alnum:][:punct:][:space:]]/" highlight nonascii guibg=Red ctermbg=2 backup: yes #- name: gaboshlib.include # copy: # src: configs/etc/bash # dest: /etc/ # owner: root # group: root # mode: "0444" # directory_mode: "0555" # backup: yes # validate: /bin/bash -n %s - name: gaboshlib from git ansible.builtin.git: repo: 'https://gitea.ds9.dedyn.io/olli/gaboshlib.git' dest: /etc/bash force: yes - name: systemd-journald settings blockinfile: path: /etc/systemd/journald.conf.d/journald.local.conf create: yes mode: "0444" owner: root group: root marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | [Journal] Storage=persistent SystemMaxUse=30M ForwardToSyslog=yes backup: yes notify: - Restart journald - name: /etc/rsyslog.d/00-services-remote.conf blockinfile: path: /etc/rsyslog.d/00-services-remote.conf create: yes mode: "0444" owner: root group: root marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | # Listen for remote Logging (UDP) module(load="imudp") input(type="imudp" port="514") # Hosts if $hostname startswith '192.168.1.1' and $msg contains 'User admin login from 192.168.1.2 successful' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $msg contains 'wdGetDidSendCredentials not implemented' and $programname contains 'citrix-wfica' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $msg contains 'CGPrecv: socket 0x' and $programname contains 'citrix-wfica' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $msg contains 'doEncryptData inbuffersize: ' and $programname contains 'citrix-wfica' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $msg contains 'SSLPutDataFn inbuffersize: ' and $programname contains 'citrix-wfica' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $msg contains 'SRC=192.168.' and $programname contains 'kernel' then stop if $hostname startswith '192.168.1.1' then /var/log/zyxel.log if $hostname startswith '192.168.1.1' then stop if $hostname startswith 'raspberry-' then /var/log/Raspberrys.log if $hostname startswith 'raspberry-' then stop if $hostname startswith 'router-' then /var/log/router.log if $hostname startswith 'router-' then stop # Auth success (for share-auth 2FA) #if $programname == 'nextcloud-audit' and $msg contains 'Login successful:' then /var/log/auth-success.log #if $programname == 'imaps' and $msg contains 'TLS User logged in' then /var/log/auth-success.log if $hostname == 'xgabosh' then /var/log/xgabosh.log if $hostname == 'xgabosh' then stop if $hostname != '{{ ansible_facts['hostname'] }}' and $hostname != 'share' and $hostname != 'backup-chroot' then /var/log/GTC-Hosts.log if $hostname != '{{ ansible_facts['hostname'] }}' and $hostname != 'share' and $hostname != 'backup-chroot' then stop backup: yes notify: - Restart rsyslog - name: /etc/rsyslog.d/01-services-local.conf blockinfile: path: /etc/rsyslog.d/01-services-local.conf create: yes mode: "0444" owner: root group: root marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | # Additional Socket from chroot input(type="imuxsock" HostName="vpn-share" Socket="/data-crypt/dev/log" CreatePath="on") input(type="imuxsock" HostName="share" Socket="/data-crypt/share/dev/log" CreatePath="on") # Auth success (for share-auth 2FA) if $programname == 'nextcloud-audit' and $msg contains 'Login successful:' then /var/log/auth-success.log if $programname == 'imaps' and $msg contains 'TLS User logged in' then /var/log/auth-success.log # Nextcloud if $msg contains '","level":0,"time":"' and $programname contains 'nextcloud' then stop if $msg contains '","level":1,"time":"' and $programname contains 'nextcloud' then stop if $programname == 'nextcloud' then /var/log/nextcloud.log if $programname == 'nextcloud' then stop if $programname == 'nextcloud-audit' then /var/log/nextcloud.log if $programname == 'nextcloud-audit' then stop if $programname == 'nextcloud-test' then /var/log/nextcloud-test.log if $programname == 'nextcloud-test' then stop if $programname == 'nextcloud-test-audit' then /var/log/nextcloud-test.log if $programname == 'nextcloud-test-audit' then stop # USV if $programname == 'apcupsd' and $syslogseverity <= '6' then /var/log/usv-apcupsd.log if $programname == 'apcupsd' then stop # SMART HDD Überwachung if $programname == 'smartd' and $syslogseverity <= '6' then /var/log/smartd.log if $programname == 'smartd' then stop # SSH TUNNEL if $programname == 'sshd-tunnel' and $syslogseverity <= '6' then /var/log/sshd-tunnel.log if $programname == 'sshd-tunnel' then stop # SSH SFTP if $programname == 'sshd-sftp' and $syslogseverity <= '6' then /var/log/sshd-sftp.log if $programname == 'sshd-sftp' then stop # SSH Share if $programname == 'sshd' and $syslogfacility-text == 'local7' then /var/log/sshd-share.log if $programname == 'sshd' and $syslogfacility-text == 'local7' then stop # firewall if $programname == 'kernel' and $msg contains 'PROTO' then /var/log/firewall.log if $programname == 'kernel' and $msg contains 'PROTO' then stop # SSH rsyncbackup if $programname == 'sshd-rsyncbackup' and $syslogseverity <= '6' then /var/log/sshd-rsyncbackup.log if $programname == 'sshd-rsyncbackup' then stop # SSH if $programname == 'sshd' and $syslogseverity <= '6' then /var/log/sshd.log if $programname == 'sshd' then stop # SFTP if $programname == 'internal-sftp' and $msg contains 'sent status ' then stop if $programname == 'internal-sftp' and $msg contains 'lstat name ' then stop if $programname == 'internal-sftp' and $msg contains '/.kodi/' then stop if $programname == 'internal-sftp' then /var/log/sftpaccess.log if $programname == 'internal-sftp' then stop # Cron if $programname == 'cron' and $syslogseverity <= '6' then /var/log/cron.log if $programname == 'cron' then stop if $programname == 'run-crons' and $syslogseverity <= '6' then /var/log/cron.log if $programname == 'run-crons' then stop if $programname == 'crontab' and $syslogseverity <= '6' then /var/log/cron.log if $programname == 'crontab' then stop # rsync if $programname == 'rsyncd' and $syslogseverity <= '6' then /var/log/rsyncd.log if $programname == 'rsyncd' then stop # DNS if $programname == 'named' and $msg contains ' 127.0.0.1#' then stop if $programname == 'named' and $msg contains ': sending notifies' then stop if $programname == 'named' and $msg contains ' loaded serial ' then stop if $programname == 'named' and $syslogseverity <= '6' then /var/log/bind.log if $programname == 'named' then stop # DHCP if $programname == 'dhcpd' and $syslogseverity <= '6' then /var/log/dhcpd.log if $programname == 'dhcpd' then stop # NFS if $programname == 'rpc.mountd' and $syslogseverity <= '6' then /var/log/nfs.log if $programname == 'rpc.mountd' then stop if $programname == 'rpc.idmapd' and $syslogseverity <= '6' then /var/log/nfs.log if $programname == 'rpc.idmapd' then stop if $programname == 'rpc.statd' and $syslogseverity <= '6' then /var/log/nfs.log if $programname == 'rpc.statd' then stop if $programname == 'rpcbind' and $syslogseverity <= '6' then /var/log/nfs.log if $programname == 'rpcbind' then stop # NTP if $programname == 'ntpd' and $syslogseverity <= '6' then /var/log/ntp.log if $programname == 'ntpd' then stop if $programname == 'ntpdate' and $syslogseverity <= '6' then /var/log/ntp.log if $programname == 'ntpdate' then stop # Mail if $msg contains 'auxpropfunc error invalid parameter supplied' then stop if $msg contains '_sasl_plugin_load failed on sasl_auxprop_plug_init for plugin: ldapdb' then stop if $msg contains 'seen_db: user ' then stop if $msg contains 'SQUAT ' then stop if $msg contains 'indexing mailbox ' then stop if $msg contains 'fetching user_deny.db' then stop if $programname == 'lmtpunix' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'lmtpunix' then stop if $programname == 'imap' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'imap' then stop if $programname == 'imaps' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'imaps' then stop if $programname == 'master' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'master' then stop if $programname == 'ctl_cyrusdb' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'ctl_cyrusdb' then stop if $programname == 'pop3' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'pop3' then stop if $programname == 'pop3s' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'pop3s' then stop if $programname == 'squatter' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'squatter' then stop if $programname == 'tls_prune' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'tls_prune' then stop if $programname == 'cyr_expire' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'cyr_expire' then stop if $programname == 'sieve' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'sieve' then stop if $programname == 'deliver' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'deliver' then stop if $programname == 'ipurge' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'ipurge' then stop if $programname == 'saslauthd' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'saslauthd' then stop if $programname == 'amavis' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'amavis' then stop if $programname == 'clamd' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'clamd' then stop if $programname == 'freshclam' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'freshclam' then stop if $programname == 'fetchmail' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'fetchmail' then stop if $programname == 'spamd' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'spamd' then stop if $programname contains 'postfix' and $syslogseverity <= '6' then /var/log/maillog.log if $programname contains 'postfix' then stop if $programname == 'reconstruct' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'reconstruct' then stop if $programname == 'policyd-spf' and $syslogseverity <= '6' then /var/log/maillog.log if $programname == 'policyd-spf' then stop # slapd if $programname == 'slapd' then /var/log/slapd.log if $programname == 'slapd' then stop # PulseAudio if $programname == 'pulseaudio' and $msg contains 'Denied access to client with invalid authentication data' then stop if $programname == 'pulseaudio' then /var/log/pulseaudio.log if $programname == 'pulseaudio' then stop # hostapd if $programname == 'hostapd' then /var/log/hostapd.log if $programname == 'hostapd' then stop # nscd if $programname == 'nscd' then /var/log/nscd.log if $programname == 'nscd' then stop # arpwatch if $programname == 'arpwatch' then /var/log/arpwatch.log if $programname == 'arpwatch' then stop # X if $programname == 'mate-session' then /var/log/x.log if $programname == 'mate-session' then stop if $programname == 'Tor' then /var/log/x.log if $programname == 'Tor' then stop # xinetd if $programname == 'xinetd' then /var/log/xinetd.log if $programname == 'xinetd' then stop # in.tftp if $programname == 'in.tftpd' then /var/log/in.tftpd.log if $programname == 'in.tftpd' then stop # pppd if $programname == 'dhcpcd' then /var/log/pppd.log if $programname == 'dhcpcd' then stop if $programname == 'radvd' then /var/log/pppd.log if $programname == 'radvd' then stop if $programname == 'pppd' then /var/log/pppd.log if $programname == 'pppd' then stop # wlan if $programname == 'wpa_cli' then /var/log/messages if $programname == 'wpa_cli' then stop # cups if $programname == 'cupsd' then /var/log/cupsd.log if $programname == 'cupsd' then stop # bash scripts using g-lib if $programname contains 'g_bash-script' then /var/log/g_bash-scripts.log if $programname contains 'g_bash-script' then stop # Rest in messages *.* /var/log/messages backup: yes notify: - Restart rsyslog - name: hd-idle for spinning down disks after XXX seconds idle blockinfile: path: /etc/default/hd-idle create: yes mode: "0444" owner: root group: root marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | HD_IDLE_OPTS="-i 300 -l /var/log/hd-idle.log" backup: yes notify: - Restart hd-idle - name: /etc/default/btrfsmaintenance blockinfile: path: /etc/default/btrfsmaintenance mode: "0444" owner: root group: root create: yes insertbefore: EOF marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | BTRFS_LOG_OUTPUT="syslog" BTRFS_BALANCE_MOUNTPOINTS="auto" BTRFS_BALANCE_PERIOD="monthly" BTRFS_SCRUB_MOUNTPOINTS="auto" BTRFS_SCRUB_PERIOD="monthly" backup: yes - name: /etc/logrotate.conf (weekly->daily) ansible.builtin.lineinfile: path: /etc/logrotate.conf regexp: '^weekly$' line: 'daily' backup: yes - name: /etc/logrotate.d/apache2 (remove delaycompress) ansible.builtin.lineinfile: path: /etc/logrotate.d/apache2 regexp: '.*delaycompress$' state: absent - name: /etc/logrotate.d/00-local blockinfile: path: /etc/logrotate.d/00-local mode: "0444" owner: root group: root create: yes marker: "# {mark} ANSIBLE MANAGED BLOCK" block: | /var/log/dmesgcron /var/log/messages /var/log/*.log { rotate 7 daily missingok notifempty copytruncate compress postrotate /usr/lib/rsyslog/rsyslog-rotate endscript } - name: Remove logrotates ansible.builtin.file: path: /etc/logrotate.d/alternatives state: absent - name: Remove logrotates ansible.builtin.file: path: /etc/logrotate.d/dpkg state: absent - name: Remove logrotates ansible.builtin.file: path: /etc/logrotate.d/rsyslog state: absent handlers: - name: setupcon ansible.builtin.shell: setupcon - name: localectl ansible.builtin.shell: localectl set-locale LANG=de_DE.UTF-8 - name: Restart sshd service: name: sshd state: restarted - name: Restart journald service: name: systemd-journald state: restarted - name: Restart rsyslog service: name: rsyslog state: restarted - name: Restart hd-idle service: name: hd-idle state: restarted