Symbol shoestring wizard でノード秘密鍵を維持して証明書更新

## 背景

Symbol shoestring v0.2.1 より、ノード証明書更新の際、秘密鍵を維持できるオプション `--retain-node-key` が追加されました。

https://github.com/symbol/product/tree/shoestring/v0.2.1/tools/shoestring#renew-certificates

コマンドで更新する際にはオプションを指定できるのですが、 wizard だとオプションを指定する方法がありません。

本記事は、 wizard でノード秘密鍵を維持して証明書を更新した際の作業ログとなります。

:::note warn
本記事の内容を実施する際は自己責任でお願いします。
:::

## 事前準備

shoestring v0.2.1 をインストール、またはアップグレードします。

執筆時点、この記事が必要となる多くの方は shoestring v0.1.x でノードを構築された方だと思います。
shoestring v0.2.1 へのアップグレード方法は以下の記事を参考にしてください。

https://qiita.com/amenoudume/items/c49b5a7366207a12d94c

あと、念のためバックアップを取りましょう。

## コード修正

wizard から更新した際のコマンドにオプションをつけるため、コードを修正します。
以降は vim での操作例を示します。

1. shoestring パッケージの格納場所を確認します
   ```shell
   $ pip show symbol-shoestring
   Name: symbol-shoestring
   Version: 0.2.1
   Summary: Symbol Shoestring Deployment Tool
   Home-page: https://github.com/symbol/product/tree/main/tools/shoestring
   Author: Symbol Contributors
   Author-email: contributors@symbol.dev
   License: MIT
   Location: {ここに格納場所のパスガ出力されます}
   Requires: aiohttp, jinja2, prompt-toolkit, pyyaml, requests, symbol-lightapi, symbol-sdk-python, websockets, zenlog
   Required-by: 
   ```
1. shoestring パッケージの格納場所をカレントディレクトリにします
   ```shell
   $ cd {前手順の Location に表示されたパス}
   ```
1. 対象ファイルを vim で開きます
   ```shell
   $ vi shoestring/wizard/ShoestringOperation.py
   ```
1. `:set number` を入力して `Enter` します
   -> 行番号が表示されます
1. `:set list` を入力して `Enter` します
   -> タブ文字等の不可視文字が表示されます
1. `i` を入力して挿入モードにします
1. 64行目に、ノード秘密鍵を維持するためのオプションを設定するコードを追加します
   以下のコードをコピー＆ペーストします
   ```vim
   	if ShoestringOperation.RENEW_CERTIFICATES == operation:
   		shoestring_args.extend(['--retain-node-key'])
   
   ```

最終的に以下のように表示されていればOKです。
![modify-code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658417/85269867-3c6e-4cf9-99c7-3da6bed692fd.png)

:::note
ここで、 `^I` はタブ文字を示します。

Python ではインデントの種類が異なるとエラーとなってしまいます。
shoestring コードではインデントの種類としてタブ文字が採用されているため、追記するコードのインデントもタブ文字にする必要があります。
このため、もしも `^I` ではなくスペースとなっている場合、タブ文字に変更する必要があります。

1. コード前のスペースを全て削除します
1. 1行目の先頭で1回、2行目の先頭で2回、 `Ctrl-v Tab` を入力します
:::

コードの修正が完了したら保存して閉じます。
`Esc` でコマンドモードに戻り、 `:wq!` を入力して `Enter` します。

## 証明書更新

秘密鍵が維持されているか確認するため、現在のノード秘密鍵を確認しておきます。
以降、ノードディレクトリは `~/symbol` （wizard で setup する際のデフォルト）とします。

```shell
$ openssl pkey -in ~/symbol/keys/cert/node.key.pem -noout -text
ED25519 Private-Key:
priv:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**
pub:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**
```

shoestring wizard を起動します。

```shell
$ python3 -m shoestring.wizard
```

`renew certificates` を選択します。
![wizard-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658417/1371b054-554e-4239-ac0d-b1bc6e38851c.png)

ノードディレクトリ、 ca.key.pem ファイルパスを入力して `Next` を選択します。
![obligately-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658417/f00e4009-350f-4c2c-b623-97ac898544d6.png)

確認画面が出るので `Finish` を選択します。
これで証明書が更新されます。

```shell
$ openssl x509 -noout -dates -in ~/symbol/keys/cert/node.crt.pem
notBefore=Jun  7 16:32:39 2025 GMT
notAfter=Jun 17 16:32:39 2026 GMT
```

証明書更新後の秘密鍵を確認します。

```shell
$ openssl pkey -in ~/symbol/keys/cert/node.key.pem -noout -text
ED25519 Private-Key:
priv:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**
pub:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:
    **:**
```

この出力内容が証明書更新前と同じになっているはずです。