Ja obecnie na serwerze, którym administruje nie uzywam, bo opieram się głównie na ips, ale niewykluczone, że wdroże w przyszłości. Istnieja specjalne programy do implementacji port knockingu jak knockd, ale jeśli się chce to można za pomocą iptables zbudować własny, a przez to nawet bardziej przejrzysty. U mnie trzeba było wykonać puknięcia na 4 porty w odpowiedniej kolejności, aby ssh zostało odblokowane. To można modyfikować dowoli. Ja opierałem się o to
howto , więc nie ma sensu się powtarzać, szczególnie, że to dobry tekst.
Logowanie na konto root poprzez ssh - zabezpieczenie serwera
Jeśli chodzi o dopuszczenie do logowania tylko z niektórych ip dla ssh, to nie trzeba kombinować z iptables, wystarczy:
Do wrzucenia na serwer (np. do /usr/local/bin/addip2host.sh) uruchamiamy w tle dodając ampersand na końcu, czyli:Nie zapominajmy o ustawieniu właściwych praw (najlepiej przez chmod 0500).
Do wrzucenia u siebie na komputerze (np. laptopie), żeby nie trzeba było sklejać i robić md5 ręcznie:
- Do /etc/hosts.deny dodajemy linijkę:
Kod: Zaznacz cały
sshd : ALL
- Do /etc/hosts.allow dodajemy linijki (przykładowo)
Gdzie, jak łatwo zgadnąć definiujemy adresy ip lub całe podsieci, z których wolno się łączyć do usługi sshd.
Kod: Zaznacz cały
sshd : 83.142.127.32/255.255.255.248 : ALLOW sshd : 83.142.121.224/255.255.255.224 : ALLOW sshd : 91.150.140.58/255.255.255.255 : ALLOW
Teraz, jak rozwiązać problem dopisywania do /etc/hosts.allow... można rozwiązać na kilka sposobów, ja wymyśliłem takie rozwiązanie. Na serwerze wybieramy jakiś nieużywany wysoki port, np. 2299 i podłączamy się z pomocą netcat, który w momencie podłączenia się do niego losuje liczbę i wysyła nam. My tą liczbę sobie łączymy z sobie i serwerowi znanym hasłem, robimy z tego skrót md5, i odsyłamy na serwer wraz z adresem IP, który chcemy dopuścić do połączenia. Serwer sobie sprawdza czy hash się zgadza z tym, który wyszedł jemu, i jeśli tak, to dopisuje odpowiednią linijkę do hosts.allow, wysyłając maila z powiadomieniem o tym fakcie na adres zdefiniowany w skrypcie. W tym momencie możemy się już połączyć przez ssh. Zaletą tego sposobu jest to, że nawet jeśli ktoś snifuje naszą sesję, to nic mu to nie da, bo hash jest na podstawie losowej liczby, której powtórzenie się w kolejnych sesjach jest mało prawdopodobnej.
Do wrzucenia na serwer (np. do /usr/local/bin/addip2host.sh) uruchamiamy w tle dodając ampersand na końcu, czyli:
Kod: Zaznacz cały
/usr/local/bin/addip2host.sh &
Kod: Zaznacz cały
#!/bin/bash
haslo='NaszeTajneHaslo'
admin='adres@email.admininstratora.com.pl'
port='2299'
function valid_ip()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
while true; do
#generuje pierwszy numer do hasha
number=$RANDOM
# wysylam numer do klienta
#echo "$number" | netcat -l -p $port
netcat -l -p $port -c "echo $number"
# licze hash ze złożenia wygenerowanego numeru i stałego hasła
lokalklucz="${number}${haslo}"
tajnyklucz=`echo $lokalklucz |md5sum |awk '{print $1}'`
sleep 1
# czekamy na hash i numer ip złączone za pomocą dwukropka
IFS=':'
linia=($(netcat -l -p $port))
klucz="${linia[0]}"
ip="${linia[1]}"
# jeśli tajny klucz się zgadza i podany jest ip, to wpisujemy do hosts.allow
if valid_ip $ip; then stat='good'; else stat='bad'; fi
if [ "$klucz" == "$tajnyklucz" ] && [ "$stat" == "good" ]; then
#echo KLUCZ OK
echo "sshd : $ip/255.255.255.255 : ALLOW" >> /etc/hosts.allow
echo "dodalem ip=$ip do /etc/hosts.allow" | mail -s "nowy ip w /etc/hosts.allow" $admin
# printf "%-20s: %s\n" "$ip" "$stat"
fi
sleep 1
done
Kod: Zaznacz cały
#!/bin/bash
host='192.168.100.100'
port='2299'
haslo='NaszeTajneHaslo'
klucz=`netcat $host $port`
sleep 2
tajnyklucz=`echo $klucz$haslo |md5sum |awk '{print $1}'`
echo -n "Podaj adres IP z którego się chcesz połączyć: ";
read ip
echo "$tajnyklucz:$ip"
echo "$tajnyklucz:$ip" |netcat $host $port
echo OK, adres dodany