Bagaimana membiarkan built-in DHCP menetapkan IP statis ke wadah LXC berdasarkan nama, bukan alamat MAC

10

Saya tahu, bahwa saya dapat menetapkan IP statis secara manual, menggunakan /etc/network/interfaces.

Saya juga tahu, bahwa saya dapat membaca alamat MAC wadah LXC (misalnya dengan mencari lxc.network.hwaddrentri /var/lib/lxc/<container-name>/configdan menetapkan IP berdasarkan menggunakan entri dhcp-host=<mac-addr>,10.0.3.3di /etc/dnsmasq.d/<some file>.

Dalam file yang /etc/default/lxc-netsaya baca

# 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

Itu akan sesuai dengan kebutuhan saya; sayangnya hal itu tidak berpengaruh.

Adam Ryczkowski
sumber
2
Ini berfungsi untuk saya, tetapi perhatikan bahwa Anda harus me-restart lxc-net agar dapat berfungsi. Dan ada masalah yang diketahui bahwa lxc-net tidak memulai ulang jika ada wadah yang sedang dimulai. Anda harus menghentikan semuanya dan kemudian restart layanan lxc-net.
HRJ
Juga, saya tidak dapat menetapkan alamat ip menggunakan nama wadah saja. Saya harus memasukkan kode alamat MAC untuk wadah dan untuk konfigurasi DHCP.
HRJ
@ HRJ, bisakah Anda memposting file dnsmasq.conf Anda?
tonytony
@HRJ Di Ubuntu 14.04 memulai kembali lxc-nettidak membantu jika Anda tidak menghapus jembatan lxcbr0 Anda. Lihat jawaban saya.
Adam Ryczkowski

Jawaban:

17

Saya mengalami ini baru-baru ini dan saya pikir saya menemukan solusi yang mudah. Saya (hanya) mengujinya di Ubuntu 14.04.

Pertama, batalkan komentar pada baris ini / etc / default / lxc-net:

LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

Di /etc/lxc/dnsmasq.conf, tentukan dhcp-hostsfile:

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

Kemudian tambahkan entri di /etc/lxc/dnsmasq-hosts.conf seperti ini:

mail,10.0.3.16
web,10.0.3.17

Hati-hati: perubahan akan menjadi efektif setelah Anda me-restart lxc-net (yang me-restart dnsmasq):

service lxc-net restart

Setelah itu Anda dapat memodifikasi /etc/lxc/dnsmasq-hosts.conf dan mengirim sinyal SIGHUP ke dnsmasq:

killall -s SIGHUP dnsmasq

Jadi ya, Anda perlu me-restart lxc-net, tetapi hanya sekali. Semoga ini membantu.

mtp
sumber
Saya suka ide mendelegasikan daftar host ke file eksternal. Selain itu, metode Anda berbeda dari saya karena killall -s SIGHUP dnsmasq. Saya setuju, bahwa hanya "SIGHUP-ing" dnsmasq lebih efisien daripada me-restart seluruh daemon (terutama jika tidak bekerja tanpa menambal skrip pemula).
Adam Ryczkowski
Restart layanan lxc-nethanya diperlukan untuk membiarkan dnsmasq menggunakan konfigurasi dari /etc/lxc/dnsmasq.conf (dan informasi ini ada di /etc/default/lxc-netmana tidak diketahui oleh dnsmasq). Jika Anda sudah mengaturnya sebelumnya, cukup SIGHUP yang lain.
Adam Ryczkowski
Hati-hati: lxc-net tidak akan memulai ulang dnsmasq jika ada wadah yang berjalan.
s3v3n
IMO ini adalah jawaban terbaik
s3v3n
kill -HUP $(cat /var/run/lxc/dnsmasq.pid)jika Anda tidak ingin menginstal killallatau memuat ulang dnsmasqinstance lain
gertas
4

Ini berfungsi dengan baik di Ubuntu 14.04.1

Batalkan komentar pada baris ini /etc/default/lxc-net

#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

hentikan semua kontainer, restart lxc-net:

service lxc-net restart

Konfigurasikan alamat ip di /etc/lxc/dnsmasq.conf

dhcp-host={NAME},10.0.3.2

di mana {NAME}nama kontainer LXC Anda:

/var/lib/lxc/{NAME}
Tombart
sumber
Ini bekerja hanya jika skrip dapat mematikan jaringan lxcbr0 , yang mengecualikan kasus ketika ada wadah lxc lainnya berjalan. Singkatnya, seperti sekarang, Anda tidak dapat menetapkan sewa dhcp statis tanpa memulai kembali semua wadah.
Adam Ryczkowski
Ya, itu benar, itu cukup merepotkan :(. Saya menemukan solusi yang jauh lebih mudah untuk mengedit /var/lib/lxc/<container-name>/rootfs/etc/network/interfacesfile dan menetapkan alamat ip statis ke wadah.
Tombart
Benar, tapi kemudian tidak ada yang melindungi Anda dari memberi dua tamu IP yang sama. Lihat jawaban saya yang diterima - itu memecahkan masalah.
Adam Ryczkowski
1

Jawaban Tombart berfungsi jika Anda cukup sabar untuk menunggu penyegaran DNS DAN Anda bersedia untuk memulai kembali wadah (tamu) sesudahnya.

Berikut ini adalah resep yang mengharuskan semua wadah lxc lainnya yang sedang berjalan dimatikan . Jika Anda tidak mampu membelinya, maka saya tidak menemukan cara untuk memaksa konfigurasi dnsmasq baru. (Untuk beberapa reasone signaling HUP ke pid dnsmasq ditemukan dalam /run/lxc/dnsmasq.pidtidak berfungsi baik.)

Jadi, jika Anda ingin memiliki sesuatu yang berfungsi secara instan dan tidak ada wadah lxc lain yang berjalan, ikuti jawaban saya. $nameadalah nama dari simpul yang ingin kita atur ulang penugasannya, dan $internalifmerupakan nama adaptor yang dijalin oleh LXC. Anda bisa mendapatkan nilai $internalifdengan misalnya augtool -L -A --transform "Shellvars incl /etc/default/lxc-net" get "/files/etc/default/lxc-net/LXC_BRIDGE" | sed -En 's/\/.* = (.*)/\1/p'jika Anda menginstal augeas-toolstetapi biasanya itu hanya 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

Sayangnya, ada bug (fitur?) Di /etc/init/lxc-net.confdalam Ubuntu 14,04 yang mencegah memuat kembali dnsmasqkecuali perangkat jembatan turun untuk tuan rumah.

Adam Ryczkowski
sumber
0

Solusi ini bekerja dengan menambal skrip pemula lxc. Itu membagi tugas kompleks membawa lxcbr0 jembatan dan memulai dnsmasqmenjadi dua pekerjaan terpisah. Sekarang Anda tidak perlu me-restart seluruh lxc-netjembatan untuk hanya memuat ulang dnsmasq- memuat kembali sudo service restart lxc-dnsmasqsudah cukup dan tidak perlu mematikan jembatan.

  1. Hentikan layanan lxc-net sudo service lxc-net stopdan pastikan tidak ada jembatan lxcbr0 (atau setara).
  2. Ganti konten /etc/init/lxc-net.confdengan konten berikut:

.

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. Tambahkan file lain, /etc/init/lxc-dnsmasqdengan konten berikut:

.

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
Adam Ryczkowski
sumber
0

Berikut ini adalah skrip python sederhana yang merilis sewa dnsmasq LXC. Anda dapat menjalankannya dari mesin host atau memalsunya dari wadah lain - ya itu berhasil !:

#!/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')]))

Persyaratan untuk di atas adalah scapy python library:

pip install scapy

Setelah dijalankan, Anda akan melihat di log sistem sesuatu seperti:

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

Untuk mengonfirmasi, cukup periksa apakah entri dihapus dari /var/lib/misc/dnsmasq.lxcbr0.leases. Wadah itu sendiri akan menyimpan IP sehingga harus dihentikan sebelum memulai wadah baru yang harus menggunakan kembali IP.

gertas
sumber
1
Itu keren! Saya bahkan tidak tahu bahwa DHCP mendukungnya! Saya akan segera memperbaiki setelah saya mengkonfirmasi itu berfungsi.
Adam Ryczkowski
0

Saya menyadari jawaban saya terlambat beberapa tahun, tetapi mungkin itu membantu orang lain. Masalahnya adalah Anda mengedit kode khusus untuk paket LXC Ubuntu ( write_lxc_netfungsi) yang dimaksudkan untuk ditulis ke tujuan lain sebagai string, tidak diproses dalam lxc-netskrip itu sendiri!

Akibatnya, proses dnsmasq tidak menerima file konfigurasi yang Anda coba lewati, meninggalkan Anda dengan "tidak ada efek", seperti yang Anda katakan.

Alih-alih, Anda ingin mengatur variabel ini di dekat bagian atas skrip, di antara yang lainnya:

#!/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=""
Adrian
sumber