feat: guest-dhcp.sh — aktifkan DHCP NIC macvlan di dalam guest
This commit is contained in:
1 parent
4a86be23c8
commit
9392f8964b
2 files changed
+133
-60
No files matched your search
@@ -1,84 +1,68 @@
|
||||
# auto-macvlan
|
||||
|
||||
Skrip untuk memasang **NIC macvlan** ke instance **Incus** dan mengaktifkan **DHCP di guest**, sehingga instance langsung mendapat IP di LAN (mis. `192.168.200.x`) — bukan IP NAT internal incus.
|
||||
Skrip **untuk dijalankan di dalam guest** incus: mengaktifkan **DHCP** pada NIC tambahan (mis. macvlan) supaya guest langsung mendapat IP LAN (`192.168.200.x`).
|
||||
|
||||
Cocok untuk instance yang perlu diakses langsung dari LAN (web, SSH, service yang di-publish podman/docker di dalamnya).
|
||||
Sisi host (menambah NIC macvlan ke instance) dianggap sudah diatur sendiri.
|
||||
|
||||
## Pemakaian
|
||||
## `guest-dhcp.sh`
|
||||
|
||||
Jalankan di dalam guest (Debian/Ubuntu/Alpine, dll):
|
||||
|
||||
```bash
|
||||
./incus-macvlan.sh <instance> [device] [network]
|
||||
# auto: semua NIC non-lo yang belum punya IPv4
|
||||
./guest-dhcp.sh
|
||||
|
||||
# NIC tertentu
|
||||
./guest-dhcp.sh eth1
|
||||
|
||||
# beberapa NIC
|
||||
./guest-dhcp.sh eth1 eth2
|
||||
```
|
||||
|
||||
Contoh:
|
||||
|
||||
```bash
|
||||
# pakai default: device eth1, network eth200
|
||||
./incus-macvlan.sh web1
|
||||
|
||||
# tentukan device & network
|
||||
./incus-macvlan.sh web1 eth1 eth200
|
||||
|
||||
# buat network macvlan bila belum ada
|
||||
./incus-macvlan.sh web1 --create --parent enp2s0
|
||||
```
|
||||
|
||||
## Opsi
|
||||
Opsi:
|
||||
|
||||
| Opsi | Default | Keterangan |
|
||||
|---|---|---|
|
||||
| `--parent <iface>` | dari default route host | Interface fisik host untuk parent macvlan |
|
||||
| `--network <name>` | `eth200` | Nama network macvlan di incus |
|
||||
| `--device <name>` | `eth1` | Nama NIC di dalam guest |
|
||||
| `--create` | mati | Buat network macvlan kalau belum ada |
|
||||
| `--metric N` | `50` | `RouteMetric` DHCPv4. Lebih kecil dari NIC incusbr0 (100) agar NIC ini jadi default route. `0` = tidak di-set. |
|
||||
| `-h, --help` | | Bantuan |
|
||||
|
||||
Argumen posisional: `$1` instance, `$2` device, `$3` network. Opsi mengalahkan posisional.
|
||||
### Cara menjalankan
|
||||
|
||||
## Yang dilakukan
|
||||
|
||||
1. Cek instance ada dan berjalan (start bila perlu).
|
||||
2. Pastikan network macvlan ada (buat dengan `--create` bila perlu).
|
||||
3. Pasang NIC `nic network=<network> name=<device>` ke instance (hotplug).
|
||||
4. Aktifkan DHCP di guest:
|
||||
- **NetworkManager** → `nmcli`
|
||||
- **systemd-networkd** → `/etc/systemd/network/20-<device>.network`
|
||||
- fallback: `dhcpcd` / `dhclient` / `udhcpc`
|
||||
5. Tunggu dan tampilkan IP LAN.
|
||||
|
||||
Idempotent — aman dijalankan ulang.
|
||||
|
||||
## Persiapan network macvlan (sekali)
|
||||
**Di dalam guest:**
|
||||
|
||||
```bash
|
||||
incus network create eth200 --type=macvlan parent=enp2s0
|
||||
curl -fsSL https://gitea.oxpoe.qzz.io/oxpoe/auto-macvlan/raw/branch/main/guest-dhcp.sh | bash
|
||||
```
|
||||
|
||||
Atau biarkan skrip membuatnya dengan `--create`.
|
||||
**Dari host incus:**
|
||||
|
||||
## Syarat
|
||||
|
||||
- Host Incus punya NIC fisik yang terhubung ke LAN (parent, mis. `enp2s0`).
|
||||
- **DHCP server di LAN** aktif (IP instance berasal dari router LAN, bukan incus).
|
||||
- Guest punya salah satu DHCP client di atas.
|
||||
|
||||
## Catatan penting
|
||||
|
||||
- **Host Incus tidak bisa menghubungi instance lewat IP LAN macvlan** (batasan macvlan). Dari host, kelola lewat `incus exec`; instance tetap bisa diakses dari perangkat LAN lain.
|
||||
- Bila instance punya **dua NIC** (incusbr0 + macvlan) dan default route dari incusbr0 menang, balasan ke LAN bisa keluar lewat NIC yang salah. Solusi: jadikan macvlan default dengan metrik lebih rendah, mis.:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/network/20-eth1.network
|
||||
[Match]
|
||||
Name=eth1
|
||||
[Network]
|
||||
DHCP=yes
|
||||
[DHCPv4]
|
||||
RouteMetric=50
|
||||
```bash
|
||||
curl -fsSL https://gitea.oxpoe.qzz.io/oxpoe/auto-macvlan/raw/branch/main/guest-dhcp.sh -o /tmp/guest-dhcp.sh
|
||||
incus file push /tmp/guest-dhcp.sh <instance>/root/guest-dhcp.sh
|
||||
incus exec <instance> -- bash /root/guest-dhcp.sh
|
||||
```
|
||||
|
||||
atau nonaktifkan NIC incusbr0 bila tidak diperlukan.
|
||||
- IP yang didapat dinamis dari LAN. Kalau butuh statis, atur DHCP reservation di router atau konfigurasi statis di guest.
|
||||
### Yang dilakukan
|
||||
|
||||
- Mendeteksi NIC tanpa IPv4 (atau yang kamu sebutkan).
|
||||
- Mengaktifkan DHCP sesuai pengelola jaringan yang tersedia:
|
||||
**NetworkManager** (`nmcli`), **systemd-networkd** (`/etc/systemd/network/20-<if>.network`),
|
||||
**dhcpcd**, **dhclient**, atau **udhcpc**.
|
||||
- Menulis `[DHCPv4] RouteMetric=50` (networkd) agar NIC LAN menang atas incusbr0.
|
||||
- Menunggu dan mencetak IP tiap NIC.
|
||||
|
||||
Persisten: file `.network` tetap ada setelah reboot (untuk systemd-networkd).
|
||||
|
||||
## Catatan
|
||||
|
||||
- Skrip ini **hanya** mengurus DHCP di guest. Menambah NIC ke network macvlan tetap di host:
|
||||
```bash
|
||||
incus config device add <instance> eth1 nic network=eth200 name=eth1
|
||||
```
|
||||
- Bila guest punya dua NIC (incusbr0 + macvlan), jadikan macvlan sebagai default
|
||||
(metrik lebih rendah) agar balasan ke LAN tidak keluar lewat NIC yang salah.
|
||||
`--metric` (default 50) sudah melakukan ini untuk systemd-networkd.
|
||||
- Host incus tidak bisa menjangkau guest lewat IP macvlan (batasan macvlan); dari host pakai `incus exec`.
|
||||
|
||||
## Lisensi
|
||||
|
||||
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# guest-dhcp.sh — aktifkan DHCP untuk NIC tambahan (mis. macvlan) DI DALAM guest incus.
|
||||
# Jalankan di dalam guest (SSH atau `incus exec`), karena sisi host (add NIC) sudah diatur.
|
||||
#
|
||||
# Pakai:
|
||||
# ./guest-dhcp.sh # auto: semua NIC non-lo yang belum punya IPv4
|
||||
# ./guest-dhcp.sh eth1 # NIC tertentu
|
||||
# ./guest-dhcp.sh eth1 eth2
|
||||
#
|
||||
# Opsi:
|
||||
# --metric N RouteMetric DHCPv4 (default 50; 0 = tidak di-set)
|
||||
# lebih kecil dari NIC incusbr0 (100) agar NIC ini jadi default route
|
||||
# -h, --help
|
||||
#
|
||||
# Idempotent. Mendukung NetworkManager, systemd-networkd, dhcpcd, dhclient, udhcpc.
|
||||
set -euo pipefail
|
||||
|
||||
METRIC=50
|
||||
TARGETS=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--metric) METRIC="${2:?--metric butuh angka}"; shift 2 ;;
|
||||
-h|--help) sed -n '2,17p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
-*) echo "opsi tak dikenal: $1" >&2; exit 2 ;;
|
||||
*) TARGETS+=("$1"); shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
have_ip(){ ip -4 addr show "$1" 2>/dev/null | grep -q 'inet '; }
|
||||
|
||||
# auto-deteksi NIC tanpa IPv4
|
||||
if [ ${#TARGETS[@]} -eq 0 ]; then
|
||||
for d in /sys/class/net/*; do
|
||||
n="$(basename "$d")"; [ "$n" = lo ] && continue
|
||||
have_ip "$n" || TARGETS+=("$n")
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ${#TARGETS[@]} -eq 0 ]; then
|
||||
echo "Semua NIC sudah punya IPv4. Tidak ada yang perlu dikonfigurasi."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# deteksi pengelola jaringan
|
||||
NM=0; NETD=0
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl is-active --quiet NetworkManager 2>/dev/null && NM=1
|
||||
systemctl is-active --quiet systemd-networkd 2>/dev/null && NETD=1
|
||||
fi
|
||||
|
||||
for iface in "${TARGETS[@]}"; do
|
||||
echo "== konfigurasi $iface"
|
||||
if [ "$NM" = 1 ]; then
|
||||
nmcli device connect "$iface" >/dev/null 2>&1 || {
|
||||
nmcli connection add type ethernet ifname "$iface" con-name "$iface" ipv4.method auto >/dev/null 2>&1 || true
|
||||
nmcli connection up "$iface" >/dev/null 2>&1 || true
|
||||
}
|
||||
elif [ "$NETD" = 1 ] || [ -d /etc/systemd/network ]; then
|
||||
{
|
||||
printf '[Match]\nName=%s\n[Network]\nDHCP=yes\n' "$iface"
|
||||
[ "$METRIC" -gt 0 ] && printf '[DHCPv4]\nRouteMetric=%s\n' "$METRIC"
|
||||
} > "/etc/systemd/network/20-$iface.network"
|
||||
systemctl restart systemd-networkd >/dev/null 2>&1 || true
|
||||
elif command -v dhcpcd >/dev/null 2>&1; then
|
||||
dhcpcd "$iface" >/dev/null 2>&1 || true
|
||||
elif command -v dhclient >/dev/null 2>&1; then
|
||||
dhclient "$iface" >/dev/null 2>&1 || true
|
||||
elif command -v udhcpc >/dev/null 2>&1; then
|
||||
udhcpc -i "$iface" >/dev/null 2>&1 || true
|
||||
else
|
||||
echo " ! tidak ada DHCP client (NetworkManager/systemd-networkd/dhcpcd/dhclient/udhcpc)" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# tunggu IP
|
||||
for _ in $(seq 1 20); do
|
||||
ready=0
|
||||
for iface in "${TARGETS[@]}"; do have_ip "$iface" && ready=$((ready+1)); done
|
||||
[ "$ready" -eq ${#TARGETS[@]} ] && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo
|
||||
for iface in "${TARGETS[@]}"; do
|
||||
ip4="$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -1)"
|
||||
printf '%-8s %s\n' "$iface" "${ip4:-belum dapat IP}"
|
||||
done
|
||||
Reference in new issue
Block a user