/bin/ip

La commande ip est une commande très importante car elle permet de manipuler la totalité de la pile réseau IP du noyau Linux. Avec cette seule commande, il est possible de configurer les adresses IPv4 et IPv6, la table ARP, les routes, et bien d'autres choses.

Tout comme la commande tc qui gère les disciplines de file (pour le QoS), la commande ip est suivie de mots-clés permettant de choisir le type d'action à effectuer. Ces mots-clés ne sont pas précédés d'un tiret.

Voici par exemple la façon d'ajouter une route avec la commande ip:

# ip route add 192.168.125.0/24 via 192.168.0.1

Le premier mot-clé: "route" est ce qu'on appelle l'objet de la commande. L'objet sélectionne un mode de fonctionnement particulier, ici l'objet "route" permet de manipuler les tables de routage. Il faut préciser un objet parmi les suivants: link, addr, route, rule, neigh, tunnel, maddr, mroute, monitor, l'utilité de chacun des objets est détaillée par la suite.

Après l'objet viennent les commandes spécifiques à celui-ci. La plupart des objets proposent les commandes add, delete et show pour ajouter, supprimer et afficher des informations relatives à l'objet.

Il est facile d'obtenir de l'aide sur les objets et commandes disponibles en utilisant le mot-clé "help" (qui peut aussi être utilisé comme objet). Celle-ci détaille la syntaxe. Grâce à l'aide du mot-clé help, il suffit de connaître le fonctionnement d'un objet pour savoir l'utiliser, il n'est donc pas nécessaire de retenir tous les mots-clés de chaque objet.

L'option link permet d'obtenir des informations les interfaces réseau et de manipuler leur configuration.

La commande ip link permet de manipuler de nombreuses propriétés d'une interface réseau (adresse, arp, multicast, etc). Plutôt que de tout retenir, le plus simple et de taper ip link help pour avoir l'ensemble des commandes:

$ ip link help
Usage: ip link set DEVICE { up | down |
                             arp { on | off } |
                             dynamic { on | off } |
                             multicast { on | off } |
                             allmulticast { on | off } |
                             promisc { on | off } |
                             trailers { on | off } |
                             txqueuelen PACKETS |
                             name NEWNAME |
                             address LLADDR | broadcast LLADDR |
                             mtu MTU }
       ip link show [ DEVICE ]
# ip link set wifi0 arp off

Lorsqu'on utilise l'option link sans commande ou avec la commande show, on affiche les informations de l'ensemble des interfaces:

$ ip link
1: lo:  mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:fa:35 brd ff:ff:ff:ff:ff:ff
3: eth1:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:11:a5 brd ff:ff:ff:ff:ff:ff
4: eth2:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:11:1a:d2:31:c3 brd ff:ff:ff:ff:ff:ff
5: wifi0:  mtu 2312 qdisc noop qlen 1

ip address

L'option address permet de manipuler une ou plusieurs adresses réseau pour une interface. Les adresses peuvent être celles de IPv4 ou d'IPv6. Avec ip address il est possible d'afficher les adresses et des informations liées, d'ajouter une nouvelle adresse et de supprimer une adresse existante.

A nouveau, il est inutile de retenir toutes les options disponibles avec la commande car il suffit de taper ip address help pour avoir le détail des options:

$ ip address help
Usage: ip addr {add|del} IFADDR dev STRING
       ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]
                            [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]
IFADDR := PREFIX | ADDR peer PREFIX
          [ broadcast ADDR ] [ anycast ADDR ]
          [ label STRING ] [ scope SCOPE-ID ]
SCOPE-ID := [ host | link | global | NUMBER ]
FLAG-LIST := [ FLAG-LIST ] FLAG
FLAG  := [ permanent | dynamic | secondary | primary |
           tentative | deprecated ]

Pour ajouter une adresse IP, il suffit donc d'utiliser add tandis qu'il faut utiliser delete pour en supprimer une :

$ ip address show dev eth0
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:21:30 brd ff:ff:ff:ff:ff:ff
# ip address add 192.168.55.1/24 dev eth0
$ ip address show dev eth0
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:21:30 brd ff:ff:ff:ff:ff:ff
    inet 192.168.55.1/24 scope global eth0
