Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colinux/1080649 to your computer and use it in GitHub Desktop.
Save colinux/1080649 to your computer and use it in GitHub Desktop.

Big warning: tout n'a pas été testé pour squeeze et ni revérifié !

Vérifier que le partitionnement convient

Avant de se lancer, rien de tel que revoir le partitionnement, car après, c'est un peu plus dur.

Changer le mot de passe root

$ passwd

Ouvrir une nouvelle fenêtre SSH et tester le nouveau mot de passe.

Reconfiguration des locales (pour mettre en UTF8 par défaut)

$ dpkg-reconfigure locales

Configuration de debconf

Par défaut debconf est en mode élevé pour le niveau de configuration des paquets installés. Sur un serveur important, il est nécessaire de passer en mode intermédiare.

$ dpkg-reconfigure debconf

Configuration du fuseau horaire

$ dpkg-reconfigure tzdata

Mise à jour des paquets via aptitude

$ aptitude update && aptitude safe-upgrade

Éventuellement, on désactive l'install automatique des paquets recommandés dans /root/.aptitude/config

aptitude "";
aptitude::Suggests-Important "false";
aptitude::Recommends-Important "false";

Dans la foulée, on installe apticron pour être notifié de la présence de mises à jour

$ aptitude install apticron

Note: le paramétrage de postfix pour l'envoi des mails sera fait plus tard

Install de git, versionnage d'/etc avec etckeeper

$ aptitude install git etckeeper
$ vi /etc/etckeeper/etckeeper.conf
AVOID_COMMIT_BEFORE_INSTALL=1
$ sudo git config --global user.name "Your name"
$ sudo git config --global user.email your@email.com
$ sudo git commit -a -m "Configuration d'etckeeper"

Il sera configuré pour faire automatiquement un commit par jour s'il y a des changements effectués, et interdira la mise à jour du système tant qu'un commit n'a pas été fait manuellement.

À partir de maintenant, il faudra régulièrement commiter pendant la suite de l'installation !

Sécurisation d'SSH

On modifie certaines options

$ vi /etc/ssh/sshd_config
Port 19849 # un numero de port aléatoire à 5 chiffres
LoginGraceTime 600 # eventuellement augmente la durée de ban après des tentatives de connexions échouées
PermitRootLogin no # desactive login root par ssh; *without-password* l'autorise mais uniquement par clé
X11Forwading no # interdit le forwading d'applications graphiques
PasswordAuthentication no # si on peut se passer d'authentifications par mot de passe, on l'interdit

En local, on adapte son .ssh/config avec le bon port, bon user, bon host...

Sur le serveur on créé le répertoire .ssh dans son home et on y copie sa clé publique pour s'identifier avec

$ mkdir -m 0700 ~/.ssh
$ vi ~/.ssh/authorized\_keys # on dépose sa clé privée (id\_rsa.pub)
$ chown -R <user>:<user> .ssh
$ chmod 0600 ~/.ssh/authorized\_keys

On relance ssh, puis sans se déconnecter, on reteste la connexion avec le nouveau port et la clé publique

$ /etc/init.d/ssh reload

Création d'un firewall

On peut utiliser http://git.evolix.org/?p=evolinux/minifirewall.git;a=summary

$ cd /root
$ git clone git://git.evolix.org/git/evolinux/minifirewall.git
$ chmod 700 ./minifirewall/minifirewall

... il faut paramétrer firewall.rc correctement, puis on le teste, en vérifiant qu'on a toujours accès à la machine avec une autre connexion ssh par exemple.

$ ./minifirewall start && sleep 60s && ./minifirewall stop

Par sécurité, les règles seront enlevées au bout d'une minute, permettant de modifier la config en cas de problème. Retester jusqu'à que tout soit ok (résolutions DNS, aptitude update...)

Une fois que tout est ok, on l'installe définitivement $ mv /root/minifirewall/firewall.rc /etc/ $ mv /root/minifirewall/minifirewall /etc/init.d/ $ update-rc.d minifirewall defaults $ /etc/init.d/minifirewall start

S'il y a des domaines et pas directement des ips dans la configuration, il faut rafraichir les dns régulièrement par cron. $ # Mettre dans /etc/cron.daily/minifirewall : #!/bin/sh # Reload the firewall to eventually update ips resolutions

FIREWALL=/etc/init.d/minifirewall

if [ -x "$FIREWALL" ] ; then
  $FIREWALL restart
fi

exit 0

Mise en place d'une alerte à chaque boot

Créer /etc/init.d/boot-alert en remplacement éventuellement le sujet et destinataire de l'email:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          boot-alert
# Required-Start:    $time mail-transport-agent
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Boot alert
# Description:       Send an alert each time the system boots or reboots
#
### END INIT INFO

# Author: Colin Darie <colindarie@gmail.com>
#
# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
DESC="Boot alert"
NAME="boot-alert"
SCRIPTNAME=/etc/init.d/$NAME

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

case "$1" in
  start)
    [ "$VERBOSE" != no ] && log_daemon_msg "Sending boot alert"
    date | mail -s "boot / reboot alert" root
    ;;
  *)
  echo "Usage: $SCRIPTNAME {start}" >&2
  exit 3
  ;;
  esac


  exit 0

Et l'activer

$ update-rc.d boot-alert start S 2 3 4 5

Création d'un user administrateur non "root"

$ adduser new_user

Le programe demande d'abord le mot de passe, puis le nom complet, …

Installation de sudo

$ aptitude install sudo

Configuration des droits, 2 possibilités

Alternative 1: on autorise tout, avec restriction éventuelle à certaines commandes

$ aptitude install sudo
$ adduser <user> sudo

On protège l'utilisateur de commandes accidentelles dans une mauvaise console qui ne pourront pas être exécutées par sudo, mais directement sous root

$ visudo # et ajouter:

Cmnd_Alias    DANGEROUS = /usr/sbin/shutdown, /usr/sbin/reboot

# Juste au-dessus de `includedir`, et sous `%sudo`...
<user>  ALL = !DANGEROUS

Note: on peut interdire d'autres commandes avec des jokers, comme /etc/init.d/\*

Alternative 2: on utilise une whitelist de commandes, le reste ne sera pas possible

$ visudo # et ajouter:

Cmnd_Alias    MAINTENANCE = /usr/bin/aptitude
Cmnd_Alias    EDITOR = /usr/bin/vi, /usr/bin/vim, /usr/bin/nano

# Juste au-dessus de `includedir`, et sous `%sudo`...
<user>  ALL = MAINTEANCE, EDITOR

Voir man 5 sudoers pour toutes les possibilités.

On met l'administrateur dans quelques groupes

$ adduser <user> admin
$ adduser <user> adm

Pour la suite, on peut quitter root et se reconnecter en tant avec cet utilisateur

Install de vim (ou autre éditeur favori)

Seul le vim minimaliste est installé par défaut, on installe le complet

$ sudo aptitude install vim

On le passe en éditeur par défaut, on force vi => vim

$ sudo update-alternatives --config editor
$ sudo update-alternatives --config vi

On configure quelques options globales en décommentant certaines proposées

$ sudo vi /etc/vim/vimrc
syntax on
set background=dark
set showcmd
set showmatch
set ignorecase
set smartcase
set incsearch
set autowrite
set hidden

et on créé ~/.vimrc set number filetype on set ruler set nowrap

Pour avoir la même config pour l'utilisateur root:

$ sudo ln -s ~/.vimrc /root/

Configuration du shell (avec zsh ici)

On installe zsh, on créé un prompt personnalisé, quelques options et alias

$ sudo aptitude install zsh
$ mkdir .zsh
$ vim .zshrc # ajouter éventuellement les options de complétions

# Initialize colors
autoload -U colors
colors

# autocompletion cache
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache

# Set the prompt: root en rouge, user en vert, path en jaune
# prefix éventuel au nom de machine en magenta
PREFIX_HOST="%{$fg[magenta]%}monprefix"
if [[ "$EUID" = "0" ]] || [[ "$USER" = 'root' ]]
then
  PROMPT="%B%{$fg[red]%}%n@${PREFIX_HOST}%m%:%{$fg[yellow]%}%~%{$fg[default]%}%b "
else
  PROMPT="%B%{$fg[green]%}%n@${PREFIX_HOST}%m:%{$fg[yellow]%}%~%{$fg[default]%}%b "
fi

# aliases
alias ls='ls --color=auto'
alias ll='ls -al'
alias grep='grep --color=auto -n'

On change le shell pour /bin/zsh

$ chsh

Si on veut la même config pour l'utilisateur root :

$ sudo mkdir /root/.zsh
$ sudo ln -s ~/.zshrc /root/
$ sudo chsh

Install de postfix

