
가상 머신 조작 프레임워크
Mofos는 가상 머신을 생성, 실행, 관리하도록 설계된 도구입니다. Libvirt/QEMU/KVM 및 Python을 활용하므로 모든 Linux 배포판과 호환됩니다. Qubes OS (https://www.qubes-os.org/)에서 많은 영감을 받았으며, Mofos는 Qubes OS의 많은 기능을 재현하는 것을 목표로 합니다.
이 도구는 Debian과 Debian 기반 가상 머신에서 광범위하게 테스트되었습니다. 다른 Linux 배포판에서도 작동할 것으로 예상되지만, 일부 추가 구성이 필요할 수 있습니다. 더 자세한 내용은 추후 추가될 예정입니다.
Mofos는 가상 머신을 안전하게 관리하는 데 중점을 둔 다양한 기능을 제공합니다:
Mofos 머신은 overlayfs를 사용하여 결합된 두 개의 디스크로 구성됩니다. 첫 번째 디스크는 하위 레이어로 알려진 읽기 전용 템플릿 디스크이고, 두 번째 디스크는 가상 머신이 수행한 모든 변경 사항을 저장합니다. 이 템플릿 디스크는 여러 가상 머신 간에 공유됩니다. 결과적으로 새 가상 머신을 생성하려면 수정된 데이터를 보관하도록 이미 파티셔닝된 빈 디스크를 복제하기만 하면 됩니다. 이 방식을 통해 새 가상 머신을 빠르게 생성할 수 있으며, 템플릿은 독립적으로 업데이트할 수 있습니다. 템플릿에 대한 업데이트는 종속 가상 머신이 다음에 재부팅할 때 적용됩니다.
Linux 배포판에 따라 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
Depending on the distribution, the Python files copied to /usr/lib/python3/dist-packages may not be detected by the Python interpreter and should be placed elsewhere. For example, on Fedora, the Python files must be copied to /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` 시스템 소켓과 상호 작용하여 머신, 네트워크 및 기타 리소스를 관리할 수 없습니다. 액세스 권한을 얻으려면 사용자는 libvirt Unix 그룹의 구성원이거나 sudo를 사용해야 합니다. 과거에는 libvirt 그룹 구성원 자격을 악용하여 root 권한을 얻는 로컬 권한 상승 취약점이 있었습니다.
이러한 위험을 완화하기 위해 이 저장소는 AppArmor를 사용하는 시스템에서 `libvirtd` 프로세스에 대한 강화된 AppArmor 프로필을 제공합니다. 이 프로필은 `libvirtd`가 파일을 쓸 수 있는 위치와 실행할 수 있는 프로그램을 크게 제한합니다.
또한 `libvirt` 그룹 구성원에게 허용되는 작업을 추가로 제어하기 위해 `polkit` 규칙이 포함되어 있습니다.
AppArmor 프로필은 `deb` 패키지에 포함되어 있지만 Makefile의 `install_files` 대상에 의해 설치되지 않으므로 별도로 설치해야 합니다.
## 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 (path): 가상 머신에 접근하는 데 사용되는 SSH 개인 키 파일입니다. 이 목적을 위해 전용 키를 생성하는 것이 좋습니다.
- user (string): 가상 머신에 SSH로 접근할 때 사용할 사용자 이름입니다.
- root_password (hashed value): 새 템플릿을 설치하는 동안 설정할 루트 비밀번호의 해시값입니다.
- root_ssh_pubkey (string): 템플릿 설치 중 root 사용자의 디렉터리에 설치할 공개 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
`ip_forward` 매개변수가 1로 설정된 경우, 네트워크의 다른 장치가 호스트를 라우터로 사용하지 못하도록 FORWARD 체인을 구성해야 합니다.
전반적으로 다음 규칙을 권장합니다:```
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 및 forwarding 규칙을 제한하여 mofos 가상 머신이 호스트 네트워크 전체에 접근하지 못하도록 하는 것이 좋습니다.
가상 머신 간 격리는 libvirt hook에 의해 자동으로 적용되며, 제대로 작동하려면 nft가 필요합니다.
### 설치
첫 번째 단계는 초기 레이어인 템플릿을 구축하는 것입니다. 기본적으로 Mofos는 Debian 12 기반 템플릿을 설치할 수 있습니다.```
mofos template create debian-template
참고: 모든 명령에서 --debug 옵션을 사용하면 예기치 않은 동작이 발생할 경우 자세한 기술 정보를 얻을 수 있습니다. 특히 이 명령의 경우 --debug 플래그는 설치 진행 상황을 표시하는 그래픽 창을 강제로 띄웁니다. 또는 virt-manager.를 사용하여 설치를 모니터링할 수 있습니다.
현재 설치에서는 Debian 12 템플릿만 지원됩니다. 아래 Python 딕셔너리는 사용할 설치 이미지를 지정합니다:```python NETBOOT = { "debian-stable-amd64": { "variant": "debian11", "url": "https://deb.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz", } }
변형(variant)은 `debian11`로 설정되어 있다. Debian 12에서는 `osinfo` 변형이 아직 libvirt를 통해 설치할 수 없기 때문이다.
다른 배포판을 설치하려면 `/usr/lib/python3/dist-packages/mofos/settings.py`에 있는 사전(dictionary)을 수정한다.
위 명령이 실행되면 Mofos는 netboot 파일을 다운로드하고 `tar.gz` 아카이브를 `$HOME/.cache/template-installer`에 캐시한다. 현재, netboot 아카이브가 이미 존재하면 Mofos는 다시 다운로드하지 않는다. 캐시된 아카이브가 오래된 경우 오류가 발생할 수 있다. 설치 중 이러한 오류가 발생하면 캐시된 아카이브를 제거하면 Mofos가 업데이트된 버전을 강제로 다운로드하게 되어 문제가 해결될 것이다.
다음으로 아카이브는 `/tmp`에 추출되고, libvirt는 TFTP를 통해 그 내용을 제공하도록 구성된다.
그런 다음 템플릿 가상 머신이 생성되어 PXE로 부팅되도록 설정되며, 제공된 preseed 파일(기본적으로 `/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 서비스를 비활성화하고 가상 소켓(vsock)을 통한 SSHD를 활성화한다.
- `/etc/resolv.conf` 파일을 비운다.
- GRUB 타임아웃을 0초로 구성한다.
- `overlay` 레이블이 지정된 파티션이 감지되면 overlayfs를 마운트하는 initramfs 훅을 설치한다.
설치가 완료되면 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 파일 외에도 이 프로세스는 머신의 이름과 공개 SSH 키가 포함된 $HOME/.local/share/mofos/ssh.json 파일에 항목을 생성합니다:```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 |
+----+-----------------+---------+-------------+-------+-----+----------------+
이를 통해 실시간 모니터링, 결과의 신속한 분류, 이해관계자와의 손쉬운 데이터 공유가 가능합니다.``` $ mofos ssh debian-template --user root root@linux:~#
## 상위 레이어 빈 디스크 생성
다음 명령은 디스크의 단일 파티션에 지정된 레이블로 빈 상위 레이어를 생성합니다:```
$ mofos template create-overlay-disk
기본적으로 이 디스크는 50GB로 설정되지만 초기에는 약 100MB만 차지합니다. 이 크기는 구성 파일에서 사용자 지정할 수 있습니다.
참고: 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과 함께 활용하여 템플릿 설치 중에 플레이북을 실행할 수 있습니다:```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
이 스크립트는 인벤토리를 동적으로 생성하고 그에 대해 플레이북을 실행합니다.
### 가상 머신 - 새 후크
가상 머신 생성 중에 예를 들어 호스트 이름을 무작위화하기 위해 다른 후크를 사용할 수 있습니다.
기본적으로 Mofos는 표준 Windows 명명 규칙(예: `DESKTOP-2BF9753`)에 따라 별칭을 생성합니다. 이 이름은 다른 정보와 함께 후크 스크립트로 전달됩니다:```
#!/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 provided in the input chunk to translate.)``` $ 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"
]
참고로 그룹은 태그뿐만 아니라 배포 변형을 기반으로 생성됩니다. 이 그룹들은 서로 다른 변수를 로드하는 데 사용할 수 있습니다.
예를 들어, 아래 스크립트는 임의의 플레이북을 실행합니다:```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
다음으로, ansible 디렉터리에 있는 사용자 플레이북을 실행하세요. 실행하기 전에 playbooks/user.yml 파일을 편집하여 사용자의 홈 디렉터리에 설치될 비밀번호 해시와 공개 SSH 키를 업데이트하세요.```
~/mofos/ansible$ ls
ansible.cfg ansible.log inventory.sh playbooks
The input chunk is empty. There is no content to translate. Please provide the Markdown text for chunk 63 of 104.```
$ 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:~$
Next, run the `Xpra` playbook. This playbook installs packages from Debian mirrors. Please note that the Mofos network does not configure DNS, proxy, or a default gateway by default. These must be set up before running the playbook.
No modifications to the playbook are required by default.```
ansible-playbook playbooks/xpra.yml -l test2
이 플레이북은 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는 가상 머신과 호스트 간의 클립보드도 관리할 수 있습니다. 이 아이디어는 현재 포커스된 VM에 SSH 연결을 트리거하는 특정 키바인드를 구성하여 X11 클립보드를 가져오거나 해당 클립보드에 콘텐츠를 푸시하는 것입니다.
가상 머신 X11 클립보드에 콘텐츠를 푸시하려면:```
mofos clipboard in pentest-0
가상 머신 X11 클립보드에서 콘텐츠를 가져오려면:``` mofos clipboard out pentest-0
각 작업에 대해 mofos는 가상 머신에 SSH 연결을 설정하고 호스트에서는 윈도우 기술(wayland vs X11)에 따라 `wl-copy` 또는 `xclip`을 사용합니다.
위 추적(trace)에서 머신 이름은 생략될 수 있으며, 이 경우 스크립트는 현재 포커스된 가상 머신을 식별하여 대상으로 삼습니다.
Gnome wayland를 사용하는 경우 `sudo make install_gnome_extension`로 [email protected] Gnome 셸 확장을 설치해야 할 수 있습니다.
확장이 설치되었는지 확인하려면 로그아웃 후 다시 로그인해야 합니다.
### 머신 간 라우팅 설정
mofos에서 VM을 라우팅하는 두 가지 옵션이 있습니다:
- `mofos route`: 게이트웨이를 받아 호스트에서 `ip rule`을 구성하여 이 게이트웨이를 통해 가상 머신을 라우팅합니다.
- `mofos pivot`: 다른 mofos 머신을 받아 IP 주소를 검색하고
현재 가상 머신의 기본 게이트웨이로 구성합니다.
두 옵션 모두 DNS 서버를 받아 구성할 수 있습니다.
### 펜테스트 박스를 통한 터널링 설정
`mofos tunnel` 명령은 SSH VPN(`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 장치를 관리할 수 있게 해줍니다.
장치는 attach 및 detach 명령에 필요한 ID(vendor_id:product_id)로 식별됩니다.```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
The `force` 옵션은 장치를 분리(detach)하고 다시 연결(re-attach)합니다. 일반적으로 먼저 분리하지 않고 분리된(뽑힌) 장치를 다시 연결할 때 사용됩니다.
참고: USB 장치 연결은 가상 머신의 현재 수명 동안에만 유효합니다. 가상 머신이 중지되면 장치는 자동으로 분리됩니다.
### PCI 장치 관리
USB 장치와 유사하게, mofos는 실행 중인 가상 머신에 PCI 장치를 연결할 수 있게 해주며, 명령어는 동일합니다.
추가 제한 사항은 일부 그룹에 속한 PCI 장치와 관련이 있습니다. 예를 들어, 실행 중인 가상 머신에 이더넷 보드를 연결하려면 전체 PCI 그룹을 가상 머신 내부로 이동해야 할 수 있습니다. 이는 순차적으로 수행할 수 없기 때문에 아직 지원되지 않습니다. 그러나 Wi-Fi 네트워크 카드와 같은 단일 PCI 장치의 경우 정상적으로 작동합니다.
### 공유 폴더
`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.
To mount a local directory:```
mofos mount test ./Public/share -d /home/user/share
공유가 마운트될 가상 머신을 방해하지 않기 위해, 원격 디렉터리가 비어 있지 않으면 경고가 표시되고 스크립트는 마운트 작업을 수동으로 수행하도록 합니다.
마지막으로, 마운트 작업은 영구적이지 않으므로 재부팅할 때마다 다시 수행해야 합니다.
Windows 가상 머신을 생성하려면 먼저 템플릿 머신을 수동으로 만들어야 합니다. 이 템플릿의 디스크는 하위 머신을 생성하기 위한 backing file로 사용됩니다. 기본적으로 Mofos로 생성된 Windows 가상 머신은 사전 구성되어 있지 않습니다. 그러나 후크를 사용하여 호스트 이름 변경 및 known_hosts 파일에 전용 항목 추가와 같은 사후 구성 작업을 수행하도록 Mofos를 구성할 수 있습니다.
생성 후 설정을 활성화하려면 다음 사전 요구 사항이 필수입니다:
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는 `cmd.exe` 대신 `PowerShell` 셸로 구성해야 합니다.```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
동일한 템플릿 디스크를 기반으로 하는 가상 머신은 네트워크 카드의 MAC 주소가 DHCP 식별자로 인해 변경되더라도 동일한 IP 주소를 얻을 수 있습니다. 이 동작은 템플릿의 네트워크 구성을 편집하여 변경할 수 있습니다:
systemd-networkd 사용 시:``` [Match] Name=eth0
[Network] DHCP=yes MulticastDNS=no IPv6AcceptRA=no
[DHCP] ClientIdentifier=mac
레거시 네트워크 인터페이스 `/etc/network/interfaces` 사용 시:```
iface eth0 inet dhcp
client no