【ゼロトラスト】Single Packet Authorizationをfwknopで試してみる

# Single Packet Authirizationとは
Single Packet Authorization (SPA)はゼロトラストネットワークを構築するための技術です。サーバクライアント間の通信を開始する前に、クライアントが「合言葉となるパケット」を送ることで、サーバにポートを開いてもらいます。認証されたクライアントにのみ、一時的にポートを解放するため、さまざまなサイバー攻撃に対して安全性が高いということができます。
![spa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675830/da5df0a2-343e-4eda-a05a-637e6e573897.png)

# fwknopでSPAを実装してみる
### 下準備
SPAを実装できるオープンソースに、fwknopがあります。
fwknopを用いて、SPAでssh接続を行う動作を確認してみましょう。
まず、以下のDockerfile、docker-compose.yamlを用意します。
```dockerfile:client/Dockerfile
FROM ubuntu:latest

RUN apt update
RUN apt install iptables -y
RUN apt install iproute2 -y
RUN apt install fwknop-client -y

CMD ["/bin/bash"]
```

```dockerfile:server/Dockerfile
FROM ubuntu:latest

RUN apt update
RUN apt install iptables -y
RUN apt install iproute2 -y
RUN apt install fwknop-server -y

CMD ["/bin/bash"]
```

```yaml:docker-compose.yaml
services:
  spa_client:
    container_name: spa_client
    build: 
      context: ./client
    tty: true
  spa_server:
    container_name: spa_server
    build:
      context: ./server
    tty: true
```

docker compose up -d で起動させておきます。

次に、spa_serverに入り、sshサーバの設定を行います。
「apt install openssh-server」を行ったのちに、sshd_configを編集します。以下の内容を追記します。

```:etc/ssh/sshd_config
#追記内容
Port 22
PermitRootLogin no
PasswordAuthentication yes
```

「service ssh restart」で設定を反映させます。

そしたら、適当にadduserでユーザ登録を行っておきましょう。
ユーザを登録したらspa_clientコンテナに入り、登録したユーザでsshできるか確認しましょう。この時点では、ssh接続が可能なはずです。


### fwknopの設定
https://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html のQuick Startを参考に、SPAの設定を行います。

spa_client側で「ip a」コマンドを用いて自身のIPを確認し、その後以下のコマンドを入力します。
```bash
fwknop -A tcp/22 -a <自身のIP> -D spa_server --key-gen --use-hmac --save-rc-stanza

#出力結果
[*] Creating initial rc file: /root/.fwknoprc.
[+] Wrote Rijndael and HMAC keys to rc file: /root/.fwknoprc
```

/root/.fwknoprcが作成されるので、中身を見てみます
```bash
cat /root/.fwknoprc
#略

[spa_server]
ALLOW_IP                    192.168.80.3
ACCESS                      tcp/22
SPA_SERVER                  spa_server
KEY_BASE64                  ZFrrMoof7qqteJqVWSwDV7WZZjOCheKd7/KjDDV754M=
HMAC_KEY_BASE64             oXZr0qT9NP9YQx9QT5s3+CeX3qgUf7JUBHjniQzlps8NazvYX75YPh67nKDOsNibGTjuIPQlQoAICKICRzRXmQ==
USE_HMAC                    Y

```
出力されたKEY_BASE64とHMAC_KEY_BASE64は、spa_server側の/etc/fwknop/access.confに設定します。

```
#略
#### fwknopd access.conf stanzas ###

SOURCE              ANY
KEY_BASE64          ZFrrMoof7qqteJqVWSwDV7WZZjOCheKd7/KjDDV754M=
HMAC_KEY_BASE64     oXZr0qT9NP9YQx9QT5s3+CeX3qgUf7JUBHjniQzlps8NazvYX75YPh67nKDOsNibGTjuIPQlQoAICKICRzRXmQ==

#略
```

これでfwknopの設定は完了しました。
最後にspa_server側のファイアウォールの設定を行います。
以下のコマンドで、tcp/22が「合言葉となるパケット」以外に応答しないように設定します。
```bash
iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -j DROP
iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
```

あとは以下のコマンドでfwknopdを起動させます。
```bash
fwknopd start
```

### SPAを試してみる

まずは、spa_clientからspa_serverにsshをしてみます。
```bash
ssh -l <ユーザ名> spa_server
```
コマンドを実行すると、spa_serverからは何も反応がないことがわかります。
このように、サーバは「合言葉となるパケット」以外には全く反応を示しません。

では、「合言葉となるパケット」を送ってみます。
```bash
fwknop -n spa_server
```
その後sshを試すと、認証が行われて無事にssh接続が許可されます。
このように、SPAでは「合言葉となるパケット」によりポートが解放され、安全な通信を開始することができます。

# 最後に
以上より、fwknopを用いたSPAを実装できました。SPAはsoftware defined perimeter（SDP）の根幹技術であり、ゼロトラストアーキテクチャの実装には不可欠です。今後、クラウド化やサイバー攻撃の高度化によってゼロトラストの必要性が高まった際、参考にしていただけると幸いです。