# ip address delete 192.168.55.1/24 dev eth0
$ ip address show dev eth0
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:21:30 brd ff:ff:ff:ff:ff:ff

Utilisée sans option, la commande affiche les informations sur toutes les interfaces:

$ ip address
1: lo:  mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:21:30 brd ff:ff:ff:ff:ff:ff
    inet 169.254.4.13/16 brd 169.254.255.255 scope link eth0:avahi
3: eth1:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:15:f2:35:3a:86 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.3/24 brd 192.168.0.255 scope global eth1
    inet6 fe80::215:f2ff:fe35:3a86/64 scope link 
       valid_lft forever preferred_lft forever
4: eth2:  mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:07:85:92:31:c3 brd ff:ff:ff:ff:ff:ff
5: wifi0:  mtu 2312 qdisc noop qlen 100
    link/ieee802.11 00:07:85:92:31:c3 brd ff:ff:ff:ff:ff:ff

ip neighbour

Le neighbour ou voisinage est un concept important dans l'implémentation IP du noyau Linux. Le noyau possède des structures neighbour permettant de représenter les hôtes directement accessibles sur le réseau. Une structure neighbour permet de retrouver l'adresse physique d'un hôte à partir de son adresse IP car elle contient les deux valeurs.

Dans l'userspace avec IPv4, les tables de voisinages du noyau sont connues sous un aute nom: les tables ARP. Les commandes utilisées pour manipuler les tables de voisinage du noyau ont donc les mêmes fonctionnalités que les commandes utilisées pour manipuler les tables ARP. Vis-à-vis de arp, la notion de voisinage est plus large car elle couvre aussi bien IPv4 que IPv6.

Comme pour les autres commandes, le moyen de le plus facile d'accéder aux options et d'utiliser l'option help qui liste les possibilités. On retrouve bien sûr avec neighbour la même syntaxe que pour les autres commandes:

ip neighbour help
Usage: ip neigh { add | del | change | replace } { ADDR [ lladdr LLADDR ]
          [ nud { permanent | noarp | stale | reachable } ]
          | proxy ADDR } [ dev DEV ]
       ip neigh {show|flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]

Le voisinage établit un lien entre une adresse physique et une adresse logique (ou adresse réseau). On retrouve donc deux adresses pour les commandes add, del, change et replace. L'adresse notée ADDR fait référence à l'adresse IP, que celle-ci soit en IPv4 ou IPv6. La seconde adresse, LLADDR fait référence à une adresse physique, le LL signifiant "link layer" distinguant la couche "liaison de données" du modèle OSI (couche 2).

On peut voir que la commande affiche les mêmes informations que arp si on utilise IPv4, les deux commandes affichent les structures neighbour du noyau:

$ ip neighbour show
192.168.0.1 dev eth1 lladdr 00:d0:09:eb:42:c2 DELAY
$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.0.1              ether   00:D0:09:EB:42:C2   C                     eth1

L'ajout ou la suppression d'adresse est de même visible dans arp:

# ip neighbour add 192.168.0.22 lladdr 00:50:27:a5:34:12 nud permanent dev eth1
$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.0.22             ether   00:50:27:A5:34:12   CM                    eth1
192.168.0.1              ether   00:D0:09:EB:42:C2   C                     eth1
# ip neighbour del 192.168.0.22 dev eth1
$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.0.22                     (incomplet)                               eth1
192.168.0.1              ether   00:D0:09:EB:42:C2   C                     eth1

ip route

La commande ip route permet de manipuler les tables de routage du noyau. Cette commande permet les mêmes manipulations que la commande "route" mais elle permet aussi de faire beaucoup plus en manipulant plusieurs tables de routage. Le choix de la table de routage pour un paquet se fait à l'aide de la politique de routage, qui est définie à l'aide de la commande ip rule décrite plus loin.

Le noyau gère donc plusieurs tables de routage, celles-ci sont numérotées de 1 à 255. La table 255 est particulière, elle gère le trafic local et les adresses de diffusion, elle est gérée par le noyau et ne doit habituellement pas être modifiée.

