UbuntuでSSHとGPGキーのパスフレーズを記憶させる

毎回パスワードを聞かれるのは面倒なのでkeychainを使って記憶させる。

確認環境

WSL2

Env Ver
keychain 2.8.5
Ubuntu 20.04.5 LTS

実機

Env Ver
keychain 2.8.5
Ubuntu 24.04.3 LTS

手順

1. keychainのインストール

sudo apt install keychain

2. keychainの設定

.zshrcに次の行を追加。

keychain -q --nogui --agents ssh,gpg --quick <SSH秘密鍵のパス> <GPG鍵のkeyid>

GPG鍵のkeyidは以下で取得可能。

gpg --list-secret-keys --keyid-format=long

3. エージェント連携をシェル設定に書く

~/.keychain配下にホスト名でHOGE-shのようなファイルができているので、これを.zshrcから読み込む。内容的にはssh-agentとkeychainが疎通するための環境設定と思われる。

具体的には以下の内容を.zshrcに追記すればよい。

source $HOME/.keychain/`hostname`-sh

最終的な.zshrcの状態としては以下のようになっていればよい。

keychain -q --nogui --agents ssh,gpg --quick <SSH秘密鍵のパス> <GPG鍵のkeyid>

source $HOME/.keychain/`hostname`-sh

hostname-sh-gpgみたいなファイルも出来ているが私の環境ではこれを読み込むと上手く動かなかったので、このファイルは指定しないほうが良さそうに見えた。

4. パスフレーズをCUI側に出す

.zshrcに以下を追記するとCUI側に出るようになる。

export GPG_TTY=$(tty)

5. パスフレーズを記憶させる

gpg-agent.confに書く。

cat <<'EOF' | tee ~/.gnupg/gpg-agent.conf
###+++--- GPGConf ---+++###
default-cache-ttl 34560000
max-cache-ttl 34560000
EOF

トラブルシュート

GPGのキーが見つからないエラーが出る

  • Warning: can't find DEADBEEF; skipping

上記が出た場合
~/.gnupg/gpg.confに対して以下の記述をすることで改善する。

keyid-format LONG

この設定をした後にkeychainに再ロードさせるには、gpg-agentを殺して.zshrcに書いたkeychainをもう一度実行するとうまくいく。

gpgconf --kill gpg-agent
keychain -q --nogui --agents ssh,gpg --quick <SSH秘密鍵のパス> <GPG鍵のkeyid>

GPGキーのパスフレーズのプロンプトがGUI側に出る

.zshrcに以下を追記するとCUI側に出るようになる。

export GPG_TTY=$(tty)

参考記事

更新履歴

  • 2026-07-06: gpgキーが認識されないときに再履行する方法を追記
  • 2026-06-04: パスフレーズをCUI側に出す方法と記憶させる方法を追記
  • 2026-01-21: エージェントとの連携設定が漏れていたのを追記
  • 2026-01-19: Ubuntu実機で確認したので、その結果を記事に反映し、記事を読みやすく改良

CloudFrontで自宅サーバーを外部公開する

今回はwell-known portsが利用出来ない環境でも自宅サーバーを公開する手法を紹介します。

自宅サーバーにhttps://service.example.com/のようにポート指定なしのサブドメインでアクセスできるようにするのがゴールです。

構成

自宅サーバーの手前にCDNを挟み、CDNを経由して接続させるようにします。要するに手前にリバプロを生やしておくわけです。

前提

前準備

DNSレコードに次のドメインを作っておく

用途 ドメイン レコード データ
CDN 用のドメイン cdn.example.com A サーバーのIP
公開用のドメイン service.example.com A サーバーのIP

自宅サーバーを公開可能な状態にする

叩き台程度ならserveを使うのが手っ取り早いですが、Node.jsでサーバー立てるのもありだと思います。今回は叩きなのでHTTPにしていますが本番運用するときはHTTPSにしましょう。

以下サンプル

const http = require('http');

const port = 12345;

const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello world!');
    console.log(req.headers.host, req.socket.remoteAddress);
});

server.listen(port, () => {
    console.log(`Running at http://localhost:${port}`);
});

