#!/bin/bash
# Начин на Генериране на Ключове:
########################################################################################################################################
# 1. ssh-keygen задава се парола за частният ключ и се създава двата ключа:)
# ~/.ssh/id_rsa.pub (публичен)
# ~/.ssh/id_rsa (частен с парола или без)
#
# 2. ssh-copy-id -i user@example.com копира публичният ключ (~/.ssh/id_rsa.pub) на сървера example.com
# във файла /home/user/.ssh/authorized_keys и задава правилните пермишъни на файла authorized_keys
# във файла authorized_keys може да има и други ключове.
# Вместо тази команда това може да се направи и на ръка през ssh, scp.
########################################################################################################################################
# унищожава промеливите на обкръжението/връзката към евентуален стартиран от системата ssh-agent
# Така както е направено в началото тези променливи да бъдат премахнати, едно бъдещо извикване на die(),
# преди да е било стартирано ssh-agent, няма да предизвика ниакакво убиване на ssh-agent защото няма променлива.
unset SSH_AUTH_SOCK SSH_AGENT_PID
# SIGINT: ctrl+c; SIGTERM: kill 1234; SIGHUP: close win;
trap "die 'Script aborted.'" SIGHUP SIGINT SIGTERM
function die(){
# Убива текущият агент. Иначе ако не се убие, може да е имало успешно стартиран от предните редове и ssh-agent-а ще остане
# работещ. В резулта на много стартирания и прекъсваня на скрита - например с ctrl+c, ще останат много работещи демони в системата.
# може и направо без проверка с eval `ssh-agent -k` но така изхода от скрипта става по четлив/лаконичен -
# няма да има съобщение "kill: No such process" ако die() е извикан само за изход на скрипта и преди да има има стартиран ssh-agent
# ако ли пък има стартиран ssh-agent ще излезе нормалното му съобщение за убиване на pid
#
# ! задължително в началото на този скрипт трябва да има unset SSH_AUTH_SOCK SSH_AGENT_PID
# иначе може да убие системният ssh-agent, защото ще види enviorment променливата SSH_AGENT_PID предадена от родителя.
# -n True if the length of "STRING" is non-zero.
[ -n "$SSH_AGENT_PID" ] && eval `ssh-agent -k`
echo -e "$1"
exit 1
}
# проверка дали частният ключ е защитен с парола или дали избощо го има.
# grep излиза с 0 когато има съвпадение и с 1, когато няма или с 2 когато има грешка.
grep --silent --no-messages ENCRYPTED ~/.ssh/id_rsa || die "\nThe private key ~/.ssh/id_rsa does NOT have password or does not exit. Script aborted. Nothing done."
# ssh-agent служи като контейнер на key-овете. През него си комуникират ssh, rsync.....
#
# линукса при стартирането си има стартиран един ssh-agent, но за да е независимо от системата а и за да оказва влияние
# само на този скрипт се стартира отделен (допълнителен) ssh-agent демон. този демон задава променливите
# SSH_AUTH_SOCK, SSH_AGENT_PID, които сочат само към него и чрез тях ssh-add, ssh, rsync си комуникират с него.
#
# Ако се стартира ssh-agent-а без eval, ssh-agent се стартира, демонизира се и изписва в станадартния изход следният текст:
# SSH_AUTH_SOCK=/tmp/ssh-CtCAWu6104/agent.1234; export SSH_AUTH_SOCK;
# SSH_AGENT_PID=1234; export SSH_AGENT_PID;
# Но понеже това е само изписано в стандартният изход, никакви променливи не се задават и се губи връзката с демона!
# Затова стартирането става през eval `ssh-agent` за да може да се зададат/изпълнят променливите.
eval `ssh-agent`
# !!! Тук скрипта спира да пита за парола !!!
#
# Зарежда частният ключ ~/.ssh/id_rsa в ssh-agent-а
# Ако частният ключ е с парола пита интерактивно за паролата на ключа. След като един път ключа е добавен в ssh-agent-а
# повече не се пита за никаква парола!
# излиза с 1 error при:
# 1 - липса на ключ ~/.ssh/id_rsa
# 1 - натискане на enter при въвеждане на парола. Това е правилно защото key-а има парола а юзера все едно казва неща да въвеждам парола
ssh-add || die "\nssh-add exit. Script aborted. Nothing done."
echo -ne "\n\n"
echo -ne "-------------------------------------------\n"
echo -ne "Main files update.\n"
echo -ne "-------------------------------------------\n"
# отдалеченият ssh се стартира с опция малко -x, --rsh="/usr/bin/ssh -x" която забранява X оторизацията.
# тази опция е козметична и не фатална, досега беше без нея.
#
# Ако не е зададена всеки път при стартиране на скрипта ssh-а ще прави файл .Xauthority в отдалечената
# home директория и ще излиза съобщение:
# "/usr/bin/xauth: creating new authority file ~/.Xauthority"
# -a === -rlptgoD --recursive,--links,--perms,--times,--group,--owner,--devices
rsync -av --rsh="/usr/bin/ssh -x" .......................... || die "\nRsync error. Script aborted. Not all jobs done."
rsync -av --rsh="/usr/bin/ssh -x" .......................... || die "\nRsync error. Script aborted. Not all jobs done."
rsync -av --rsh="/usr/bin/ssh -x" .......................... || die "\nRsync error. Script aborted. Not all jobs done."
rsync -av --rsh="/usr/bin/ssh -x" .......................... || die "\nRsync error. Script aborted. Not all jobs done."
echo -ne "\n\n"
# търка ключовете. Може и без тази стъпка, защото при долната, когато се убива агента ще се изтрият и ключовете.
ssh-add -d
# Убива текущият агент
eval `ssh-agent -k`
echo -ne "-------------------------------------------\n"
echo -ne "The script executed successfully. All done.\n"
echo -ne "-------------------------------------------\n"
echo -ne "\n"