Les commandes de ip route proposent toujours de spécifier la table de routage à l'aide d'une option table TABLE_IDTABLE_ID est un identificateur de table:

$ ip route show table 254
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.3 
169.254.0.0/16 dev eth0  proto kernel  scope link  src 169.254.4.13 
169.254.0.0/16 dev eth1  scope link  metric 1000 
default via 192.168.0.1 dev eth1 
default dev eth0  scope link  metric 1000

Il est possible de donner un nom à une table pour éviter de manipuler les numéros, le fichier /etc/iproute2/rt_tables permet de lier un nom à un numéro de table:

$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep

La commande précédente utilisée pour afficher la table 254 peut dès lors être utilisée comme ceci:

$ ip route show table main
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.3
169.254.0.0/16 dev eth0  proto kernel  scope link  src 169.254.4.13
169.254.0.0/16 dev eth1  scope link  metric 1000
default via 192.168.0.1 dev eth1
default dev eth0  scope link  metric 1000

En dehors de cette spécificité des différentes tables de routage, ip route peut être utilisé pour manipuler les routes avec la même syntaxe que pour les autres commandes de ip. Pour obtenir l'intégralité des options de la commande, utilisez l'option "help":

$ ip route help
Usage: ip route { list | flush } SELECTOR
       ip route get ADDRESS [ from ADDRESS iif STRING ]
                            [ oif STRING ]  [ tos TOS ]
       ip route { add | del | change | append | replace | monitor } ROUTE
SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]
            [ table TABLE_ID ] [ proto RTPROTO ]
            [ type TYPE ] [ scope SCOPE ]
ROUTE := NODE_SPEC [ INFO_SPEC ]
NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]
             [ table TABLE_ID ] [ proto RTPROTO ]
             [ scope SCOPE ] [ metric METRIC ]
             [ mpath MP_ALGO ]
INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...
NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS
OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]
           [ rtt NUMBER ] [ rttvar NUMBER ]
           [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]
           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]
TYPE := [ unicast | local | broadcast | multicast | throw |
          unreachable | prohibit | blackhole | nat ]
TABLE_ID := [ local | main | default | all | NUMBER ]
SCOPE := [ host | link | global | NUMBER ]
FLAGS := [ equalize ]
MP_ALGO := { rr | drr | random | wrandom }
NHFLAGS := [ onlink | pervasive ]
RTPROTO := [ kernel | boot | static | NUMBER ]

Voici par exemple comment ajouter et enlever une route par défaut vers 192.168.0.1:

$ ip route
172.18.13.17 dev tun0  proto kernel  scope link  src 172.18.13.18 
172.17.13.0/24 via 172.18.13.17 dev tun0 
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.3 
192.168.13.0/24 via 172.18.13.17 dev tun0 
172.18.13.0/24 via 172.18.13.17 dev tun0 
172.16.12.0/23 via 172.18.13.17 dev tun0 
169.254.0.0/16 dev eth0  proto kernel  scope link  src 169.254.4.13 
169.254.0.0/16 dev eth1  scope link  metric 1000 
# ip route add default via 192.168.0.1
$ ip route
172.18.13.17 dev tun0  proto kernel  scope link  src 172.18.13.18 
172.17.13.0/24 via 172.18.13.17 dev tun0 
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.3 
192.168.13.0/24 via 172.18.13.17 dev tun0 
172.18.13.0/24 via 172.18.13.17 dev tun0 
172.16.12.0/23 via 172.18.13.17 dev tun0 
169.254.0.0/16 dev eth0  proto kernel  scope link  src 169.254.4.13 
169.254.0.0/16 dev eth1  scope link  metric 1000 
default via 192.168.0.1 dev eth1 
# ip route delete default
$ ip route
172.18.13.17 dev tun0  proto kernel  scope link  src 172.18.13.18 
172.17.13.0/24 via 172.18.13.17 dev tun0 
192.168.0.0/24 dev eth1  proto kernel  scope link  src 192.168.0.3 
192.168.13.0/24 via 172.18.13.17 dev tun0 
172.18.13.0/24 via 172.18.13.17 dev tun0 
172.16.12.0/23 via 172.18.13.17 dev tun0 
169.254.0.0/16 dev eth0  proto kernel  scope link  src 169.254.4.13 
169.254.0.0/16 dev eth1  scope link  metric 1000 