手順

  1. CloudFrontを開く
  2. 「ディストリビューションを作成」
  3. 「オリジンドメイン」にcdn.example.comを設定
  4. 「プロトコル」を選ぶ
  5. cdn.example.comの「ポート」を設定する
  6. 設定までスクロール
  7. 「代替ドメイン名 (CNAME) - オプション」で「項目を追加」しservice.example.comを入力
  8. 「カスタムSSL証明書 - オプション」で「証明書をリクエスト」
  9. 「パブリック証明書をリクエスト」
  10. 「完全修飾ドメイン名」にservice.example.comを入力し「リクエスト」
  11. 「証明書を表示」
  12. DNSレコードに「CNAME名」で「CNAME値」を追加
  13. 「保留中の検証」が終わるのを待つ
  14. 「カスタムSSL証明書 - オプション」で作成した「ACM証明書」を選択
  15. 「ディストリビューションを作成」
  16. service.example.comのDNSレコードをCNAMEにし、データを「ディストリビューションドメイン名」に変更
  17. https://service.example.com/にアクセスできればOK

参考資料

トラブルシュート

ディストリビューションを削除したい

  1. ディストリビューションの一覧で消したいのにチェック入れて無効化
  2. しばらく待つ
  3. 消したいのにチェック入れて削除

参考:ディストリビューションを削除する (docs.aws.amazon.com)

後書き

副次的効果ですがCDN挟んでキャッシュされてるお陰で連続アクセスしてもサーバーまでリクエスト来ないので感動しました。

CloudFrontには他にも様々な機能があるみたいなので活用できれば便利そうです。

WSL2の中にMastodonの開発環境を作る

公式のドキュメントには書かれていない気がするがDockerだけあればセットアップ可能。WSL2でのセットアップが面倒なVargantは不要

本記事ではWSL2内のUbuntuの中でDockerとDocker Composeを使った構築法について記述する。Windows向けのDocker Desktopは使用しない

前提

  • WSL2のUbuntuにVSCodeで接続して作業
  • 起動してログイン、トゥート、設定と言った最低限の画面操作が可能な程度まで

確認環境

Env ver
Mastodon v3.5.3
Docker 20.10.21, build baeda1f
Docker Compose v2.12.2
Ubuntu 20.04.5 LTS
WSL2 1.0.3.0
DevContainer v0.266.1
VSCode 1.73.0

手順

  1. git clone https://github.com/mastodon/mastodon.git
    1. 最新版などバージョン指定が必要な場合は追加でtagをチェックアウトする
  2. VSCodeでClone先を開く
  3. Reopen Containerする
  4. セットアップが走るので暫く待つ
  5. foreman startを流す
  6. http://localhost:3000/ へアクセス

操作方法

ユーザーを作ったりしたい場合、Using the admin CLIが参考になる

一例としてユーザー作成は次の書式で行ける

./bin/tootctl accounts create foo --email foo@example.com --confirmed

トラブルシュート

DB接続エラーが出る

ActiveRecord::ConnectionNotEstablished at /
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql//.s.PGSQL.5432"?

上記のエラーが出る場合、ビルドしたDockerイメージが壊れてるので以下のコマンドで全て消して作り直すとうまく行く

docker rm -f `docker ps -a -q`
docker rmi `docker images -q`
docker system prune

他のMastodonインスタンスが動かない

複数のMastodonインスタンスのDocker環境を同居させると多分コンフリクトする

WSL2へのUbuntu 20.04セットアップメモ

Ubuntu22.04 LTSのターミナルのレンダリングが異常に重いのでバージョンを落として運用するためのメモ
Node.jsの開発環境だけ入れる

環境

環境 Version
Windows 11 Pro Build 22621.3155
Ubuntu 20.04.6 LTS
zsh 5.8 (x86_64-ubuntu-linux-gnu)
MariaDB Ver 15.1 Distrib 10.3.38-MariaDB
Docker 20.10.17, build 100c701
Git 2.42.0

WSL2の構成

  1. 管理者権限のPowerShellで以下を流す
    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    
  2. OS再起動
  3. Linuxカーネル更新プログラム パッケージをインストールする
  4. Ubuntuを入れる

Ubuntu側のセットアップ

適当な開発環境をサクッと。

~/.ssh/には予め鍵を入れておき、パーミッション700で作っておく。

# systemdの有効化
cat <<EOF | sudo tee /etc/wsl.conf
[boot]
command=service docker start; service nginx start; service mysql start;

[interop]
appendWindowsPath = false

[user]
default=ここにユーザー名
EOF

sudo apt update -y
sudo apt upgrade -y
sudo apt install -y \
    zsh \
    ssh \
    net-tools \
    traceroute \
    unzip \
    mariadb-server \
    nginx \
    git \
    keychain

# chsh
sudo apt -y install unzip traceroute
chsh -s $(which zsh)

# Docker
sudo apt remove docker docker-engine docker.io containerd runc
sudo apt update
# 依存関係のインストール
sudo apt install -y \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg \
   lsb-release
# Docker公式のGPG鍵を追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# リポジトリをパッケージマネージャーに登録
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
# docker本体のインストール
sudo apt install -y dockerdocker-ce docker-ce-cli containerd.io docker-compose-plugin
# sudo緩和
sudo usermod -aG docker $USER

# WSLをリブート

# dot file設定
git clone https://github.com/Lycolia/my-dotfiles.git
rm -Rf my-dotfiles/.git/
mv my-dotfiles/.* .
rm -Rf my-dotfiles/

# Node.js @ nvm
export NVM_DIR="$HOME/.nvm" && (
  git clone https://github.com/nvm-sh/nvm.git "$NVM_DIR"
  cd "$NVM_DIR"
  git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
nvm install --lts

# Keychain設定
cat <<'EOF' | tee -a ~/.zshrc
Keychain
keychain -q --nogui $HOME/.ssh/id_ed25519
source $HOME/.keychain/hostname-sh
EOF

トラブルシューティング

上記手順に書いてないことをすると起きるが、一応付記しておく

<3>WSL (639) ERROR: CreateProcessEntryCommon:345: getpwnam(USER_NAME) failed 0というエラーが出る

wsl.confの[user]セクションでdefault=USER_NAMEが存在しないユーザーを指定していると出る

Dockerやnginxのサービスが起動しない

systemdが有効になっていると起動しないので/etc/wsl.confからsystemd=trueを消す

keychainがError: Problem adding; giving upという

パーミッションを治す

chmod -R 700 .ssh

if:条件分岐

ifの書き方メモ。中身はtestコマンドなので[[]]の中はtestと同じ書き方が可能。コマンドなので演算子の間とかはスペースが無いとうまく動かない。余談だがzshでwhichすると組み込みコマンドであることが確認できる

which [[
zsh: bad pattern: [[
which [
[: shell built-in command
which test
test: shell built-in command

基本構文

あくまでコマンドなので演算子の間には半角スペースが必要。[より[[の方が高機能らしい

https://fumiyas.github.io/2013/12/15/test.sh-advent-calendar.html
https://yukidarake.hateblo.jp/entry/2015/12/14/205610

if-elif-else

if [[ $var = "条件" ]]; then
    # 処理
elif [[ $var -eq 0 ]]; then
    # 処理
else
    # 処理
fi

and / or

[[]]を&&か||で区切れば成立する。これらは演算をしているわけではなく[[の終了コードを見て次のコマンドを実行するかどうかを判断しているだけ

if [[ $var1 = "条件1" ]] && [[ $var2 = "条件2" ]]; then
    # 処理
fi

if [[ $var1 = "条件1" ]] || [[ $var2 = "条件2" ]];
    # 処理
fi
動作機序

testコマンドは条件を満たせば0、満たさなければ1を終了コードに設定するため、単純にこれを利用している。[[で代替可能なため基本的にtestは使わない方がいい

# 条件1の$?が0なら条件2が走る
[[ $var1 = "条件1" ]] && [[ $var2 = "条件2" ]]
# 条件1の$?を無視して条件2が走る
[[ $var1 = "条件1" ]] || [[ test $var2 = "条件2" ]]

オプション

文字列用

オプション 意味 補足
string = string 等しい -
string != string 等しくない -
string =~ string 正規表現一致 -
-n string 空文字でない non-zero
-z string 空文字 zero
-d path ディレクトリ directory
-s path ファイルサイズが 0 を超える size

数値用

オプション 意味 補足
0 -eq 0 等しい equals
0 -ne 0 等しくない not equals
0 -lt 0 未満 less than
0 -le 0 以下 less than or equal to
0 -gt 0 超える greater than
0 -ge 0 以上 greater than or equal to

ファイル用

オプション 意味 補足
-d path ディレクトリ directory
-e path 存在するパス exists
-f path ファイル file

参考