laft’s diary

備忘録か日記

ふるさと納税×確定申告の罠

はじめに

私は毎年、ふるさと納税の限度額をスプレッドシートで手計算しています。 その計算過程で気づいた、危うくハマりかけた「罠」について紹介したいと思います。

ご存知のように、ふるさと納税の申告方法には「ワンストップ特例」と「確定申告」の2種類があります。 ワンストップ特例は、一定件数以下の寄付であれば簡略化された手続きで済むため、確定申告の手間を省きたい方には非常に便利な制度です。 一方で、副業や医療費控除などで元々確定申告が必要な方にとっては、確定申告でまとめて行うのが一般的でしょう。

しかし、ワンストップ特例と確定申告では、稀なケースにおいて控除額に差が出ることがあります。 特定の条件に当てはまる場合、確定申告を選択するだけで確実に損失が出てしまうのです。 今回は、そんな意外な落とし穴についてお話しします。

ふるさと納税のしくみ

この話をする上で避けて通ることのできない、ふるさと納税のシステムをざっくり解説します。 ※私は税の専門家ではないため、一部内容に誤りがあるかもしれません。ご容赦ください。

まず、ふるさと納税は、住民税と所得税における既存の「寄付金控除」をブーストし、自己負担額を除いた寄付額のほぼ100%を税額控除する仕組みです。

本来の寄付金控除による減税分は、 (寄付額-2000) * (所得税率*1.021 + 0.1) です。 これを100%控除にするため、「ふるさと納税の特例分」として (寄付額-2000) * {1-(所得税率*1.021 + 0.1)} が住民税から追加で控除されます。 ここで「2000円」は自己負担額、「0.1」は住民税(所得割)の標準税率です。

当然ながら控除額には上限があり、この「特例分」については住民税所得割の20%が限度と定められています。住民税所得割の税率は前述の通り10%ですので、所得全体から見ると2%が上限の目安となります。

ふるさと納税の限度額

詳細な計算は割愛しますが、余談として限度額の求め方にも触れておきます。

住民税の課税所得を a、寄付額を k、所得税率を r とおくと、特例分の控除額は住民税所得割の20%(0.02a)が上限であるため、以下の式が成立します。 0.02a \leq (k-2000)(1-(1.021r + 0.1)) = (k-2000)(0.9-1.021r)

これを k について整理すると、寄付額上限 k は以下のようになります。 k = \frac{0.02a}{0.9-1.021r}+2000

この式は、ふるさと納税のシミュレーションを詳しく調べたことがある方なら、見覚えがあるかもしれません。

例として、課税所得が500万円の人が、自己負担2000円のみで寄付できる上限額を計算してみましょう。 国税庁の所得税率表 によると、2025年現在の課税所得500万円に対応する所得税率は20%です。 a = 500万、r = 0.2 を代入して計算すると、寄付額上限は 14万5719円 となります。 (※ここでの「所得」は、給与控除や基礎控除などを差し引いた後の「課税所得」である点に注意してください。)

計算してみるとわかる通り、ふるさと納税は所得税率が高い(=所得が多い)人ほど、より大きな金額の寄付で恩恵を受けられる制度となっています。

ふるさと納税の罠

さて、ここからが本題です。

ふるさと納税の控除額を左右する重要な要素である「所得税率」ですが、この値がワンストップ特例を利用した場合と確定申告を行った場合で、参照元がズレてしまうケースがあります。

基本的には課税所得に基づいて税率が決まりますが、それぞれのケースで「どの控除を適用した後の課税所得を参照するか」が異なります。

確定申告を行う場合、所得税の還付額は「実際に適用される所得税率」で計算されます。しかし、住民税側で計算される「ふるさと納税特例分」の控除額において参照される所得税率は、住民税の課税体系に基づいた値となります。 問題は、所得税と住民税で「適用される控除額」が異なることです。特定の控除によって、所得税の税率区分と住民税における税率区分が境界線を跨いでズレてしまった場合、控除の合計が寄付額の100%に届かず、損が発生してしまうのです。

