@@@@@ Setting up a shared clipboard between Arch Linux (Wayland, you can redo it for any Linux yourself) and Whonix-Gateway (Wayland) works by pressing a button (for example, the “Pause” key):
@@@@@ Настройка общего буфера обмена между Arch Linux (Wayland, можете сами переделать под любой Linux) и Whonix-Gateway (Wayland) работает по нажатию кнопки (например, клавиши “Pause”):
1.0. Заходим в настройки Whonix-Gateway в Qemu “Обзор” xml - Найдите <channel> добавьте новые каналы связи:
<channel type='unix'>
<target type='virtio' name='clip.gw2host'/>
</channel>
<channel type='unix'>
<target type='virtio' name='clip.host2gw'/>
</channel>
1.1. Добавить пользователя в группу libvirt-qemu:
sudo usermod -aG libvirt-qemu $(whoami)
1.2. Перезапустить ПК
2.0. НИЖЕ НАСТРОЙКА РЕАЛЬНОГО ПК (Arch Linux, Wayland):
sudo pacman -S --noconfirm wl-clipboard socat
2.1. Скрипт автоприёма от Gateway:
tee ~/.local/bin/clip-gw2host-listen.sh > /dev/null <<'EOF'
#!/bin/bash
PID_FILE="/tmp/.clip-gw2host-wlcopy-pid"
while true; do
SOCK=$(find /run/libvirt/qemu/channel -iname "clip.gw2host" 2>/dev/null | head -1)
if [ -n "$SOCK" ]; then
socat -u UNIX-CONNECT:"$SOCK" - | while IFS='|' read -r MIME B64; do
[ -z "$B64" ] && continue
OLD_PID=$(cat "$PID_FILE" 2>/dev/null)
[ -n "$OLD_PID" ] && kill "$OLD_PID" 2>/dev/null
echo "$B64" | base64 -d | wl-copy --foreground -t "$MIME" &
echo $! > "$PID_FILE"
done
fi
sleep 1
done
EOF
chmod +x ~/.local/bin/clip-gw2host-listen.sh
2.2. Сервис автоприёма от Gateway:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/clip-gw2host.service <<'EOF'
[Unit]
Description=Clipboard sync Gateway->host
[Service]
ExecStart=%h/.local/bin/clip-gw2host-listen.sh
Restart=always
KillMode=control-group
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now clip-gw2host.service
2.3. Персистентный скрипт отправки (host → Gateway VM):
mkfifo -m 600 /tmp/clip-host2gw-fifo 2>/dev/null
tee ~/.local/bin/clip-host2gw-sender-daemon.sh > /dev/null <<'EOF'
#!/bin/bash
FIFO="/tmp/clip-host2gw-fifo"
[ -p "$FIFO" ] || mkfifo -m 600 "$FIFO"
exec 3<>"$FIFO"
while true; do
GW_SOCK=$(find /run/libvirt/qemu/channel -iname "clip.host2gw" 2>/dev/null | head -1)
if [ -n "$GW_SOCK" ]; then
socat -u FD:3 UNIX-CONNECT:"$GW_SOCK"
fi
sleep 1
done
EOF
chmod +x ~/.local/bin/clip-host2gw-sender-daemon.sh
2.4. Персистентный сервис отправки (host → Gateway VM):
cat > ~/.config/systemd/user/clip-host2gw-sender.service <<'EOF'
[Unit]
Description=Persistent clipboard sender host->Gateway
[Service]
ExecStart=%h/.local/bin/clip-host2gw-sender-daemon.sh
Restart=always
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now clip-host2gw-sender.service
2.5. Один скрипт для отправки буфера обмена во все запущенные в данный момент VM по нажатию кнопки (host → Gateway VM):
mkdir -p ~/.local/bin
tee ~/.local/bin/send_clipboard_to_all_vm.sh > /dev/null <<'EOF'
#!/bin/bash
MIME=""
for TYPE in image/png image/bmp image/tiff image/jpeg image/gif image/webp; do
FOUND=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^${TYPE}\$")
[ -n "$FOUND" ] && { MIME="$FOUND"; break; }
done
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 '^text/plain;charset=utf-8$')
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 '^text/plain$')
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 '^UTF8_STRING$')
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 '^STRING$')
[ -z "$MIME" ] && exit 0
RAW_SIZE=$(timeout 3 wl-paste -n -t "$MIME" 2>/dev/null | wc -c)
[ "$RAW_SIZE" -eq 0 ] && exit 0
[ "$RAW_SIZE" -gt 1073741824 ] && exit 0
B64=$(timeout 3 wl-paste -n -t "$MIME" 2>/dev/null | base64 -w0)
[ -z "$B64" ] && exit 0
LINE="${MIME}|${B64}"
for FIFO in /tmp/clip-host2vm-fifo /tmp/clip-host2gw-fifo; do
[ -p "$FIFO" ] || continue
( printf '%s\n' "$LINE" > "$FIFO" ) &
WPID=$!
( sleep 1.5; kill -9 "$WPID" 2>/dev/null ) 2>/dev/null &
done
wait 2>/dev/null
EOF
chmod +x ~/.local/bin/send_clipboard_to_all_vm.sh
2.6. Добавить бинд на синхронизацию последних скопированных данных (c ПК на VM):
- Важно: Редактирование существующее сочетания нельзя (может не примениться), нужно пересоздавать!
- Название: send_clipboard_to_all_vm
- Команда:
sh -c "$HOME/.local/bin/send_clipboard_to_all_vm.sh" - Кнопка: например, клавиша “Pause”
3.0. НИЖЕ НАСТРОЙКА ВНУТРИ Whonix-Gateway:
3.1. Чтобы все команды ниже не переписывать вручную - создаем блокнот “New Paste | Rocket Powered Pastebin” и вставляем пункты 3 и 4 гайда ниже (внутри VM открываем свою короткую ссылку, замените “https://paste.rs/Tguxi” обязательно без .txt в конце ссылки):
sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get install -y torsocks
torsocks curl -s https://paste.rs/Tguxi ;echo
3.2. Установить пакеты:
sudo apt-get install -y wl-clipboard socat
3.3. Разрешить чтение устройства без root:
sudo tee /etc/udev/rules.d/99-virtio-clip-gw.rules > /dev/null <<'EOF'
SUBSYSTEM=="virtio-ports", ATTR{name}=="clip.host2gw", MODE="0660", GROUP="sudo"
SUBSYSTEM=="virtio-ports", ATTR{name}=="clip.gw2host", MODE="0660", GROUP="sudo"
EOF
sudo udevadm control --reload-rules
sudo udevadm trigger
3.4. Скрипт приёма (host → Gateway VM):
sudo tee /usr/local/bin/clip-host2gw.sh > /dev/null <<'EOF'
#!/bin/bash
PID_FILE="/tmp/.clip-host2gw-wlcopy-pid"
while true; do
while IFS='|' read -r MIME B64; do
[ -z "$B64" ] && continue
OLD_PID=$(cat "$PID_FILE" 2>/dev/null)
[ -n "$OLD_PID" ] && kill "$OLD_PID" 2>/dev/null
printf "%s" "$B64" | base64 -d | wl-copy --foreground -t "$MIME" &
echo $! > "$PID_FILE"
done < /dev/virtio-ports/clip.host2gw
sleep 0.2
done
EOF
sudo chmod +x /usr/local/bin/clip-host2gw.sh
3.5. Сервис приёма (просто вызывает скрипт выше):
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/clip-host2gw.service <<'EOF'
[Unit]
Description=Clipboard sync host->Gateway
After=graphical-session.target
[Service]
ExecStart=/usr/local/bin/clip-host2gw.sh
Restart=always
RestartSec=3
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now clip-host2gw.service
systemctl --user status clip-host2gw.service --no-pager
3.6. Скрипт автоотправки (Gateway VM → host):
sudo tee /usr/local/bin/clip-gw2host-send.sh > /dev/null <<'EOF'
#!/bin/bash
MIME=""
for TYPE in image/png image/bmp image/tiff image/jpeg image/gif image/webp; do
FOUND=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^${TYPE}\$")
[ -n "$FOUND" ] && { MIME="$FOUND"; break; }
done
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^text/plain;charset=utf-8\$")
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^text/plain\$")
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^UTF8_STRING\$")
[ -z "$MIME" ] && MIME=$(timeout 2 wl-paste --list-types 2>/dev/null | grep -m1 "^STRING\$")
[ -z "$MIME" ] && exit 0
RAW_SIZE=$(timeout 3 wl-paste -n -t "$MIME" 2>/dev/null | wc -c)
[ "$RAW_SIZE" -eq 0 ] && exit 0
[ "$RAW_SIZE" -gt 1073741824 ] && exit 0
B64=$(timeout 3 wl-paste -n -t "$MIME" 2>/dev/null | base64 -w0)
[ -z "$B64" ] && exit 0
printf "%s|%s\n" "$MIME" "$B64" > /dev/virtio-ports/clip.gw2host
EOF
sudo chmod +x /usr/local/bin/clip-gw2host-send.sh
3.7. Добавить бинд на синхронизацию последних скопированных данных (c Gateway VM на ПК), например клавиша “Pause”:
mkdir -p ~/.config/labwc
cat > ~/.config/labwc/rc.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<openbox_config>
<keyboard>
<keybind key="Pause">
<action name="Execute" command="/usr/local/bin/clip-gw2host-send.sh"/>
</keybind>
</keyboard>
</openbox_config>
EOF
labwc --reconfigure
RU - Написать код было тяжело, получился он довольно безопасным, умеет передавать как текст так и фото, код я тестировал/чинил долгое время это финальный вариант. Тоже самое на Github (еще у меня там есть гайд общего буфера обмена между Arch Linux и Arch Linux VM оба Wayland):
EN - It was hard to write the code, it turned out to be quite secure, it can transmit both text and photos, I tested / repaired the code for a long time, this is the final version. The same is on Github (I also have a shared clipboard guide there between Arch Linux and Arch Linux VM, both Wayland):
https://github.com/MonExpl/Fix-copy-paste-Whonix-Gateway-VM-Clipboard