jeudi 21 août 2008

PF et attaques ssh

Vous avez surement déja vu dans vos logs de connexion des tentatives de connexion par attaque bruteforce (sshd, httpd, ftpd…). C'est chiant, ca remplit vos logs, et ca fait loader votre serveur qui n'avait pas besoin de ca.

Heureusement, l'ami Daniel Hartmeier pense à vous, et a ajouté des options convi à son fameux firewall PacketFilter, affectueusement surnommé PF. Il s'agit de 'max-src-conn-rate' et de 'max-src-conn', a utiliser en combinaison avec 'overload'. Ces options sont disponibles dans PF à partir d'OpenBSD 3.7, FreeBSD 6.0 et NetBSD 2.0.

Ca se passe donc dans le fichier de conf de pf, /etc/pf.conf. Je donne l'exemple pour ssh, mais le principe est le même pour les autres ports.

Avant, pour autoriser les connexions ssh de l'extérieur, on avait une ligne ressemblant à cela (avec $external le nom de son interface réseau externe) :

pass in quick on $external inet proto tcp from any to any port ssh flags S/SA keep state 

Il suffit de remplacer ces lignes par:

table <ssh-bruteforce> persist
block in quick from <ssh-bruteforce>
pass in quick on $external inet proto tcp from any to any port ssh flags S/SA keep state \
( max-src-conn-rate 2/10, overload <ssh-bruteforce> flush global)

Dans l'ordre :

  • on crée une table qui va conserver les ip des attaquants
  • on bloque tout ce qui provient de ces ips
  • on autorise les connexions ssh si il y a moins de 2 tentatives de connexion en 10 secondes
  • sinon on enregistre l'ip dans la table, et on détruit toutes les connexions correspondant à cette ip.

Évidemment, on peut personnaliser la fréquence des tentatives de connexion, et utiliser aussi 'max-src-conn' pour limiter le nombre total de connexions provenant d'une ip.

Voila, à vous la tranquillité, et adieu les attaques bêtes et méchantes !!

mercredi 20 août 2008

Sécuriser commande SMTP Sendmail

Pour interdire les commandes expn et vrfy, restreindre l'accès à la queue de messages et forcer l'identification du client : ajouter la ligne suivante dans /etc/sendmail.mc :

define('confPRIVACY_FLAGS', authwarnings novrfy noexpn restrictmailq neddmailhelo)

Une fois le fichier /etc/sendmail.mc ainsi modifié il convient de générer le nouveau fichier de configuration de Sendmail :

m4 /etc/sendmail.mc > /etc/sendmail.cf

Puis relancer le démon avec ce nouveau fichier de configuration :

/etc/rc.d/init.d/sendmail restart

Sendmail paramètres anti-DOS

De nombreux de paramètres peuvent être configurés dans le fichier /etc/sendmail.mc afin d'offrir une résistance plus importante aux attaques visant à saturer les ressources du système. Il est donc intéressant de fixer les variables suivantes dans le fichier /etc/sendmail.mc :

Variables du fichier /etc/sendmail.mc Signification
define('confMIN_FREE_BLOCKS','100') Nb. minimum de bloques libres dans la queue pour accepter de nouveaux messages
define('confMAX_MESSAGE_SIZE','5000000') Taille maximale des messages acceptés (en bits)
define('confAUTO_REBUILD','False') Recompilation automatique des alias
define('confQUEUE_LA,'10') Valeur : 8*nb_processeurs
define('confREFUSE_LA','8') Valeur : 12*nb_processeurs
define('confMAX_DAEMON_CHILDREN','40') Nb. max de processus fils autorisés par le démon Sendmail (par défaut : infini ; 40 pour 128 MB RAM). Au-delà, les connexions sont refusées.
Attention : fixer cette variable peut constituer une source de déni de service !
define('confMAX_HEADERS_LENGTH','64') Taille maximale de la somme des en-têtes
define('confMAX_MIME_HEADER_LENGTH','1024') Taille maximale de certaines valeurs dans les en-têtes MIME
define('confMAX_RCPTS_PER_MESSAGE','100') Nombre maximal de destinataires d'un message (par défaut : infini).
Si ce nombre est dépassé, les destinateurs suivants reçoivent un code d'erreur 452 et la livraison du message est effectuée à la prochaine connexion.

Message d'accueil Sendmail

Par défaut, Sendmail envoie un certain nombre d'information lorsque l'on se connecte sur le serveur de messagerie :

telnet localhost 25
220-mail.domaine.fr ESMTP Sendmail 8.9.3/8.8.7 Tue, 20 Feb 2001 23:30:58 +0100

Ces informations permettent de découvrir sans effort la version de Sendmail utilisée (ici 8.9.3) ainsi que la version du fichier sendmail.cf (ici 8.8.7).
Pour éviter cela, il convient d'éliminer les options $v et $Z du fichier /etc/sendmail.mc :

define('confSMTP_LOGIN_MSG',$j Sendmail; $b)

FreeBSD blowfish et message d'acceuil

Conversion des password à Blowfish

Pour se protéger contre les exploits locaux, il peut etre interessant de pouvoir changer l'algorithme utilisé par défault.

Blowfish est rapide et sûr. Pour implémenter les hash Blowfish, éditez /etc/login.conf et changez la ligne suivante :

:passwd_format=blf:\

Sauvegardez, puis recompiler la base des logins avec la commande suivante :

cap_mkdb /etc/login.conf

Il va falloir à présent changer tous les mot de passe des utilisateurs pour avoir un nouveau hash Blowfish.
Pour vérifier si cela à bien fonctionner, éditez (en root) le fichier /etc/master.passwd Les mots de passe doivent commencer par $2.
Pour terminer, configurez l'utilitaire adduser pour utiliser Blowfish par défault, éditez /etc/auth.conf file :

crypt_default=blf

Changer le message d'accueuil

Quand vous vous loggez, vous avez un message vous rappelant que vous êtes sous FreeBSD, la verson et le nom du kernel... Vous ne voulez pas forcément faire partager ces informations sensibles.

Editez le fichier /etc/motd avec ce que vous voulez ;-)
Enlevons à présent le copyright. Créez un fichier de copyright vide en lançant la commande :

