Added option for DHCP

This commit is contained in:
Kroese 2023-04-20 06:49:53 +02:00 committed by GitHub
commit 0909931446
7 changed files with 154 additions and 55 deletions

View File

@ -1,5 +1,5 @@
on: [workflow_call] on: [workflow_call]
name: "Check" name: "Shellcheck"
permissions: {} permissions: {}
jobs: jobs:

View File

@ -17,15 +17,16 @@ RUN apt-get update && apt-get -y upgrade && \
fdisk \ fdisk \
unzip \ unzip \
procps \ procps \
dnsmasq \ xz-utils \
iptables \ iptables \
iproute2 \ iproute2 \
xz-utils \ dnsmasq \
net-tools \ net-tools \
btrfs-progs \ btrfs-progs \
bridge-utils \ bridge-utils \
netcat-openbsd \
ca-certificates \ ca-certificates \
isc-dhcp-client \
netcat-openbsd \
qemu-system-x86 \ qemu-system-x86 \
&& apt-get clean && apt-get clean

View File

@ -134,9 +134,17 @@ fi
# Display message in docker log output # Display message in docker log output
echo "-------------------------------------------" IP=$(ip address show dev eth0 | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
echo " You can now login to DSM at port 5000 "
echo "-------------------------------------------" if [[ "$IP" == "20.20"* ]]; then
MSG="port 5000"
else
MSG="http://${IP}:5000"
fi
echo "--------------------------------------------------------"
echo " You can now login to DSM at ${MSG}"
echo "--------------------------------------------------------"
# Wait for NMI interrupt as a shutdown signal # Wait for NMI interrupt as a shutdown signal

View File

@ -128,10 +128,22 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
--ip-range=192.168.0.100/28 \ --ip-range=192.168.0.100/28 \
-o parent=eth0 vdsm -o parent=eth0 vdsm
``` ```
Modify these values to match your local subnet. And change the docker network of the container from `bridged` to `vdsm` in your run command or compose file: Modify these values to match your local subnet.
Now change the containers configuration in your compose file:
``` ```
--network vdsm --ip=192.168.0.100 networks:
vdsm:
ipv4_address: 192.168.0.100
```
And add the network to the very bottom of your compose file:
```
networks:
vdsm:
external: true
``` ```
This also has the advantage that you don't need to do any portmapping anymore, because all ports will be fully exposed this way. This also has the advantage that you don't need to do any portmapping anymore, because all ports will be fully exposed this way.

View File

@ -3,9 +3,9 @@ set -eu
# Docker environment variabeles # Docker environment variabeles
: ${DISK_IO:='native'} # I/O Mode : ${DISK_IO:='native'} # I/O Mode, can be set to 'native', 'threads' or 'io_turing'
: ${DISK_ROTATION:='1'} # Rotation rate : ${DISK_ROTATION:='1'} # Rotation rate, set to 1 for SSD storage and increase for HDD
: ${DISK_CACHE:='none'} # Caching mode : ${DISK_CACHE:='none'} # Caching mode, can be set to 'writeback' for better performance
BOOT="$STORAGE/$BASE.boot.img" BOOT="$STORAGE/$BASE.boot.img"
SYSTEM="$STORAGE/$BASE.system.img" SYSTEM="$STORAGE/$BASE.system.img"

View File

@ -103,7 +103,7 @@ BOOT=$(find $TMP -name "*.bin.zip")
BOOT=$(echo "$BOOT" | head -c -5) BOOT=$(echo "$BOOT" | head -c -5)
unzip -q -o "$BOOT".zip -d $TMP unzip -q -o "$BOOT".zip -d $TMP
[ "$ALLOCATE" != "Z" ] && echo "Install: Allocating diskspace..." [ "$ALLOCATE" != "Z" ] && echo "Install: Allocating diskspace..."
SYSTEM="$TMP/sys.img" SYSTEM="$TMP/sys.img"
SYSTEM_SIZE=4954537983 SYSTEM_SIZE=4954537983
@ -121,10 +121,8 @@ if ! fallocate -l "${SYSTEM_SIZE}" "${SYSTEM}"; then
fi fi
if [ "$ALLOCATE" = "Z" ]; then if [ "$ALLOCATE" = "Z" ]; then
echo "Install: Preallocating 4 GB of diskspace..." echo "Install: Preallocating 4 GB of diskspace..."
dd if=/dev/urandom of="${SYSTEM}" count="${SYSTEM_SIZE}" bs=1M iflag=count_bytes status=none dd if=/dev/urandom of="${SYSTEM}" count="${SYSTEM_SIZE}" bs=1M iflag=count_bytes status=none
fi fi
# Check if file exists # Check if file exists

View File

@ -3,22 +3,85 @@ set -eu
# Docker environment variabeles # Docker environment variabeles
: ${VM_NET_TAP:=''}
: ${VM_NET_IP:='20.20.20.21'}
: ${VM_NET_HOST:='VirtualDSM'} : ${VM_NET_HOST:='VirtualDSM'}
: ${VM_NET_MAC:='02:11:32:AA:BB:CC'} : ${VM_NET_MAC:='02:11:32:AA:BB:CC'}
: ${DHCP:='N'}
: ${DNS_SERVERS:=''} : ${DNS_SERVERS:=''}
: ${DNSMASQ:='/usr/sbin/dnsmasq'}
: ${DNSMASQ_OPTS:=''} : ${DNSMASQ_OPTS:=''}
: ${DNSMASQ:='/usr/sbin/dnsmasq'}
: ${DNSMASQ_CONF_DIR:='/etc/dnsmasq.d'} : ${DNSMASQ_CONF_DIR:='/etc/dnsmasq.d'}
# ###################################### # ######################################
# Functions # Functions
# ###################################### # ######################################
# Setup macvtap device to connect later the VM and setup a new macvlan device to connect the host machine to the network configureDHCP() {
configureNatNetworks () {
# Create /dev/vhost-net
if [ ! -c /dev/vhost-net ]; then
mknod /dev/vhost-net c 10 238
chmod 660 /dev/vhost-net
fi
if [ ! -c /dev/vhost-net ]; then
echo -n "Error: VHOST interface not available. Please add the following "
echo "docker variable to your container: --device=/dev/vhost-net" && exit 85
fi
VM_NET_TAP="_VmMacvtap"
echo "Info: Retrieving IP via DHCP using MAC ${VM_NET_MAC}..."
ip l add link eth0 name ${VM_NET_TAP} address ${VM_NET_MAC} type macvtap mode bridge || true
ip l set ${VM_NET_TAP} up
ip a flush eth0
ip a flush ${VM_NET_TAP}
DHCP_IP=$( dhclient -v ${VM_NET_TAP} 2>&1 | grep ^bound | cut -d' ' -f3 )
if [[ "${DHCP_IP}" == [0-9.]* ]]; then
echo "Info: Retrieved IP ${DHCP_IP} via DHCP"
else
echo "ERROR: Cannot retrieve IP from DHCP using MAC ${VM_NET_MAC}" && exit 16
fi
ip a flush ${VM_NET_TAP}
TAP_PATH="/dev/tap$(</sys/class/net/${VM_NET_TAP}/ifindex)"
# create dev file (there is no udev in container: need to be done manually)
IFS=: read MAJOR MINOR < <(cat /sys/devices/virtual/net/${VM_NET_TAP}/tap*/dev)
if (( MAJOR < 1)); then
echo "ERROR: Cannot find: sys/devices/virtual/net/${VM_NET_TAP}" && exit 18
fi
[[ ! -e ${TAP_PATH} ]] && [[ -e /dev0/${TAP_PATH##*/} ]] && ln -s /dev0/${TAP_PATH##*/} ${TAP_PATH}
if [[ ! -e ${TAP_PATH} ]]; then
if ! mknod ${TAP_PATH} c $MAJOR $MINOR ; then
echo "ERROR: Cannot mknod: ${TAP_PATH}" && exit 20
fi
fi
if ! exec 30>>$TAP_PATH; then
echo -n "ERROR: Please add the following docker variables to your container: "
echo "--device=/dev/vhost-net --device-cgroup-rule='c ${MAJOR}:* rwm'" && exit 21
fi
if ! exec 40>>/dev/vhost-net; then
echo -n "ERROR: VHOST can not be found. Please add the following docker "
echo "variable to your container: --device=/dev/vhost-net" && exit 22
fi
NET_OPTS="-netdev tap,id=hostnet0,vhost=on,vhostfd=40,fd=30"
}
configureNAT () {
VM_NET_IP='20.20.20.21'
VM_NET_TAP="_VmNatTap"
#Create bridge with static IP for the VM guest #Create bridge with static IP for the VM guest
brctl addbr dockerbridge brctl addbr dockerbridge
@ -34,6 +97,9 @@ configureNatNetworks () {
iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT --to $VM_NET_IP iptables -t nat -A PREROUTING -i eth0 -p tcp -j DNAT --to $VM_NET_IP
iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT --to $VM_NET_IP iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT --to $VM_NET_IP
# Hack for guest VMs complaining about "bad udp checksums in 5 packets"
iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill
#Enable port forwarding flag #Enable port forwarding flag
[[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]] && sysctl -w net.ipv4.ip_forward=1 [[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]] && sysctl -w net.ipv4.ip_forward=1
@ -43,6 +109,33 @@ configureNatNetworks () {
# Create lease file for faster resolve # Create lease file for faster resolve
echo "0 $VM_NET_MAC $VM_NET_IP $VM_NET_HOST 01:${VM_NET_MAC}" > /var/lib/misc/dnsmasq.leases echo "0 $VM_NET_MAC $VM_NET_IP $VM_NET_HOST 01:${VM_NET_MAC}" > /var/lib/misc/dnsmasq.leases
chmod 644 /var/lib/misc/dnsmasq.leases chmod 644 /var/lib/misc/dnsmasq.leases
NET_OPTS="-netdev tap,ifname=${VM_NET_TAP},script=no,downscript=no,id=hostnet0"
# Build DNS options from container /etc/resolv.conf
nameservers=($(grep '^nameserver' /etc/resolv.conf | sed 's/nameserver //'))
searchdomains=$(grep '^search' /etc/resolv.conf | sed 's/search //' | sed 's/ /,/g')
domainname=$(echo $searchdomains | awk -F"," '{print $1}')
for nameserver in "${nameservers[@]}"; do
if ! [[ $nameserver =~ .*:.* ]]; then
[[ -z $DNS_SERVERS ]] && DNS_SERVERS=$nameserver || DNS_SERVERS="$DNS_SERVERS,$nameserver"
fi
done
[[ -z $DNS_SERVERS ]] && DNS_SERVERS="1.1.1.1"
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:dns-server,$DNS_SERVERS --dhcp-option=option:router,${VM_NET_IP%.*}.1"
if [ -n "$searchdomains" -a "$searchdomains" != "." ]; then
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:domain-search,$searchdomains --dhcp-option=option:domain-name,$domainname"
else
[[ -z $(hostname -d) ]] || DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:domain-name,$(hostname -d)"
fi
[ "$DEBUG" = "Y" ] && echo && echo "$DNSMASQ $DNSMASQ_OPTS"
$DNSMASQ $DNSMASQ_OPTS
} }
# ###################################### # ######################################
@ -58,47 +151,34 @@ fi
[ ! -c /dev/net/tun ] && echo "Error: TUN network interface not available..." && exit 85 [ ! -c /dev/net/tun ] && echo "Error: TUN network interface not available..." && exit 85
if [ "$DEBUG" = "Y" ]; then
ifconfig
ip link
ip route
fi
update-alternatives --set iptables /usr/sbin/iptables-legacy > /dev/null update-alternatives --set iptables /usr/sbin/iptables-legacy > /dev/null
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy > /dev/null update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy > /dev/null
VM_NET_TAP="_VmNatTap" GATEWAY=$(ip r | grep default | awk '{print $3}')
configureNatNetworks
NET_OPTS="-netdev tap,ifname=${VM_NET_TAP},script=no,downscript=no,id=hostnet0"
# Build DNS options from container /etc/resolv.conf
nameservers=($(grep '^nameserver' /etc/resolv.conf | sed 's/nameserver //'))
searchdomains=$(grep '^search' /etc/resolv.conf | sed 's/search //' | sed 's/ /,/g')
domainname=$(echo $searchdomains | awk -F"," '{print $1}')
for nameserver in "${nameservers[@]}"; do
if ! [[ $nameserver =~ .*:.* ]]; then
[[ -z $DNS_SERVERS ]] && DNS_SERVERS=$nameserver || DNS_SERVERS="$DNS_SERVERS,$nameserver"
fi
done
[[ -z $DNS_SERVERS ]] && DNS_SERVERS="1.1.1.1"
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:dns-server,$DNS_SERVERS --dhcp-option=option:router,${VM_NET_IP%.*}.1"
if [ -n "$searchdomains" -a "$searchdomains" != "." ]; then
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:domain-search,$searchdomains --dhcp-option=option:domain-name,$domainname"
else
[[ -z $(hostname -d) ]] || DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:domain-name,$(hostname -d)"
fi
if [ "$DEBUG" = "Y" ]; then if [ "$DEBUG" = "Y" ]; then
echo "$DNSMASQ $DNSMASQ_OPTS"
IP=$(ip address show dev eth0 | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
echo "Info: Container IP is ${IP} with gateway {GATEWAY}"
ifconfig
ip route
fi fi
$DNSMASQ $DNSMASQ_OPTS if [ "$DHCP" != "Y" ]; then
# Configuration for static IP
configureNAT
else
if [[ "$GATEWAY" == "172."* ]]; then
echo -n "ERROR: You cannot enable DHCP while the container is "
echo "in a bridge network, only on a macvlan network!" && exit 86
fi
# Configuration for DHCP IP
configureDHCP
fi
NET_OPTS="${NET_OPTS} -device virtio-net-pci,romfile=,netdev=hostnet0,mac=${VM_NET_MAC},id=net0" NET_OPTS="${NET_OPTS} -device virtio-net-pci,romfile=,netdev=hostnet0,mac=${VM_NET_MAC},id=net0"
# Hack for guest VMs complaining about "bad udp checksums in 5 packets"
iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill