Securiser linux

From Wikichris
Jump to: navigation, search

Page à l'état d'embrillon (pense-bête)


SSH

Voici la page dédiée à la connexion SSH par Clé Privée / Clé Publique. J'y explique pourquoi cette solution.

Users

Dans son fichier ~/.ssh/authorized_keys chaque user devra avoir indiqué sa(ses) clé(s) publique(s)

ssh-dss AAAAB3NzaC1kc3MAAACBAL5ZMWRk9Oaj/enDrrcOtfud/PWbEbDKjhtZjv4NcsXgugKdvmZ2M591XFvswNpyBMiWc+UnUFPymALY+ly9GtIuVX3krrw70wgZ3U+9drO8aKNFdb6penUYBVO502s4zrVykSxi6UftQq0fJ1o9DgO3oDHrUph9BLw6+El3VuYtAAAAFQClHS9FTiqhF54K9a2r+4Kx5KLurwAAAIBWRUHNCIy7Thcpz7J3n7wGQXd76FqVOVTSNQF7vTyLUDwmA7qFXJUi0MK740hD/JUT1JqIU3i87BnrOtWQ6DmBarfZAkDGPJAg4LQvYo4w5QgrLs4kQMC4QVaBRtoyax9L8wLq/qQC4lvPCaYVrmQH6kgVnFWt6EeuhPg2uKD+PAAAAIA6r0YUuKmwIBKI2LhmOghDu5vH16xWP1YNRWqk6oBPoE3mmXSmsfWpTU4oweSziN/PcbHC3hhNDeZoR0uGhcQ7sFpi4P0OZhjJ96DUwu0Wsj7OBYff4ymGfO941aT/bnfr+EWBoLuBJ1OV0lMJmBrf+qCPVQolzHqqJsozzwe/Uw== chris
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDS/snZWsdmccUHHOY6umSSrYUQLUwUJkPBsvGNsR8C3DFSclz9HJMexQYhpulNdq8OOg4CD6LxrMXFtK9efGwTK2m9hzqOD8R26LWLjQw6VQssNS5laBxBmGh4cGD3KR3X2gMr+m4xjmhfV+2PQpLbE1G1iNLxNhEVwvos+ykCWZLurGGgpqZ0xExpYZB0bndmCuQBCP/AugiU2Uj0Z46dP7a8Rj1NhOkkyN8rxRdi1I6iJ6agE9/Felds3AtsqYR7/r7oP/HSPNE857fgbJnNgW+Yu3La1RFHlzoSXcmZA9hbrrf/UcXj10SCicMNr/VVxsO7I3XgaXkTgy4TMK+j chris

Serveur

Pour chaque utilisateur qui voudra se connecter, on crée un groupe ssh_users. Cette option permettra l'accès aux logins clairement identifiés par l'admin, on utilise un groupe pour éviter de redémarrer ssh à chaque nouveau user. Il y a bien trop d'utilisateurs générés automatiquement par les installations de programmes.

groupadd ssh_users

ajoutons les users (ici on ajoute chris):

addgroup chris ssh_users


Modifier le fichier /etc/ssh/sshd_config afin d'y trouver les lignes suivantes :

il faudra vous connecter sur le port 22222 à présent

Port 22222

interdit de se connecter via ssh avec root

PermitRootLogin no

interdit la connexion ssh avec mot de passe

PasswordAuthentication no 
UsePAM no

seuls ces users peuvent le loger en ssh, incompatible avec AllowGroups

#AllowUsers chris

si on ne veut pas avoir à relancer sshd à chaque ajout de user

AllowGroups ssh_users

20s et 1 seul essai également suffisent avec une clé privée,

LoginGraceTime 20s
MaxAuthTries 1

2 lancement simultané de login suffisent avec clé privée

MaxStartups 2 #2 session en cours d'ouvertures pas plus car clé privée rapide

Les autres auth ne sont pas nécessaires

RSAAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no

on relance le daemon SSH pour que les changements soient pris en compte :

/etc/init.d/ssh restart

sudo

Pour éviter que plusieurs utilisateurs connaissent le mot de passe root sans bloquer leur mission d'admin, activater Sudo Utilisateur

installer sudo

apt-get install sudo

utiliser la commande suivante et modifier le fichier pour ajouter une ligne par utilisateur

visudo

Si le groupe sudo est déjà ajouté, il suffit d'ajouter un utilisateur au groupe sudo

addgroup chris sudo


Client NTP

ntpdate est présent par défaut dans l'install de base Debian Squeeze d'OVH, mais pas dans ses machines virtuelles. On doit donc parfois l'installer avant usage

apt-get install ntpdate

Vous pouvez lancer une synchro ponctuelle de l'heure

ntpdate 0.debian.pool.ntp.org

Afin être sur que l'heure ne se décale jamais, on place un script dans le cron.daily

/etc/cron.daily/ntpdate

#!/bin/sh
/usr/sbin/ntpdate -s 0.debian.pool.ntp.org # L'option -s permet de faire apparraitre le résultat dans les logs

Ne surtout pas oublier de donner les droits en execution au script

chmod a+x /etc/cron.daily/ntpdate

