
إطار عمل للتلاعب بالأجهزة الافتراضية
Mofos هي أداة مصممة لإنشاء الأجهزة الافتراضية وتشغيلها وإدارتها. تعتمد على Libvirt/QEMU/KVM وPython، مما يجعلها متوافقة مع أي توزيعة لينكس. مستوحاة بشدة من Qubes OS (https://www.qubes-os.org/)، تهدف Mofos إلى تكرار العديد من ميزاتها.
تم اختبار الأداة على نطاق واسع على Debian مع أجهزة افتراضية مبنية على Debian. في حين أنه من المتوقع أن تعمل توزيعات لينكس الأخرى، قد يكون بعض التكوين الإضافي ضروريًا. سيتم إضافة المزيد من التفاصيل لاحقًا.
توفر Mofos مجموعة من الميزات التي تركز على إدارة الأجهزة الافتراضية بشكل آمن، بما في ذلك:
تتكون آلة mofos من قرصين مدمجين باستخدام overlayfs. القرص الأول، المعروف بالطبقة السفلية، هو قرص قالب للقراءة فقط، بينما يخزن القرص الثاني جميع التغييرات التي يجريها الجهاز الافتراضي. تتم مشاركة قرص القالب هذا عبر أجهزة افتراضية متعددة. ونتيجة لذلك، فإن إنشاء جهاز افتراضي جديد يتطلب فقط استنساخ قرص فارغ مقسّم مسبقًا لاحتواء البيانات المعدّلة. يضمن هذا النهج إمكانية إنشاء أجهزة افتراضية جديدة بسرعة، مع السماح بتحديث القالب بشكل مستقل. ستسري أي تحديثات على القالب على الأجهزة الافتراضية التابعة عند إعادة تشغيلها التالية.
اعتمادًا على توزيعة لينكس، يمكن استخدام Makefile إما لإنشاء حزمة deb أو لتثبيت الملفات مباشرة.```
make deb
apt install ./mofos-VERSION.deb
أثناء تثبيت `apt`، سيتم طلب إعدادات متنوعة. يمكن قبول الخيارات الافتراضية بشكل عام. الإعداد الوحيد الذي يتطلب الانتباه هو عنوان الشبكة الفرعية المستخدم بواسطة شبكة mofos libvirt (الافتراضي: `192.168.90.0/24`).
أو
قم بتثبيت التبعيات التالية:
- guestfs-tools
- libnotify-bin
- libvirt
- libvirt-clients
- libvirt-daemon
- make
- python3-click
- python3-click-completion
- python3-colorama
- python3-cryptography
- python3-dbus
- python3-jinja2
- python3-lxml
- python3-prettytable
- python3-pyroute2
- python3-tqdm
- qemu-system-common
- qemu-system-modules-spice
- socat
- spice-client-gtk
- sudo
- virtinst
- virt-install
- virtiofsd
- virt-manager
- virt-viewer```
make install_files
اعتمادًا على التوزيعة، قد لا يكتشف مفسّر بايثون ملفات بايثون المنسوخة إلى /usr/lib/python3/dist-packages، لذا يجب وضعها في مكان آخر. على سبيل المثال، في فيدورا، يجب نسخ ملفات بايثون إلى /usr/lib/python3.11/site-packages.
[!WARNING] انتبه: منذ Debian trixie، لم يعد
xpraمُحزَّمًا بعد الآن، وعليك تثبيته يدويًا من مستودعاته المخصصة. راجع https://github.com/Xpra-org/xpra/wiki/Download#-for-debian-based-distributions للحصول على تعليمات مفصّلة.
يستخدم Mofos جلسة نظام QEMU/KVM، وللسماح لأمر virsh بالوصول إلى الأجهزة الافتراضية والموارد ذات الصلة، عيّن متغير البيئة LIBVIRT_DEFAULT_URI إلى qemu:///system:```console
export LIBVIRT_DEFAULT_URI=qemu:///system
### اعتبارات الأمن
استخدام جلسات النظام QEMU/KVM يحسّن العزل بين المضيف والأجهزة الافتراضية الضيفة من خلال تشغيل مثيلات qemu تحت مستخدم مخصص (`libvirt-qemu`) وتطبيق ملفات تعريف أمنية محددة على كل مثيل.
ومع ذلك، لا يمكن للمستخدمين العاديين افتراضيًا التفاعل مع مقبس النظام `libvirtd` لإدارة الأجهزة والشبكات والموارد الأخرى. للوصول، يجب أن يكون المستخدمون إما أعضاء في مجموعة Unix الخاصة بـ libvirt أو استخدام sudo. تاريخيًا، استغلت ثغرات تصعيد الامتيازات المحلية العضوية في مجموعة libvirt للحصول على صلاحيات الجذر.
للتخفيف من هذه المخاطر، يوفر هذا المستودع ملف تعريف AppArmor معززًا لعملية `libvirtd` على الأنظمة التي تستخدم AppArmor. يقيد هذا الملف بشكل كبير الأماكن التي يمكن لـ `libvirtd` كتابة الملفات فيها والبرامج التي يمكنه تنفيذها.
بالإضافة إلى ذلك، تم تضمين قواعد `polkit` للتحكم بشكل أكبر في الإجراءات المسموح بها لأعضاء مجموعة `libvirt`.
لاحظ أن ملفات تعريف AppArmor معبأة في حزمة `deb` ولكن لا يتم تثبيتها بواسطة هدف `install_files` في Makefile، وبالتالي يجب تثبيتها بشكل منفصل.
## إعدادات Mofos
يتطلب Mofos ملف إعدادات موجود في `$HOME/.config/mofos/config.toml` بإعدادات دنيا ليعمل بشكل صحيح. يمكن العثور على مثال لإعدادات دنيا في `/usr/share/mofos/config.minimal.toml`، بينما يتم توثيق إعدادات أكثر شمولاً في `/usr/share/mofos/config.sample.toml`.
يشير الخطأ التالي إلى أنه لم يتم العثور على ملف الإعدادات:```
[-] Copy the sample configuration file from /usr/share/mofos/config.minimal.toml to ~/.config/mofos/config.toml
يشير الخطأ التالي إلى أن المستخدم الحالي ليس عضوًا في مجموعة libvirt:``` [-] libvirtError("authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'")
إعدادات التكوين الرئيسية التي يجب تخصيصها في ملفات التكوين هي كما يلي:
- key (مسار): ملف مفتاح SSH الخاص المستخدم للوصول إلى الأجهزة الافتراضية. يُنصح بإنشاء مفتاح مخصص لهذا الغرض.
- user (نص): اسم المستخدم للوصول عبر SSH إلى الأجهزة الافتراضية.
- root_password (قيمة مشفرة): كلمة مرور الجذر المشفرة التي سيتم تعيينها أثناء تثبيت قالب جديد.
- root_ssh_pubkey (نص): مفتاح SSH العام الذي سيتم تثبيته في دليل مستخدم الجذر أثناء تثبيت القالب.
بالإضافة إلى ذلك، يجب تكوين المعاملات التالية لتثبيت القالب:
- ntp
- dns (اختياري إذا تم توفير وكيل)
- proxy
## تثبيت قالب
### تكوين جدار الحماية
نظرًا لأن عملية التثبيت تعتمد على الإقلاع عبر الشبكة PXE، يلزم وجود اتصال إنترنت نشط. يجب تكوين قواعد جدار الحماية التالية:```
sysctl net.ipv4.ip_forward=1
iptables -t nat -I POSTROUTING -s 192.168.90.0/24 -j MASQUERADE
iptables -t nat -I POSTROUTING -s 192.168.91.0/24 -j MASQUERADE
أو مع nftables:``` sysctl net.ipv4.ip_forward=1 nft insert inet nat postrouting iifname "install-*" masquerade nft insert inet nat postrouting iifname "mof0" masquerade
When the `ip_forward` parameter is set to 1, the FORWARD chain should be configured to prevent other devices on the network from using the host as a router.
Overall, the following rules are recommended:```
iptables -I INPUT -i mof0 -p udp --sport 68 --dport 67 -j ACCEPT -m comment --comment "mofos dhcp"
iptables -I INPUT -i mof0 -p udp --dport 69 -j ACCEPT -m comment --comment "mofos tftp"
iptables -I OUTPUT -o mof0 -j ACCEPT -m comment --comment "host -> mofos"
iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD -i mof0 -j ACCEPT -m comment --comment "mofos ->"
iptables -t nat -I POSTROUTING -s 192.168.90.0/24 -j MASQUERADE
iptables -t nat -I POSTROUTING -s 192.168.91.0/24 -j MASQUERADE
أو مع nftables:```
table inet filter {
chain input {
type filter hook input priority 0; policy drop
iifname "install-*" ip daddr 255.255.255.255 udp sport 68 udp dport 67 accept comment "mofos dhcp"
iifname "mof0" ip daddr 255.255.255.255 udp sport 68 udp dport 67 accept comment "mofos dhcp"
iifname "install-*" udp dport 69 accept comment "mofos tftp"
}
chain forward {
type filter hook forward priority 0; policy drop
ct state established,related accept;
ct state invalid drop;
iifname "mof0" counter accept
iifname "install-*" counter accept
}
chain output {
type filter hook output priority 0; policy drop
oifname "mof0" counter accept
}
} table inet nat { chain postrouting { type nat hook postrouting priority 100 iifname "mof0" masquerade iifname "install-*" masquerade } }
يُوصى بتقييد قواعد masquerade وإعادة التوجيه بناءً على احتياجاتك المحددة، لمنع أجهزة Mofos الافتراضية من الوصول إلى شبكة المضيف بالكامل.
يتم فرض العزل بين الأجهزة الافتراضية تلقائيًا عبر خطاف libvirt، والذي يتطلب عمل nft بشكل صحيح.
### التثبيت
الخطوة الأولى هي بناء الطبقة الأولية: القالب. افتراضيًا، يمكن لـ Mofos تثبيت قالب يعتمد على Debian 12.```
mofos template create debian-template
ملاحظة: بالنسبة لكل أمر، يمكن استخدام خيار --debug للحصول على معلومات تقنية مفصلة في حالة حدوث سلوك غير متوقع. وبشكل خاص لهذا الأمر، فإن علامة --debug تفرض أيضًا ظهور نافذة رسومية لعرض تقدم التثبيت. بدلاً من ذلك، يمكن مراقبة التثبيت باستخدام virt-manager.
حاليًا، يُدعم قالب Debian 12 فقط للتثبيت. يحدد قاموس بايثون أدناه صورة التثبيت التي سيتم استخدامها:```python NETBOOT = { "debian-stable-amd64": { "variant": "debian11", "url": "https://deb.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz", } }
يتم تعيين المتغير إلى `debian11` لأنه في دبيان 12، لا يمكن تثبيت متغير `osinfo` لدبيان 12 عبر libvirt بعد.
لتثبيت توزيعة أخرى، قم بتعديل القاموس الموجود في `/usr/lib/python3/dist-packages/mofos/settings.py`.
عند تشغيل الأمر أعلاه، يقوم Mofos بتنزيل ملفات الإقلاع عبر الشبكة (netboot) وتخزين أرشيف `tar.gz` مؤقتًا في `$HOME/.cache/template-installer`. حاليًا، إذا كان أرشيف netboot موجودًا بالفعل، فلن يقوم Mofos بتنزيله مرة أخرى. يمكن أن يتسبب هذا في أخطاء إذا كان الأرشيف المخزن مؤقتًا قديمًا. إذا حدثت مثل هذه الأخطاء أثناء التثبيت، فإن إزالة الأرشيف المخزن مؤقتًا ستجبر Mofos على تنزيل نسخة محدثة، مما يجب أن يحل المشكلة.
بعد ذلك، يتم استخراج الأرشيف إلى `/tmp`، ويتم تكوين libvirt لتقديم محتوياته عبر TFTP.
ثم يتم إنشاء الجهاز الظاهري القالب وضبطه على الإقلاع عبر PXE، لتثبيت التوزيعة المحددة باستخدام ملف البذر المسبق المقدم (افتراضيًا `/usr/share/mofos/templates/debian/preseed.cfg.j2`). هذا الملف هو قالب `jinja2`؛ قبل نسخه إلى الدليل الجذر لـ TFTP، يتم حقن المتغيرات من ملفات التكوين (`ntp`, `proxy`, `dns`, `root_password`).
في نهاية التثبيت، يتم وضع سكربت `postinstall` في دليل TFTP وتنفيذه على القالب. افتراضيًا، يتم استخدام السكربت الموجود في `/usr/share/mofos/templates/postinstall.sh.j2`. يقوم قالب `jinja2` هذا بحقن مفتاح SSH العام الذي سيتم تكوينه على القالب.
بالإضافة إلى تكوين مفتاح SSH العام للجذر، يتم تنفيذ العمليات التالية:
- تعطيل خدمة SSH القياسية وتمكين SSHD عبر المقابس الافتراضية (vsock).
- إفراغ ملف `/etc/resolv.conf`.
- ضبط مهلة GRUB على 0 ثانية.
- تثبيت خطاف initramfs يقوم بتركيب overlayfs عند اكتشاف قسم مسمى `overlay`.
بمجرد اكتمال التثبيت، يتم استرجاع الجهاز الظاهري libvirt وضغطه في ملف `qcow2` محلي محفوظ في الدليل الحالي.```
$ mofos template create debian-template
[*] Installing debian-template
[*] Configure the SSH host key of the template
[*] Waiting for the installation to be complete
[*] Installation is complete
[*] Downloading the resulting qcow2 disk
[*] Compressing the disk
[*] Save template's public ssh host key
[+] Template installation finished
[+] Template disk is debian-template-disk.qcow2
بالإضافة إلى ملف qcow2، تنشئ هذه العملية أيضًا إدخالًا في الملف $HOME/.local/share/mofos/ssh.json يحتوي على اسم الجهاز ومفتاح SSH العام الخاص به:```json
{
"disk": {
"debian-template-disk.qcow2": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINrbOdOPENEj2KeHrYLdorQe9Ez1b9Bu5agZmgNDMayy"
}
}
يتم استخدام هذا الملف تلقائيًا أثناء عملية الاستيراد.
### الاستيراد
الخطوة التالية هي استيراد ملف القالب `qcow2` الذي تم إنشاؤه إلى Mofos.```
$ mofos template import debian-template debian-template-disk.qcow2 http://debian.org/debian/11
[*] Uploading debian-template-disk.qcow2 to mofos pool
[*] Creating the virtual machine debian-template
[*] Configuring the template metadata
[*] Configuring the SSH key
[+] debian-template successfully imported
في الوقت الحالي، يُعد المتغير osinfo إلزاميًا. يمكن العثور عليها في الملف:
/usr/lib/python3/dist-packages/mofos/settings.py.
بمجرد استيراده، يمكن رؤية القالب في الأمر mofos ls:```
$ mofos ls
+----+-----------------+---------+-------------+-------+-----+--------------+
| Id | Name | State | Description | Alias | Cid | IPv4 address |
+----+-----------------+---------+-------------+-------+-----+--------------+
| | debian-template | shutoff | | | | |
+----+-----------------+---------+-------------+-------+-----+--------------+
من هذه النقطة، يمكن بدء القالب والوصول إليه للتعديل حسب الحاجة.```
$ mofos start debian-template
$ mofos ls
+----+-----------------+---------+-------------+-------+-----+----------------+
| Id | Name | State | Description | Alias | Cid | IPv4 address |
+----+-----------------+---------+-------------+-------+-----+----------------+
| 3 | debian-template | running | | | 3 | 192.168.90.202 |
+----+-----------------+---------+-------------+-------+-----+----------------+
The input content is empty, so there is nothing to translate.``` $ mofos ssh debian-template --user root root@linux:~#
## إنشاء قرص الطبقة العليا الفارغ
ينشئ الأمر التالي طبقة علوية فارغة بالتسمية المحددة على القسم الوحيد من القرص:```
$ mofos template create-overlay-disk
بشكل افتراضي، يتم ضبط هذا القرص على 50 جيجابايت لكنه يشغل في البداية حوالي 100 ميجابايت فقط. يمكن تخصيص هذا الحجم في ملف الإعدادات.
ملاحظة: يُنصح دائمًا بإيقاف تشغيل قالب قبل التعامل مع الأجهزة الافتراضية الخاصة بـ Mofos. على الرغم من أن تشغيل قالب وأجهزته الافتراضية في نفس الوقت مدعوم، إلا أنه قد يؤدي إلى عدم الاستقرار.``` $ mofos new test [] New virtual machine name is test [+] Virtual machine test successfully created [] Triggering post install actions [] Create SSH known_hosts entries for test [] Waiting for test to be up [+] test is ready $ mofos ssh test -u root Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@linux:~#
ضع في اعتبارك أن اتصالات SSH تتم عبر مآخذ افتراضية، لذا لا يمكنك الاتصال مباشرة عبر SSH بالجهاز المُنشأ حديثًا. بدلاً من ذلك، يجب استخدام أمر mofos ssh. أو بدلاً من ذلك، يمكنك إنشاء إعداد SSH يحدد `ProxyCommand `للوصول إلى منفذ SSH الخاص بالجهاز:```
$ mofos inventory --format ssh
Host debian-template
User user
PasswordAuthentication no
IdentityFile /home/user/.ssh/id_ed25519
ProxyCommand /usr/bin/mofos proxy-cmd %h
CanonicalizeHostname=no
Host test
User user
PasswordAuthentication no
IdentityFile /home/user/.ssh/id_ed25519
ProxyCommand /usr/bin/mofos proxy-cmd %h
CanonicalizeHostname=no
$ mofos inventory --format ssh > ~/.ssh/mofos $ echo "Include ~/.ssh/mofos" >> ~/.ssh/config $ ssh root@test Linux linux 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64
The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@linux:~#
أثناء جلسة `mofos ssh`، يتم إنشاء مقبس `ControlMaster` مسبقًا لتسريع الاتصالات اللاحقة. لهذا السبب لا يتم عرض MOTD.
## التخصيص
لتبسيط تخصيص القوالب والآلات الافتراضية، تقدم Mofos مفهوم الخطافات (hooks) والوسوم (tags). لكل وسم، يمكن تنفيذ خطاف مقابل (سكربت Bash) لتنفيذ إجراءات آلية على الآلة الافتراضية أو القالب المستهدف وتهيئته وفقًا لذلك.
تقع الخطافات الأساسية في `/usr/share/mofos/hooks`. وهي سكربتات Bash بسيطة تستقبل المدخلات التالية:```
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
يمكن الاستفادة من هذه الآلية مع Ansible لتنفيذ playbooks أثناء تثبيت القالب:```bash #!/bin/bash
TAG=$1 NAME=$2 OS=$3 DISTRIB=$4 HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${DISTRIB}" ] ; then exit 1 fi
ANSIBLE_DIRECTORY="/home/user/Documents/ansible" RANDOM_SUFFIX=$(printf "%x" $RANDOM) INVENTORY_FILE="${ANSIBLE_DIRECTORY}/inventory-${NAME}-${RANDOM_SUFFIX}.ini"
trap 'rm -f "${INVENTORY_FILE}"; exit' EXIT
cat > $INVENTORY_FILE <<EOF [all:vars] ansible_ssh_common_args="-o ProxyCommand='mofos proxy-cmd %h' -o CanonicalizeHostname=no"
[${TAG}] ${NAME}
[${DISTRIB}] ${NAME} EOF
export ANSIBLE_CONFIG="/home/user/Documents/ansible/ansible.cfg" export ANSIBLE_VERBOSITY=1
/usr/bin/ansible-playbook
-i "${INVENTORY_FILE}"
-l "${NAME}"
/home/user/Documents/ansible/playbooks/pentest/install.yml
يقوم هذا السكربت بإنشاء قائمة جرد (inventory) ديناميكية وتشغيل دليل تشغيل (playbook) عليها.
### الجهاز الافتراضي - hook جديد
أثناء إنشاء الجهاز الافتراضي، يمكن استخدام hook آخر، على سبيل المثال، لتعشية اسم المضيف (hostname).
بشكل افتراضي، يولّد Mofos اسمًا مستعارًا (alias) استنادًا إلى اصطلاح التسمية الكلاسيكي لنظام Windows (مثل `DESKTOP-2BF9753`). يتم تمرير هذا الاسم، إلى جانب معلومات أخرى، إلى سكربت الـ hook:```
#!/bin/bash
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${OS}" ] ; then
exit 1
fi
if [ -z "${HOSTNAME}" ] ; then
HOSTNAME="${NAME}"
fi
mofos run -u root "${NAME}" "echo ${HOSTNAME} > /etc/hostname && hostname ${HOSTNAME}"
بعد ذلك، يجب تعديل الإعدادات لتفعيل هذا الخطاف:``` [hooks.test] new = "/home/user/.config/mofos/hooks/new.sh"
ثم، أثناء إنشاء الجهاز الافتراضي، سيتم تنفيذ هذا السكربت:```
$ mofos new test2 --tags test
[*] New virtual machine name is test2
[+] Virtual machine test2 successfully created
[*] Triggering post install actions
[*] Create SSH known_hosts entries for test2
[*] Waiting for test2 to be up
[*] Running new hook: test
[+] test2 is ready
No content was provided to translate. Please supply the chunk text.``` $ mofos ssh test2 -u root Last login: Mon Jun 2 11:09:51 2025 from UNKNOWN root@DESKTOP-2BF9753:~#
على غرار مرحلة التثبيت، يمكن أيضًا تنفيذ دفاتر تشغيل Ansible في هذه المرحلة. في هذه الحالة، يمكن استخدام الأمر `mofos inventory` لإنشاء جرد Ansible، مما يبسّط عملية اختيار الأجهزة الافتراضية والوصول إليها:```
$ mofos inventory
{
"_meta": {
"hostvars": {
"debian-template": {
"ansible_host": "debian-template",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
},
"test": {
"ansible_host": "test",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
},
"test2": {
"ansible_host": "test2",
"ansible_ssh_common_args": "-o ProxyCommand='/usr/bin/mofos proxy-cmd %h' -o CanonicalizeHostname=no"
}
}
},
"debian": [
"debian-template",
"test",
"test2"
],
"test": [
"test2"
]
لاحظ أن المجموعات تُنشأ بناءً على متغير التوزيع وكذلك الوسوم. يمكن استخدام هذه المجموعات لتحميل متغيرات مختلفة.
على سبيل المثال، السكربت أدناه يشغّل أي playbook:```bash #!/bin/bash
TAG=$1 NAME=$2 OS=$3 DISTRIB=$4 HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] || [ -z "${OS}" ] ; then exit 1 fi
if [ -z "$HOSTNAME" ] ; then HOSTNAME=$NAME fi
if [ $OS == "windows" ] ; then TAGS="hostname,desktop" else TAGS="hostname,hosts,desktop" fi
export ANSIBLE_CONFIG="/home/user/Documents/ansible/ansible.cfg" export ANSIBLE_VERBOSITY=0
/usr/bin/ansible-playbook
-i /home/user/Documents/ansible/inventory.py
-l "${NAME}"
-t "${TAGS}"
-e "hostname=${HOSTNAME}"
/home/user/Documents/ansible/playbooks/pentest/update.yml
### الآلة الافتراضية - خطاف البدء
بالمثل، يتم تنفيذ خطاف البدء عند بدء تشغيل آلة افتراضية. ويُستخدم عادةً لتشغيل الخدمات المطلوبة من قِبل الآلة الافتراضية.
على سبيل المثال، لتمكين التكامل السلس مع Windows داخل الآلة الافتراضية، يمكنك تثبيت `Xpra`.
أولاً، قم بتثبيت `ansible`:```
# apt install ansible
بعد ذلك، قم بتشغيل playbook المستخدم الموجود في دليل ansible. قبل القيام بذلك، قم بتحرير ملف playbooks/user.yml لتحديث هاش كلمة المرور والمفتاح العام SSH الذي سيتم تثبيته في الدليل الرئيسي للمستخدم.```
~/mofos/ansible$ ls
ansible.cfg ansible.log inventory.sh playbooks
The input content is empty — no source text was provided for chunk 63. Please resend the chunk content so I can translate it into Arabic.```
$ ansible-playbook playbooks/user.yml -l test2
Using /home/user/mofos/ansible/ansible.cfg as config file
[WARNING]: Found both group and host with same name: test
PLAY [Create and configure a user]
[...]
PLAY RECAP
test2 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
بعد ذلك، يمكنك الاتصال عبر SSH بحساب المستخدم هذا، بشرط أن يحدد التكوين هذا المستخدم كمستخدم افتراضي:``` $ mofos ssh test2 user@DESKTOP-2BF9753:~$
بعد ذلك، قم بتشغيل playbook الخاص بـ `Xpra`. يقوم هذا الـ playbook بتثبيت الحزم من مرايا Debian. يُرجى ملاحظة أن شبكة Mofos لا تقوم بتهيئة DNS أو البروكسي أو البوابة الافتراضية افتراضيًا. يجب إعدادها قبل تشغيل الـ playbook.
لا يلزم إجراء أي تعديلات على الـ playbook افتراضيًا.```
ansible-playbook playbooks/xpra.yml -l test2
هذا الـ playbook يقوم بتثبيت وتهيئة Xpra ويشغّل خدمة xpra على الجهاز الافتراضي.
يمكن بدء الخدمة البعيدة يدويًا باستخدام:``` user@DESKTOP-2BF9753:~$ systemctl --user start xpra
بخلاف ذلك، ستبدأ الخدمة تلقائيًا عند إعادة التشغيل التالية.
ثم، يمكن أيضًا بدء خدمة العميل المحلي يدويًا:```
$ mofos xpra start test2
بالعودة إلى الجهاز الافتراضي، يجب ضبط العرض على :10 (الافتراضي)، وبعد ذلك يمكن تشغيل تطبيق رسومي وسيظهر داخل بيئة سطح المكتب للمضيف.```
user@DESKTOP-2BF9753:$ export DISPLAY=:10
user@DESKTOP-2BF9753:$ xterm
لضمان عمل هذه الآلية بسلاسة وتلقائية، يمكن بدء تشغيل الأمر `mofos xpra` من خطاف البدء.```bash
#!/bin/bash
TAG=$1
NAME=$2
OS=$3
DISTRIB=$4
HOSTNAME=$5
if [ -z "${TAG}" ] || [ -z "${NAME}" ] ; then
exit 1
fi
mofos xpra start "${NAME}"
لإعلامك ببدء تشغيل وإيقاف أجهزة libvirt/qemu، يمكن تعديل خطاف libvirt الخاص بـ qemu لتحديد اسم مستخدم المضيف (افتراضيًا user):```
### الحافظة
يمكن لـ Mofos أيضًا إدارة الحافظة بين الأجهزة الافتراضية والمضيف. الفكرة هي تكوين مفتاح اختصار محدد لتشغيل اتصال SSH بالجهاز الافتراضي المركّز حاليًا، إما لسحب محتوى حافظة X11 أو لدفع المحتوى إليها.
لدفع المحتوى إلى حافظة X11 للجهاز الافتراضي:```
mofos clipboard in pentest-0
لسحب المحتوى من حافظة X11 للجهاز الافتراضي:``` mofos clipboard out pentest-0
لكل عملية، سينشئ mofos اتصال SSH بالجهاز الافتراضي ويستخدم xclip وعلى المضيف `wl-copy` أو `xclip` وفقًا لتقنية النوافذ (Wayland مقابل X11).
قد يتم حذف اسم الجهاز في التتبع أعلاه، وفي هذه الحالة سيحدد السكريبت الجهاز الافتراضي المركّز عليه حاليًا ويستهدفه.
إذا كنت تستخدم Gnome wayland، فقد تحتاج إلى تثبيت امتداد Gnome shell الخاص بـ [email protected] باستخدام `sudo make install_gnome_extension`.
ستحتاج إلى تسجيل الخروج ثم تسجيل الدخول مرة أخرى للتأكد من تثبيت الامتداد.
### إعداد التوجيه بين الأجهزة
يوجد خياران في mofos لتوجيه جهاز افتراضي:
- `mofos route` الذي يأخذ بوابة (gateway) ويقوم بتهيئة `ip rule` على المضيف لتوجيه الجهاز الافتراضي عبر هذه البوابة.
- `mofos pivot` الذي يأخذ جهاز mofos آخر، ويستعيد عنوان IP الخاص به ويضبطه كبوابة افتراضية للجهاز الافتراضي الحالي.
يمكن لكلا الخيارين قبول خادم DNS لضبطه.
### إعداد الأنفاق عبر صناديق اختبار الاختراق
يقوم أمر `mofos tunnel` بإعداد VPN عبر SSH (`ssh -w`) لتوجيه حركة مرور جهاز mofos عبر خادم. تعتمد هذه الميزة على عدد قليل من الإعدادات:
بشكل ملموس، يقوم أمر `mofos tunnel` بالإجراءات التالية (لا سحر هنا):
1. إنشاء واجهة tun محلية (`sudo /usr/libexec/mofos/mofosnet.py tun add pentest_box`) وتعيين عنوان IP لهذه الواجهة.
2. تشغيل `tunneling.command` على الخادم البعيد، ويجب أن يقوم هذا الأمر بإنشاء واجهة tun ليتم ربطها لاحقًا بالواجهة المحلية (`/usr/libexec/mofos/mofosnet.py sshvpn start pentest_box`).
3. توجيه حركة مرور جهاز mofos عبر بوابة الصندوق البعيد (`/usr/libexec/mofos/mofosnet.py route mofos_vm_ip gateway_ip`)، كما يتم تغيير البوابة الافتراضية للجهاز الافتراضي mofos.
يجب تعريف `tunneling.command` في ملف الإعدادات `/etc/mofos/mofosnet.toml`. على سبيل المثال:```toml
[tunneling.command]
start = "sudo ssh-vpn start" # the peer remote address will be supplied as argv[1]
stop = "sudo ssh-vpn stop"
أما بالنسبة لأوامر route و pivot، فيمكن توفير DNS لتهيئته أيضًا.
يتيح أمر mofos usb إدارة أجهزة USB.
يتم تحديد الأجهزة بواسطة معرفها (vendor_id:product_id) وهو مطلوب لأمرَي الإرفاق والفصل (attach و detach):```console $ mofos ls usb +-----------+------------------------------------------------+-------------+ | ID | Device | Attached to | +-----------+------------------------------------------------+-------------+ | 0bda:8153 | Realtek, RTL8153 Gigabit Ethernet Adapter | | | 046d:c077 | Logitech, Mouse | | | 0a5c:5842 | Broadcom Corp, 58200 | | | 1bcf:28d2 | CN0Y9V728LG003AGBCJZA01, Integrated_Webcam_FHD | | +-----------+------------------------------------------------+-------------+ $ mofos usb attach pentest-1 0bda:8153 $ mofos usb +-----------+------------------------------------------------+-------------+ | ID | Device | Attached to | +-----------+------------------------------------------------+-------------+ | 0bda:8153 | Realtek, RTL8153 Gigabit Ethernet Adapter | pentest-1 | | 046d:c077 | Logitech, Mouse | | | 0a5c:5842 | Broadcom Corp, 58200 | | | 1bcf:28d2 | CN0Y9V728LG003AGBCJZA01, Integrated_Webcam_FHD | | +-----------+------------------------------------------------+-------------+ $ mofos usb detach pentest-4 0bda:8153
خيار `force` يفصل الجهاز ويعيد توصيله. يُستخدم عادةً لإعادة توصيل جهاز تم نزعه دون أن يتم فصله أولاً.
ملاحظة: إرفاق جهاز USB يكون صالحًا فقط طوال عمر الجهاز الافتراضي الحالي. عندما يتوقف، يتم فصل الجهاز تلقائيًا.
### إدارة أجهزة PCI
على غرار أجهزة USB، يتيح mofos إرفاق جهاز PCI بجهاز افتراضي قيد التشغيل، والأوامر هي نفسها.
هناك قيود إضافية تتعلق ببعض أجهزة PCI التي تنتمي إلى مجموعة. على سبيل المثال، قد يتطلب إرفاق بطاقة الإيثرنت بجهاز افتراضي قيد التشغيل نقل مجموعة PCI بأكملها داخل الجهاز الافتراضي. وبما أنه لا يمكن القيام بذلك بشكل تسلسلي، فإنه غير مدعوم حاليًا. ومع ذلك، بالنسبة لجهاز PCI فريد مثل بطاقة شبكة Wi-Fi، فإنه يعمل بشكل جيد.
### المجلدات المشتركة
ينشئ أمر `mofos mount` مجلدات مشتركة ويمكنه تثبيت نظام الملفات المضاف حديثًا في دليل داخل الجهاز الافتراضي. وسيقوم `mofos umount` بإلغاء تثبيت الدليل وإزالة المجلدات المشتركة من تكوين الجهاز الافتراضي.
تعتمد هذه الآلية على تقنية `virtiofsd` التي تتطلب تمكين الذاكرة المشتركة، ويتم ذلك الآن افتراضيًا عند إنشاء جهاز افتراضي. وإلا، فإن الأمر التالي سيقوم بتمكينها:```console
virt-xml -c qemu:///system --edit --memorybacking source.type=memfd,access.mode=shared DOMAIN
علاوةً على ذلك، تقيّد سياسات AppArmor المقدَّمة الدلائل التي يمكن مشاركتها من المضيف. ويتم ذلك لمنع المستخدم من تكوين مشاركة على دليل /etc أو جذر نظام الملفات وتعديلها باستخدام صلاحيات الجذر داخل الجهاز الافتراضي. لذلك، يلزم تعديل سياسة usr.lib.qemu.virtiofsd للسماح بمشاركة دلائل عشوائية.
ينبغي تكييف سطرين:``` @{SHARE_DIRS}=/data/libvirt/shares// /home/user/Public/**/ [...] pivot_root /data/libvirt/shares//, pivot_root /home/user/Public/**/,
The `SHARE_DIRS` variable is reused in the policy, however, due to apparmor limitations, it is not possible to reuse it for `pivot_root` directives. Therefore, it is required to manually adapt the `pivot_root` directives for each shared directories.
يتم إعادة استخدام متغير `SHARE_DIRS` في السياسة، ومع ذلك، نظرًا لقيود apparmor، لا يمكن إعادة استخدامه لتوجيهات `pivot_root`. لذلك، يلزم تكييف توجيهات `pivot_root` يدويًا لكل دليل مشترك.
لتثبيت دليل محلي:```
mofos mount test ./Public/share -d /home/user/share
من أجل عدم إزعاج الجهاز الافتراضي حيث سيتم تثبيت المشاركة، إذا كان الدليل البعيد غير فارغ، يتم إصدار تحذير ويتيح لك السكربت إجراء عملية التثبيت يدويًا.
أخيرًا، عملية التثبيت ليست دائمة ويجب إعادة تنفيذها عند كل إعادة تشغيل.
لإنشاء أجهزة افتراضية تعمل بنظام Windows، يجب إنشاء قالب جهاز يدويًا أولاً. يُستخدم قرص هذا القالب بعد ذلك كملف أساسي لإنشاء الأجهزة الفرعية. بشكل افتراضي، أجهزة Windows الافتراضية التي يتم إنشاؤها باستخدام Mofos ليست مُهيأة مسبقًا. ومع ذلك، من الممكن تكوين Mofos لتنفيذ مهام ما بعد التهيئة، مثل تغيير اسم المضيف وإضافة إدخال مخصص في ملف known_hosts، باستخدام الخطافات.
لتمكين الإعداد بعد الإنشاء، المتطلبات الأساسية التالية إلزامية:
authorized_keys في C:\Program Data\ssh\administrators_authorized_keys مع ACL محدد```powershell
$admin_group = "Administrators"
$system = "SYSTEM"$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys $acl.SetAccessRuleProtection($true, $false) $administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule($admin_group,"FullControl","Allow") $systemRule = New-Object system.security.accesscontrol.filesystemaccessrule($system,"FullControl","Allow") $acl.SetAccessRule($administratorsRule) $acl.SetAccessRule($systemRule) $acl | Set-Acl
- يجب تكوين OpenSSH باستخدام shell من نوع `PowerShell` بدلاً من `cmd.exe`.```powershell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" `
-Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-PropertyType String `
-Force
$HOME/.local/share/mofos/ssh.json. سيضمن ذلك إنشاء إدخال known_hosts مطابق لكل جهاز جديد باستخدام مفتاح مضيف القالب.## الإكمال التلقائي
يجب أن يكون الإكمال التلقائي مدعومًا افتراضيًا لكل من `bash` و`fish`. بالنسبة إلى `zsh`، قد تحتاج إلى تنفيذ الأوامر التالية:```
autoload -Uz compinit
compinit
source /usr/share/zsh/vendor-completions/_mofos
قد تحصل الأجهزة الافتراضية المستندة إلى نفس قرص القالب على نفس عنوان IP حتى وإن تغيّر عنوان MAC الخاص ببطاقة شبكتها بسبب معرّف DHCP. يمكن تغيير هذا السلوك عن طريق تحرير إعدادات الشبكة الخاصة بالقالب:
مع systemd-networkd:``` [Match] Name=eth0
[Network] DHCP=yes MulticastDNS=no IPv6AcceptRA=no
[DHCP] ClientIdentifier=mac
مع واجهات الشبكة القديمة `/etc/network/interfaces`:```
iface eth0 inet dhcp
client no