Значи чат-пат нещо се размирисва около това че е много модерно разни хахори да сканират IP ranges, търсейки отворен ssh порт, където някакъв скрипт пробва да брутфорсва акаунти със слаби пароли. Това, което е още по-потресаващо е че това нещо има успеваемост, не знам на какво се дължи този факт, но хората явно няма никога да се научат да си правят по-сложни пароли. След като и аз не съм се научил да го правя, няма какво да мрънкам 

'>
Та значи освен гореспоменатия (и най-сигурен според мен начин) същестуват и други решения:
* ssh порта се сменя така че глупавите автоматизирани скенери да не го ловят (тъпа идея, но донякъде работи)
* Слага се някакъв лимит на SYN пакетите с dstport=22 за минута и хостовете, които го надминат, биват REJECT-вани или дропвани. По принцип е идейно решение, с тази разлика че човек, който може да ти прати пакети с spoof-nat source адрес (например от същия етернет сегмент) може да ти сътвори една прекрасна мизерия, карайки те да вдигнеш хиляди правила в iptables. Ако това е рутер дето бута много трафик това може да се окаже малко гадно.
* Port-knocking. Идеята е много добра, но е също така ужасно неудобна. Освен което също до известна степен е податлива на DoS, макар и доста по-трудно.
* host-базиран контрол. Идейно и аз го предпочитам понякога. Обаче понякога все пак ти се налага да се връзваш от неавторизирано място и тогава почваш да се логваш от хост на хост докато стигнеш докъдето трябва.
И въпреки това, тези методи са си успешни. Нооо...аз обаче понеже съм тъп реших да потърся малко по-гъвкав (и податлив на гаври начин). За последното се изискват малко познания по С (малко, щото и аз не съм кой знае какъв програмист). Ииии спокойно, няма да пачваме sshd, въпреки че и там може човек да си даде поле за изява на ТНТМ-ските идиотии 

'>
Значи една огромна част от линукс дистрибуциите така или иначе ползват PAM за да автентицират потребители пред дадени услуги. Което е много удобно. Ами какво ще стане ако вземем че си напишем наш си PAM модул, който да прави НАШИ си проверки? В такъв случай вариантите стават доста много 

'>
Този случай, който аз ще разгледам сега е доста опростен, значи идеята при мен е един ssh клиент да бъде допуснат САМО ако на неговият хост нещо слухти на определен порт. Това е глупаво, но пък много лесно за реализация. Определено може да се разшири по много други начини (примерно по друг сокет да се обменя допълнителна информация за автентикация, с curl да се дърпа от някъде уеб документ и да се гледа в него за нещо, да се проверява за активационен мейл и кой знае колко още идиотски идеи).
Не мисля да навлизам особено в детайли за PAM модулите - накратко тук:
http://www.linuxdevcenter.com/pub/a/linux/2001/09/27/pamintro.htmlИ по този повод ето го сорса на моя примерен PAM модул:
| Примерен код  | 
 #include <security/pam_modules.h> //pam #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <syslog.h> #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h>
  #define portno 7000 // change if needed
  PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags ,int argc , const char **argv ) {     int retval;     struct sockaddr_in sin;     struct hostent *host;     int len;     int sd;     const char *token=NULL;
      retval=pam_get_item(pamh,PAM_RHOST,&token); //getrhost
      host = gethostbyname(token); // resolve     sd = socket(AF_INET, SOCK_STREAM, 0);     memcpy(&sin.sin_addr.s_addr, host->h_addr, host->h_length);     sin.sin_family = AF_INET;     sin.sin_port = htons(portno);     // someone listening?     if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0)     {         syslog(1,"Remote host %s does not listen on port %d\n",token,portno);         return PAM_AUTH_ERR;     }     return PAM_SUCCESS; }
  | 
Компилираме го и го копираме където му е мястото:
| Примерен код  | 
 # cc pmt.c -lpam -shared -o pmt.sо # cp pmt.so /lib/security/ 
  | 
И добавяме следния ред в /etc/pam.d/ssh:
| Цитат  | 
 auth    required        pmt.so
  | 
И това е достатъчно 
'>
Оттам нататък може да почваме с пробите:
| Цитат  | 
 gat3way:~/pamtest# ssh gat3way@localhost gat3way@localhost's password: (въвеждаме_правилна_парола) Permission denied, please try again. gat3way@localhost's password: ^C gat3way:~/pamtest# tail -n 3 /var/log/auth.log Sep  5 12:55:02 gat3way sshd[27928]: Remote host localhost does not listen on port 7000 Sep  5 12:55:02 gat3way sshd[27928]: pam_unix(ssh:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost  user=gat3way Sep  5 12:55:04 gat3way sshd[27928]: Failed password for gat3way from 127.0.0.1 port 37452 ssh2
  | 
Не иска да ни пусне. Мммм, нека в друга конзола пуснем netcat да ни слухти на порт 7000:
| Цитат  | 
| gat3way@gat3way:~$ nc -l -p 7000 | 
и да пробваме пак:
| Цитат  | 
 gat3way:~/pamtest# ssh gat3way@localhost gat3way@localhost's password: Linux gat3way ..... ^D gat3way:~/pamtest# tail  /var/log/auth.log ... Sep  5 12:58:29 gat3way sshd[27988]: Accepted password for gat3way from 127.0.0.1 port 45824 ssh2
  | 
Воала.
Сега разбира се това горе е прекален прост случай, не е много удобно (щото трябва преди да вържеш ssh трябва да осигуриш нещо да слухти там на клиентската машина), не е практично (ако си зад НАТ кво правим?) и не е чак толкова сигурно (злия хахор може и да забележи, че отсреща някой се опитва да се върже обратно към него).
Но никой не е казал, че нещата трябва да се реализират точно така. Както казах има огромна свобода по отношение на това каква проверка може да се реализира. Може например да се напише да ти иска 2 пъти парола, първият път да каже че е грешна, на втория да те пусне (идейно според мен)...може много неща може.
В тоя ред на мисли приемам идеи 
'>