Pour pouvoir a minima envoyer des mails de maintenance à l'extérieur, il faut un serveur de mail, comme postfix. Ceci n'est pas prévu pour fonctionner avec un réel serveur de mails qui supporte des connexions entrantes etc... Toute cette partie est largement inspirée de ce que propose evolix http://trac.evolix.net/infogerance/wiki/HowtoMail/Postfix

$ sudo aptitude install postfix

On choisit Pas de configuration lors de l'installation pour permettre une conf minimale manuelle.

On édite les aliases et reconstruit sa db pour postfix

$ sudo vi /etc/aliases
# See man 5 aliases for format
postmaster:    root

root: <user>
abuse: root
noc: root
security: root

MAILER-DAEMON: postmaster

<user>: youreal@email.com

daemon: /dev/null
bin: /dev/null
sys: /dev/null

On configure postfix:

$ sudo vi /etc/postfix/main.cf

# minimal configuration: we only want to send maintenance mails

command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix
myhostname = <real-hostname-fqdn-qualified>
alias_maps = hash:/etc/aliases

mydestination = $myhostname <machine-name> localhost
localhost.<domain.tld> = 127.0.0.1 ip.of.ser.ver

mynetworks = 127.0.0.0/8,[::1]/128

smtpd_client_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject
smtpd_helo_restrictions = reject_invalid_hostname

smtpd_recipient_restrictions =
  reject_invalid_hostname,
  reject_non_fqdn_hostname,
  reject_non_fqdn_sender,
  reject_non_fqdn_recipient,
  reject_unknown_sender_domain,
  reject_unknown_recipient_domain,
  reject_unauth_pipelining,
  permit_mynetworks,
  permit_sasl_authenticated,
  reject

smtpd_helo_required = yes

On démarre postfix, et on vérifie qu'un mail nous arrive bien avec sendmail

$ sudo /etc/init.d/postfix start
$ echo "Ceci est un test d'envoi d'email" | mail -s "Test email" your@email.com

L'email devrait arriver à votre réelle adresse email, adresse définie dans les aliases.

Bind doit être chrooté (non testé avec debian squeeze)

On utilise l'excellent script de Grégory Colpart qui va bien nous faciliter le travail :

$ mkdir -p /usr/local/src
$ cd /usr/local/src
$ git clone git://git.evolix.org/git/evolinux/chroot-bind.git
$ cp /usr/local/src/chroot-bind/chroot-bind.sh /usr/local/bin/chroot-bind.sh
$ chmod 744 /usr/local/bin/chroot-bind.sh
$ /usr/local/bin/chroot-bind.sh

Il faut aussi indiquer à *Bind* qu'il doit démarer dans un chroot, ça se fait dans */etc/default/bind9* :

OPTIONS="-u bind -t /var/chroot-bind"

Puis on (re)démarre *Bind*

$ /etc/init.d/bind9 (re)start

**Attention** : après chaque mise à jour de *Bind* ou d'une dépendance de *Bind*, il faut penser à relancer ce script.

Installation de MySQL

$ aptitude install mysql-server mysql-client libmysqlclient15-dev

On met les nouvelles bases en UTF8 par défaut dans le fichier /etc/mysql/my.cnf

[mysqld] (...) default-character-set=utf8 (...)

On installe aussi mysqltuner.pl pour aider à optimiser la config

$ cd /usr/local/bin $ wget http://mysqltuner.pl $ chmod 755 mysqltuner.pl

Installation de Apache

$ aptitude install apache2 apache2-mpm-prefork apache2-prefork-dev $ aptitude install phpmyadmin

On active quelques modules :

$ a2enmod ssl rewrite include

On active le site default-ssl :

$ a2ensite default-ssl

On force le renvoi vers https dans sites-available/default :

RewriteEngine On RewriteCond %{HTTPS} off RewriteCond %{REQUEST_URI} !^/server-status RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} RewriteLog "/var/log/apache2/rewrite.log" RewriteLogLevel 2

On relance Apache :

$ /etc/init.d/apache2 restart

Installation de PHP5

Si on a besoin de plus que ce que l'install de phpMyAdmin installe par dépendance, on peut faire

$ aptitude install php-pear php5 php5-common php5-curl php5-dev \
php5-gd php5-idn php5-imagick php5-imap php5-json php5-mcrypt \
php5-memcache php5-mhash php5-ming php5-mysql php5-ps php5-pspell \
php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Éventuellement on modifie la taille maximale d’upload via PHP (16Mo par exemple), dans le fichier /etc/php5/apache2/php.ini

Installation de Ruby et Rubygems

$ aptitude install ruby-full rake

