web-dev-qa-db-fra.com

Comment laisser le DHCP intégré attribuer une adresse IP statique au conteneur LXC en fonction du nom, pas de l'adresse MAC

Je sais que je peux attribuer une adresse IP statique manuellement, en utilisant /etc/network/interfaces.

Je sais aussi que je peux lire l’adresse MAC du conteneur LXC (par exemple, en cherchant l’entrée lxc.network.hwaddr dans /var/lib/lxc/<container-name>/config et en assignant l’adresse IP en utilisant les entrées dhcp-Host=<mac-addr>,10.0.3.3 dans /etc/dnsmasq.d/<some file>.

Dans le fichier /etc/default/lxc-net j'ai lu

# Uncomment the next line if you'd like to use a conf-file for the lxcbr0
# dnsmasq.  For instance, you can use 'dhcp-Host=mail1,10.0.3.100' to have
# container 'mail1' always get ip address 10.0.3.100.
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

Cela conviendrait à mes besoins. Malheureusement, cela n'a aucun effet.

10
Adam Ryczkowski

Cette solution fonctionne en corrigeant les scripts de démarrage lxc. Il divise la tâche complexe consistant à activer le pont lxcbr0 et à démarrer un dnsmasqen deux travaux distincts. Maintenant, vous n'avez pas besoin de redémarrer le pont lxc-net au complet pour recharger simplement le dnsmasq- le rechargement du Sudo service restart lxc-dnsmasq est suffisant et ne nécessite pas l'arrêt du pont.

  1. Arrêtez le service lxc-net Sudo service lxc-net stop et assurez-vous qu’il n’ya pas de passerelle lxcbr0 (ou équivalente).
  2. Remplacez le contenu du /etc/init/lxc-net.conf par le contenu suivant:

.

description "lxc network"
author "Serge Hallyn <[email protected]>"

start on starting lxc
stop on stopped lxc

env USE_LXC_BRIDGE="true"
env LXC_BRIDGE="lxcbr0"
env LXC_ADDR="10.0.3.1"
env LXC_NETMASK="255.255.255.0"
env LXC_NETWORK="10.0.3.0/24"
env varrun="/run/lxc"
env LXC_DOMAIN=""

pre-start script
    [ -f /etc/default/lxc ] && . /etc/default/lxc

    [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { stop; exit 0; }

    use_iptables_lock="-w"
    iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock=""
    cleanup() {
        # dnsmasq failed to start, clean up the bridge
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true
        iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
        ifconfig ${LXC_BRIDGE} down || true
        brctl delbr ${LXC_BRIDGE} || true
    }
    if [ -d /sys/class/net/${LXC_BRIDGE} ]; then
        if [ ! -f ${varrun}/network_up ]; then
            # bridge exists, but we didn't start it
            stop;
        fi
        exit 0;
    fi

    # set up the lxc network
    brctl addbr ${LXC_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; }
    echo 1 > /proc/sys/net/ipv4/ip_forward
    mkdir -p ${varrun}
    ifconfig ${LXC_BRIDGE} ${LXC_ADDR} netmask ${LXC_NETMASK} up
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
    iptables $use_iptables_lock -I FORWARD -i ${LXC_BRIDGE} -j ACCEPT
    iptables $use_iptables_lock -I FORWARD -o ${LXC_BRIDGE} -j ACCEPT
    iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE
    iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill

    touch ${varrun}/network_up
end script

post-stop script
    [ -f /etc/default/lxc ] && . /etc/default/lxc
    [ -f "${varrun}/network_up" ] || exit 0;
    # if $LXC_BRIDGE has attached interfaces, don't shut it down
    ls /sys/class/net/${LXC_BRIDGE}/brif/* > /dev/null 2>&1 && exit 0;

    if [ -d /sys/class/net/${LXC_BRIDGE} ]; then
        use_iptables_lock="-w"
        iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock=""
        ifconfig ${LXC_BRIDGE} down
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true
        iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
        pid=`cat ${varrun}/dnsmasq.pid 2>/dev/null` && kill -9 $pid || true
        rm -f ${varrun}/dnsmasq.pid
        brctl delbr ${LXC_BRIDGE}
    fi
    rm -f ${varrun}/network_up
end script
  1. Ajoutez un autre fichier, /etc/init/lxc-dnsmasq avec le contenu suivant:

.

description "lxc dnsmasq service"
author "Adam Ryczkowski, ispired by Serge Hallyn <[email protected]>"

expect fork

start on started lxc-net
stop on stopped lxc-net

env USE_LXC_BRIDGE="true"
env LXC_BRIDGE="lxcbr0"
env LXC_ADDR="10.0.3.1"
env LXC_NETMASK="255.255.255.0"
env LXC_NETWORK="10.0.3.0/24"
env LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
env LXC_DHCP_MAX="253"
env LXC_DHCP_CONFILE=""
env varrun="/run/lxc-dnsmasq"
env LXC_DOMAIN=""

pre-start script
    [ -f /etc/default/lxc ] && . /etc/default/lxc

    [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { stop; exit 0; }

    if [ ! -d ${varrun} ]; then
        mkdir -p ${varrun}
    fi
    opts="$LXC_DOMAIN_ARG -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq2.${LXC_BRIDGE}.leases --dhcp-authoritative --keep-in-foreground"

    /usr/sbin/dnsmasq $opts &

end script

post-stop script
    if [ -f ${varrun}/dnsmasq.pid ]; then
        PID=`cat ${varrun}/dnsmasq.pid`
        kill $PID
    fi
end script
0
Adam Ryczkowski

Je me suis heurté à cela récemment et je pense avoir trouvé une solution facile. Je l'ai (seulement) testé sur Ubuntu 14.04.

Commencez par décommenter cette ligne/etc/default/lxc-net:

LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

Dans /etc/lxc/dnsmasq.conf, définissez un fichier dhcp-hosts:

dhcp-hostsfile=/etc/lxc/dnsmasq-hosts.conf

Ajoutez ensuite des entrées dans /etc/lxc/dnsmasq-hosts.conf comme ceci:

mail,10.0.3.16
web,10.0.3.17

Attention: les modifications entreront en vigueur après le redémarrage de lxc-net (qui redémarre dnsmasq):

service lxc-net restart

Ensuite, vous pouvez modifier /etc/lxc/dnsmasq-hosts.conf et envoyer le signal SIGHUP à dnsmasq:

killall -s SIGHUP dnsmasq

Donc oui, vous devez redémarrer lxc-net, mais une seule fois. J'espère que cela t'aides.

16
mtp

Cela fonctionne très bien dans Ubuntu 14.04.1

Décommentez cette ligne /etc/default/lxc-net

#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

arrêtez tous les conteneurs, redémarrez lxc-net:

service lxc-net restart

Configurez les adresses IP dans /etc/lxc/dnsmasq.conf

dhcp-Host={NAME},10.0.3.2

{NAME} est le nom de votre conteneur LXC:

/var/lib/lxc/{NAME}
4
Tombart

La réponse de Tombart fonctionne si vous êtes suffisamment patient pour attendre l'actualisation DNS ET si vous souhaitez redémarrer le conteneur (l'invité) par la suite.

Ce qui suit est la recette qui nécessite que tous les autres conteneurs éventuellement exécutés lxc sont arrêtés. Si vous ne pouvez pas vous le permettre, je ne vois aucun moyen de forcer la nouvelle configuration Dnsmasq. (Pour certains cas, signaler HUP au pid de dnsmasq trouvé dans /run/lxc/dnsmasq.pid ne fonctionne pas non plus.)

Donc, si vous voulez avoir quelque chose qui fonctionne instantanément et qu'il n'y a pas d'autres conteneurs lxc en cours d'exécution, suivez ma réponse. $name est le nom du noeud pour lequel on veut réinitialiser l'affectation, et $internalif est le nom de l'adaptateur ponté de LXC. Vous pouvez obtenir la valeur de $internalif avec, par exemple, augtool -L -A --transform "Shellvars incl /etc/default/lxc-net" get "/files/etc/default/lxc-net/LXC_BRIDGE" | sed -En 's/\/.* = (.*)/\1/p' si vous installez augeas-tools mais il s’agit généralement de lxcbr0.

Sudo lxc-stop -n $name >/dev/null
Sudo service lxc-net stop >/dev/null
if [ -d /sys/class/net/$internalif ]; then
   Sudo brctl delbr $internalif >/dev/null #Why? See below.
fi
Sudo rm /var/lib/misc/dnsmasq.$internalif.leases
Sudo service lxc-net start >/dev/null
Sudo lxc-start -d -n $name >/dev/null
sleep 5

Malheureusement, il existe un bogue (fonctionnalité?) Dans le /etc/init/lxc-net.conf dans Ubuntu 14.04 qui empêche de recharger le dnsmasq à moins que le périphérique de pont ne soit hors service pour l'hôte.

1
Adam Ryczkowski

Je me rends compte que ma réponse a plusieurs années de retard, mais peut-être que cela aide quelqu'un d'autre. Le problème était que vous aviez édité du code spécifique au paquet LXC Ubuntu (fonction write_lxc_net) destiné à être écrit dans une autre destination sous forme de chaîne, non traité dans le script lxc-net!

En conséquence, le processus dnsmasq n'a pas reçu le fichier de configuration que vous avez essayé de transmettre, ce qui vous laisse "sans effet", comme vous le dites.

Au lieu de cela, vous voudriez définir cette variable près du haut du script, parmi les autres:

#!/bin/sh -

distrosysconfdir="/etc/default"
varrun="/run/lxc"
varlib="/var/lib"

# These can be overridden in /etc/default/lxc
#   or in /etc/default/lxc-net

USE_LXC_BRIDGE="true"
LXC_BRIDGE="lxcbr0"
LXC_BRIDGE_MAC="00:16:3e:00:00:00"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
LXC_DHCP_MAX="253"
LXC_DHCP_CONFILE="/etc/lxc/dnsmasq.conf"   <-- Here for instance
LXC_DOMAIN=""
0
Adrian

Voici un simple script python qui publie le bail LXC dnsmasq. Vous pouvez l'exécuter à partir de la machine hôte ou le falsifier à partir d'un autre conteneur - oui, cela fonctionne !:

#!/usr/bin/env python
from scapy.all import *
conf.checkIPaddr=False
leaseMAC = '00:16:3e:11:71:b0' #container MAC here
releaseIP='10.0.3.33' #container IP here
serverIP='10.0.3.1'
hostname='container-name-here'
rawMAC = leaseMAC.replace(':','').decode('hex')
send(IP(dst=serverIP) / \
     UDP(sport=68,dport=67) / \
     BOOTP(chaddr=rawMAC, ciaddr=releaseIP, xid=RandInt()) / \
     DHCP(options=[('message-type','release'),('server_id',serverIP),('hostname',hostname), ('end')]))

Le prérequis pour ce qui précède est scapy python bibliothèque:

pip install scapy

Une fois exécuté, vous devriez voir dans le journal système quelque chose comme:

dnsmasq-dhcp[3242]: DHCPRELEASE(lxcbr0) 10.0.3.33 00:16:3e:11:71:b0 container-name-here

Pour confirmer, vérifiez si l'entrée est supprimée de /var/lib/misc/dnsmasq.lxcbr0.leases. Le conteneur lui-même conservera l'adresse IP. Il convient donc de l'arrêter avant de démarrer tout nouveau conteneur devant réutiliser l'adresse IP.

0
gertas