chrootkit

(Wikipedia) chkrootkit est un logiciel libre permettant de détecter si un système unix n'a pas été compromis par un [Rootkit].

Il permet de détecter les traces d'une attaque et de rechercher la présence d'un rootkit sur un système Unix/Linux en vérifiant les quelques points suivants :

  • si des fichiers exécutables du système ont été modifiés ;
  • si la carte réseau est en mode « promiscuous » ;
  • si un ou des Vers informatiques LKM (Loadable Kernel Module) sont présents.

La vérification effectuée au sujet du mode promiscuous consiste à voir si la carte réseau est configurée pour récupérer et lire toutes les trames, indiquant la possibilité qu'un sniffer soit installé sur le système.

La définition exacte de rootkit donnée par Le Jargon Français est : « ensemble d'exploits réunis afin d'avoir des chances maximales de piquer un compte root sur une machine Unix. »

 apt-get install chkrootkit

Puis on crée un cron

00 4 * * 1  /usr/sbin/chkrootkit 2>&1 | mail votre@email.com -s "[SRV-TEST] Résultats de chkrootkit"

Anti Intrusion IPv4 : fail2ban

http://doc.ubuntu-fr.org/fail2ban

Ce programme est basé sur l'analyse des log du système. Pour l'instant il ne fonctionne qu'en IPv4.

Pour l'installer

apt-get install fail2ban

dans /etc/fail2ban/jail.conf activer ssh sur le port 22222

[ssh]

enabled = true
port    = 22222
filter  = sshd
logpath  = /var/log/auth.log
maxretry = 6


Si Apache est utilisé : activer le filtre http et https dans /etc/fail2ban/jail.conf

enabled   = true
port      = http,https
filter    = apache-auth
logpath   = /var/log/apache*/*error.log
maxretry  = 6

Puis ajouter à la fin de /etc/fail2ban/jail.conf

[apache-w00tw00t]
enabled = true
filter = apache-w00tw00t
action = iptables[name=Apache-w00tw00t,port=80,protocol=tcp]
logpath = /var/log/apache2/access*.log
maxretry = 1

Créez le fichier /etc/fail2ban/filter.d/apache-w00tw00t.conf

[Definition]

failregex = ^<HOST> -.*"GET \/w00tw00t\.at\.ISC\.SANS\.DFind\:\).*".* 

ignoreregex =

En redémarrant il ajoutera des règles dans iptables basées sur ce qu'il trouvera dans les logs

/etc/init.d/fail2ban restart


fail2ban avec support IPv6

http://www.debian-fr.org/fail2ban-et-ipv6-t38368.html

Serveur Mail

J'utilise un serveur que je comprend (EXIM je n'y comprend rien), postfix est si clair qu'on le configure correctement :

apt-get install postfix

choix : mode "internet" Par défaut il est correctement configuré pour ne pas servir de Relay à tout va, mais pour vérifier http://www.abuse.net/relay.html est très utile.


Pour avoir la commande mail

apt-get install bsd-mailx

ajouter dans le fichier /etc/aliases

# /etc/aliases
mailer-daemon: postmaster
postmaster: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
noc: root
security: root
root: votreemail@domaine.com

pour que le changement d'alias soit pris en compte executer

newaliases

Vérifier le bon fonctionnement, envoyez un email à root que vous devriez recevoir sur votre email votreemail@domaine.com (peut-être en spam ?)

# mail root
Subject: essai
test
.
Cc:


Serveur Web

GIT / SVN

Bloquez l'accès aux dossiers et fichiers de GIT et SVN qui pourrait avoir été téléchargés avec vos sites web. Il est possible d'y trouver en clair vos mots de passe et tout votre code PHP (et plus facilement trouver les failles de sécurité de vos sites)

En 2008 j'avais écrit ceci : http://offroad.gonzofamily.com/2008/05/03/preventing-access-to-svn-folders-in-apache/ . A metre à jour avec GIT

SSL

Utiliser autant que possible HTTPS pour éviter le transport en clair de vos mots de passe sur internet.

Limiter les accès à certaines IP

Ajouter des .htaccess pour limiter l'affichage des dossiers vides, le ficher peut contenir simplement cette ligne:

Options -Indexes

Vous pouvez limiter l'access à certains dossier (comme le /wp-admin/ de wordpress) avec ce fichier .htaccess

Order deny,allow
Deny from All
allow from 88.22.11.22
allow from 59.59.59.59
allow from 2001:db8:13:66bb::/64

Voir juste un fichier (comme le fichier wp-login.php de wordpress) en ajoutant dans votre .htaccess:

<Files wp-login.php>
 Order deny,allow
 Deny from All
 allow from 88.22.11.22
 allow from 59.59.59.59
 allow from 2001:db8:13:66bb::/64
</Files>

PHP

Add to you php.ini

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
expose_php = Off
allow_url_fopen = Off

Wordpress

Install http://wordpress.org/extend/plugins/bulletproof-security/

Routage

décommanter les 2 lignes suivantes dans /etc/sysctl.conf

# Do not accept ICMP redirects (prevent MITM attacks)
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

Si votre serveur n'est pas un routeur les options suivantes sont également intéressantes

# Do not send ICMP redirects (we are not a router)
net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Log Martian Packets
net.ipv4.conf.all.log_martians = 1

Pour activer ces modifications immédiatement

sysctl -p

Mises à jour automatiques

Il est trop risqué, sur un serveur en prod d'effectuer toutes les mises à jours diponibles debian.
Le package cron-apt se contente de lister les mises à jour disponibles et d'envoyer un email. On peut toutefois utiliser des repository différents (par exemple limiter à security)

apt-get install cron-apt

pour recevoir un email à chaque fois (et non pas seulement en cas d'erreur) ajouter dans le fichier /etc/cron-apt/config

MAILON="upgrade"

pour changer l'heure de programmation :

vi /etc/cron.d/cron-apt

le premier email a mis 30min a être envoyé.

Firewall

Créons un dossier /etc/iptables.rules qui contiendra vos règles de filtrage ipv4 et ipv6

mkdir /etc/iptables.rules

Créons /etc/iptables.rules/ipv4.rules avec le contenu suivant :

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:in-new - [0:0]
:monitoring-servers - [0:0]

#Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

#monitoring-servers
-A monitoring-servers -s 178.33.33.33 -j ACCEPT
-A monitoring-servers -s 176.31.31.31 -j ACCEPT
-A monitoring-servers -j DROP

#Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP
#new connections unknown to the kernel are handled in a separate chain
-A INPUT -m state --state NEW -j in-new
#pass SYN packets for SSH
-A in-new -p tcp -m tcp --dport 22222 --syn -j ACCEPT

#Allows all outbound traffic
#You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#If its a HTTP Server
#Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
#-A in-new -p tcp --dport 80 -j ACCEPT
#-A in-new -p tcp --dport 443 -j ACCEPT

#Allows SNMP for monitoring servers only
#-A in-new -p udp --dport 161 -j monitoring-servers

#Allow all ICMP traffic
-A INPUT -p icmp -j ACCEPT

#log and reject everything else
#-A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT6]: "
-A INPUT -j REJECT

#log iptables denied calls (access via 'dmesg' command)
#-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#disallow FORWARD explicitly (despite chain policy)
-A FORWARD -j REJECT

COMMIT


Créons /etc/iptables.rules/ipv6.rules avec le contenu suivant :

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:in-new - [0:0]
:monitoring-servers - [0:0]

#Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d ::1/128 -j REJECT

#monitoring-servers
-A monitoring-servers -s 2001:db8:13:66bb:2::2 -j ACCEPT
-A monitoring-servers -s 2001:db8:13:66bb:1::223 -j ACCEPT
-A monitoring-servers -j DROP

#Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# packets that are out-of-sequence are silently dropped
-A INPUT -m state --state INVALID -j DROP
#new connections unknown to the kernel are handled in a separate chain
-A INPUT -m state --state NEW -j in-new
#pass SYN packets for SSH
-A in-new -p tcp -m tcp --dport 22222 --syn -j ACCEPT 

#Allows all outbound traffic
#You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#If its a HTTP Server
#Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
#-A in-new -p tcp --dport 80 -j ACCEPT
#-A in-new -p tcp --dport 443 -j ACCEPT

#Allows SNMP for monitoring servers only
#-A in-new -p udp --dport 161 -j monitoring-servers

#Allow all ICMPv6 traffic
-A INPUT -p icmpv6 -j ACCEPT

#log and reject everything else
#-A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT6]: "
-A INPUT -j REJECT

#log iptables denied calls (access via 'dmesg' command)
#-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#disallow FORWARD explicitly (despite chain policy)
-A FORWARD -j REJECT

COMMIT

Avant de configurer le système pour appliquer ces filtres à chaque démarrage, il est important de vérifier s'ils sont corrects avec la commande iptables-restore, ainsi si nous perdons la main sur notre serveur, il suffit de redémarrer grace au Manager d'OVH qui propose un hard reboot :

iptables-restore /etc/iptables.rules/ipv4.rules
ip6tables-restore /etc/iptables.rules/ipv6.rules

Une fois les règles testées par vos soins (le plus important: vous pouvez toujours lancer une nouvelle connexion SSH vers votre serveur), vous pouvez indiquer au Système de les lancer à chaque démarrage en créant le fichier suivant :

/etc/network/if-pre-up.d/iptables :

#!/bin/bash
/sbin/iptables-restore < /etc/iptables.rules/ipv4.rules
/sbin/ip6tables-restore < /etc/iptables.rules/ipv6.rules

Penser à rendre ce script exécutable :

chmod a+x /etc/network/if-pre-up.d/iptables


Sauvegarde

Il n'est plus vraiment question du même type de sécurité, mais la sauvegarde ne devrait jamais être sous-estimée. J'ai des scripts automatiques quotidiens pour apache + mysql + /etc .

Database

If you are running MySQL, is would be wise to run this command as root

mysql_secure_installation

This will allow you to:

  • Choose a root password if not set, or keep yours if you like it
  • Remove Anonymous users
  • Disallow root login remotely
  • Remove test database and access to it
  • Reload privilege tables