kazeno memo

メモとか

Ryzen CPUでGPU Passthrough出来ない問題

ProxmoxでGPU passthroughをしようと試みたけど、VMGPUを渡せていないようで上手く行かなかった。

が、BIOSのバージョンを上げたらどうにかなった話。

この人と使っているハードも症状も似通っていて、すごく助かった。

結論

  • BIOSのバージョンをAMD AGESA Combo-AM4 1.0.0.4 Patch B(3.70)にする
  • passthroughしたいGPUは2つ目以降のスロットに刺す。

構成

  • CPU
    Ryzen 7 1700
  • Motherboard
    ASRock X470 Master SLI
  • GPU (Host)
    NVIDIA ???
  • GPU (Guest Passthrough)
    NVIDIA GTX 1060

  • OS
    Proxmox 6.3

  • Kernel
    Linux 5.4.78-2-pve x86_64

パススルーのための設定

マザーボードのPCIeスロット

GPU passthrough関連のチュートリアルを見ていると、一番目のPCIeスロットにGPUを刺しているとpassthrough出来ないよ、といった注意が書いてあります。

これは、UEFI(BIOS)が起動時にROM(vBIOS)を改竄してからOS側へ渡すので、passthroughしようとすると、ハイパーバイザが正常に扱えず失敗するということのようです。つまりUEFIにパススルーしたいGPU以外のGPUを使わせれば良いということです。

多くのマザーボードではCPUに近いスロットのGPUを優先して使うようなので、一番目のスロットにホストOS用、二番目のスロットにはゲストOS用のGPUを刺すことになります。

Gigabyteマザーボードだと、UEFIの設定で起動時に使うGPUを指定出来るらしい。

CPUがCore iシリーズやAPUだったり、オンボードGPUが付いているマザーボードの場合はそっちを使えば良い(?)

ハイパーバイザ側でROMファイルを指定する

Proxmox使っているならここを見れば良い

GPUが複数枚用意できない場合、ハイパーバイザ側でオリジナルの(改竄されていない)ROMファイルを読み込ませることで、改竄されたROMを上書きするという方法もある。

ROMファイルを用意する方法は、

  • GPUから抽出
  • TechPowerUpからダウンロード

のいずれか。

GPUから抽出する場合、vfio dump gpu romとかでググれば出てくると思う。

TechPowerUpGPU関連の情報サイト。GPU-ZというツールやGPUの詳細スペック、過去バージョン含めたvBIOSのアーカイブとかあって便利。私は信頼できるサイトだと思ってる。

TechPowerUpのvBIOSファイルは、ファイル先頭にGPU-Z用のヘッダが埋め込まれているのでそのまま使えないようです。ヘッダを除去するスクリプトGithubにたくさんあります。「dump nvidia vbios OR rom site:github.com」などと調べると出てくると思います。

UEFI(BIOS)の設定

次の項目を有効化する。

Proxmoxの設定

/etc/modprobe.d/vfio.conf

options vfio-pci ids=<GPUのID>,<GPU内蔵サウンドデバイスのID> disable_idle_d3=1

IDは# lspci -nnv | less -NVIDIAを検索すれば見つけられる。サウンドバイスも一緒に指定しないとpassthrough出来ないので注意。

disable_idle_d3=1"Refused to change power state, currently in D3"というエラーに対応したとき指定したものなので、必要ないかもしれない。

/etc/modules-load.d/vfio.conf

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

/etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=pt"

modprobeを編集したのでupdate-initramfs -uでinitramfsを再生成する。

update-grubGrubのエントリを更新する。

システムを再起動する。

VMの作成

  • BIOSはOVMF (UEFI)
  • Machineはq35
  • Displayはnone

で作成する。

HardwareタブでAddからPCI Deviceを追加する。

  • DeviceはGPUの名前が表示されているのでそれを選ぶ
  • All Functionsにチェック(これでサウンドバイスもまとめて指定できる)
  • Primary GPUにチェック
  • ROM-Barにチェック
  • PCI-Expressにチェック

起動

これでVMを起動するとハングする。