一方でワンストップ特例の場合は、所得税からの還付を行わず、全額を住民税から控除する仕組みです。このとき参照される税率は、本来の所得税率に基づいた計算が維持されるため、このような逆転現象は起こりません。 この点においては、ワンストップ特例の方が「計算のズレが起きない」というメリットがあると言えるでしょう。

対象となる控除

では、具体的にどのような控除がこの「ズレ」を引き起こすのでしょうか。

代表的なものは 生命保険料控除 です。 生命保険料控除は、所得税と住民税で最大控除額が異なります(所得税の方が大きい)。

一般的に、所得税の方が住民税よりも控除項目や控除額が多いため、所得税ベースの税率の方が一段階低くなりやすい傾向があります。

どの程度損するのか

例えば、住民税の課税所得ベースでの所得税率が20%、所得税の課税所得ベースでの実際の税率が10%という、境界線を跨いだケースを考えてみます。寄付額を k とします。

確定申告を行うと、所得税からの還付(本来の寄付金控除分)は実際の税率で計算されるため、 (k-2000)(0.1 \times 1.021 + 0.1) となります。

一方で、住民税側の「ふるさと納税特例分」は、参照税率20%として計算されるため、 (k-2000)(1-(0.2 \times 1.021 + 0.1)) = (k-2000)(0.9 - 0.2 \times 1.021) となります。

これらを足し合わせると、合計の控除額は (k-2000)(1 - 0.1 \times 1.021) となり、自己負担2000円を除いたとしても、寄付額の約10%分が控除されずに損失となってしまいます。

こうなってしまうと、ふるさと納税をするほど10%の手数料を支払っているような状態になり、もったいない結果となります。

まとめ

自分の課税所得が所得税率の境界線付近にある場合、ふるさと納税と確定申告を安易に組み合わせると、このような思わぬ損失を招くことがあります。

私のように毎年確定申告を行う習慣がある方は、税率の「段差」に自分がかかっていないか、一度注意深く確認してみるとよいかもしれません。

zshをzinitでいい感じにする

背景

Windows OSを最近クリーンインストールしたので、WSLのシェルをいい感じにしたい。 前世ではpreztoを使っていたので、使用感をあまり変えずに流行りの(?)zinit使いたい。 そんな感じの作業ログをお届けします。

やったこと

1. zshのインストール&デフォルトのシェル変更

sudo apt install zsh
chsh -s /usr/bin/zsh

2. zinitのインストール

以下、世界はzshです。

bash -c "$(curl --fail --show-error --silent --location https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"
zinit self-update

