Remote MOTD

This commit is contained in:
Élie Deloumeau-Prigent 2021-09-29 16:57:02 +02:00
parent b95595ef6e
commit ea56ef6c69
No known key found for this signature in database
GPG Key ID: 94F059CE0C5FF9D9
6 changed files with 40 additions and 129 deletions

View File

@ -11,6 +11,8 @@
Install and configure dynamic MOTD and SSH banner
This role uses [https://github.com/claranet/motd](https://github.com/claranet/motd) by default to get the banner and the MOTD
```
System info:
Hostname·········: claranet_motd_ubuntu-20.04
@ -44,11 +46,19 @@ ansible-galaxy install claranet.motd
## :gear: Role variables
Variable | Default value | Description
--------------------------|-----------------------|----------------------------------------
motd_disable_default_motd | true | Disable system default MOTD (/etc/motd)
motd_banner_template | etc/banner | SSH banner template
motd_template | usr/local/bin/dynmotd | Dynmaic MOTD template
Variable | Default value | Description
-----------------------------|---------------------------------------------------------------|----------------------------------------------------------------
motd_disable_default_motd | true | Disable system default MOTD (/etc/motd)
motd_banner_template | https://raw.githubusercontent.com/claranet/motd/master/banner | SSH banner template<br>Can be a URL, a local template or `null`
motd_banner_template_prepend | "" | Prepend raw content to `motd_banner_template`
motd_banner_template_append | "" | Append raw content to `motd_banner_template`
motd_banner_template_username| {{ motd_template_username }} | Used when `motd_banner_template` is an URL
motd_banner_template_password| {{ motd_template_password }} | Used when `motd_banner_template` is an URL
motd_template | https://raw.githubusercontent.com/claranet/motd/master/motd | Dynmaic MOTD template<br>Can be a URL or a local template
motd_template_prepend | "" | Prepend raw content to `motd_template`
motd_template_append | See [defaults/main.yml](defaults/main.yml) | Append raw content to `motd_template`
motd_template_username | "" | Used when `motd_template` is an URL
motd_template_password | "" | Used when `motd_template` is an URL
## :pencil2: Example Playbook
@ -56,7 +66,8 @@ motd_template | usr/local/bin/dynmotd | Dynmaic MOTD template
---
- hosts: all
roles:
- claranet.motd
- role: claranet.motd
motd_template: "{{ playbook_dir }}/templates/dynmotd.j2"
```
## :closed_lock_with_key: [Hardening](HARDENING.md)

View File

@ -1,4 +1,17 @@
---
motd_disable_default_motd: true
motd_banner_template: etc/banner
motd_template: usr/local/bin/dynmotd
motd_banner_template: https://raw.githubusercontent.com/claranet/motd/master/banner
motd_template: https://raw.githubusercontent.com/claranet/motd/master/motd
motd_banner_template_prepend: ""
motd_banner_template_append: ""
motd_template_prepend: ""
motd_template_append: |
echo -e "\e[0;39mAnsible:
Last deployment\e[2m···\e[0m: {{ ansible_date_time.iso8601_micro }}
"
motd_template_username: ""
motd_template_password: ""
motd_banner_template_username: "{{ motd_template_username }}"
motd_banner_template_password: "{{ motd_template_password }}"

View File

@ -23,8 +23,8 @@
when: motd_disable_default_motd|bool
- name: Apply template {{ motd_banner_template }} on {{ _motd_banner_file_path }}
template:
src: "{{ motd_banner_template }}"
copy:
content: "{{ motd_banner_template_prepend|default('') + _motd_banner_template_content + motd_banner_template_append|default('') }}"
dest: "{{ _motd_banner_file_path }}"
owner: root
group: root
@ -40,8 +40,8 @@
notify: Restart sshd
- name: Apply template {{ motd_template }} on {{ _motd_file_path }}
template:
src: "{{ motd_template }}"
copy:
content: "{{ motd_template_prepend|default('') + _motd_template_content + motd_template_append|default('') }}"
dest: "{{ _motd_file_path }}"
owner: root
group: root

View File

@ -1,32 +0,0 @@
,╓╗╖æææææ╖╖,
,╗╣╬╬╣╝╜╙╙"╙╙╜╝╣Ñ╬æ╖
╓╣╬╝╜ "╙╣╬╣µ
╓╬╬M "╢╬╣,
╣╬╝ ╣Ñæ ╙╬╬╖╖╖╖╖╓,
,,╓╣╬M ,╗ ╬╬╬ ╓╖, ╝╜╜╜╜╝╣╬╬╣╖
╓æ╣Ñ╬╣╝╝╝ ╓╣╬╝ ╬╬╬ ²╣╬╣µ `╙╣╬æ,
╓╣╬╝^ ╣╬╝ ╬╬╬ `╣╬æ ╙╬╬φ
╣╬M ║╬╬ ╢╣M ╬╬U ╢╬φ
╬╬M ║╬╬ ╬╬M ╬╬∩
║╬╬ "╬ѵ ╓Ñ╬ ╟╬┼
╟╬┼ `╣╬╖, ,╢╬╣ ╟╬┼
║╬╬ ╙╢╬╬╣ææ╬╣╬╬╝` ╬╬M
╬╬µ `"""` ╣╬M
`╬╬φ ╓╬╬M
╚╬╬╖, ,╗╣╬╝
╙╣Ñ╬╣æ╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖æ╣╬╬╝╜
`"╙╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╙" ®
╖╖┬ ╓╖╖
╬╬M ╓╬╬
,╗╣╬╬╣æ, ╬╬M ,æ╣╬╬╬æ╖ ß╣ß╓æ╣ ╓æ╣╬╬╣æ, -╣╣╓æ╣╬╣╖ ,╖╣╬╬╣╖, ╢╣╬╬╣╣
║╬╬" `╝╜* ╬╬M ╝╝┘ ╟╬φ ╬╬╬M"` ª╝╝ ╙╬Ñ "╬╬M ║╬╬ ╢╬M ╢╬φ ╓╬╬
-╬╬H ╬╬M ╓æ╣╬╬╣╬╬M ╬╬╬ ╗╢╣╬╣╣╬╬⌐ "╬╬ ╓╬╬ ╬╬╬╬╬╬╬╬╬╬ ╓╬╬
╢╬φ ╓,, ╬╬M ╢╬M ╟╬M ╬╬╪ ╬╬M ,╬╬⌐ "╬╬ ╓╬╬ ╬╬φ ╓ ╓╬╬
╚╬╬╣╣╣╬╝ ╬╬M ╙╣╬╣æ╣╬╬╬M ╬╬╪ ║╬╬ææ╣╣╬╬⌐ "╬╬ ╓╬╬ ╚╬╬╣╣╣╬╣╜ '╬╬╣æ
`` `` ``` ``` ```
WARNING : Unauthorized access to this system is forbidden and will be
prosecuted by law. By accessing this system, you agree that your actions
may be monitored if unauthorized usage is suspected.

View File

@ -1,85 +0,0 @@
#!/bin/bash
# get load averages
IFS=" " read LOAD1 LOAD5 LOAD15 <<<$(awk '{ print $1,$2,$3 }' /proc/loadavg)
# get free memory
IFS=" " read USED AVAIL TOTAL <<<$(free -htm | grep "Mem" | awk {'print $3,$7,$2'})
# get processes
PROCESS=$(ps -eo user=|sort|uniq -c | awk '{ print $2 " " $1 }')
PROCESS_ALL=$(echo "$PROCESS"| awk {'print $2'} | awk '{ SUM += $1} END { print SUM }')
PROCESS_ROOT=$(echo "$PROCESS"| grep root | awk {'print $2'})
PROCESS_USER=$(echo "$PROCESS"| grep -v root | awk {'print $2'} | awk '{ SUM += $1} END { print SUM }')
# get processors
PROCESSOR_NAME=$(grep "model name" /proc/cpuinfo | cut -d ' ' -f3- | awk {'print $0'} | head -1)
PROCESSOR_COUNT=$(grep -ioP 'processor\t:' /proc/cpuinfo | wc -l)
LOCAL_IP_ADDRESSES=$(hostname -I | sed 's/ /\n\ /g' | sed '/^[[:space:]]*$/d')
# Processing available updates with yum is too long
{% if ansible_pkg_mgr == "apt" %}
UPDATES_AVAILABLE=$(apt list --upgradable 2>/dev/null)
UPDATES_AVAILABLE_NB=$(echo -e "$UPDATES_AVAILABLE" | wc -l)
SECURITY_UPDATES_AVAILABLE_NB=$(echo -e "$UPDATES_AVAILABLE" | grep "\-security" | wc -l)
{% endif %}
# colors
W="\e[0;39m"
G="\e[1;32m"
R="\e[1;31m"
dim="\e[2m"
undim="\e[0m"
echo -e "${W}System info:
$W Hostname$dim·········$undim: $W${HOSTNAME}
$W Distro$dim···········$undim: $W$(grep "PRETTY_NAME" /etc/*release | cut -d "=" -f 2- | sed 's/"//g')
$W Kernel$dim···········$undim: $W$(uname -sr)
{% if ansible_pkg_mgr == "apt" %}
$W Updates available: $W$UPDATES_AVAILABLE_NB ($SECURITY_UPDATES_AVAILABLE_NB security)
{% endif %}
$W Uptime$dim···········$undim: $W$(uptime -p)
$W Load$dim·············$undim: $G$LOAD1$W (1m), $G$LOAD5$W (5m), $G$LOAD15$W (15m)
$W Processes$dim········$undim: $G$PROCESS_ROOT$W (root), $G$PROCESS_USER$W (user), $G$PROCESS_ALL$W (total)
$W CPU$dim··············$undim: $W$PROCESSOR_NAME ($G$PROCESSOR_COUNT$W vCPU)
$W Memory$dim···········$undim: $G$USED$W used, $G$AVAIL$W avail, $G$TOTAL$W total
$W Local IPs$dim········$undim: $LOCAL_IP_ADDRESSES$W"
# config
max_usage=90
bar_width=50
# disk usage: ignore zfs, squashfs & tmpfs
mapfile -t dfs < <(df -H -x zfs -x squashfs -x tmpfs -x devtmpfs -x overlay --output=target,pcent,size | tail -n+2)
printf "\nDisk usage:\n"
for line in "${dfs[@]}"; do
# get disk usage
usage=$(echo "$line" | awk '{print $2}' | sed 's/%//')
used_width=$((($usage*$bar_width)/100))
# color is green if usage < max_usage, else red
if [ "${usage}" -ge "${max_usage}" ]; then
color=$R
else
color=$G
fi
# print green/red bar until used_width
bar="[${color}"
for ((i=0; i<$used_width; i++)); do
bar+="="
done
# print dimmmed bar until end
bar+="${W}${dim}"
for ((i=$used_width; i<$bar_width; i++)); do
bar+="·"
done
bar+="${undim}]"
# print usage line & bar
echo "${line}" | awk '{ printf("%-31s%+3s used out of %+4s\n", $1, $2, $3); }' | sed -e 's/^/ /'
echo -e "${bar}" | sed -e 's/^/ /'
done
printf "\n"
echo -e "${W}Ansible:
${W} Last deployment$dim···$undim: {{ ansible_date_time.iso8601_micro }}
"

View File

@ -5,3 +5,7 @@ _motd_pam_sshd_file_path: /etc/pam.d/sshd
_motd_banner_file_path: /etc/banner
_motd_banner_state: "{{ 'present' if motd_banner_template else 'absent' }}"
_motd_file_path: /usr/local/bin/dynmotd
_motd_lookup_method: "{{ 'url' if motd_template is match('http(s)?:\/\/') else 'template' }}"
_motd_template_content: "{{ lookup(_motd_lookup_method, motd_template, split_lines=False, username=motd_template_username, password=motd_template_password) }}"
_motd_banner_lookup_method: "{{ 'url' if motd_banner_template is match('http(s)?:\/\/') else 'template' }}"
_motd_banner_template_content: "{{ lookup(_motd_banner_lookup_method, motd_banner_template, split_lines=False, username=motd_banner_template_username, password=motd_banner_template_password) }}"