dmesgには、vfio_bar_restore: reset recovery - restoring BARsとかいろいろ出てくる。

lspci -nnvを見てみると、GPUの項目が!!! Unknown header type 7fとだけ表示されている。

原因

BIOS(というかAGESA)の問題らしい。

vfio関連のスレッドを見ているとAGESAのバージョン一つでエラーが出たり治ったりといった感じで結構シビア。

私が使っているマザーボードAMD AGESA Combo-AM4 1.0.0.4 Patch Bが適用されているBIOSのバージョンは3.70。

注意書きを見てみると、

*ASRock do NOT recommend updating this BIOS if Pinnacle, Raven or Summit Ridge CPU is being used on your system.

(Pinnacle, Raven, Summit RidgeのCPUを使っている人は、BIOSの更新おすすめしないよ。)

と書いてあって怖かったけど、GPU passthroughのために4~5回BIOS焼き直してもちゃんと起動できました。(自己責任で!)

そんなわけで、冒頭で述べたようにBIOSを3.70にすることでGPU passthrough出来るようになりました。

Freenetは安全なの? 開発者の主張

Freenetの開発者がHacker Newsに書き込んでいました。

FreenetはTorのように匿名性・耐検閲性があるネットワークです。Torと異なる点は完全なP2Pネットワークであるということ。各ピアはファイルの断片を少しずつホストしており、仮に違法なファイルが共有されたとしても、ネットワークに参加しただけでは罪に問われないはずです。

しかし、アメリカではFreenet利用者が訴追される事例があったようです。これは、Freenetの匿名性が破られたということなのでしょうか?

法執行機関によるFreenet利用者への訴訟を巡る話が興味深かったので翻訳します。


Freenetはまだ存在してるけど、Tor経由で使わない限り危険すぎると思う。

私は10年以上Freenetの開発に携わっているので、このレスに書いていることを解説します。

Freenetは今でも開発されていて、今週も新たなリリースが行われたばかりです。

確かにアメリカでの訴訟は存在しますが、これは「危険」というよりは、よく分からない感じです。

Freenetは匿名化されたP2Pネットワークです。接続方法は3種類ありますが、潜在的に危険なのはそのうちの1つだけです。

  1. オープンネット: 不特定多数のランダムなピアと接続する。

  2. ダークネット: 友人など、特定のピアを選んで接続する。

  3. オープンネットとダークネットの混合: (ここではミックスモードと呼ぶことにしましょう)

オープンネットでは、法執行機関の囮ノードと接続されることでトラフィックを分析される恐れがあります。だからといって、何をダウンロードしたのか他のピアがはっきりわかる訳ではありません。

トラフィックが通過するピアの数は常にランダムで、ダウンロードしているのか通過させているのかを他のピアに通知しないため、もっともらしい反証が成り立ちます。

すべてのトラフィックが暗号化されており、受信者のみがそれを復号できます。つまり、トラフィックを監視して違法なJPEGをフィルタリングする、などということは不可能です。

法執行機関が行ったのは、何らかの計算に基づいて違法ファイルをダウンロードした可能性が高いと主張することでした。Freenetのコアチームもこの計算について認識していて、議論されています。

そのうち対処されると思いますが、開発者の議論を見る限り、この計算はかなりアバウトだと言えるでしょう。つまり、違法ファイルのダウンローダーとされた人物が、実際にダウンローダーだったという絶対的な証拠にはなりえません。

Freenetは20万行以上の複雑なコードなので、もしかすると間違っているかもしれませんが、それでもこれは単なる確率論に過ぎません。

Freenetはランダムな参加者のパソコンにコンテンツを暗号化して保存しているので(これがTorに対するメリットであり、Freenetは完全に分散化されてます!)、能動的にダウンロードしたのではなく、たまたま保存されていたユーザーを法執行機関が告発してしまうことは想像できます。

ただし、Freenetをダークネットかミックスモードで使えばそれなりに安全です。攻撃者に支配されていない友人が多ければ多いほど、統計的な攻撃は難しくなります。

さらに、私の知る限りにおいて同様の訴訟は米国でしか起きておらず、同国の法制度には少し欠陥があると思います。