(https://github.com/zdharma-continuum/zinit 参照)

3. いい感じのプラグインを入れる

a. powerlevel10k

以下に従って ~/.zshrczinit ice depth=1; zinit light romkatv/powerlevel10k を追記して、 source ~/.zshrc https://github.com/romkatv/powerlevel10k?tab=readme-ov-file#zinit

すると、interactiveなconfigure画面に入るので、設定する。 (powerlevel10k configure と入力するといつでも再設定できる)

b. その他プラグインを入れる(雑)

.zshrcに下記を追記した

# zinit plugins
zinit light zsh-users/zsh-syntax-highlighting
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-completions
zinit snippet PZTM::completion
zinit snippet PZTM::directory

PZTM::<モジュール名>preztoのrepoのmodule以下init.zshを参照するための特殊な構文。 元々使っていた補完の使用感と合わせるために、ひとまず completiondirectoryだけ持ってきた。

一応構文についても解説しておく。(少し調べた程度なのであまり自信はない)

zinit light <GitHubのrepo> でloadできる。 初回時はcloneもしてくれる。

zinit snippet <ファイルのurl> とすると、curl的なのでそのファイルをダウンロードして、実行する。

c. エイリアス

Ubuntuのデフォルトのbashに入ってるエイリアス群を .zshrcに追加。 ll とか手癖で打っちゃうので入れておくに越したことないかな。 その他エイリアスは困り次第追加する予定。

alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

前使ってたディスクからWSL移行

背景

最近PC交換のついでにwindowsクリーンインストールをしてた。 前世のディスクはEドライブに挿しているので、データ自体はいつでも参照可能になっている。 今回はこれに入っていた前世のWSLをぶっこ抜いて今世のWSLにインポートしたい。

ググると↓がヒットしたので、これをやるだけです。 github.com

前世のWindows OSを起動可能な場合は、WSL側が用意しているエクスポート&インポート手段があるので、以下の手法を利用せずともそれを利用するとよさそう。

手法

端的には、インポートしたいWSLと同じディストロで新規に起動し、参照しているディスクを置き換えればよい。

1. WSLのインストール

(対象読者層を考えると知らないことないはず。知らない人は適宜調べてください)

2. インポートしたい前世のWSLディスクを探す

だいたいこの辺 E:\Users\username\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onhoge\LocalState\ext4.vhdx

3. インポートしたいのと同じディストロで新規に起動

Powershellwsl --install Ubuntu-22.04 など、 Ubuntu-22.04 の部分に対象のディストロを入れる。

(私の環境は当初20.04だったのを後からアップデートしたため、なぜか名前がUbuntu20.04なのに実体が22.04になっている)

4. WSLのシャットダウン

Powershellwsl --shutdown

5. WSLが指すディスクファイルの置き換え

2のパスの先頭文字をCドライブに変えたのと大体同じ場所に ext4.vhdxがあるので、これを前世のに置き換える。

6. 起動して置き換わったか確認

Powershellwsl -d Ubuntu-22.04

起動して ls などして前世のWSLのファイルにアクセスできていることを確認

Proxmox VEさわったのでやったことまとめ

Proxmox VEをIntel NUCに導入

家で温めていたIntel NUC (RNUC12WSHI50000) があったのでProxmox VE を導入した。 ProxmoxはDebianをベースにしたLinuxディストリビューションであり、VMの管理をWeb UIなどから行える便利ツール。

ProxmoxのWeb UI

Ansibleに入門

適当にいくつかVMをたてて、以下の記事を参考に手を動かしながら入門した。

zenn.dev

WindowsVMGPUパススルー

ProxmoxはGPUパススルーが比較的に容易に行えることでも知られており、NUCのiGPUをパススルーした。 iGPUのパススルーは通常の機能では行えなかったので、以下を参考に行った。(試験的な機能を利用しているため、注意が必要。)

qiita.com

www.derekseaman.com

cloud-initで遊ぶ

下記の記事を参考にしてcloud-initを利用してVMの構成の簡易化を行った。

blog.nishi.network

pve.proxmox.com

感想

今まではCockpit+KVMVMの管理をしていたが、Proxmoxの方がUIが洗練されていると感じた。 特に、OSイメージをProxmox側で管理してくれたり、メトリクスがしっかりしていたりと使い勝手が良いと思う。

今後はLXCコンテナでも立てて、自宅インフラの向上に努めたい。

steam版ダンガンロンパV3のモノモノマシーン自動化

要約

pydirectinputを利用してsteam版ダンガンロンパV3のモノモノマシーン等の自動化を行った。 本編のネタバレはしません。

実装

import pydirectinput
import time

time.sleep(2)

for i in range(100):
    pydirectinput.press("w")
    pydirectinput.press("enter")
    time.sleep(2)
    pydirectinput.press("enter")

説明

github.com

上記のパッケージを利用した。 特にダンガンロンパのウィンドウをactive化する実装を含まないので、Alt+Tabなどで最初の2秒のスリープの間に自力でフォーカスしてください。

また、このスクリプトを実行している間は他の操作は不可能です。通常のキーボード入力等の操作をスクリプトが代行しているに過ぎないため。

感想

最初はWindows API叩くつもりだったけど、いい感じのラッパがあったので助かる。 pyautoguiはDirectX を利用するゲームには入力できないがちなので気をつける(1敗)。

pydirectinputはあんまりメンテされてないけどとても便利。 これをフォークしてるactiveなリポジトリもあったんだけど、こっちはなぜかうまくいかなかった。

pydirectinputについて付記しておくべき事項として、clickがうまくいかないので、clickが必要な場合はmousedown→mouseupするとよい。

おまけ

ギャラリーの解放も自動化した。これもかなりめんどいよね……。

import pydirectinput
import time

time.sleep(2)

for i in range(20):
    pydirectinput.press("enter")
    time.sleep(0.2)
    pydirectinput.press("enter")
    time.sleep(1)
    pydirectinput.press("s")

GPGで遊んでみた話(WSL2, WSLg)

GPG、認知はしてたけどちゃんと使ったことなかったので鍵を作ってkeybaseに登録してyubikeyに副鍵を入れるところまでやった(WSL2, WSLg環境)。

再現できるように手順をメモしておく。

GPGとは

PGP(Pretty Good Privacy)というソフトウェアが存在していた。 これは公開鍵暗号方式を用いて暗号化を行うソフトウェアである。

現在はRFCにてOpen PGPとして規格化されており、現在はRFC4880となっている。 GPG(GNU Privacy Guard)はOpen PGPに準拠したフリーソフトウェアである。

GPGで主鍵を生成

GPG自体は普通にUbuntuにプリインストールされているので、とりあえず主鍵を生成する。

$ gpg --full-gen-key --expert
gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection?

楕円曲線を使いたいので11を選択(もちろんRSAでもよい)。 (expertオプションをつけてないと楕円曲線は表示されない。)

Your selection? 11

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Sign Certify

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection?

主鍵にはCertify(他の鍵への署名)の機能だけを与え、他の機能は主鍵の署名がついた副鍵で行う。 そのため、ここでは Current allowed actions にCertifyだけが残るようにsを1回入力し、finishする。

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Sign Certify

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Certify

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q

好きな楕円曲線を選ぶ。SSHとかでも使われている1で良さそう。

Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1

鍵の生存期間を選ぶ。この期間を過ぎても、後からこの鍵を使って更新できるので敢えて短く設定する意味はない。 ここでは無期限を選ぶことにする。

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

するとReal nameとemailを聞かれるので、適当に答える。 本来の用途からすると実名が望ましいが、公開鍵のメタデータとして公開される。 emailについても、githubでverifyしてもらうには、githubで登録されたメールアドレスにする必要がある。 GitHubTwitterと連携したい場合においてはその辺りを考慮した上で選ぶとよい。

fingerprintをそのままに後から追加したり変更したりすることは可能なので、そこまで悩む必要もないかも。 Commentも聞かれるが空で良い。

GnuPG needs to construct a user ID to identify your key.

Real name: laft2
Email address: laft@example.com
Comment:
You selected this USER-ID:
    "laft2 <laft@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

Okayのoを入力したら、後は秘密鍵パスフレーズを設定して終わり。

副鍵の生成

主鍵は盗まれたりすると本当に終わりなので、基本的には主鍵によって署名された副鍵を用いて署名、復号(暗号化)、認証を行う。 機能ごとに副鍵を生成するが、手順はほぼ同じなので、ここでは署名を例に行う。

副鍵は主鍵に紐づけて生成するので、主鍵のeditから行う。 以下laftとなっているところは適宜自分のメールアドレスのprefixを書けばよい。 他の主鍵と識別可能であればよいので、初めて作るなら1文字でも大丈夫なはず。

$ gpg --expert --edit-key laft

Secret key is available.

sec  ed25519/XXXXXXXXXXXXXXXX
     created: yyyy-mm-dd  expires: never       usage: C
     trust: ultimate      validity: ultimate
[ultimate] (1). laft2 <laft@example.com>

gpg>

となっているはずなので、addkeyする。どのようなコマンドが存在するかはhelpと入力することで確認できる。

gpg> addkey

すると主鍵の時のように暗号化アルゴリズムを選択する画面に入るので、好きなアルゴリズムを選ぶ。 ここでは署名onlyな楕円曲線を選び、25519を選ぶ。

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 10
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1

生存期間を選ぶ。主鍵と異なり、副鍵を更新するには主鍵の秘密鍵が必要である。 ここでは主鍵同様に0にするが、きちんと設定する方が望ましい。

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

これで完成。暗号用の副鍵も同様に生成しておく。(アルゴリズムを選ぶときに12のencrypt onlyな楕円曲線暗号を選択すればよい。)

最後にsaveして抜ける。

gpg> save

gpg -k と打つと公開鍵の情報を確認できる。(-Kオプションで秘密鍵の確認もできる。)

$ gpg -k
/home/user/.gnupg/pubring.kbx
-----------------------------
pub   ed25519 yyyy-mm-dd [C]
      XXXXXXXXXXXXXXXXXXXXXXXXX
uid           [ultimate] laft2 <laft@example.com>
sub   ed25519 yyyy-mm-dd [S]
sub   cv25519 yyyy-mm-dd [E]

主鍵をオフラインストレージに移す

GPGの秘密鍵をオンラインなデバイスに置いておくのは危険なので、オフラインストレージに移した上で削除する。 基本的な機能は副鍵が行ってくれるので、主鍵の秘密鍵を削除しておいても問題ない。 新たに副鍵を作ったり、主鍵の公開鍵の情報を変更したい場合に必要なので無くさないようにすること(自戒)。

$ gpg -K # 秘密鍵を確認
/home/user/.gnupg/pubring.kbx
-----------------------------
sec ed25519 yyyy-mm-dd [C]
      XXXXXXXXXXXXXXXXXXXXXXXXX
uid           [ultimate] laft2 <laft@example.com>
ssb   ed25519 yyyy-mm-dd [S]
ssb   cv25519 yyyy-mm-dd [E]

秘密鍵をexportする。aオプションをつけるとasciiで出力されてうれしい。(つけないとバイナリで出力されてかなしい。)

$ gpg --export-secret-keys -a laft > secret-key.asc

これをオフラインストレージ(USBメモリなど)に保存したり、QRコードエンコードして家に保存したりするとよいらしい。 (gpg のリリース 2.1からはデフォルトで秘密鍵のパスフレーズによる暗号化がなされるようになっているため、ここから更に暗号化する必要はそれほどない。)

保存したら、今つくったものを消す。

$ shred -u secret-key.asc

その後、主鍵の秘密鍵だけを削除する。主鍵の秘密鍵だけを削除するには、削除のダイアログで「主鍵を削除しますか」にyと答え、その後の「副鍵を削除しますか」にnと答える必要がある。

$gpg --delete-secret-keys laft

<keyの情報>

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y
(私の環境はWSLgなので、ここで2回GUIダイアログが出現する。1回目にdelete keyと答え、2回目はNoと答える)
gpg: deleting secret subkey failed: Operation cancelled
gpg: laft: delete key failed: Operation cancelled

再度秘密鍵を確認すると、鍵の後ろに"#"がついている。 主鍵だけについていれば成功。

$ gpg -K # 秘密鍵を確認
/home/user/.gnupg/pubring.kbx
-----------------------------
sec# ed25519 yyyy-mm-dd [C]
      XXXXXXXXXXXXXXXXXXXXXXXXX
uid           [ultimate] laft2 <laft@example.com>
ssb   ed25519 yyyy-mm-dd [S]
ssb   cv25519 yyyy-mm-dd [E]

ちなみに、オフラインストレージなどに保存した秘密鍵をimportするときは以下のコマンドを実行すればよい。

$ gpg --import secret-key.asc

ここまででgpgの事前設定は全て完了した。 公開鍵は公開しないと意味がないので、その方法を紹介する。

keybaseに鍵を登録する

keybase.ioというサービスがあり、ここで公開鍵を登録した上で、TwitterGitHubのアカウントを連携することができる。

keybase上で他人をフォローすることは、その人の公開鍵を信頼することを意味し、 その人がフォローしている人の公開鍵についても、程度の差はあれど信頼することができる。

このように、確実な知り合いをフォローすることで信頼の輪(Web of Trust)を広げていくことができる。何hopまで信頼するかはその人の裁量しだい。

keybaseのインストール

keybase.io の通りに進めていく。

2023/2/17時点では以下のコマンドを実行すればよい。

curl --remote-name https://prerelease.keybase.io/keybase_amd64.deb
sudo apt install ./keybase_amd64.deb
run_keybase

run_keybaseを実行すると、当環境(WSLg)ではGUIのkeybaseアプリが起動する。

sign up

$ keybase signup

これで案内が出るのでその通りに進める。

keybaseにGitHubを登録

GUIのkeybaseアプリのSettings > Your account > Website login からkeybase.io にログインする。

ログインするとtwitterが設定できそうなマークが画面中央にあると思うので、そこから案内に従って連携すればOK。 Gistを用いて連携する。

yubikeyに副鍵の秘密鍵をexport

yubikey持ってて遊びたい人用コンテンツです。

これをやると、yubikeyがささっている時だけ秘密鍵を使うことができるようになる。 また、普段使っていないデバイスでもyubikeyを挿すことで、その秘密鍵を利用できる。

先に言っておくと、WSLからyubikeyを常用するのは若干面倒なので、yubikey用の鍵と常用する鍵は別でもいいかもしれない。(私はそうした。)

yubikeyをWSLから認識させる

普通に指すとWSL側から認識してくれないので、Windowsにusbipdをインストールする(参考)。

# (powershell)
$ winget install --interactive --exact dorssel.usbipd-win

インストールしたら、管理者モードでpowershellを開いて、yubikeyっぽいのを探す。

# (powershell 管理者モード)
$ usbipd wsl list
BUSID  VID:PID    DEVICE                                                        STATE
X-X    XXXX:XXXX  USB 入力デバイス, Microsoft Usbccid Smartcard Reader (WUDF)   Not attached

これがyubikeyっぽいので、このBUSIDを指定してWSLに渡してあげる。

# (powershell 管理者モード)
$ usbipd wsl attach --busid X-X

これをやると、WSL側からyubikeyが見えるようになる。(Windows側からは見えなくなる)

# (WSL)
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

が、このままだとGPGが認識してくれないので、以下のコマンドを入力する必要がある(参考)。

sudo apt install scdaemon
sudo apt install pcscd
sudo service pcscd start

これで見えるようになるはず。gpg --card-statusを実行して以下のようになっていれば大丈夫。

$ gpg --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID
Application ID ...: 
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
...

yubikeyに焼く

ここまでできたらgpg --edit-cardから実際にyubikeyに焼いていく(参考)。

まずは初期設定から。

$ gpg --edit-card
(yubikeyの情報と鍵の情報)

gpg/card> admin
Admin commands are allowed

gpg/card> kdf-setup # 初回のみ。
gpg/card> passwd # PIN変更。初回のみ。
gpg: OpenPGP card no. XXXX detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection?

PINとAdmin PINの変更を行う。初期PINは123456、初期Admin PINは12345678

初期設定が終わったら、一旦gpgから抜けてgpg --edit-key laftする。

$ gpg --edit-key laft
pub  ed25519/XXXXXXXXX
     created: 2023-02-16  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  ed25519/XXXXXXXXXXXXX
     created: 2023-02-17  expires: never       usage: S
ssb  cv25519/XXXXXXXXXXXXX
     created: 2023-02-17  expires: never       usage: E
gpg> key 1 # 副鍵の1番目を選択
pub  ed25519/XXXXXXXXX
     created: 2023-02-16  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb*  ed25519/XXXXXXXXXXXXX
     created: 2023-02-17  expires: never       usage: S
ssb  cv25519/XXXXXXXXXXXXX
     created: 2023-02-17  expires: never       usage: E

key Xで上からX番目の副鍵を選択できる。 選択すると*がつく。

この状態でkeytocardする

gpg> keytocard
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

で移せる。暗号用の鍵についても同様。 認証用の鍵を別途作っておいてAuthentication keyとしてyubikeyに秘密鍵を移すこともできる。

全ての操作が終わったら、saveすることでlocalから秘密鍵を削除される。

$ gpg -K
sec# ed25519 yyyy-mm-dd [C]
      XXXXXXXXXXXXXXXXXXXXXXXXX
uid           [ultimate] laft2 <laft@example.com>
ssb>  ed25519 yyyy-mm-dd [S]
ssb>  cv25519 yyyy-mm-dd [E]

smart cardに移された鍵は>マークがつく。

これで全て完了。

GPGの使い道

  • gitのcommitに署名する。
    • GitHubに公開鍵を登録しておくと、コミットにVerifiedがつく
      verified in GitHub
  • 人と暗号化されたテキストをやりとりする。
  • メールに署名をする。
  • passを用いてlastpassなどのプロプライエタリなパスワードマネージャーから脱却する。

参考文献

BluetoothでPCのDiscordのミュート切り替えをできるようにした話

表題の通り、Discordをマイクミュート及びアンミュートの切り替えをBluetoothが届くくらいのところから行いたいという野望があり、達成できたので軽くメモ。

背景

  • Bluetoothイヤホンで通話しながら料理したりその他諸々をしており、一々PCのところまで行ってミュート切り替えするのは面倒。
    • スマホ版Discordを使えという話はある。私の場合、PCで作業等しながら通話に参加し、その後通話を繋いだまま家事をすることが多く、イヤホンを含めた繋ぎ直しがかなり面倒だったのでPC版のまま繋いでいた。
  • Discordのキー割り当て機能はかなり便利であり、これを用いて解決するのが妥当そう。

要件

  • 離れたところからキー入力ができる。
  • 普段使わないキーが付いているか、キーマップの書き換えができる。
  • 防水か、ジップロックを上から被せてもそれなりに使いやすいこと。
  • ポケットに入る程度にコンパクトなこと。

方法

以上の要件から、メディアボタンという音楽プレーヤーを遠隔操作するBluetoothのリモコンを採用した。

  1. メディアボタンを買う。買ったのはこれだけど、多分何でもよい。
  2. PCとペアリングする。
  3. 適当なキーをDiscordのキー割り当てでミュート切り替えに設定する。真ん中の再生キーはYouTubeとかの再生が始まるキーで使いにくい。今回は早送りキーを採用した。このキーはYouTubeとは干渉しない。(YouTube Musicとは干渉するので注意)
    キー割り当て

感想

当初はBluetoothキーボードを採用しようと思ったが、コンパクトなものが意外となかったことや、安いものがあまりなかったこと、防水性に大きな不安があったことなどから採用を見送った。

色々調べているとメディアボタンという概念に辿り着き、これを試しに買ってみてキーマップをリマップしようと考えた。 結果的には普段全く使っていないFAST FORWARDというキーが早送りに割り当てられていたため、リマップする必要もなかった。 4000円ほどで買ったが意外と良い買い物だった。

難点としては、思ったより小さかったこと、買ったものには防水についての記載が無かったことが挙げられる。前者については、なくしそうな程度に小さいため不安が残る。後者については、レビューを見るとバイクのハンドルに付けている人がいるようで、その人は濡れても平気だと言っており、最低限の信頼ができる。また、十分に端末が小さいのでジップロックに密閉するという解決策によって一応ことなきを得られた。

電池がどの程度もつのかや、長期的に使ってみると何かあるような気もするが、今のところはこんな感じでそれほど悪くない。

そのうちキーマップのリマップもやるような気がする。やっぱり真ん中のボタン使いたいし。