ip rule

La commande "ip rule" permet de gérer les règles qui régissent le choix de la table de routage à utiliser (définie avec ip route), c'est ce qu'on appelle la politique de routage (routing policy). Linux permet de sélectionner la table de routage en fonction des éléments suivants d'un paquet:

La commande ip rule permet de créer et de supprimer des règles de routage, chacune de celles-ci définit un ou plusieurs éléments parmi la liste précédente, la table à utiliser et la priorité de la règle. Lors de la réception d'un paquet, Linux passe en revue chaque règle par ordre de priorité croissante afin d'en trouver une applicable. Lorsque celle-ci est trouvée, le noyau utilise la table de routage qui y est associée.

Les tables de routage multiple et les politiques de routage sont des outils puissants pour réaliser un routage efficace. Un politique de routage peut par exemple permettre de détourner le trafic non crucial vers une ligne moins fiable et donc moins coûteuse.

L'ensemble des options de ip rule sont reprises ici:

$ ip rule help
ip rule [ list | add | del | flush ] SELECTOR ACTION
SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]
            [ dev STRING ] [ pref NUMBER ] [ prio NUMBER ]
ACTION := [ table TABLE_ID ]
          [ prohibit | reject | unreachable ]
          [ realms [SRCREALM/]DSTREALM ]
TABLE_ID := [ local | main | default | NUMBER ]

On peut voir que les règles sont formées d'un sélecteur et d'une action. Le sélecteur comprend les champs précités ainsi que la priorité (prio). L'action est composée de la table à utiliser ou d'un sélecteur de rejet. Les sélecteurs de rejet permettent de définir explicitement qu'une route n'est plus disponible, ils ne doivent pas être utilisés à des fins de par-feux; pour réaliser un firewall il faut utiliser iptables.

ip maddress et ip mroute

Les deux commandes commençant par M permettent de gérer le multicast.

La commande ip maddress permet d'attacher et de détacher des adresses multicast, les adresses peuvent au niveau liaison de données ou IP.

La commande ip mroute permet d'afficher le cache de routage multicast.

ip tunnel

La commande ip tunnel permet de gérer les tunnels IP, de tels tunnels consistent à encapsuler des packets dans des packets IPv4.

Pour réaliser des réseaux privés virtuels (VPN), qui sont aussi composés de tunnels mais qui utilisent des connexions cryptées pour des raisons de sécurité, utilisez de préférence un outil dédié tel que OpenVPN, VTun ou encore OpenSSH.

ip monitor

La commande ip monitor permet de suivre les changements de la couche liaison de données et/ou de la couche IP. La syntaxe de la commande est la suivante:

ip monitor [ all | LISTEdOBJETS ]

L'option LISTEdOBJETS permet de spécifier les données à suivre parmi link, address et route.

Par exemple voici le résultat d'un suivi des adresses lors de l'ajout d'une adresse sur l'interface eth0:2:

$ ip monitor address
2: eth0    inet 192.168.125.1/24 brd 192.168.125.255 scope global eth0:2

Raccourcis

Avec la commande ip, il n'est pas nécessaire de préciser un mot clé en entier si celui-ci peut être identifié sans ambigüité. Par exemple les commandes suivantes sont équivalentes:

$ ip address show
$ ip addr sh
$ ip a s

Ceci est possible car aucun autre objet que "address" ne commence par un A et que le S de "show" ne peut être confondu avec aucun autre mot clé de l'objet "address".

Parmi les trois exemples de la même commande, la seconde version est la plus utilisée en console, la troisième ne sert vraiment qu'a épater les copains tant elle est peu claire. Pour une utilisation dans un script, il est plus que conseillé d'utiliser la syntaxe complète pour que le script continue à fonctionner avec de nouvelles versions de la commande ip et pour en rendre la relecture plus facile.