swanctl.confでstrongSwanを設定する方法を調べるためのTips

#はじめに
はじめまして、Lyxionと申します。これまでQiitaでは記事を読む側として利用させてもらってましたが、今回初投稿となります。
ガイドラインなど確認しておりますが、もしQiitaに投稿する記事としてよろしくない点などございましたらコメントなどでご指摘くださればと思います。

#本記事の概要
本記事では、strongSwanの設定ファイルの一つであるswanctl.confの設定方法を調べるための方法について記載します。
※具体的な記述例にはあまり触れません

#要約

* [公式のドキュメント](https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation)はもちろん参考になりますが、英語力とIKE/IPsecの知識のどちらかが欠けていると読むのが結構きついです
* ipsec.confの設定をswanctl.confの設定に書き換えるための[対応表](https://wiki.strongswan.org/projects/strongswan/wiki/Fromipsecconf)が公式サイトにあるので、ipsec.confの設定例を示した記事もswanctl.confの設定の参考にできます
    * ただし、ipsec.confを使ったときとswanctl.confを使ったときのデフォルトの挙動は異なるので注意しましょう


#背景
strongSwanを利用してIKE通信を行いIPsec通信を確立するためにどのような設定を行えばよいのか、ということを調べていると設定方法は大きく分けてipsec.confを使う方法とswanctl.confを使う方法があるということがわかりました。
[公式のドキュメント](https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation)は英語なのでちょっと読み込むのに苦労しそうな気がして日本語の記事を探してみると、ipsec.confを利用した設定方法を説明するものが多く、swanctl.confについて触れている記事が少ないような印象を受けました。
私は諸事情でswanctl.confを利用する必要があり、結局は[公式のドキュメント](https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation)を読むしかないのかな～と思っていたのですが、なんだかんだでipsec.confについての記事もswanctl.confの設定の参考にできるということが分かりましたので、記事にしようと思いました。

なお、本記事の作成時点(2021/08/16)ではQiitaで"ipsec.conf"と検索すると162件ヒットしますが、"swanctl.conf"と検索するとヒットするのはわずか5件です。また、これは体感レベルではありますがGoogle検索などでもipsec.confでの設定方法についての記事の方が圧倒的に多いと思います。
#swanctl.confを利用するためには(インストール方法)
そもそも、「strongswanにswanctl.confなんて設定ファイルはあるのか？(ipsec.confしかない)」という方もいらっしゃるかもしれません。実は、aptなどパッケージ管理システムを利用して単純にstrongSwanインストールした場合はipsec.confはあるけどswanctl.confが見当たらない、swanctlコマンドが叩けないといった状況になっている場合があります。
aptであれば、おそらく"strongswan-swanctl"というパッケージが未インストールの状態かと思いますので、インストールしてみてください。swanctlコマンドを引数を渡さずに叩いて以下のようにヘルプ表示が出力されれば大丈夫です。
※apt以外はわかりません、ごめんなさい

```
$ swanctl
strongSwan 5.9.1 swanctl
loaded plugins: aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem fips-prf gmp xcbc hmac drbg
usage:
  swanctl --counters         (-C)  list or reset IKE event counters
  swanctl --initiate         (-i)  initiate a connection
  swanctl --terminate        (-t)  terminate a connection
  swanctl --rekey            (-R)  rekey an SA
  swanctl --redirect         (-d)  redirect an IKE_SA
  swanctl --uninstall        (-u)  uninstall a trap or shunt policy
  swanctl --install          (-p)  install a trap or shunt policy
  swanctl --list-sas         (-l)  list currently active IKE_SAs
  swanctl --monitor-sa       (-m)  monitor for IKE_SA and CHILD_SA changes
  swanctl --list-pols        (-P)  list currently installed policies
  swanctl --list-authorities (-B)  list loaded authority configurations
  swanctl --list-conns       (-L)  list loaded configurations
  swanctl --list-certs       (-x)  list stored certificates
  swanctl --list-pools       (-A)  list loaded pool configurations
  swanctl --list-algs        (-g)  show loaded algorithms
  swanctl --flush-certs      (-f)  flush cached certificates
  swanctl --load-all         (-q)  load credentials, authorities, pools and connections
  swanctl --load-authorities (-b)  (re-)load authority configuration
  swanctl --load-conns       (-c)  (re-)load connection configuration
  swanctl --load-creds       (-s)  (re-)load credentials
  swanctl --load-pools       (-a)  (re-)load pool configuration
  swanctl --log              (-T)  trace logging output
  swanctl --version          (-v)  show version information
  swanctl --stats            (-S)  show daemon stats information
  swanctl --reload-settings  (-r)  reload daemon strongswan.conf
  swanctl --help             (-h)  show usage information
                                                                 
```

#swanctl.confの記載例
今後の説明を簡単にするために、swanctl.confのを公式サイトから引用して以下に示します。[[引用元]](https://www.strongswan.org/testing/testresults/ikev2/net2net-cert/moon.swanctl.conf)
{}を使ってセクションを区切るような構造になっています。{ の前に来ている"connections"や"gw-gw"といった単語はセクション名です。
この例にはありませんが、#でコメントアウトが可能です。#があると、その行で#以降に書かれていることは設定に影響を与えません。
また、設定の行ひとつひとつにセミコロンなどの区切り文字をつける必要はありません。（強いて言うなら改行や空白文字が区切りとなります）

```
connections {

   gw-gw {
      local_addrs  = 192.168.0.1
      remote_addrs = 192.168.0.2 

      local {
         auth = pubkey
         certs = moonCert.pem
         id = moon.strongswan.org
      }
      remote {
         auth = pubkey
         id = sun.strongswan.org 
      }
      children {
         net-net {
            local_ts  = 10.1.0.0/16 
            remote_ts = 10.2.0.0/16 

            updown = /usr/local/libexec/ipsec/_updown iptables
            rekey_time = 5400
            rekey_bytes = 500000000
            rekey_packets = 1000000
            esp_proposals = aes128gcm128-x25519
         }
      }
      version = 2
      mobike = no
      reauth_time = 10800
      proposals = aes128-sha256-x25519
   }
}
```

#swanctl.confの設定の調べ方
ここから、swanctl.confの書き方をどう調べたらよいかを示します。
以下の2通りのやり方を想定して記載します。なお、本題は後者です。

* [公式サイトのstrongSwan User Documentationを読む](https://qiita.com/drafts/c4cc414f43c0d2b444da/edit#%E5%85%AC%E5%BC%8F%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AEstrongswan-user-documentation%E3%82%92%E8%AA%AD%E3%82%80)
* [strongSwanユーザたちが書いた記事を参考にする](https://qiita.com/drafts/c4cc414f43c0d2b444da/edit#strongswan%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%9F%E3%81%A1%E3%81%8C%E6%9B%B8%E3%81%84%E3%81%9F%E8%A8%98%E4%BA%8B%E3%82%92%E5%8F%82%E8%80%83%E3%81%AB%E3%81%99%E3%82%8B)

##公式サイトの[strongSwan User Documentation](https://wiki.strongswan.org/projects/strongswan/wiki/UserDocumentation)を読む
当然ではありますが、一番確実かつ正確な情報が得られます。swanctl.confだけでなく、もちろんipsec.confについても書かれています。
IKE/IPsecの知識がある程度あってかつ英語が苦手でなければ公式ドキュメントを参考にするのが速いでしょう。
英語を読めなくてもDeepLやGoogle翻訳なんかで日本語訳をすればある程度内容はわかるはずです。

###swanctl.confのドキュメントページの読み方

swanctl.confの設定方法は、[swanctl.conf](https://wiki.strongswan.org/projects/strongswan/wiki/Swanctlconf)ページに記載されています。
このページには設定キー名がずらりと記載されていて、セットでその設定キーは何がを設定できるのかの説明およびデフォルト値が記載されています。基本的にはこれを元にswanctl.confを記述することになります。
例えば、ローカル側で利用する相手の認証方法を決める*connections.\<conn\>.local\<suffix\>.auth*という設定キーがありますが、このデフォルト値はpubkey(証明書での認証)とされています。

設定キーの記述はドット"."で区切られていますが、これはセクションの親子関係を示しています。
また、設定キー名で\<\>で囲まれている部分は任意の文字列を利用できます。ただし、同じセクション内ではユニークである必要があります。

つまり、上記に示した*connections.\<conn\>.local\<suffix\>.auth*であれば例えば以下のように記述することになります。


```
connections {
    abc {
        local-xyz {
            auth = pubkey
        }
    }
}
            
```

また、\<\>で囲まれている部分が「同じセクション内ではユニークである必要がある」とは、以下のような書き方はできないということです(以下では、hogeサブセクションがconnectionsセクション内で重複している)

```
connections {
    hoge {
        #何かしらの設定
    }
    hoge {
        #重複しているセクション、ダメ！
    }
}
```

※swanctl.confの文法の詳細はここ→[[Link]](https://wiki.strongswan.org/projects/strongswan/wiki/Strongswanconf#Syntax)を参照してください。

このドキュメントはIKEやIPsecについてはある程度知っている前提で記述されています。そのため、IKE/IPsecの初心者だったり英語が苦手だったりする場合にきつさを感じると思います。

そこで「ドキュメント見たけどよくわかんなくて、Qiitaなりブログなりで自分のしたいことと同じことをswanctl.confでやった先人の記事を探そう」ということになったりすると、swanctl.confの記事があまりなくてipsec.confの記事ならたくさん出てくる、といった状況になると思います（私はなりました）。
※改めてですが、これが今回この記事を書いた[背景](https://qiita.com/drafts/c4cc414f43c0d2b444da/edit#%E8%83%8C%E6%99%AF)です。

##strongSwanユーザたちが書いた記事を参考にする

strongSwanはIKEデーモンのOSSとしてはかなり有名なためか、ググると情報自体はたくさん出てきます。
くどいようですが、現状ipsec.confを利用した設定例を示してくれているページが多く、swanctl.confについての示してくれているページはまだまだ少ないです。
そのため、ipsec.confでの設定例は見つけたけどswanctl.confでどうやるのかはわからないという状況が発生し得ます。

**そんなときに、ipsec.confからswanctl.confへの移行にやり方について記している公式サイトのページが大活躍します。**
[Migration from ipsec.conf to swanctl.conf - strongSwan](https://wiki.strongswan.org/projects/strongswan/wiki/Fromipsecconf)
※結局公式サイトなので英語ではあります

このページの[Manual](https://wiki.strongswan.org/projects/strongswan/wiki/Fromipsecconf#Manual)セクションを見てみると、「ipsec.confではこうやってた設定は、swanctl.confではこうやって設定するよ」という情報が表になってずらっと並んでいます。

見つけたipsec.confの設定例をこの表に従ってswanctl.confに変換すれば、ほぼ等価な設定が可能となります！
ただし、注意点があります。

###ipsec.confのデフォルト値とswanctl.confのデフォルト値は一緒ではない
ipsec.confとswanctl.confのどちらもデフォルトの設定が存在していますので、設定をある程度省略することが可能です。実際ほとんどの設定はデフォルト値を持っているので、利用する暗号アルゴリズムやライフタイムなどの設定を省いたconfファイルでもstrongSwanは動作します。
そのため、実際に自分でconfファイルを書くときもWeb上に存在する記述例を見てみてもおそらくすべて設定を記述したものはほとんどないのではないかと思います。

ここで気を付けなければならないのが、以下の点です。
**ipsec.confとswanctl.confのデフォルト設定は異なる箇所がところどころあります。**

[Migration from ipsec.conf to swanctl.conf - strongSwan](https://wiki.strongswan.org/projects/strongswan/wiki/Fromipsecconf)をよく見てみると、実はデフォルト値が異なる部分があります。
これは、ipsecコマンドで設定を読みこむときとswanctlコマンドで設定を読み込むときの仕様の違いだと私は認識しています（異論あればコメントなどいただければと思います）。

例えば、ipsec.confのconnセクションの*auto*という設定です。
*auto*は、「そのセクションの設定をどうするか（起動した瞬間SAを立てるのか、カーネルで通信をトラップするのか、など）」を決める設定です。
ipsec.confに*auto*を記載しなかった場合は *auto = ignore* が書かれた扱いとなり、「そのセクションの設定は無視する」ということになり、設定自体をロードしない挙動となります。つまり、ipsec.confに接続設定を書いてもそのconnセクションで*auto*を明示的に指定しなければその設定は利用できません。

これに対応したswanctl.confの設定キーは*connections.\<conn\>.children.\<child\>.start_action*なのですが、こちらはデフォルト値が"none"となっていて、ipsec.confでいうと*auto = add*と同じ挙動となっています。これは、コマンドなどで明示的にSAを立てることができるように設定のロードだけしておくという挙動です。これはipsec.confと異なる挙動です。

といったように、かなり基本的な挙動のデフォルト値も異なっていたりするため、設定を変換する際は注意しましょう。

###この変換を自動でやってくれるツールがあるらしい
私は使ったことがないのですが、公式サイトで変換ツールが紹介されていました。
興味があれば使ってみるのもよいかと思います。
[Ipsec2swanctl](https://gitlab.com/Thermi/ipsec2swanctl)

#おわりに
公式サイトを見ていると開発陣としては「swanctlコマンド/swanctl.conf」を利用した設定を推奨している雰囲気を感じますが、まだまだ「ipsecコマンド/ipsec.conf」を利用している人が多いのかなぁという印象があります。
今後徐々にswanctl.confの情報が増えてくるとは思いますが、それまではipsec.confを利用した設定例を発信してくれた先人の情報を有効活用していくとstrongSwanがより使いやすくなるでしょう。

「ipsec.confそのまま使えばいいじゃん」とツッコミをしたくなる方もいらっしゃるかもしれませんが、個人的にswanctlコマンドの方が使いやすく柔軟性があるなと感じています（あまりユースケースはないかもしれませんが、特定のCHILD SAだけ切ってそのCHILD SAを立てたIKE SAを残したりとかできます）。
これまでipsec.confを利用していた方も、これを機にswanctlコマンドを試してみるのはいかがでしょうか？

今後swanctl関連の情報が増えてくれればいいなーと願っています（自分でも今後増やしていければいいなぁとは思います）。