おそらく、アメリカ以外の国でオープンネットを実行していても、Torノードの運営と同じリスクを負うだけでしょう。(暗号化されていて)調べられないトラフィックを転送し、(暗号化されていて)調べられないトラフィックを保存しているわけですから、それの何が違法なんでしょうか?


cgtzczykldpqさんは、この投稿に続き「シビル攻撃」についても言及しています。


オープンネットでは、法執行機関の囮ノードと接続されることでトラフィックを分析される恐れがあります。

これについては、Freenet固有の問題ではないことを明確にする必要があります。

匿名性を確保しようとするネットワークは、ランダムな人と接続することで、いわゆる「シビル攻撃」に悩まされます。

実際の利用者が1,000人ほどのネットワーク上で、攻撃者が例えば100,000台のマシンを実行していると仮定すれば、あるユーザは攻撃者のマシンにしか接続できない可能性が非常に高くなります。

また、匿名化は複数のピア間でトラフィックをリダイレクトすることが必要ですが、すべてのピアが攻撃者のものであればそれは不可能です。

私の理解では、Torはヒューリスティックな手法によってこの問題に対処しています。 たとえば、ネットワーク内の重要なマシンを入念に監視し、それらが実際に異なるエンティティであることを確認しようとしています。ただ、これは単なる推測であって、厳密な数学的セキュリティとは言えません。

Torを本当に安全なものにしたいならば、ダークネットモードを追加する必要があるでしょう。


mirimirさんは、Freenetの匿名性に否定的な投稿が多いHacker Newsユーザです。Freenetについて様々な記事で言及していて、Freenetの問題点について同意できる部分もありました。(IVPNのプライバシーガイドやブログに寄稿している方だそうです。)

ちなみに、シビル攻撃については、Tor上のBitcoinに関するトラフィックを改ざんし、窃取することを目的としていた「BTCMITM20」や、50以上のAS上で900以上のリレーを運営していた「KAX17」と呼ばれる攻撃者が実際に確認されています。

APTでインストール済みパッケージの一覧を日付順でソート

インストール済みパッケージの一覧を生成

$ find /var/lib/dpkg/info -name '*.list' -exec stat -c $'%n\t%y' '{}' \; \
  | sed -e 's,/var/lib/dpkg/info,,' -e 's/,\.list\t,\t,' \
  | sort > ./dpkg.list

パッケージ一覧を昇順でソート

$ sort -t$'\t' -k2 ./dpkg.list | column -t | less -

VoidLinux Repodata

Main

/current/x86_64-repodata
/current/musl/x86_64-musl-repodata
/current/i686-repodata
/current/aarch64/aarch64-repodata
/current/aarch64/aarch64-musl-repodata
/current/armv6l-repodata
/current/musl/armv6l-musl-repodata
/current/armv7l-repodata
/current/musl/armv7l-musl-repodata

Nonfree

/current/nonfree/x86_64-repodata
/current/musl/nonfree/x86_64-musl-repodata
/current/nonfree/i386-repodata
/current/aarch64/nonfree/aarch64-repodata
/current/aarch64/nonfree/aarch64-musl-repodata
/current/nonfree/armv6l-repodata
/current/musl/nonfree/armv6l-musl-repodata
/current/nonfree/armv7l-repodata
/current/musl/nonfree/armv7l-musl-repodata

Multilib (only x86_64 glibc)

/current/multilib/x86_64-repodata
/current/multilib/nonfree/x86_64-repodata

Debug

/current/debug/x86_64-repodata
/current/musl/debug/x86_64-repodata
/current/debug/i686-repodata
/current/aarch64/debug/aarch64-repodata
/current/aarch64/debug/aarch64-musl-repodata
/current/debug/armv6l-repodata
/current/musl/debug/armv6l-musl-repodata
/current/debug/armv7l-repodata
/current/musl/debug/armv7l-musl-repodata

Value-server SSHホワイトリストに任意のIPアドレスを登録したい

バリューサーバーにSSH/FTP接続する際、IPアドレスを事前に登録しておく必要があります。

ブラウザからコントロールパネルにアクセスしなければ登録できないわけですが、実際にはPOSTリクエストを投げているだけなので、cURLでどうにかなります。

curl https://<サーバー番号>.valueserver.jp/cp/admin.cgi \
  -X POST \
  -H 'Cookie: ID=<コンパネID>; PASS=<コンパネPASS>' \
  --data-raw 'id=<コンパネID>&pass=<コンパネPASS>&id=<コンパネID>&pass=<コンパネPASS>&nomenu=1&remote_host=<IPアドレス>&ssh2=SSH%93o%98%5E'

面倒くさいことに、自身のパブリックIPアドレスとリクエストのIPアドレスが異なっていると、不正なリクエストと言われてしまいます。

mpvでyoutube-dlの代わりにyt-dlpを使う

mpvベースのBaka Mplayerというメディアプレイヤーを使っています。

mpvyoutube-dlと組み合わせることができますが、呼び出すyoutube-dlをyt-dlpに置き換えたいわけです。(シンボリックリンク張れば良さそうですが……)

このコミットによると、ytdl_pathyoutube-dlの代替パスを指定できるようです。

具体的には、mpvの設定ファイル(もしくはコマンドラインのオプションに)にscript-opts=ytdl_hook-ytdl_path=<代替パス>を追加するということです。

mpvの設定ファイルは~/.config/mpv/mpv.confにあります。

$ cat ~/.config/mpv/mpv.conf
script-opts=ytdl_hook-ytdl_path=yt-dlp

試しにBaka MplayerTverのURLをCtrl+Vしてみると、問題なく再生することができました。

Librewolf AppImage版 PGP公開鍵の場所

LibreWolf-96.0.3-2.x86_64.AppImage.sigA98C3D1364D8C16408143C2E2954CC8585E27A3Fで署名されています。

これは、Librewolfのコア開発者である@ohfpさんの鍵です。

"ohfp repo key (Repository signing key for privacyshark repo) <1813007-ohfp@users.noreply.gitlab.com>"

GitLabやGitHubの場合、ユーザーページのURL末尾に.gpgを追加することで、PGP公開鍵を入手できます。(同様に、.keysを追加することでSSH公開鍵を入手できます)

GnuPGを使用している場合、--recv-keysオプションを使うことで、公開鍵サーバから対応する鍵を検索し自動でインポートしてくれます。

$ gpg --recv-keys 0xA98C3D1364D8C16408143C2E2954CC8585E27A3F

Rootless modeでlinuxserver.ioコンテナのPUID/PGIDがうまく設定できない?

linuxserver.ioの提供するコンテナは、環境変数PUID(uid) PGID(gid)で実行ユーザーを指定できます。(例えば、PUID/PGID=1000とすれば一般ユーザーで実行できます。)

ただし、DockerをRootless modeで実行している場合、PUID=1000を指定するとホスト側は100999に、PUIDを指定しないと100910といったuid/gidになってしまいます。

これは、ホスト・コンテナ間のuid/gidマッピングが通常のDockerとRootless modeで異なることが原因だと思われます。

Rootless modeでは、ホストのuid 1000がコンテナ内のuid 0として扱われます。1 2

そして、Rootless mode上のlinuxserver.ioコンテナでは、uid/gidがこのようにマッピングされているようです。

PUID ホスト
PUID=指定せず 100910
PUID=1000 100999
PUID=0 1000

つまり、Rootless modeでlinuxserver.ioコンテナのuid/gidに1000を指定したい時は、明示的にPUID/PGID=0を指定する必要があるということです。

動画のリサイズ 垂直・水平解像度 どちらに合わせるのが最適か?

1920x1040の動画ファイルをHD(720p)に縮小する場合、垂直解像度(1040)を720に合わせるのか、水平解像度(1920)を1280に合わせるのが良いのか。

また、ffmpeg--scale=を使いリサイズする場合、サイズを偶数にする必要があるようですが、1920x1040の場合は奇数で、あまりが出ます。これは切り捨てたほうが良いのでしょうか?

1920x1040という解像度は、映画で使用されるビスタビジョン(アメリカンビスタ)というようです。

VLCのフォーラムにトリミングとサイズ変更についてのガイドがありました。ただし、これが正しいのかそうでないか全くわからないです。


  1. まず、元動画のアスペクト比を計算します。

    アスペクト比=水平/垂直なので、1920x1040の場合、1.84615384615=1920/1040となります。

    (Wikipediaによればアメリカンビスタのアスペクト比は「1.85:1」とのことで、上記の計算とほぼ合致します)

  2. 元動画のアスペクト比を計算したら、次に720pの解像度を計算する必要があります。

    720p規格では、水平解像度が最大1280px・垂直解像度が最大720pxと規定されているそうです。これに基づいて次のいずれかの計算が必要です。

    • アスペクト比 > 16:9=1.77(7)の場合(アスペクト比が1.77より高い)

      水平解像度を1280pxに固定します。垂直=1280/アスペクト比という式で垂直解像度を計算します。

    • アスペクト比 > 16:9=1.77(7)の場合(アスペクト比が1.77より低い)

      垂直解像度を720pxに固定します。水平=720*アスペクト比という式で水平解像度を計算します。

    1920x1040の場合、1.77より高いので水平解像度を1280に固定します。垂直解像度は上記の式によって693.333333335=1280/1.84615384615となります。

  3. 垂直解像度が693.333333335の場合、偶数にするため切り上げ(694)、もしくは切り捨て(692)が必要です。この場合「アスペクト比 誤差(AR error)」が低い方を選ぶ必要があります。

    切り上げ・切り捨て両方のアスペクト比を求め、元動画のアスペクト比とより誤差の少ない方が最適な解像度ということです。

    まず、694と692のアスペクト比を計算し、そこから元動画のアスペクト比(1.84615384615)を引きます。

    • 1280/694=1.84438040346 1.84438040346-1.84615384615=-0.00177344269
    • 1280/692=1.84971098266 1.84971098266-1.84615384615= 0.00355713651

    最適な垂直解像度は694であることがわかりました。


1.33:1 - 1436x1080 or 1440x1080? 1.37:1 - 1480x1080 or 1484x1080? 1.66:1 - 1788x1080 or 1792x1080 or 1796x1080 or 1800x1080? 1.85:1 - 1920x1036 or 1920x1040? 2.35:1 - 1920x816? 2.55:1 - 1920x752? 2.39:1 - 1920x800?

Debian Busterでfirewall-cmd --reloadするとクラッシュする

Debian Busterのファイアウォールufwからfirewalldへ移行したのですが、firewall-cmd --reloadするとクラッシュしてしまいます。

journalctlを使ってログを眺めると、このようなエラーを吐いてました。

ERROR: COMMAND_FAILED: '/usr/sbin/ip6tables-restore -w -n' failed: ip6tables-restore v1.8.2 (nf_tables): 
line 4: RULE_REPLACE failed (No such file or directory): rule in chain INPUT

ERROR: 'python-nftables' failed: internal:0:0-0: Error: No such file or directory
internal:0:0-0: Error: No such file or directory

samjhandleyさんのこのIssueによると、iptables 1.8.2のバグなんだとか。

確認してみるとbusterのレポジトリにあるiptablesは1.8.2-4で、buster-backportsiptablesは1.8.5-3でした。

余談ですが、Debian Busterからnftablesがデフォルトとなりました。iptablesパッケージの中身もnftablesなので、nftablesパッケージをインストールする必要はありません。

buster-backportsレポジトリの追加

必要に応じてbackportsレポジトリを追加してください。

/etc/apt/sources.list.d/buster-backports.list

deb https://deb.debian.org/debian buster-backports main contrib non-free

iptables 1.8.5のインストール

backportsからパッケージ取得するには、aptに-t buster-backportsを指定します。

# apt update
# apt install -t buster-backports iptables
$ iptables --version
iptables v1.8.5 (nf_tables)

firewalldの再起動

# systemctl restart firewalld.service
# firewall-cmd --reload
# journalctl -xeu firewalld.service

firewalldは正常にリロードできるし、systemd serviceのログにもエラーは出ていません。