touch /etc/COPYRIGHT 

Puis pour changer le texte qui apparait au prompt, editez le /etc/gettytab . Trouvez la ligne dans la section default:\ qui commence avec :cb:ce:ck:lc

Prudement, changez le texte entre \r\n\ \r\n\r\nr\n: avec ce que vous voulez.
Re-vérifier bien que vous avez le bon nombre de \rs et \ns et sauvegardez.
Testez en vous re-loggant.
Finalement, FreeBSD va rajouter ses informations à chaque fois que vous vous loggerez. Pour éviter cela, ajoutez la ligne suivante à /etc/rc.conf , puis rebootez

update_motd="NO"

mardi 19 août 2008

Gestion des process

FreeBSD

On a FreeBSD Unix system, as with other BSD Unix systems, you have a number of utilities with a base system install that can be used for listing open files, running processes, and network connections. The netstat utility is maintained as a part of the FreeBSD base system by the FreeBSD core developers, and offers exactly the sort of functionality you need to list open ports on your system.

netstat

To list open network ports and the processes that own them on FreeBSD with netstat, you can use this command:

  netstat -a | egrep 'Proto|LISTEN'

The output for this on my laptop running FreeBSD is:

Proto Recv-Q Send-Q  Local Address      Foreign Address    (state)
tcp4 0 0 localhost.ipp *.* LISTEN
tcp6 0 0 localhost.ipp *.* LISTEN
tcp4 0 0 *.2200 *.* LISTEN
tcp6 0 0 *.2200 *.* LISTEN
tcp4 0 0 *.x11 *.* LISTEN
tcp6 0 0 *.x11 *.* LISTEN

The localhost.ipp entry refers to the Internet Printing Protocol, used by CUPS to talk to the network printer. The *.2200 entry refers to SSH, which I have set to a nonstandard port — so it’s not recognized by netstat’s port-to-service association capabilities. *.x11, meanwhile, refers to the X Window System protocol.

You can add the -n option to netstat to get port numbers instead of having the utility try to provide names for services:

  netstat -an | egrep 'Proto|LISTEN'

The output would then look somewhat different:

Proto Recv-Q Send-Q  Local Address      Foreign Address    (state)
tcp4 0 0 127.0.0.1.631 *.* LISTEN
tcp6 0 0 ::1.631 *.* LISTEN
tcp4 0 0 *.2200 *.* LISTEN
tcp6 0 0 *.2200 *.* LISTEN
tcp4 0 0 *.6000 *.* LISTEN
tcp6 0 0 *.6000 *.* LISTEN

This information can be used to determine what services are running, in cases where services are using standard ports. On a FreeBSD system, you can get a listing of standard port associations by searching through the contents of /etc/services. For instance, if you wanted to find out what was up with port 631, you might use this command:

  grep -w 631 /etc/services

The output:

ipp     631/tcp    #IPP (Internet Printing Protocol)
ipp 631/udp #IPP (Internet Printing Protocol)

sockstat

In addition to netstat, the more limited command sockstat is effectively tailor-made for this kind of information gathering. To get a listing of listening ports and their associated processes, you can use this command:

  sockstat -4l

The output may even be more useful than that of netstat above:

USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root cupsd 1701 4 tcp4 127.0.0.1:631 *:*
root cupsd 1701 6 udp4 *:631 *:*
root sshd 1685 4 tcp4 *:2200 *:*
root Xorg 1154 3 tcp4 *:6000 *:*
root syslogd 907 7 udp4 *:514 *:*

Linux distributions

As with FreeBSD, the obvious choice of tool to use for listing open ports is netstat. Most Linux distributions use a different version of the utility, however — maintained separately from the Linux distribution, as an independent software development project.

One consequence of that fact is that the command line options used to achieve the same results may be different with FreeBSD than with Debian, Ubuntu, or Fedora Core Linux systems. On a typical Linux system, this command will list open network ports and the processes that own them:

  netstat -lnptu

The output should look something like this:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 2458/cupsd
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 2353/postgres
tcp6 0 0 :::22 :::* LISTEN 2335/sshd
udp 0 0 0.0.0.0:631 0.0.0.0:* 2458/cupsd

As you can see from this output, the Debian GNU/Linux system on which I ran that command has only four open ports — two for CUPS, so that the computer can communicate with the network printer; one for PostgreSQL so that it can be contacted by applications in development; SSH, so that I can access it remotely, from my laptop.

Microsoft Windows XP

Microsoft Windows also offers a netstat command that can be executed from the command line to get a list of open ports. The standard MS Windows version of netstat is slightly more limited than its Unix-like system counterparts, but still suffices to get a listing of listening services:

  netstat -a | find "LISTENING"

The output of this command should look something like this:

TCP    hostname:epmap           hostname:0               LISTENING
TCP hostname:microsoft-ds hostname:0 LISTENING
TCP hostname:10110 hostname:0 LISTENING
TCP hostname:netbios-ssn hostname:0 LISTENING

. . . with “hostname” replaced by the system’s hostname, of course.