From 9974777698302ed05906bc7ef1e66d3c4d59d198 Mon Sep 17 00:00:00 2001 From: ange Date: Sun, 10 Mar 2024 22:42:43 +0100 Subject: [PATCH] feat: CPU/RAM limit + port forward docs --- README.md | 21 ++- fedora39/nft | 369 ++++++++++++++++++++++++++++++++++++++++++++++++ fedora39/run.sh | 2 +- fedora39/todo | 1 + lib.sh | 12 +- startnat.sh | 1 - 6 files changed, 397 insertions(+), 9 deletions(-) create mode 100644 fedora39/nft create mode 100644 fedora39/todo diff --git a/README.md b/README.md index a56ae24..fc65ea9 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,29 @@ # VMs ## HOW-TO -To start (or create) a VM, go in the desired folder and run +To start (or create) a VM, go in the desired folder and run ```console $ ./run.sh ``` -## USB passthrough +### CPU/RAM limit +See QEMU(1) for CPU limit
. +Default RAM flag: `-m "2G,maxmem=$((MAX_RAM - 2))G"`.
+You can limit the CPU/RAM usage with these flags: +``` +./run.sh -smp "$NB_CPUS,maxcpus=$MAX_CPUS" \ + -m "${RAM}G,maxmem=${MAX_RAM}G" +``` +You can make this permanent in run.sh (this VM only) or lib.sh (all VMs). + +### Port forwarding +To forward host port 2222 to guest 22: +``` +./run.sh -nic user,hostfwd=tcp::2222-:22 +``` +You can make this permanent in run.sh (this VM only) or lib.sh (all VMs). + +### USB passthrough If you need USB passthrough, uncomment and fill in the corresponding line in `run.sh`. diff --git a/fedora39/nft b/fedora39/nft new file mode 100644 index 0000000..f3c46cf --- /dev/null +++ b/fedora39/nft @@ -0,0 +1,369 @@ +table inet firewalld { + ct helper helper-netbios-ns-udp { + type "netbios-ns" protocol udp + l3proto ip + } + + chain mangle_PREROUTING { + type filter hook prerouting priority mangle + 10; policy accept; + jump mangle_PREROUTING_POLICIES + } + + chain mangle_PREROUTING_POLICIES { + iifname "enp0s2" jump mangle_PRE_policy_allow-host-ipv6 + iifname "enp0s2" jump mangle_PRE_FedoraWorkstation + iifname "enp0s2" return + jump mangle_PRE_policy_allow-host-ipv6 + jump mangle_PRE_FedoraWorkstation + return + } + + chain nat_PREROUTING { + type nat hook prerouting priority dstnat + 10; policy accept; + jump nat_PREROUTING_POLICIES + } + + chain nat_PREROUTING_POLICIES { + iifname "enp0s2" jump nat_PRE_policy_allow-host-ipv6 + iifname "enp0s2" jump nat_PRE_FedoraWorkstation + iifname "enp0s2" return + jump nat_PRE_policy_allow-host-ipv6 + jump nat_PRE_FedoraWorkstation + return + } + + chain nat_POSTROUTING { + type nat hook postrouting priority srcnat + 10; policy accept; + jump nat_POSTROUTING_POLICIES + } + + chain nat_POSTROUTING_POLICIES { + iifname "enp0s2" oifname "enp0s2" jump nat_POST_FedoraWorkstation + iifname "enp0s2" oifname "enp0s2" return + oifname "enp0s2" jump nat_POST_FedoraWorkstation + oifname "enp0s2" return + iifname "enp0s2" jump nat_POST_FedoraWorkstation + iifname "enp0s2" return + jump nat_POST_FedoraWorkstation + return + } + + chain nat_OUTPUT { + type nat hook output priority -90; policy accept; + jump nat_OUTPUT_POLICIES + } + + chain nat_OUTPUT_POLICIES { + oifname "enp0s2" jump nat_OUT_FedoraWorkstation + oifname "enp0s2" return + jump nat_OUT_FedoraWorkstation + return + } + + chain filter_PREROUTING { + type filter hook prerouting priority filter + 10; policy accept; + icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept + meta nfproto ipv6 fib saddr . mark . iif oif missing drop + } + + chain filter_INPUT { + type filter hook input priority filter + 10; policy accept; + ct state { established, related } accept + ct status dnat accept + iifname "lo" accept + ct state invalid drop + jump filter_INPUT_POLICIES + reject with icmpx admin-prohibited + } + + chain filter_FORWARD { + type filter hook forward priority filter + 10; policy accept; + ct state { established, related } accept + ct status dnat accept + iifname "lo" accept + ct state invalid drop + ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 addr-unreachable + jump filter_FORWARD_POLICIES + reject with icmpx admin-prohibited + } + + chain filter_OUTPUT { + type filter hook output priority filter + 10; policy accept; + ct state { established, related } accept + oifname "lo" accept + ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 addr-unreachable + jump filter_OUTPUT_POLICIES + } + + chain filter_INPUT_POLICIES { + iifname "enp0s2" jump filter_IN_policy_allow-host-ipv6 + iifname "enp0s2" jump filter_IN_FedoraWorkstation + iifname "enp0s2" reject with icmpx admin-prohibited + jump filter_IN_policy_allow-host-ipv6 + jump filter_IN_FedoraWorkstation + reject with icmpx admin-prohibited + } + + chain filter_FORWARD_POLICIES { + iifname "enp0s2" oifname "enp0s2" jump filter_FWD_FedoraWorkstation + iifname "enp0s2" oifname "enp0s2" reject with icmpx admin-prohibited + iifname "enp0s2" jump filter_FWD_FedoraWorkstation + iifname "enp0s2" reject with icmpx admin-prohibited + oifname "enp0s2" jump filter_FWD_FedoraWorkstation + oifname "enp0s2" reject with icmpx admin-prohibited + jump filter_FWD_FedoraWorkstation + reject with icmpx admin-prohibited + } + + chain filter_OUTPUT_POLICIES { + oifname "enp0s2" jump filter_OUT_FedoraWorkstation + oifname "enp0s2" return + jump filter_OUT_FedoraWorkstation + return + } + + chain filter_IN_FedoraWorkstation { + jump filter_IN_FedoraWorkstation_pre + jump filter_IN_FedoraWorkstation_log + jump filter_IN_FedoraWorkstation_deny + jump filter_IN_FedoraWorkstation_allow + jump filter_IN_FedoraWorkstation_post + meta l4proto { icmp, ipv6-icmp } accept + } + + chain filter_IN_FedoraWorkstation_pre { + } + + chain filter_IN_FedoraWorkstation_log { + } + + chain filter_IN_FedoraWorkstation_deny { + } + + chain filter_IN_FedoraWorkstation_allow { + ip6 daddr fe80::/64 udp dport 546 accept + tcp dport 22 accept + udp dport 137 ct helper set "helper-netbios-ns-udp" + udp dport 137 accept + udp dport 138 accept + ip daddr 224.0.0.251 udp dport 5353 accept + ip6 daddr ff02::fb udp dport 5353 accept + udp dport 1025-65535 accept + tcp dport 1025-65535 accept + } + + chain filter_IN_FedoraWorkstation_post { + } + + chain filter_OUT_FedoraWorkstation { + jump filter_OUT_FedoraWorkstation_pre + jump filter_OUT_FedoraWorkstation_log + jump filter_OUT_FedoraWorkstation_deny + jump filter_OUT_FedoraWorkstation_allow + jump filter_OUT_FedoraWorkstation_post + } + + chain filter_OUT_FedoraWorkstation_pre { + } + + chain filter_OUT_FedoraWorkstation_log { + } + + chain filter_OUT_FedoraWorkstation_deny { + } + + chain filter_OUT_FedoraWorkstation_allow { + } + + chain filter_OUT_FedoraWorkstation_post { + } + + chain nat_OUT_FedoraWorkstation { + jump nat_OUT_FedoraWorkstation_pre + jump nat_OUT_FedoraWorkstation_log + jump nat_OUT_FedoraWorkstation_deny + jump nat_OUT_FedoraWorkstation_allow + jump nat_OUT_FedoraWorkstation_post + } + + chain nat_OUT_FedoraWorkstation_pre { + } + + chain nat_OUT_FedoraWorkstation_log { + } + + chain nat_OUT_FedoraWorkstation_deny { + } + + chain nat_OUT_FedoraWorkstation_allow { + } + + chain nat_OUT_FedoraWorkstation_post { + } + + chain nat_POST_FedoraWorkstation { + jump nat_POST_FedoraWorkstation_pre + jump nat_POST_FedoraWorkstation_log + jump nat_POST_FedoraWorkstation_deny + jump nat_POST_FedoraWorkstation_allow + jump nat_POST_FedoraWorkstation_post + } + + chain nat_POST_FedoraWorkstation_pre { + } + + chain nat_POST_FedoraWorkstation_log { + } + + chain nat_POST_FedoraWorkstation_deny { + } + + chain nat_POST_FedoraWorkstation_allow { + } + + chain nat_POST_FedoraWorkstation_post { + } + + chain filter_FWD_FedoraWorkstation { + jump filter_FWD_FedoraWorkstation_pre + jump filter_FWD_FedoraWorkstation_log + jump filter_FWD_FedoraWorkstation_deny + jump filter_FWD_FedoraWorkstation_allow + jump filter_FWD_FedoraWorkstation_post + } + + chain filter_FWD_FedoraWorkstation_pre { + } + + chain filter_FWD_FedoraWorkstation_log { + } + + chain filter_FWD_FedoraWorkstation_deny { + } + + chain filter_FWD_FedoraWorkstation_allow { + oifname "enp0s2" accept + } + + chain filter_FWD_FedoraWorkstation_post { + } + + chain nat_PRE_FedoraWorkstation { + jump nat_PRE_FedoraWorkstation_pre + jump nat_PRE_FedoraWorkstation_log + jump nat_PRE_FedoraWorkstation_deny + jump nat_PRE_FedoraWorkstation_allow + jump nat_PRE_FedoraWorkstation_post + } + + chain nat_PRE_FedoraWorkstation_pre { + } + + chain nat_PRE_FedoraWorkstation_log { + } + + chain nat_PRE_FedoraWorkstation_deny { + } + + chain nat_PRE_FedoraWorkstation_allow { + } + + chain nat_PRE_FedoraWorkstation_post { + } + + chain mangle_PRE_FedoraWorkstation { + jump mangle_PRE_FedoraWorkstation_pre + jump mangle_PRE_FedoraWorkstation_log + jump mangle_PRE_FedoraWorkstation_deny + jump mangle_PRE_FedoraWorkstation_allow + jump mangle_PRE_FedoraWorkstation_post + } + + chain mangle_PRE_FedoraWorkstation_pre { + } + + chain mangle_PRE_FedoraWorkstation_log { + } + + chain mangle_PRE_FedoraWorkstation_deny { + } + + chain mangle_PRE_FedoraWorkstation_allow { + } + + chain mangle_PRE_FedoraWorkstation_post { + } + + chain filter_IN_policy_allow-host-ipv6 { + jump filter_IN_policy_allow-host-ipv6_pre + jump filter_IN_policy_allow-host-ipv6_log + jump filter_IN_policy_allow-host-ipv6_deny + jump filter_IN_policy_allow-host-ipv6_allow + jump filter_IN_policy_allow-host-ipv6_post + } + + chain filter_IN_policy_allow-host-ipv6_pre { + } + + chain filter_IN_policy_allow-host-ipv6_log { + } + + chain filter_IN_policy_allow-host-ipv6_deny { + } + + chain filter_IN_policy_allow-host-ipv6_allow { + icmpv6 type nd-neighbor-advert accept + icmpv6 type nd-neighbor-solicit accept + icmpv6 type nd-router-advert accept + icmpv6 type nd-redirect accept + } + + chain filter_IN_policy_allow-host-ipv6_post { + } + + chain nat_PRE_policy_allow-host-ipv6 { + jump nat_PRE_policy_allow-host-ipv6_pre + jump nat_PRE_policy_allow-host-ipv6_log + jump nat_PRE_policy_allow-host-ipv6_deny + jump nat_PRE_policy_allow-host-ipv6_allow + jump nat_PRE_policy_allow-host-ipv6_post + } + + chain nat_PRE_policy_allow-host-ipv6_pre { + } + + chain nat_PRE_policy_allow-host-ipv6_log { + } + + chain nat_PRE_policy_allow-host-ipv6_deny { + } + + chain nat_PRE_policy_allow-host-ipv6_allow { + } + + chain nat_PRE_policy_allow-host-ipv6_post { + } + + chain mangle_PRE_policy_allow-host-ipv6 { + jump mangle_PRE_policy_allow-host-ipv6_pre + jump mangle_PRE_policy_allow-host-ipv6_log + jump mangle_PRE_policy_allow-host-ipv6_deny + jump mangle_PRE_policy_allow-host-ipv6_allow + jump mangle_PRE_policy_allow-host-ipv6_post + } + + chain mangle_PRE_policy_allow-host-ipv6_pre { + } + + chain mangle_PRE_policy_allow-host-ipv6_log { + } + + chain mangle_PRE_policy_allow-host-ipv6_deny { + } + + chain mangle_PRE_policy_allow-host-ipv6_allow { + } + + chain mangle_PRE_policy_allow-host-ipv6_post { + } +} diff --git a/fedora39/run.sh b/fedora39/run.sh index 9924530..fa4f5be 100755 --- a/fedora39/run.sh +++ b/fedora39/run.sh @@ -3,7 +3,7 @@ cd "$(dirname "$0")" . ../lib.sh ISO=( - [fedora39.iso]='https://download.fedoraproject.org/pub/fedora/linux/releases/39/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-39-1.5.iso' + [fedora39]='https://download.fedoraproject.org/pub/fedora/linux/releases/39/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-39-1.5.iso' ) if ! [ -f hda.qcow2 ]; then diff --git a/fedora39/todo b/fedora39/todo new file mode 100644 index 0000000..54213e3 --- /dev/null +++ b/fedora39/todo @@ -0,0 +1 @@ +/var/lib/misc/dnsmasq.leases diff --git a/lib.sh b/lib.sh index 3f7ac04..99f0554 100644 --- a/lib.sh +++ b/lib.sh @@ -21,12 +21,15 @@ function ask_yn() { declare -A ISO declare -a OPTS function download_isos() { + local file + for iso in "${!ISO[@]}"; do - if ! [ -f "$iso" ] && ask_yn "download $iso?"; then - curl -LC- -o "$iso" "${ISO[$iso]}" + file="$iso.iso" + if ! [ -f "$file" ] && ask_yn "download $file?"; then + curl -LC- -o "$file" "${ISO[$iso]}" fi - if [ -f "$iso" ]; then - OPTS+=(-drive "file=$iso,media=cdrom,readonly=on") + if [ -f "$file" ]; then + OPTS+=(-drive "file=$file,media=cdrom,readonly=on") fi done } @@ -51,7 +54,6 @@ function _getnet() { echo "$net" } -# TODO: -bios /usr/share/OVMF/OVMF_CODE.fd function qemu() { local maxram; maxram="$(_getmaxram)" local net; net="$(_getnet)" diff --git a/startnat.sh b/startnat.sh index 367ab6d..0ed6679 100755 --- a/startnat.sh +++ b/startnat.sh @@ -36,7 +36,6 @@ ip link set dev "$BRIDGE" up ip address flush dev "$BRIDGE" ip address add 192.168.123.1/24 dev "$BRIDGE" -# TODO: firewalld/nft? newtable INPUT newtable FORWARD newtable POSTROUTING -tnat