Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
freebsd:sysctl_avance [2006/02/28 19:25]
127.0.0.1 (old revision restored)
freebsd:sysctl_avance [2010/01/12 13:29] (current)
Line 1: Line 1:
 +Sysctl est un outil extrêmement pratique au sein de FreeBSD. En effet, avec le bit suid convenable il nous permet de verifier ou de manipuler l'etat du kernel à chaud ou on the fly (ca fait hype). Les informations sont stockées et
 +affichées à travers une Management Information Base ou MIB selon le même modèle que SNMP. Par exemple pour afficher une liste des differentes variables d'etat kernel, il vous suffit d'​effectuer un simple
 +<​code>​
 +huyhuy# sysctl -a
 +</​code>​
 +de la même manière que vous utiliseriez un ls. Notez que vous pouvez preciser l'​entrée de la MIB si vous la connaissez juste apres l'​option afin de n'​afficher qu'​elle. Suivant le principe des MIB, vous pouvez reduire
 +l'​affichage en precisant un champ de la MIB. Par exemple pour afficher toutes les entrées en rapport avec IP
 +<​code>​
 +huyhuy# sysctl net.inet.ip.*
 +</​code>​
 +Notez aussi que certaines variables ne sont pas modifiables et que certaines entrées de la MIB sont sous forme de tableaux utilisés à l'​occasion par ps, netsat ou systat. Enfin pour obtenir une liste des variables sysctl que vous
 +pouvez modifier, consultez la page de manuel de sysctl.
  
 +L'une des fonctionnalités interessantes de FreeBSD - et donc par extension de sysctl en kernel tuning dynamique - consiste en l'​établissement de secure level au sein du systeme. Il existe ainsi 4 levels de securité au sein de FreeBSD qui peuvent etre augmentes uniquement par un processus root mais qu'​aucun processus
 +ne peut diminuer, une modification a la baisse necessitera donc la configuration de la ligne suivante dans **rc.conf**
 +<​code>​
 +kern_securelevel_enable="​YES"​
 +kern_securelevel="​N"​
 +</​code>​
 +Ou N represente l'​entier correspondant au securelevel que vous desirez.
 +Il existe donc 4 niveaux de securite qui instaurent principalement des options
 +appelees file flags permettant de definir certains droits par default et
 +recursivement :
 +  * -1 qui instaure le mode insecure (0) de maniere permanente. Notez qu'il represente la valeur par defaut.
 +  * 0 represente le mode insecure dans lequel les files flags immutable et sappend-only peuvent être retirés et ou on peut effectuer des operations de lecture/​ecriture sur tous les péripheriques avec pour seule restriction les droits deja instaurés par exemple dans la fstab. Adapté à une workstation.
 +  * 1 represente le Secure mode dans lequel les flags system immutable et system append only ne peuvent etre désactivés,​ /dev/mem et /dev/kmem ne supportent plus d'​operation d'​ecriture et enfin les kernel modules ne peuvent plus etre charges ou decharges. A partir de ce niveau de securelevel,​ des problemes d'​utilisation essentiellement liés au serveur XFree86 et aux installations ou recompilations,​ peuvent apparaitre. Adapte à un serveur léger.
 +  * 2 instaure le Highly secure mode qui est strictement le même que le secure mode a l'​exception du fait que les seules operations desormais effectuees sur les disques sont le montage et demontage. En mode multiuser vous risquez d'​avoir de nombreuses difficultes d'​utilisation.
 +  * 3 signifie l'​instauration du Network secure mode qui est similaire au securelevel avec en plus l'​impossibilite de modifier les rules ipfw ou la configuration dummynet, une load balancer basique fonctionnement a partir d'​ipfw. ​
 +Ces 2 derniers levels sont vraiment paranoid et uniquement adaptes dans le cas d'une configuration de tres haute securite avec une utilisation statique.
 +
 +Pour entrer le secure level qui correspond a votre utilisation,​ entrez la ligne
 +<​code>​
 +#huyhuy sysctl -w kern.securelevel=N
 +</​code>​
 +Ou **N** correspond au securelevel desiré.
 +
 +Directement lie a l'​option securelevel,​ on trouve la commande chflags qui permet
 +de modifier les flags qui ont ete actives par les securelevels. Les flags sont
 +les suivants :
 +  * arch, transforme le fichier en archive, uniquement utilisable par le root.
 +  * opaque, rend le fichier "​opaque"​ à certaine lecture (utile contre la lecture par d'​autres applications) et modifiable uniquement par l'​owner ou le root.
 +  * nodump, permet d'​interdire un backup du fichier grace a l'​utilitaire dump. Modifiable uniquement par le owner ou le root.
 +  * sappnd, instaure le system append-only flag uniquement modifiable par le root en securelevel supérieur à 0.
 +  * schg place le flag system immutable qui comme son nom l'​indique est censé empêcher toute évènement. Modifiable par le root uniquement en niveau 0.
 +  * sunlnk permet d'​interdire la suppression d'un fichier, sachant que cette option n'est modifiable que par le root
 +  * uappnd, uchg et uunlnk sont les pendant respectifs de sappnd, schg et sunlnk mais a l'​exception pres d'​inclure des capacites de modifications pour le owner egalement en plus du root.
 +
 +Ils s'​utilisent tous avec la syntaxe suivante :
 +<​code>​
 +huyhuy# chflags -RH sappnd /bin
 +huyhuy# chflags -RH sappnd /sbin
 +huyhuy# chflags -RH sappnd /​usr/​libexec
 +huyhuy# chflags -RH sappnd /usr/lib
 +huyhuy# chflags -RH sappnd /​usr/​share/​lib
 +huyhuy# chflags -RH sappnd /boot
 +huyhuy# chflags sappnd /kernel
 +</​code>​
 +Notez qu'en effectuant un man chflags, vous decouvrez les quelques options -notamment la recursivité - que propose cette commande. Pour retirer un file flag ce sont les mêmes options avec le prefix no tel que nosappnd. Les file
 +flags sont interessants a placer sur certains fichiers sensibles precis ou alors carrement sur un repertoire dont vous souhaitez vous assurez de l'​integrite et qui sera rarement modifie tel que dans l'​exemple ou R et H permettent de suivre les liens symboliques et ce recursivement. Cependant, les restrictions que requierent les securelevel sont rebutantes dans la configuration d'une workstation necessitant par exemple l'​utilisation d'un serveur X (qui ecrit dans /dev/kmem) ou des compilations ou recompilations regulieres. Une idée à utiliser de pair avec les securelevel consisterait à placer dans votre kernel l'​option NO_LKM afin de se préserver du patching à chaud abusif.
 +
 +Dernier detail qui n'a pas grand chose à voir avec sysctl mais qui importe beaucoup dans la gestion des droits et des fichiers. Vous avez le loisir de modifier la fstab afin de monter vos diverses partitions avec certaines options.
 +Sous FreeBSD, au lieu de ne creer qu'une unique partition root /, le systeme cree simultanement une partition /usr et /var. Vous pouvez definir dans votre fstab pour l'​ensemble de vos file systems :
 +
 +  * les droits d'​écriture avec l'​option rw pour read-write, ou ro pour read-only.
 +  * les droits d'​exécution avec l'​option noexec.
 +  * les privilèges accordés avec l'​option nosuid.
 +<​code>​
 +huyhuy# edit /​etc/​fstab ​
 +</​code>​
 +<​code>​
 +#device mountpoint fs options dump pass
 +/​dev/​ad0s2b none swap sw 0 0
 +/​dev/​ad0s2a /​ ufs rw,​nosuid 2 2
 +/​dev/​ad0s2f /​usr ufs rw 2 2
 +/​dev/​ad0s2c /​home ufs rw,​nosuid,​userquota 2 1
 +/​dev/​ad0s2e /​var ufs rw,​noexec,​nosuid 2 2
 +/​dev/​acd0c /​cdrom cd9660 ro,​noauto 0
 +</​code>​
 +Nous limitons ici l'​exécution dans les fichiers tmp et var afin d'​éviter qu'un intrus tente d'y placer des répertoires ou des binaires et nous limitons également la presence de binaire de bit de privilège root.
 +
 +Sysctl peut également nous apporter une aide précieuse dans la configuration systeme et réseau à des fins de performances élevées. Il va ainsi nous permettre d'​activer certaines capacités reseau que supporte parfaitement la
 +pile TCP/IP BSD - qui est cela dit en passant certainement la plus stable, la plus performante et la plus standard des piles TCP/IP - mais qui ne sont pas activées par defaut.
 +
 +La première entrée intéressante est l'​option log_in_vain qui va loguer à travers une simple entrée dans le fichier de log correspondant de syslogd, toute tentative d'​accès à un service même si aucun service n'est à l'​écoute sur le port de la tentative d'​accès. Ceci peut nous permettre dans un environnement securisé, allié de préference avec un outil d'​analyse de log tel que logcheck ou ASAX, de réperer des tentatives de network mapping même si nous avons un minimum de services disponibles et qui plus est un firewall. Cependant je ferai remarquer 2 difficultés : tout d'​abord log_in_vain ne logue en réalité que les paquets avec un flags SYN, ce qui n'est pas assez pour réellement détecter un scan. Et d'​autre part, dans un environnement "​chaud"​ comme une machine servant de passerelle ou un serveur au sein d'une DMZ, l'​utilisation de log_in_vain peu entrainer une quantité de log assez impressionante et capable d'​occuper un analyste ou un administrateur sans outils d'​analyse pendant des semaines. Mais au sein d'un réseau d'ores et deja securisé ou sur une machine critique, cette capacité de log peut etre intéressante. Pour l'​activer il vous suffit de saisir:
 +<​code>​
 +huyhuy# sysctl -w net.inet.tcp.log_in_vain=1
 +huyhuy# sysctl -w net.inet.udp.log_in_vain=1
 +</​code>​
 +Les astuces suivantes sont intéressantes si votre machine doit servir de passerelle, de filtre ou de load balancer pour d'​autres machines. La commande suivante vous offre la possibilité d'​activer le forwarding IP et donc de transformer notre machine en gateway ce qui s'​avérera utile pour le partage de connexion ou le deploiement d'une jail
 +<​code>​
 +huyhuy# sysctl -w net.inet.ip.forwarding=1
 +</​code>​
 +L'​entrée suivante est particulierement utile dans le cadre d'un serveur qui necessité une haute disponibilité ou une grande fiabilité. En effet, nous allons apporter à notre machine le support des extensions TCP pour hautes performances. Ces extensions sont decrites dans la RFC 1323 que je vous recommande d'​étudier. Elles sont constituées de 3 extensions. La première est le champ Window Scale qui est un facteur appliqué au champ Window Size et utile
 +sur les Large Fat Network (LFN) afin d'​optimiser le flux de donnees sur ces grands reseaux et d'​apporter un meilleur controle en multipliant la Window Size. Nous trouvons ensuite 2 options extrêmement utiles dans le cas d'​utilisation de load balancing en fournissant des informations aux algorithmes de repartition de charge. Le Round-Trip Time Mesurement (RTTM) et le Protection Against Wrapper Sequence Numbers (PAWS) se basent tous les 2 sur l'​adjonction d'une option de timestamp aux segments TCP. Avec de simples verifications de timestamp on peut ainsi calculer le temps d'​aller retour entre 2 ACK et ainsi optimiser le flux ou modifier la route. On peut egalement se prevenir du hijacking, de l'​overlapping et surtout du rejeu en effectuant une double vérification sur le numero de sequence et le timestamp. Ces options viennent s'​ajouter à l'​option SackOK permettant à eux tous de ne renvoyer que les paquets effectivement perdus et ainsi d'​ameliorer la fiabilité et les performances d'une connexion. L'​unique bemol est que ces options ne fonctionnent bien sur qu'​entre des machines supportant toutes les 2 ces options de manière similaire, or ces options ne semblent pas être très utilisées - notez que la branche 4.4 supporte la RFC 1323 par défaut - et enfin vous pourriez risquer des désagrements face à certains firewalls ou plugins de normalisation de trafic s'ils ne reconnaissent pas ces options. Cependant nous décidons de l'​aborder dans cet article afin de faciliter sa diffusion et nous l'​appliquons à notre système par acquis de conscience ! Et nous verifions en même temps le support de l'​option Selective Acknowledgment definie dans la RFC 2018 tout en augmentant la taille par défaut de notre window size et enfin nous activons l'​implémentation de la RFC 1948 appliquant la recommendation de Steve Bellovin
 +sur la génération aléatoire d'ISN selon le schéma ISN = M + F(localhost,​localport,​remotehost,​remoteport) où M est un timestamp.
 +
 +Pour cela, il vous suffit d'​effectuer les commandes suivantes :
 +<​code>​
 +huyhuy# sysctl -w net.inet.tcp.rfc1323=1
 +huyhuy# sysctl -w net.inet.tcp.sack=1
 +huyhuy# sysctl -w net.inet.tcp.sendspace=32768
 +huyhuy# sysctl -w net.inet.tcp.recvspace=32768
 +huyhuy# sysctl -w net.inet.tcp.strict_rfc1948=1
 +</​code>​
 +Nous décidons maintenant de nous proteger face a certaines tentatives de DoS ainsi que de diverses techniques de network mapping. Les lignes suivantes nous permettant ainsi de modifier le TTL par defaut utilisé dans l'OS
 +fingerprinting,​ de ne pas repondre au icmp mask reply permettant une cartographie reseau, mais aussi de ne pas repondre aux message icmp broadcast très souvent source de smurf ou DoS par amplification,​ de mettre la limite
 +maximale de paquets icmp en réponse à 300 par seconde, d'​augmenter la taille de la queue de connexion afin d'​eviter le DoS par ressource starvation tels que le SYN Flood ou le Naptha tout en augmentant le nombre maximal de socket (2 fois le maximum de connexion environ) et en verifiant si une connexion est toujours reellement active et non pas conserver dans un etat artificiel suite a un SYN Flood ou Naptha, et enfin le blackhole consiste à empêcher votre systeme d'etre scanné en ne repondant pas par un RST à chaque segment ainsi qu'a ne pas répondre par un ICMP port unreachable aux segment UDP, envoye sur un port fermé et ainsi transformer votre systeme en "trou noir" :
 +<​code>​
 +huyhuy# sysctl -w net.inet.ip.ttl=128
 +huyhuy# sysctl -w net.inet.icmp.maskrepl=0
 +huyhuy# sysctl -w net.inet.icmp.bmcastecho=0
 +huyhuy# sysctl -w net.inet.icmp.icmplim=300
 +huyhuy# sysctl -w kern.ipc.somaxconn=4096
 +huyhuy# sysctl -w kern.ipc.maxsockets=8212
 +huyhuy# sysctl -w net.inet.tcp.always_keepalive=1
 +huyhuy# sysctl -w net.inet.tcp.blackhole=2
 +huyhuy# sysctl -w net.inet.udp.blackhole=1
 +</​code>​
 +Toujours dans les protections contre les DoS mais cette fois-ci cote ressource plutot que reseau, les 2 entrees suivantes de la MIB vont nous permettent de limiter les ressources a la disposition d'un processus et d'​eviter ainsi le ressource starvation qu'​entrainent plusieurs DoS tels que les SYN Flood et Napthas. Notez enfin que le nombre de fichiers par processus inclut également les sockets et IPC :
 +<​code>​
 +huyhuy# sysctl -w kern.maxprocperuid=128
 +huyhuy# sysctl -w kern.maxfilesperproc=128
 +huyhuy# sysctl -w kern.maxfiles=65536
 +</​code>​
 +Par ailleurs nous possédons également quelques astuces afin d'​éviter les tentatives de cache poisoning en accélérant le temps de rafraichissement de la table de routage.
 +<​code>​
 +huyhuy# sysctl -w net.inet.ip.rtexpire=60
 +huyhuy# sysctl -w net.inet.ip.rtminexpire=10
 +</​code>​
 +Finissons avec quelques modifications liees au systeme a modifier :
 +<​code>​
 +huyhuy# sysctl -w vfs.vmiodirenable=1
 +huyhuy# sysctl -w kern.coredump=1
 +huyhuy# sysctl -w kern.corefile=%N.sexfault
 +huyhuy# sysctl -w kern.ps_showallprocs=0
 +</​code>​
 +La première option permet d'​améliorer le traitement notamment sur des larges volumes de fichiers. Il concerne les fichiers unix qui seront cachés dans le buffer cache plutôt que directement sur le disque exploitant ainsi pleinement
 +la memoire virtuelle FreeBSD par ailleurs désormais très performante. Ensuite nous decidons d'​activer l'​application savecore qui permet de conserver une trace du core dump associe a un kernel permettant son etude apres un crash
 +par exemple afin d'en determiner les causes - par exemple un buffer overflow. En tout dernier lieu, nous faisons en sorte que les utilisateurs ne voient que leurs propres processus et que seul le root puisse voir l'​ensemble.
 +
 +Nous disposons également de paramètre pour ipfw notamment pour les options keep-state de ipfw impliquant la création automatique d'une state table permettant le suivi des flux pour le filtrage de paquets. La state table et les règles ipfw qui vont avec, créent pour chaque paquet que '​match'​ une règle une nouvelle règle dynamique permettant de suivre et autoriser la connexion. Pour ce faire, ipfw utilise notamment pour la couche protocol un mécanisme de lifetime qui permet de conserver la règle dynamique active en attente d'un nouveau paquet qui relancera la décrémentation de ce lifetime. Si le lifetime arrive à zero sans nouveau paquet, alors la règle dynamique disparaît et les paquets sont refusés. Les entrées sysctl suivantes vous permettent de spécifier la taille de la table hashage destinée aux règles dynamiques de votre ruleset ceci ne fonctionnant qu'​après avoir flushé. Enfin, la dernière entrée permet d'​augmenter encore la verbosité d'ipfw en ajoutant à l'​affichage des champs DiffServ, IP ID et TTL ; les champs ack number, sequence number et TCP flags.
 +Voir http://​people.freebsd.org/​~cjc/​ipfw_verbose_stable.patch.
 +<​code>​
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_ack_lifetime=300
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_syn_lifetime=20
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_fin_lifetime=20
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_rst_lifetime=5
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_short_lifetime=30
 +huyhuy# sysctl -w net.inet.ip.fw.dyn_buckets=256
 +huyhuy# sysctl -w net.inet.ip.fw.curr_dyn_buckets=256
 +huyhuy# sysctl -w net.inet.ip.fw.verbose=2
 +</​code>​
 +Notez que nous disposons également de quelques fonctionnalités configurables par l'​intermédiaire du loader. Si vous disposez d'un disque IDE, la commande suivante permet d'​activier le cache en écriture
 +<​code>​
 +huyhuy# loader set hw.ata.wc=1
 +</​code>​
 +Si vous disposez par ailleurs de disques IBM DPTA ou DTLA, vous pouvez utiliser à la place l'​entrée hw.ata.tags mais à vos risques et périls puisqu'​elle est encore experimentale. Ces modifications doivent être répercutées sur
 +/​boot/​loader.conf. De la même manière, les options sysctl voudrez retrouver à chaque demarrage, vous devez reporter chaque entrées dans un fichier /​etc/​sysctl.conf sous la forme '​entrée=parametre'​.
 +
 +Ci-dessous notre sysctl.conf final.
 +<​code>​
 +------------------------------------- SNiP ------------------------------------
 +net.inet.tcp.rfc1323=1
 +net.inet.tcp.log_in_vain=1
 +net.inet.tcp.sack=1
 +net.inet.tcp.sendspace=32768
 +net.inet.tcp.recvspace=32768
 +net.inet.tcp.strict_rfc1948=1
 +net.inet.tcp.always_keepalive=1
 +net.inet.tcp.blackhole=2
 +net.inet.icmp.maskrepl=0
 +net.inet.icmp.bmcastecho=0
 +net.inet.icmp.icmplim=300
 +net.inet.udp.blackhole=1
 +net.inet.udp.log_in_vain=1
 +net.inet.ip.ttl=128
 +net.inet.ip.forwarding=1
 +net.inet.ip.fw.dyn_ack_lifetime=300
 +net.inet.ip.fw.dyn_syn_lifetime==20
 +net.inet.ip.fw.dyn_fin_lifetime=20
 +net.inet.ip.fw.dyn_rst_lifetime=5
 +net.inet.ip.fw.dyn_buckets=256
 +net.inet.ip.fw.curr_dyn_buckets=256
 +net.inet.ip.fw.verbose=2
 +net.inet.ip.rtexpire=60
 +net.inet.ip.rtminexpire=10
 +net.inet.ipsec.esp_trans_deflev=1
 +net.inet.ipsec.esp_net_deflev=1
 +net.inet.ipsec.ah_trans_deflev=1
 +net.inet.ipsec.ah_net_deflev=1
 +net.inet.ipsec.def_policy=0
 +net.inet.ipsec.ecn=1
 +vfs.vmiodirenable=1
 +kern.coredump=1
 +kern.corefile=%N.sexfault
 +kern.ps_showallprocs=0
 +kern.maxprocperuid=128
 +kern.maxfilesperproc=128
 +kern.maxfiles=65536
 +kern.ipc.maxsockets=8212
 +kern.ipc.somaxconn=4096
 +kern.jail.set_hostname_allowed=1
 +kern.jail.socket_unixiproute_only=1
 +kern.jail.sysvipc_allowed=0
 +compat.linux.osname=FreeBSD
 +compat.linux.osrelease=4.4-STABLE
 +------------------------------------- SNiP ------------------------------------
 +</​code>​
 +-- eberkut
 +
 +------------------------------------- UPDATE ------------------------------------
 +<​code>​
 +kern.ps_showallprocs=0 ​
 +sysctl: unknown oid '​kern.ps.showallprocs'​
 +=> ne semble pas exister sous FreeBSD (5.4 / 6.1)
 +
 +kern.ipc.maxsockets=8212
 +kern.ipc.maxsockets:​ Invalid argument
 +  cela fonctionne avec les valeurs : 16424 / 32768
 +
 +MODIFICATION FreeBSD version 6.1
 +net.inet.tcp.sack=1 ​ ==> net.inet.tcp.sack.enable=1
 +net.inet.tcp.inflight_enable=1 ​ ==> net.inet.tcp.inflight.enable=1 (une "​."​ au lieu de "​_"​) ​
 +net.inet.tcp.inflight_min=6144 ​ devient net.inet.tcp.inflight.min=6144 (une "​."​ au lieu de "​_"​) ​
 +
 +</​code>​
 +Kzper
freebsd/sysctl_avance.txt · Last modified: 2010/01/12 13:29 (external edit)