$ cd /usr/local/src/
$ wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz
$ tar xzf rubygems-1.3.6.tgz
$ cd rubygems-1.3.6
$ ruby setup.rb
$ cd /usr/bin
$ ln -s gem1.8 gem

On installe Gemcutter pour faciliter l'installation de gems supplémentaires

$ gem install gemcutter

Pour *bz2* :

$ aptitude install libbz2-dev

Pour *curb*

$ aptitude install curl libcurl3-dev

Pour *libxml-ruby*, *roxml* et *nokogiri*

$ aptitude install libxml2-dev libexpat1-dev libxslt-dev

Pour *Rmagick*

$ aptitude install imagemagick libmagick9 libmagick9-dev

Maintenant on peut installer les gems

$ gem install --no-ri --no-rdoc rails passenger activewarehouse-etl \
  adapter_extensions amatch authlogic bz2 calendar_date_select compass \
  compass-960-plugin chronic colored compass compass-960-plugin curb daemons \
  fastercsv fastthread g gemcutter geokit ghazel-daemons git_remote_branch \
  haml handsoap hashie hoe hpricot json_pure libxml-ruby mime-types mysql \
  net-scp net-ssh nokogiri paperclip rest-client rmagick roxml \
  rspec rspec-rails ruby-growl rubyzip sprockets syntax factory_girl \
  vestal_versions whenever will_paginate

Install de Phusion Passenger

  $ passenger-install-apache2-module

  On colle bien la config pour Passenger dans */etc/apache/conf.d/passenger.conf*

  On peut y ajouter des éléments de config mais il faut les vérifier et ajuster selon les besoins :

  PassengerMaxPoolSize 35
  PassengerMaxInstancesPerApp 20
  PassengerUseGlobalQueue on
  PassengerDefaultUser deploy

RailsFrameworkSpawnerIdleTime 0

  RailsAppSpawnerIdleTime 60

Install d'outils divers

  $ aptitude install iftop htop apachetop dnstop
  $ aptitude install tree
  $ aptitude install ntp
  $ aptitude install apticron
  $ aptitude install denyhosts
  $ aptitude install webalizer

Install de Munin

  $ aptitude install munin munin-node libwww-perl
  $ cd /etc/munin/plugins
  $ ln -s /usr/share/munin/plugins/apache_accesses ./
  $ ln -s /usr/share/munin/plugins/apache_processes ./
  $ ln -s /usr/share/munin/plugins/apache_volume ./
  $ ln -s /usr/share/munin/plugins/apt_all ./
  $ ln -s /usr/share/munin/plugins/uptime ./
  $ ln -s /usr/share/munin/plugins/ntp_offset ./
  $ invoke-rc.d munin-node restart

  Il faut penser à activer le *mod_status* (en mode étendu) dans Apache. Je l'ai fait en créant un fichier */etc/apache2/conf.d/status* dans lequel j'ai mis :

  <IfModule mod_status.c>
  ExtendedStatus On
  <Location /server-status>
  SetHandler server-status
  Order Deny,Allow
  Deny from all
  Allow from 127.0.0.1
  </Location>
  </IfModule>

Install de Monit

  $ aptitude install monit

  Monit n'est pas activé par défaut, il faut mettre "startup=1" dans le fichier */etc/default/monit*

Install de BackupNinja

  $ aptitude install backupninja

  Il faut cependant créer ses stratégies de backup, rien n'est fourni de fonctionnel par défaut, juste des exemples.

  À la suite, j'ai mis 3 stratégies que j'utilise :

  * **05-system.sys** : sauvegarde du hardware en général, des disques en particulier et des paquets
  * **10-alldatabases.mysql** : un dump de toutes les bases hébergées
  * **80-general.rdiff** : une sauvegarde sélective par rdiff-backup

  NB: les fichiers mis en exemple ici n'ont plus leurs commentaires d'explication. On peut retrouver les exemples d'origine dans */usr/share/doc/backupninja/examples/*.

Création d'un user deploy pour les applis Rails

$ adduser deploy --home /var/apps/
databases = all
backupdir = /var/backups/mysql
hotcopy = no
sqldump = yes
compress = yes
when = everyday at 06:00
when = everyday at 20:00
[source]
label = localhost
type = local
keep = 30
include = /var/spool/
include = /var/backups
include = /etc
include = /root
include = /home
include = /usr/local/bin
include = /usr/local/sbin
include = /var/backups
include = /var/chroot-bind
include = /var/lib
include = /var/log
exclude = /home/backups
[dest]
type = local
directory = /home/backups
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment