
QubesOS용 미니멀 유니커널 방화벽으로, 네트워크 트래픽을 필터링하고 NAT를 구현하며 Qubes DB 및 qrexec를 통해 통신합니다.
QubesOS ProxyVM으로 실행되어 sys-firewall을 대체할 수 있는 유니커널입니다.
Qubes 프로토콜을 구현하기 위해 mirage-qubes 라이브러리를 사용합니다.
자세한 내용은 QubesOS용 유니커널 방화벽을 참조하세요.
미리 빌드된 바이너리는 릴리스 페이지에서 받을 수 있습니다. 설치 방법은 아래의 Deploy 섹션을 참조하세요.
참고: 빌드하는 가장 확실한 방법은 Docker 또는 Podman을 사용하는 것입니다. Fedora 42가 잘 작동하며 Debian 12도 작동하지만, Docker를 얻으려면 docker.com의 지침을 따라야 합니다 (Debian 버전을 사용하지 마세요).
새 Fedora-42 AppVM을 만들거나 기존 AppVM을 재사용하세요. Qube 설정(기본 / 디스크 저장 공간)에서 개인 저장 공간 최대 크기를 기본 2048 MiB에서 8192 MiB로 늘리세요. 터미널을 엽니다.
이 Git 저장소를 클론하고 build-with.sh 스크립트를 docker 또는 podman 인자로 실행하세요 (참고: 새 SELinux 정책이 표준적으로 docker 이미지를 홈 디렉터리에 유지하는 것을 허용하지 않는 Fedora에서는 chcon 호출이 필수입니다):
mkdir /home/user/docker
sudo ln -s /home/user/docker /var/lib/docker
sudo chcon -Rt container_file_t /home/user/docker
sudo dnf install docker
sudo systemctl start docker
git clone https://github.com/mirage/qubes-mirage-firewall.git
cd qubes-mirage-firewall
sudo ./build-with.sh docker
또는
sudo systemctl start podman
git clone https://github.com/mirage/qubes-mirage-firewall.git
cd qubes-mirage-firewall
./build-with.sh podman
제 노트북에서는 약 15분이 걸렸습니다 (다시 실행하면 훨씬 빨라집니다). 빌드 VM이 독립형(standalone)인 경우 시작 부분의 심볼릭 링크 단계는 필요하지 않습니다. 이는 Docker에 더 많은 디스크 공간을 제공하고 Qube를 재부팅할 때 Docker 이미지 캐시가 손실되는 것을 방지합니다. Podman은 기본적으로 컨테이너가 홈 디렉터리에 저장되므로 필요하지 않습니다.
참고: 객체 파일은 증분 빌드 속도를 높이기 위해 _build 디렉터리에 저장됩니다.
종속성을 변경하는 경우 다시 빌드하기 전에 이 디렉터리를 삭제해야 합니다.
재부팅 후에도 유지하려면 템플릿 VM에 Docker 또는 Podman 패키지를 설치해도 괜찮지만, 방화벽 자체의 빌드는 일반 AppVM에서 수행해야 합니다.
일반적인 Mirage 유니커널과 마찬가지로 이 스크립트 없이도 빌드할 수 있습니다. 자세한 내용은 Mirage 설치 지침을 참조하세요.
빌드 스크립트는 사용하는 라이브러리 버전을 고정하므로 릴리스에 있는 것과 정확히 동일한 바이너리를 얻을 수 있습니다. 이 스크립트 없이 빌드하면 최신 버전을 대상으로 빌드됩니다 (따라서 해시는 아마 일치하지 않을 것입니다). 그래도 정상적으로 작동할 것입니다.
수동으로 배포하려면 domU에서 qubes-firewall.xen과
qubes-firewall.sha256을 다운로드하고 .xen 파일이 해당
해시섬과 일치하는지 확인하기만 하면 됩니다. qubes-firewall.xen은 유니커널 자체이며 dom0의 /var/lib/qubes/vm-kernels/mirage-firewall 디렉터리에 있는
vmlinuz로 복사해야 합니다. 예를 들어
(dev가 빌드한 AppVM인 경우):
[tal@dom0 ~]$ mkdir -p /var/lib/qubes/vm-kernels/mirage-firewall/
[tal@dom0 ~]$ cd /var/lib/qubes/vm-kernels/mirage-firewall/
[tal@dom0 mirage-firewall]$ qvm-run -p dev 'cat mirage-firewall/qubes-firewall.xen' > vmlinuz
위에서 추가한 mirage-firewall 커널을 사용하여 mirage-firewall VM을 만들려면 dom0에서 다음 명령을 실행하세요
qvm-create \
--property kernel=mirage-firewall \
--property kernelopts='' \
--property memory=32 \
--property maxmem=32 \
--property netvm=sys-net \
--property provides_network=True \
--property vcpus=1 \
--property virt_mode=pvh \
--property audiovm='' \
--label=green \
--class StandaloneVM \
mirage-firewall
qvm-features mirage-firewall qubes-firewall 1
qvm-features mirage-firewall no-default-kernelopts 1
qvm-features mirage-firewall skip-update 1
Qubes에서 salt state를 실행하는 방법에 익숙하다면 SaltScriptToDownloadAndInstallMirageFirewallInQubes.sls 스크립트를 사용하여 Qubes OS에 최신 버전의 Mirage 방화벽을 자동으로 배포할 수도 있습니다. 소개는 여기와 여기에서 확인할 수 있습니다. 이전 링크의 지침을 따라 dom0에서 sudo qubesctl --show-output state.apply SaltScriptToDownloadAndInstallMirageFirewallInQubes saltenv=user 명령으로 스크립트를 실행할 수 있습니다. 스크립트는 통합 서버의 체크섬을 확인하고 GitHub 릴리스에서 제공되는 최신 버전과 비교합니다. 기본 템플릿에 curl 및 tar 도구가 기본 설치되어 있지 않은 경우, Mirage 유니커널 다운로드에 사용되는 VM 템플릿을 스크립트에서 조정해야 할 수 있습니다. 또한 유니커널을 사용해야 하는 VM을 변경하거나 "Qubes 전역 설정"을 조정하는 것을 잊지 마세요.
이전 릴리스에서 업그레이드하려면 /var/lib/qubes/vm-kernels/mirage-firewall/vmlinuz를 새 버전으로 덮어쓰고 방화벽 VM을 다시 시작하기만 하면 됩니다.
기존 sys-firewall와 함께 mirage-firewall을 실행할 수 있으며 GUI를 통해 어떤 AppVM이 어떤 방화벽을 사용할지 선택할 수 있습니다.
AppVM이 이를 사용하도록 구성하려면 GUI의 앱 VM 설정으로 이동하여 해당 NetVM을 default (sys-firewall)에서 mirage-firewall로 변경하세요.
dom0에서 다음 명령을 실행하여 구성할 수도 있습니다 (my-app-vm을 AppVM 이름으로 바꾸세요):
qvm-prefs --set my-app-vm netvm mirage-firewall
또는 mirage-firewall을 기본 방화벽 VM으로 구성할 수 있습니다.
기본적으로 dom0은 sys-firewall을 "UpdateVM"(업데이트 다운로드를 위한 프록시)으로 사용합니다. mirage-firewall은 이 용도로 사용할 수 없지만 Linux VM은 무엇이든 괜찮습니다. https://www.qubes-os.org/doc/software-update-dom0/ 에 따르면:
UpdateVM의 역할은 Qubes VM Manager에서 모든 VM에 할당할 수 있으며, 이 선택에 중요한 보안 영향은 없습니다. 기본적으로 이 역할은 firewallvm에 할당됩니다.
OpenBSD는 현재 netvm으로 사용할 수 없으므로 BSD를 sys-net VM으로 사용하려면 해당 netvm을 qubes-mirage-firewall로 설정해야 합니다 (자세한 내용은 https://github.com/mirage/qubes-mirage-firewall/issues/146 참조).
즉, AppVMs -> qubes-mirage-firewall <- OpenBSD 구조가 되며 화살표는 netvm 속성 설정을 나타냅니다.
이 경우 업링크로 사용할 AppVM 클라이언트를 qubes-mirage-firewall에 알려야 합니다:
qvm-prefs --set mirage-firewall -- kernelopts '--ipv4=X.X.X.X --ipv4-gw=Y.Y.Y.Y'
여기서 X.X.X.X는 mirage-firewall의 IP 주소이고 Y.Y.Y.Y는 OpenBSD HVM의 IP 주소입니다.
이 다이어그램은 주요 구성 요소를 보여줍니다 (각 상자는 동일한 이름의 소스 .ml 파일에 해당합니다):
이더넷 프레임은 클라이언트 qubes(work 또는 personal 등) 또는 sys-net에서 도착합니다.
인터넷(IP) 패킷은 firewall로 전송되며, NAT 테이블과 QubesDB의 규칙을 참조하여 패킷을 어떻게 처리할지 결정합니다.
패킷을 전달해야 한다면 router를 사용하여 선택한 대상으로 보냅니다.
client_net은 dom0에서 제공하는 XenStore 데이터베이스를 감시하여
클라이언트를 추가하거나 제거해야 하는 시기를 파악합니다.
부팅 과정:
config.ml은 사용되는 라이브러리와 정적 구성 설정(NAT 테이블 크기)을 설명합니다.
mirage 도구는 이를 사용하여 main.ml을 생성합니다.main.ml은 config.ml에서 선택한 드라이버를 초기화하고
unikernel.ml의 start 함수를 호출합니다.unikernel.ml은 Qubes 에이전트를 연결하고 네트워킹 구성 요소를 설정한
다음 종료 요청을 기다립니다.개발 중에는 test-mirage 스크립트를 사용하여 개발 AppVM에서 유니커널(qubes-firewall.xen)을 배포하세요.
처음에는 설정이 조금 더 필요하지만 그 이후에는 훨씬 빠릅니다. 예:
[user@dev ~]$ test-mirage dist/qubes-firewall.xen mirage-firewall
Waiting for 'Ready'... OK
Uploading 'dist/qubes-firewall.xen' (7454880 bytes) to "mirage-test"
Waiting for 'Booting'... OK
Connecting to mirage-test console...
Solo5: Xen console: port 0x2, ring @0x00000000FEFFF000
| ___|
__| _ \ | _ \ __ \
\__ \ ( | | ( | ) |
____/\___/ _|\___/____/
Solo5: Bindings version v0.7.3
Solo5: Memory map: 32 MB addressable:
Solo5: reserved @ (0x0 - 0xfffff)
Solo5: text @ (0x100000 - 0x319fff)
Solo5: rodata @ (0x31a000 - 0x384fff)
Solo5: data @ (0x385000 - 0x53ffff)
Solo5: heap >= 0x540000 < stack < 0x2000000
2022-08-13 14:55:38 -00:00: INF [qubes.rexec] waiting for client...
2022-08-13 14:55:38 -00:00: INF [qubes.db] connecting to server...
2022-08-13 14:55:38 -00:00: INF [qubes.db] connected
2022-08-13 14:55:38 -00:00: INF [qubes.db] got update: "/mapped-ip/10.137.0.20/visible-ip" = "10.137.0.20"
2022-08-13 14:55:38 -00:00: INF [qubes.db] got update: "/mapped-ip/10.137.0.20/visible-gateway" = "10.137.0.23"
2022-08-13 14:55:38 -00:00: INF [qubes.rexec] client connected, using protocol version 3
2022-08-13 14:55:38 -00:00: INF [unikernel] QubesDB and qrexec agents connected in 0.041 s
2022-08-13 14:55:38 -00:00: INF [dao] Got network configuration from QubesDB:
NetVM IP on uplink network: 10.137.0.4
Our IP on uplink network: 10.137.0.23
Our IP on client networks: 10.137.0.23
DNS resolver: 10.139.1.1
DNS secondary resolver: 10.139.1.2
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] connect 0
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] create: id=0 domid=1
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] sg:true gso_tcpv4:true rx_copy:true rx_flip:false smart_poll:false
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] MAC: 00:16:3e:5e:6c:00
2022-08-13 14:55:38 -00:00: INF [ethernet] Connected Ethernet interface 00:16:3e:5e:6c:00
2022-08-13 14:55:38 -00:00: INF [ARP] Sending gratuitous ARP for 10.137.0.23 (00:16:3e:5e:6c:00)
2022-08-13 14:55:38 -00:00: INF [ARP] Sending gratuitous ARP for 10.137.0.23 (00:16:3e:5e:6c:00)
2022-08-13 14:55:38 -00:00: INF [udp] UDP layer connected on 10.137.0.23
2022-08-13 14:55:38 -00:00: INF [dao] Watching backend/vif
2022-08-13 14:55:38 -00:00: INF [memory_pressure] Writing meminfo: free 20MiB / 27MiB (72.68 %)
방화벽을 테스트하는 유니커널은 test/ 하위 디렉터리에 있습니다.
사용하려면 test.sh를 실행하고 지침에 따라 테스트 환경을 설정하세요.
방화벽에 영향을 미치는 보안 권고는 “security” 태그가 지정된 이슈를 참조하세요.
LICENSE.md 참조