Single Packet Authorization(SPA)を見たい!

仕事でSoftware Defined Perimeter(SDP)について調べていたら、OSS版のSDPがあることを知りました。 Single Packet Authorization(以後、SPAと省略します)を自分の目で見たくて、苦労してUbuntuで構築してSPAを確認することが出来ました。 諸事情によりRHEL系でもSPAを構築する必要があり、これまた一苦労して構築したので、いい加減何かアウトプットしないとまた時間を溶かすと思いブログを書くことにしました。

1. Single Packet Authorization(SPA)

SPAは、ポートノッキングの利点を持ちつつ、ポートノッキングの課題に対処したものになります。 詳しくは、以下をご確認ください。 cloudsecurityalliance.jp

2. SPAイメージと構成図

CentOS Linux release 7.9.2009 (Core)

3. SPA(Client-Server)構築


gccコンパイラ)とlibpcap(パケットキャプチャライブラリ)が必要です。 Ubuntuの時は、apt-get でinstall出来てしまったので躓きながら構築していきました。

3.1 SPA(Client-Server共通)インストール

wget をインストール

yum install wget

② fwknopをダウンロード

wget http://www.cipherdyne.org/fwknop/download/fwknop-2.6.10.tar.gz

③ tarball を解凍

tar xfz fwknop-2.6.10.tar.gz

④ 解凍したディレクトリに移動

cd fwknop-2.6.10

⑤ 環境を調査して、環境に合わせて設定したMakefileを生成

./configure --prefix=/usr --sysconfdir=/etc && make

(。´・ω・)ん?ナニコレ?

configure: error: no acceptable C compiler found in $PATH

コンパイラがないので怒られたということか。

gccコンパイラ)インストール

yum install gcc

⑦ 再度 configure 実行

configure: error: fwknopd needs libpcap

(。´・ω・)ん? libpcap て何?

What is libpcap used for?

Libpcap enables administrators to capture and filter packets. Packet sniffing tools like tcpdump use the Libpcap format. For Windows users, there is the WinPcap format. WinPcap is another portable packet capture library designed for Windows devices.

クライアントから来るSPAパケットを見るのがサーバなので当然パケットキャプチャ用のライブラリが必要ということになります。

⑧ libpcap(libpcap.so)インストール

yum install -y libpcap-devel

⑨ ./configure (再々トライ)

./configure --prefix=/usr --sysconfdir=/etc && make

⑩ やっとインストール開始

make install

⑪ パスの確認

[root@test-sv fwknop]# which fwknop
/usr/bin/fwknop
[root@test-sv fwknop]# which fwknopd
/usr/sbin/fwknopd
[root@test-sv fwknop]#

⑫ バージョン確認

[root@test-sv fwknop]# fwknop -V
fwknop: error while loading shared libraries: libfko.so.3: cannot open shared object file: No such file or directory

どうやら共通ライブラリが見えないようです。

⑬ 本当にないのかと疑う

[root@test-sv fwknop]# ldconfig -p | grep libfko
[root@test-sv fwknop]# 

確かに無いようだ

⑭ 念のため設定変更せずに、再読み込みして見る

[root@test-sv fwknop]# ldconfig
[root@test-sv fwknop]# 

⑮ 期待せずに確認

[root@test-sv fwknop]# ldconfig -p | grep libfko
        libfko.so.3 (libc6,x86-64) => /lib/libfko.so.3
        libfko.so (libc6,x86-64) => /lib/libfko.so
[root@test-sv fwknop]#

あるじゃないか!!

⑯ バージョン確認(リトライ)

[root@test-sv fwknop]# fwknop -V
fwknop client 2.6.10, FKO protocol version 3.0.0
[root@test-sv fwknop]#
[root@test-sv fwknop]# fwknopd -V
fwknopd server 2.6.10, compiled for firewall bin: /usr/bin/firewall-cmd
[root@test-sv fwknop]#

3.2 SPA(Client)共通鍵の生成

① 共通鍵を生成します。暗号は、Advanced Encryption Standard:AES を使います。送信元:203.0.113.1(Client) / 送信先:203.0.113.254(Server) / サーバの制御対象:tcp/22 を指定します。

[root@test-cl fwknop-2.6.10]# fwknop -A tcp/22 -a 203.0.113.1 -D 203.0.113.254 --key-gen --use-hmac --save-rc-stanza
[+] Wrote Rijndael and HMAC keys to rc file: /root/.fwknoprc
[root@test-cl fwknop-2.6.10]# 

② 鍵生成をしたユーザの $HOME/.fwknoprc に出力されているので確認して内容をコピーします。

[root@test-cl fwknop-2.6.10]# cat $HOME/.fwknoprc
[default]

[203.0.113.254]
ALLOW_IP                    203.0.113.1
ACCESS                      tcp/22
SPA_SERVER                  203.0.113.254
KEY_BASE64                  xO5mM5lEJUVKxMn6PcNUKTn1qdivpLA1AHsMALKdhlU=
HMAC_KEY_BASE64             i0Asqvm0zGB867vcZT15RlL9TWrkbUs+4tNXAemTYF/D4MBWQX6dCWbCLSJ8ltj/VEPMBc/TNlGYwTlLCEVbVQ==
USE_HMAC                    Y
[root@test-cl fwknop-2.6.10]#

KEY_BASE64 と HMAC_KEY_BASE64 を Server の定義で使います。

3.3 SPA(Server)定義

Server の定義ファイルはかなり細かいのですが、最低限設定が必要な箇所はとても少ないです。

① /etc/fwknop/fwknopd.conf で動作させるNICを定義します。

# Define the ethernet interface on which we will sniff packets.
# Default if not set is eth0.  The '-i <intf>' command line option overrides
# the PCAP_INTF setting.
#
PCAP_INTF                   ens34;

【参考】/etc/fwknop/fwknopd.conf

##############################################################################
#
#         [+] fwknopd - Firewall Knock Operator Daemon [+]
#
# This is the configuration file for fwknopd, the Firewall Knock Operator
# daemon.  The primary authentication and authorization mechanism offered
# by fwknop is known as Single Packet Authorization (SPA).  More information
# about SPA can be found at: http://www.cipherdyne.org/fwknop/docs/SPA.html
#
# There are no access control directives in this file.  All access
# control directives are located in the file "/etc/fwknop/access.conf".
# You will need to edit the access.conf file in order for fwknop to function
# correctly.
#
# Most of these can remain commented out unless you need to override the
# default setting.
#
# It is also important to note that there are some subtle (and some not
# so subtle) differences between this configuration file, its parameters
# and valid values and the configuration file used by the legacy Perl
# version of fwknopd.  Please pay careful attention to the format and
# values used in this file if you are migrating from the legacy Perl
# version.
#
##############################################################################
#

#
# Define the default verbosity level the fwknop server should use.
# A value of "0" is the default verbosity level. Setting it up to "1" or
# higher will allow debugging messages to be displayed.
#
#VERBOSE                     0;

# Define the ethernet interface on which we will sniff packets.
# Default if not set is eth0.  The '-i <intf>' command line option overrides
# the PCAP_INTF setting.
#
PCAP_INTF                   ens34;

# By default fwknopd does not put the pcap interface into promiscuous mode.
# Set this to 'Y' to enable promiscuous sniffing.
#
#ENABLE_PCAP_PROMISC         N;

# Define the filter used for PCAP modes; we default to udp port 62201.
# However, if an fwknop client uses the --rand-port option to send the
# SPA packet over a random port, then this variable should be updated to
# something like "udp dst portrange 10000-65535;".
# Default is "udp port 62201".
#
#PCAP_FILTER                 udp port 62201;

### Netfilter Queue (NFQ) Parameters ###
#
# These settings apply only if fwknopd was compiled with libnetfilter_queue
# support (configure with --enable-libnetfilter_queue). If this was not
# enabled, leave these commented out.
#
# Uncomment and set to "Y" to capture via libnetfilter_queue. This is the
# only option that must be set in order for NFQ capture.  The remaining
# options have reasonable default values.
#
#ENABLE_NFQ_CAPTURE          Y;

# If you want to limit capture to a specific network interface, specify it
# here. If NFQ is enabled and this is left commented out, SPA packets will
# be captured on any/all network interfaces (which is the default).
#
#NFQ_INTERFACE               eth0;

# Specify the UDP port for incoming SPA packets (default is 62201).
#
#NFQ_PORT                    62201;

# Specify the iptable table for NFQ use (should stay the default of "mangle").
#
#NFQ_TABLE                   mangle;

# The name for the chain we will use for NFQ (default is "FWKNOP_NFQ").
#NFQ_CHAIN

# Specify the NFQ queue number.  The default is "1".
#
#NFQ_QUEUE_NUMBER            1;
#
### End of Netfilter Queue (NFQ) Options ###

# This instructs fwknopd to not honor SPA packets that have an old time
# stamp.  The value for "old" is defined by the MAX_SPA_PACKET_AGE variable.
# If ENABLE_SPA_PACKET_AGING is set to "N", fwknopd will not use the client
# time stamp at all.
#
#ENABLE_SPA_PACKET_AGING     Y;

# Defines the maximum age (in seconds) that an SPA packet will be accepted.
# This requires that the client system is in relatively close time
# synchronization with the fwknopd server system (NTP is good).  The default
# age is two minutes.
#
#MAX_SPA_PACKET_AGE          120;

# Track digest sums associated with previous fwknop process.  This allows
# digest sums to remain persistent across executions of fwknop.
#
#ENABLE_DIGEST_PERSISTENCE   Y;

# Sets the number of packets that are processed when the pcap_dispatch()
# call is made.  The default is zero, since this allows fwknopd to process
# as many packets as possible in the corresponding callback where the SPA
# handling routine is called for packets that pass a set of prerequisite
# checks.  However, if fwknopd is running on a platform with an old
# version of libpcap, it may be necessary to change this value to a positive
# non-zero integer.  More information can be found in the pcap_dispatch(3)
# man page.
#PCAP_DISPATCH_COUNT            0;

# Sets the number of microseconds to pass as an argument to usleep() in
# the pcap loop.  The default is 100000 microseconds, or 1/10th of a second.
#PCAP_LOOP_SLEEP                100000;

# Specify the the maximum number of bytes to sniff per frame - 1500
# is a good default
#
#MAX_SNIFF_BYTES             1500;

# If GPG keys are used instead of a Rijndael symmetric key, this is
# the default GPG keys directory.  Note that each access stanza in
# fwknop access.conf can specify its own GPG directory to override
# this default.
#
#GPG_HOME_DIR        /root/.gnupg;

# Set the default GPG path when GPG is used for SPA encryption and
# authentication.
#
#GPG_EXE            /usr/bin/gpg;

# Allow fwknopd to acquire SPA data from HTTP requests (generated with the
# fwknop client in --HTTP mode).  Note that the PCAP_FILTER variable would
# need to be updated when this is enabled to sniff traffic over TCP/80
# connections.
#
#ENABLE_SPA_OVER_HTTP        N;

# Allow fwknopd to resolve hostnames in NAT access messages.
#ENABLE_NAT_DNS              Y;

# Allows the use of the X-Forwarded-for header from a captured packet as the
# Source IP. This can happen when using SPA through an HTTP proxy.
#
#ENABLE_X_FORWARDED_FOR      N;

# Instead of appending new firewall rules to the bottom of the chain, this
# option inserts rules at the top of the chain. This causes newly created
# rules to have precedence over older ones.
#
#ENABLE_RULE_PREPEND         N;

# Enable the fwknopd TCP server.  This is a "dummy" TCP server that will
# accept TCP connection requests on the specified TCPSERV_PORT.
# If set to "Y", fwknopd will fork off a child process to listen for and
# accept incoming TCP requests.  This server only accepts the
# request.  It does not otherwise communicate. This is only to allow the
# incoming SPA over TCP packet which is detected via PCAP. The connection
# is closed after 1 second regardless.
# Note that fwknopd still only gets its data via pcap, so the filter
# defined by PCAP_FILTER needs to be updated to include this TCP port.
#
#ENABLE_TCP_SERVER           N;
#TCPSERV_PORT                62201;

# Set/override the locale (via the LC_ALL locale category).  Leave this
# entry commented out to  have fwknopd honor the default system locale.
#
#LOCALE                      C;

# Override syslog identity and facility (the defaults are usually ok).
# The SYSLOG_FACILITY variable can be set to one of LOG_LOCAL{0-7}
# or LOG_DAEMON (the default).
#
#SYSLOG_IDENTITY             fwknopd;
#SYSLOG_FACILITY             LOG_DAEMON;

# Define this to have fwknopd read pcap data from a file instead of sniffing
# a live interface.  This is usually only used for debugging purposes, and is
# equivalent to the '-r <pcap file>' command line option.
#
#PCAP_FILE                   /some/path/to/file.pcap;

# This variable controls whether fwknopd is permitted to sniff SPA packets
# regardless of whether they are received on the sniffing interface or sent
# from the sniffing interface.  In the latter case, this can be useful to have
# fwknopd sniff SPA packets that are forwarded through a system and destined
# for a different network.  If the sniffing interface is the egress interface
# for such packets, then this variable will need to be set to "Y" in order for
# fwknopd to see them.  The default is "N" so that fwknopd only looks for SPA
# packets that are received on the sniffing interface (note that this is
# independent of promiscuous mode).
#
# ENABLE_PCAP_ANY_DIRECTION     N;

# Controls whether fwknopd will set the destination field on the firewall
# rule to the destination address specified on the incoming SPA packet.
# This is useful for interfaces with multiple IP addresses hosting separate
# services. If ENABLE_IPT_OUTPUT is set to "Y", the source field of
# the firewall rule is set. FORWARD and SNAT rules are not affected however,
# DNAT rules will also have their destination field set. The default is
# "N", which sets the destination field to 0.0.0.0/0 (any).
#
# ENABLE_DESTINATION_RULE       Y;

##############################################################################
# NOTE: The following EXTERNAL_CMD functionality is not yet implemented.
#       This is a possible future feature of fwknopd.
#
# The following four variables control whether a global set of "open" and
# "close" commands are executed after receiving a valid SPA packet.  These
# variables are used only if FIREWALL_TYPE is set to "external_cmd", but
# the same variables can also exist within the access.conf file so that
# mixed deployments are possible - that is, some SPA packets will operate
# as usual and result in firewall commands being executed, but others will
# result in the commands defined by these variables (in access.conf) being
# executed.
#     The "open" and "close" commands might be manually supplied firewall
# commands, and both support variable substitution of any of the variables
# in the access.conf file with "$VAR".  Also, three special variables are
# supported: $SRC, $PORT, and $PROTO, which are derived from actual values
# from within valid SPA packets (as opposed to $SOURCE from access.conf
# which may contain a list of networks instead of a single IP address).
# Here are some examples:
#     - Execute a specific iptables command on behalf of the source IP
#     in a valid SPA packet to add a new ACCEPT rule, and execute
#     another command (to delete the same rule after a timeout):
#         EXTERNAL_CMD_OPEN       iptables -A INPUT -s $SRC -j ACCEPT
#         EXTERNAL_CMD_CLOSE      iptables -D INPUT -s $SRC -j ACCEPT
#     - Execute a custom binary with the SOURCE and OPEN_PORTS variables
#     from the access.conf file as input on the command line, and after
#     a timeout execute a different program but use the real SPA source
#     IP:
#         EXTERNAL_CMD_OPEN       /path/someprog $SOURCE $OPEN_PORTS
#         EXTERNAL_CMD_OPEN       /path/otherprog $SRC
#
#ENABLE_EXTERNAL_CMDS        N;
#EXTERNAL_CMD_OPEN           __NONE__;
#EXTERNAL_CMD_CLOSE          __NONE__;
#EXTERNAL_CMD_ALARM          30;

# if EXTERNAL_CMD_OPEN is used above, then the following two variables can
# be used to enforce a prefix on variable substitutions - useful if there
# are any naming conflicts with the external script and command line
# arguments that are named the same as the variables to be substituted.
#
#ENABLE_EXT_CMD_PREFIX       N;
#EXT_CMD_PREFIX              FWKNOP_;

##############################################################################
# Parameters specific to firewalld:

# Flush all existing rules in the fwknop chains at fwknop start time and/or
# exit time. They default to Y and it is a recommended setting for both.
#
#FLUSH_FIREWD_AT_INIT           Y;
#FLUSH_FIREWD_AT_EXIT           Y;
#

# Allow SPA clients to request access to services through a firewalld
# firewall instead of just to it (i.e. access through the FWKNOP_FORWARD
# chain instead of the INPUT chain).
#
#ENABLE_FIREWD_FORWARDING       N;

# Allow SPA clients to request access to a local socket via NAT.  This still
# puts an ACCEPT rule into the FWKNOP_INPUT chain, but a different port is
# translated via DNAT rules to the real one.  So, the user would do
# "ssh -p <port>" to access the local service (see the --NAT-local and
# --NAT-rand-port on the fwknop client command line).
#
#ENABLE_FIREWD_LOCAL_NAT        Y;

# By default, if forwarding access is enabled (see the ENABLE_FIREWD_FORWARDING
# variable above), then fwknop creates DNAT rules for incoming connections,
# but does not also complement these rules with SNAT rules at the same time.
# In some situations, internal systems may not have a route back out for the
# source address of the incoming connection, so it is necessary to also
# apply SNAT rules so that the internal systems see the IP of the internal
# interface where fwknopd is running.  This functionality is only enabled
# when ENABLE_FIREWD_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also define an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_FIREWD_SNAT             N;
#SNAT_TRANSLATE_IP           __CHANGEME__;

# Add ACCEPT rules to the FWKNOP_OUTPUT chain. This is usually only useful
# if there are no state tracking rules to allow connection responses out and
# the OUTPUT chain has a default-drop stance.
#
#ENABLE_FIREWD_OUTPUT           N;

# fwknopd adds allow rules to a custom firewalld chain "FWKNOP_INPUT".
# This chain is called from the INPUT chain, and by default no other
# firewalld chains are used.  However, additional chains can be added
# (say, if access needs to be allowed through the local system via the
# FORWARD chain) by altering the FIREWD_FORWARD_ACCESS variable below.
# For a discussion of the format followed by these keywords, read on:
#
# Specify chain names to which firewalld blocking rules will be
# added with the FIREWD_INPUT_ACCESS and FIREWD_FORWARD_ACCESS keyword.
# The format for these variables is:
#
#   <Target>,<Table>,<From_chain>,<Jump_rule_position>,\
#       <To_chain>,<Rule_position>.
#
# "Target":
#   Can be any legitimate firewalld target, but should usually just be "DROP".
#
# "Table":
#   Can be any firewalld table, but the default is "filter".
#
# "From_chain":
#   Is the chain from which packets will be jumped.
#
# "Jump_rule_position":
#   Defines the position within the From_chain where the jump rule is added.
#
# "To_chain":
#   Is the chain to which packets will be jumped. This is the main chain
#   where fwknop rules are added.
#
# "Rule_position":
#   Defines the position where rules are added within the To_chain.
#
#FIREWD_INPUT_ACCESS        ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1;

# The FIREWD_OUTPUT_ACCESS variable is only used if ENABLE_FIREWD_OUTPUT is enabled
#
#FIREWD_OUTPUT_ACCESS       ACCEPT, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1;

# The FIREWD_FORWARD_ACCESS variable is only used if ENABLE_FIREWD_FORWARDING is
# enabled.
#
#FIREWD_FORWARD_ACCESS      ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1;
#FIREWD_DNAT_ACCESS         DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1;

# The FIREWD_SNAT_ACCESS variable is not used unless both ENABLE_FIREWD_SNAT and
# ENABLE_FIREWD_FORWARDING are enabled.  Also, the external static IP must be
# set with the SNAT_TRANSLATE_IP variable.  The default is to use the
# FIREWD_MASQUERADE_ACCESS variable.
#
#FIREWD_SNAT_ACCESS         SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#FIREWD_MASQUERADE_ACCESS   MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1;

# The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the
# firewalld 'comment' match at start up.  If it's not found, then fwknopd will
# exit and throw an error.  This variable is enabled by default, but can be
# disabled if you want fwknopd to run without being sure that the comment match
# is available (not recommended, since the comment match enables new SPA rules
# to be timed out).
#
#ENABLE_FIREWD_COMMENT_CHECK        Y;

##############################################################################
# Parameters specific to iptables:

# Flush all existing rules in the fwknop chains at fwknop start time and/or
# exit time. They default to Y and it is a recommended setting for both.
#
#FLUSH_IPT_AT_INIT           Y;
#FLUSH_IPT_AT_EXIT           Y;
#

# Allow SPA clients to request access to services through an iptables
# firewall instead of just to it (i.e. access through the FWKNOP_FORWARD
# chain instead of the INPUT chain).
#
#ENABLE_IPT_FORWARDING       N;

# Allow SPA clients to request access to a local socket via NAT.  This still
# puts an ACCEPT rule into the FWKNOP_INPUT chain, but a different port is
# translated via DNAT rules to the real one.  So, the user would do
# "ssh -p <port>" to access the local service (see the --NAT-local and
# --NAT-rand-port on the fwknop client command line).
#
#ENABLE_IPT_LOCAL_NAT        Y;

# By default, if forwarding access is enabled (see the ENABLE_IPT_FORWARDING
# variable above), then fwknop creates DNAT rules for incoming connections,
# but does not also complement these rules with SNAT rules at the same time.
# In some situations, internal systems may not have a route back out for the
# source address of the incoming connection, so it is necessary to also
# apply SNAT rules so that the internal systems see the IP of the internal
# interface where fwknopd is running.  This functionality is only enabled
# when ENABLE_IPT_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also define an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_IPT_SNAT             N;
#SNAT_TRANSLATE_IP           __CHANGEME__;

# Add ACCEPT rules to the FWKNOP_OUTPUT chain. This is usually only useful
# if there are no state tracking rules to allow connection responses out and
# the OUTPUT chain has a default-drop stance.
#
#ENABLE_IPT_OUTPUT           N;

# fwknopd adds allow rules to a custom iptables chain "FWKNOP_INPUT".
# This chain is called from the INPUT chain, and by default no other
# iptables chains are used.  However, additional chains can be added
# (say, if access needs to be allowed through the local system via the
# FORWARD chain) by altering the IPT_FORWARD_ACCESS variable below.
# For a discussion of the format followed by these keywords, read on:
#
# Specify chain names to which iptables blocking rules will be
# added with the IPT_INPUT_ACCESS and IPT_FORWARD_ACCESS keyword.
# The format for these variables is:
#
#   <Target>,<Table>,<From_chain>,<Jump_rule_position>,\
#       <To_chain>,<Rule_position>.
#
# "Target":
#   Can be any legitimate iptables target, but should usually just be "DROP".
#
# "Table":
#   Can be any iptables table, but the default is "filter".
#
# "From_chain":
#   Is the chain from which packets will be jumped.
#
# "Jump_rule_position":
#   Defines the position within the From_chain where the jump rule is added.
#
# "To_chain":
#   Is the chain to which packets will be jumped. This is the main chain
#   where fwknop rules are added.
#
# "Rule_position":
#   Defines the position where rule are added within the To_chain.
#
#IPT_INPUT_ACCESS        ACCEPT, filter, INPUT, 1, FWKNOP_INPUT, 1;

# The IPT_OUTPUT_ACCESS variable is only used if ENABLE_IPT_OUTPUT is enabled
#
#IPT_OUTPUT_ACCESS       ACCEPT, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1;

# The IPT_FORWARD_ACCESS variable is only used if ENABLE_IPT_FORWARDING is
# enabled.
#
#IPT_FORWARD_ACCESS      ACCEPT, filter, FORWARD, 1, FWKNOP_FORWARD, 1;
#IPT_DNAT_ACCESS         DNAT, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1;

# The IPT_SNAT_ACCESS variable is not used unless both ENABLE_IPT_SNAT and
# ENABLE_IPT_FORWARDING are enabled.  Also, the external static IP must be
# set with the SNAT_TRANSLATE_IP variable.  The default is to use the
# IPT_MASQUERADE_ACCESS variable.
#
#IPT_SNAT_ACCESS         SNAT, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#IPT_MASQUERADE_ACCESS   MASQUERADE, nat, POSTROUTING, 1, FWKNOP_MASQUERADE, 1;

# The ENABLE_COMMENT_MATCH_CHECK variable instructs fwknopd to check for the
# iptables 'comment' match at start up.  If it's not found, then fwknopd will
# exit and throw an error.  This variable is enabled by default, but can be
# disabled if you want fwknopd to run without being sure that the comment match
# is available (not recommended, since the comment match enables new SPA rules
# to be timed out).
#
#ENABLE_IPT_COMMENT_CHECK        Y;

##############################################################################
# Parameters specific to ipfw:
#
#
# This variable defines the rule number that fwknopd uses to insert an ipfw
# pass rule.  You would most likely want to change this parameter to a
# number that makes sense in your current ipfw firewall configuration.
#
#IPFW_START_RULE_NUM         10000;

# This variable defines the maximum number of rules fwknopd will create at
# a time. This also tells fwknopd where to stop when flushing all rules.
#
#IPFW_MAX_RULES              1000;

# Flush all existing rules in the fwknop ipfw sets at fwknop start time and/or
# exit time. They default to Y and it is a recommended setting for both.
#
#FLUSH_IPFW_AT_INIT           Y;
#FLUSH_IPFW_AT_EXIT           Y;

# This variable defines the rule set fwknopd uses for active rules. By
# default, it is set 1 and fwknopd assumes that it has full control over this
# set.  That is, fwknopd routinely creates and deletes rules in this set, and
# the entire set itself is also created/deleted during routine operations.
# You have some measure of control over whether the entire set is deleted at
# init/exit with the FLUSH_IPFW_AT_INIT and FLUSH_IPFW_AT_EXIT, but in general
# it is recommended to leave these variables set to the default "Y" setting.
#
#IPFW_ACTIVE_SET_NUM         1;

# This variable defines the rule set that will be used to store expired rules
# that still have a dynamic rule associated to them. That set will be disabled
# by fwknop and should not be enabled while fwknop is running. Not used when
# ipfw isn't using dynamic rules.  By default, it is set 2, but can be anything
# in the range 1-31 except that it shouldn't be the same as
# IPFW_ACTIVE_SET_NUM.  Note that fwknopd disables this set through routine
# operations according to the FLUSH_IPFW_AT_INIT and FLUSH_IPFW_AT_EXIT
# variables.
#
#IPFW_EXPIRE_SET_NUM         2;

# Set the interval (in seconds) over which rules that are expired and
# have no remaining dynamic rules associated with them will be removed.
#
#IPFW_EXPIRE_PURGE_INTERVAL  30;

# Set this variable to "Y" if you want fwknopd to create its own "check-state"
# rule as the first rule in the set.  This would only be needed if there
# was not already a check-state rule in the current firewall configuration.
#
# IPFW_ADD_CHECK_STATE       N;

##############################################################################
# Parameters specific to the pf firewall:
#
#
# This variable defines the pf anchor name to which fwknopd will add and
# delete rules.  This anchor must be linked into the pf policy (typically
# done by adding it into the /etc/pf.conf file), and fwknopd runs a check at
# init time to ensure that the anchor exists.
#
#PF_ANCHOR_NAME             fwknop;

# Set the interval (in seconds) over which rules that are expired
#
#PF_EXPIRE_INTERVAL         30;

##############################################################################

# Directories - These can override compile-time defaults.
#
#FWKNOP_RUN_DIR              /var/run/fwknop;
#FWKNOP_CONF_DIR             /etc/fwknop;

# Files
#
#ACCESS_FILE                 access.conf;
#FWKNOP_PID_FILE             $FWKNOP_RUN_DIR/fwknopd.pid;
#DIGEST_FILE                 $FWKNOP_RUN_DIR/digest.cache;
### The DB version is only used if fwknopd was built with gdbm/ndbm
### support (not needed by default).
#DIGEST_DB_FILE              $FWKNOP_RUN_DIR/digest_db.cache;

# System binaries
#
#FIREWALL_EXE                /bin/firewall-cmd;
#FIREWALL_EXE                /sbin/iptables;

###EOF###

② /etc/fwknop/access.conf で共通鍵を定義します。
変更前”CHANGEME”とあるので分かり易いです。

~ 途中省略 ~

#### fwknopd access.conf stanzas ###

SOURCE              ANY
KEY_BASE64          __CHANGEME__
HMAC_KEY_BASE64     __CHANGEME__

~ 以下省略 ~

変更後(3.3 SPA(Client)共通鍵の生成 ②で控えた内容をコピペします)

~ 途中省略 ~
#### fwknopd access.conf stanzas ###

SOURCE              ANY
KEY_BASE64                  xO5mM5lEJUVKxMn6PcNUKTn1qdivpLA1AHsMALKdhlU=
HMAC_KEY_BASE64             i0Asqvm0zGB867vcZT15RlL9TWrkbUs+4tNXAemTYF/D4MBWQX6dCWbCLSJ8ltj/VEPMBc/TNlGYwTlLCEVbVQ==

~ 以下省略 ~

③ FW_ACCESS_TIMEOUT を定義します。有効なSPAパケットを受信してからXX秒間指定ポートへのアクセスを許可します。

FW_ACCESS_TIMEOUT     <10>
#
# Define the length of time access will be granted by fwknop through the
# firewall after a valid SPA packet is received from the source IP address
# that matches this stanza's SOURCE.
#
# If FW_ACCESS_TIMEOUT is not set then a default timeout of 30 seconds will
# automatically be set.
#

【参考】/etc/fwknop/access.conf

##############################################################################
#
# File:    access.conf
#
# Purpose: This file defines how fwknopd will modify firewall access
#          controls for specific IPs/networks.  It gets installed in
#          the fwknop config directory and is consulted by fwknopd on
#          startup or a reconfiguration signal.
#
# Note:    This file supports multiple entries (stanzas) for different
#          levels of access based on the SOURCE of the incoming SPA packet.
#          If multiple stanzas are used, you should make sure they are
#          entered in order from most specific to the more general SOURCE
#          specifications as the first matching SOURCE wins.
#
#          For example, a SOURCE that is a specific IP address should come
#          before a SOURCE that specifies multiple IP's or a Subnet.  The
#          SOURCE: "ANY" (if used) should be the last one.
#
#          At least one stanza MUST be defined.
#
##############################################################################
#
### Directives ###

# %include /etc/fwknop/myInlcudeFile.conf
#
# This processes the access.conf stanzas from an additional file.
# Complete stanzas should be contained within each file.

# %include_folder /etc/fwknop/myFolder.d
#
# This processes all the *.conf files in the specified directory.

# %include_keys /home/user/fwknop_keys.conf
#
# This directive loads the encryption and HMAC keys from an external file.
# Any other commands in the stanza must come before the %include_keys
# directive.

### Commands ###

# SOURCE                <IP,..,IP/NET,..,NET/ANY>
#
# This defines the source address from which a SPA packet will be accepted.
# Every  authorization stanza in this file must start  with  the  SOURCE
# keyword. Networks should be specified in CIDR  (e.g. "192.168.10.0/24")
# notation. Individual IP addresses can be specified as well.
#
# Also, multiple IP’s and/or networks can be defined as a comma-separated
# list  (e.g. "192.168.10.0/24,10.1.1.123").
#
# The string "ANY" is also accepted if a valid authorization packet should
# be honored from any source IP.
#

# DESTINATION                <IP,..,IP/NET,..,NET/ANY>
#
# This defines the destination address for which a SPA packet will be accepted.
# Networks should be specified in CIDR  (e.g. "192.168.10.0/24") notation.
# Individual IP addresses can be specified as well.
#
# Also, multiple IP’s and/or networks can be defined as a comma-separated
# list  (e.g. "192.168.10.0/24,10.1.1.123").
#
# The string "ANY" is also accepted if a valid authorization packet should
# be honored to any destination IP.
#

# OPEN_PORTS            <proto/port>, ..., <proto/port
#
# Define a set of ports and protocols (tcp or udp) that are allowed to be
# opened if a valid SPA packet is received and its access request matches
# one of the entries here.
#
# If this entry is not set, then fwknopd will attempt to honor the request
# specified in the SPA data.
#

# RESTRICT_PORTS        <proto/port>, ..., <proto/port>
#
# Define a set of ports and protocols (tcp or udp) that are *NOT* allowed
# to be opened even if a valid SPA packet is received.
#

# KEY                   <password>
#
# Define the key used for decrypting an incoming SPA packet that is using
# its built-in encryption (e.g. not GPG).  This variable is required for
# all non-GPG-encrypted SPA packets.
#

FW_ACCESS_TIMEOUT     <10>
#
# Define the length of time access will be granted by fwknop through the
# firewall after a valid SPA packet is received from the source IP address
# that matches this stanza's SOURCE.
#
# If FW_ACCESS_TIMEOUT is not set then a default timeout of 30 seconds will
# automatically be set.
#

# MAX_FW_TIMEOUT     <seconds>
#
# Define the maximum length of time access will be granted by fwknop through
# the firewall after a valid SPA packet is received. This is mostly useful to
# ensure that clients using the --fw-timeout argument do not grant themselves
# unduly long access.
#
# If MAX_FW_TIMEOUT is not set then a default timeout of 300 seconds (five
# minutes) will automatically be set.
#

# ENABLE_CMD_EXEC       <Y/N>
#
# This specifies whether or not fwknopd will accept complete commands that
# are contained within a SPA packet.  Any such command will be executed as
# user specified using the CMD_EXEC_USER parameter by the fwknopd server.
# If not set here, the default is "N".
#

# CMD_EXEC_USER         <username>
#
# This specifies the user that will execute commands contained within a SPA
# packet.  If not specified, fwknopd will execute it as the user it is
# running as (most likely root). Setting this to a non-root user is highly
# recommended.
#

# REQUIRE_USERNAME      <username>
#
# Require a specific username from the client system as encoded in the SPA
# data.  This variable is optional and if not specified, the username data
# in the SPA data is ignored.
#

# REQUIRE_SOURCE_ADDRESS    <Y/N>
#
# Force all SPA packets to contain a real IP address within the encrypted
# data.  This makes it impossible to use the "-s" command line argument
# on the fwknop client command line, so either "-R" has to be used to
# automatically resolve the external address (if the client is behind a
# NAT) or the client must know the external IP.  If not set here, the
# default is "N".
#

# GPG_HOME_DIR          <path>
#
# Define the path to the GnuPG directory to be used by fwknopd.  If this
# keyword is not specified here, then fwknopd will default to using the
# "/root/.gnupg" directory for the server key(s).
#

# GPG_DECRYPT_ID        <keyID>
#
# Define a GnuPG key ID to use for decrypting SPA messages that have been
# encrypted by an fwknop client using GPG.  This keyword is required for
# authentication that is based on gpg keys.  The gpg key ring on the client
# must have imported and signed the fwknopd server key, and vice versa.
#
# It is ok to use a sensitive personal gpg key on the client, but each
# fwknopd server should have its own gpg key that is generated specifically
# for fwknop communications.  The reason for this is that this decryption
# password within this file.
#
# Note that you can use either keyID or its corresponding email address.
#
# For more information on using fwknop with GnuPG keys, see the following
# link: http://www.cipherdyne.org/fwknop/docs/gpghowto.html
#

# GPG_DECRYPT_PW        <decrypt password>
#
# Specify the decryption password for the gpg key defined by the
# GPG_DECRYPT_ID above.  This is a required field for gpg-based
# authentication.
#

# GPG_REQUIRE_SIG       <Y/N>
#
# With this setting set to 'Y',  fwknopd check all GPG-encrypted SPA
# messages for a signature (signed by the sender's key).  If the incoming
# message is not signed, the decryption process will fail.  If not set, the
# default is 'N'.

# GPG_IGNORE_SIG_VERIFY_ERROR   <Y/N>
#
# Setting this will allow fwknopd to accept incoming GPG-encrypted packets
# that are signed, but the signature did not pass verification (i.e. the
# signer key was expired, etc.).  This setting only applies if the
# GPG_REQUIRE_SIG is also set to 'Y'.

# GPG_REMOTE_ID         <keyID,...,keyID>
#
# Define a list of gpg key ID’s that are required to have signed any
# incoming SPA messages that have been encrypted with the fwknopd server
# key.  This ensures that the verification of the remote user is accomplished
# via a strong cryptographic mechanism. This setting only applies if the
# GPG_REQUIRE_SIG is set to 'Y'.
#

#### fwknopd access.conf stanzas ###

SOURCE              ANY
KEY_BASE64                  xO5mM5lEJUVKxMn6PcNUKTn1qdivpLA1AHsMALKdhlU=
HMAC_KEY_BASE64             i0Asqvm0zGB867vcZT15RlL9TWrkbUs+4tNXAemTYF/D4MBWQX6dCWbCLSJ8ltj/VEPMBc/TNlGYwTlLCEVbVQ==

# If you want to use GnuPG keys then define the following variables
#
#GPG_HOME_DIR           /homedir/path/.gnupg
#GPG_DECRYPT_ID         ABCD1234
#GPG_DECRYPT_PW         __CHANGEME__

# If you want to require GPG signatures:
#GPG_REQUIRE_SIG                    Y
#GPG_IGNORE_SIG_VERIFY_ERROR        N
#GPG_REMOTE_ID                      1234ABCD

help を確認すると分かりますが、fwknopd(fwknopd server)は、systemctl ではなく fwknopd コマンドで起動停止を行います。

【参考】fwknopd 's help

[root@test-sv fwknop]# fwknopd -h

fwknopd server version 2.6.10
Single Packet Authorization server - http://www.cipherdyne.org/fwknop/

Usage: fwknopd [options]

 -a, --access-file       - Specify an alternate access.conf file.
     --access-folder     - Specify an access.conf folder. All .conf
                           files in this folder will be processed.
 -c, --config-file       - Specify an alternate configuration file.
 -f, --foreground        - Run fwknopd in the foreground (do not become
                           a background daemon).
 -i, --interface         - Specify interface to listen for incoming SPA
                           packets.
 -C, --packet-limit      - Limit the number of candidate SPA packets to
                           process and exit when this limit is reached.
 -d, --digest-file       - Specify an alternate digest.cache file.
 -D, --dump-config       - Dump the current fwknop configuration values.
 -K, --kill              - Kill the currently running fwknopd.
 -l, --locale            - Provide a locale setting other than the system
                           default.
 -O, --override-config   - Specify a file with configuration entries that will
                           override those in fwknopd.conf.
 -p, --pid-file          - Specify an alternate fwknopd.pid file.
 -P, --pcap-filter       - Specify a Berkeley packet filter statement to
                           override the PCAP_FILTER variable in fwknopd.conf.
 -R, --restart           - Force the currently running fwknopd to restart.
     --rotate-digest-cache
                         - Rotate the digest cache file by renaming the file
                           to the same path with the -old suffix.
 -r, --run-dir           - Set path to local state run directory.
                         - Rotate the digest cache file by renaming it to
                           '<name>-old', and starting a new one.
 -S, --status            - Display the status of any running fwknopd process.
 -t, --test              - Test mode, process SPA packets but do not make any
                           firewall modifications.
 -U, --udp-server        - Set UDP server mode.
 -v, --verbose           - Set verbose mode.
     --syslog-enable     - Allow messages to be sent to syslog even if the
                           foreground mode is set.
 -V, --version           - Print version number.
 -A, --afl-fuzzing       - Run in American Fuzzy Lop (AFL) fuzzing mode so
                           that plaintext SPA packets are accepted via stdin.
 -h, --help              - Print this usage message and exit.
 --dump-serv-err-codes   - List all server error codes (only needed by the
                           test suite).
 --exit-parse-config     - Parse config files and exit.
 --exit-parse-digest-cache - Parse and validate digest cache and exit.
 --fault-injection-tag   - Enable a fault injection tag (only needed by the
                           test suite).
 --pcap-file             - Read potential SPA packets from an existing pcap
                           file.
 --pcap-any-direction    - By default fwknopd processes packets that are
                           sent to the sniffing interface, but this option
                           enables processing of packets that originate from
                           an interface (such as in a forwarding situation).
     --fw-list           - List all firewall rules that fwknop has created
                           and then exit.
     --fw-list-all       - List all firewall rules in the complete policy,
                           including those that have nothing to do with
                           fwknop.
     --fw-flush          - Flush all firewall rules created by fwknop.
     --gpg-home-dir      - Specify the GPG home directory (this is normally
                           done in the access.conf file).
     --gpg-exe           - Specify the path to GPG (this is normally done in
                           the access.conf file).
     --sudo-exe          - Specify the path to sudo (the default path is
                           /usr/bin/sudo).
 --no-firewd-check-support
                         - Disable test for 'firewall-cmd ... -C' support.
 --no-ipt-check-support  - Disable test for 'iptables -C' support.

[root@test-sv fwknop]#

④ fwknopd(fwknopd server)を起動します。

[root@test-sv fwknop]# fwknopd
[root@test-sv fwknop]#

⑤ 状態を確認します。

[root@test-sv fwknop]# fwknopd -S
Detected fwknopd is running (pid=14859).
[root@test-sv fwknop]#
[root@test-sv fwknop]# ps -ef | grep fwknopd
root      14859      1  0 19:39 ?        00:00:00 fwknopd
root      14971   1435  0 19:41 pts/0    00:00:00 grep --color=auto fwknopd
[root@test-sv fwknop]#

⑥ fwknopd(fwknopd server)を停止します。

[root@test-sv fwknop]# fwknopd -K
Killed fwknopd (pid=14859) via SIGTERM
[root@test-sv fwknop]#

⑦ 状態を確認します。

[root@test-sv fwknop]# fwknopd -S
No running fwknopd detected.
[root@test-sv fwknop]#
[root@test-sv fwknop]# ps -ef | grep fwknopd
root      15040   1435  0 19:42 pts/0    00:00:00 grep --color=auto fwknopd
[root@test-sv fwknop]#

3.4 SPA(Server)iptables

iptables を用いてインターフェース ens34 で、tcp/22(ssh) を DROP させます。

iptables -I INPUT 1 -i ens34 -p tcp --dport 22 -j DROP
iptables -I INPUT 1 -i ens34 -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

4. 検証

① nmap(ポートスキャン)をインストールしておきます。

yum install nmap

② Serverは tcp/22(ssh) を閉じています。

[root@test-cl ~]# nmap -sS -p 22 203.0.113.254

Starting Nmap 6.40 ( http://nmap.org ) at 2023-05-01 11:12 EDT
Nmap scan report for 203.0.113.254
Host is up (0.0012s latency).
PORT   STATE    SERVICE
22/tcp filtered ssh
MAC Address: 00:0C:29:09:EE:A8 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.44 seconds
[root@test-cl ~]#

③ Serverで fwknopd をデバッグモードで起動します。

[root@test-sv fwknop]# fwknopd -f
Warning: REQUIRE_SOURCE_ADDRESS not enabled for access stanza source: 'ANY'
Starting fwknopd
Added jump rule from chain: INPUT to chain: FWKNOP_INPUT
firewalld 'comment' match is available
Sniffing interface: ens34
PCAP filter is: 'udp port 62201'
Starting fwknopd main event loop.

④ Client からSPAパケットを送信します。

[root@test-cl ~]# fwknop -n 203.0.113.254 --verbose -R
SPA Field Values:
=================
   Random Value: 1134573741576223
       Username: root
      Timestamp: 1682954415
    FKO Version: 3.0.0
   Message Type: 1 (Access msg)
 Message String: 203.0.113.1,tcp/22
     Nat Access: <NULL>
    Server Auth: <NULL>
 Client Timeout: 0
    Digest Type: 3 (SHA256)
      HMAC Type: 3 (SHA256)
Encryption Type: 1 (Rijndael)
Encryption Mode: 2 (CBC)
   Encoded Data: 1134573741576223:cm9vdA:1682954415:3.0.0:1:MjAzLjAuMTEzLjEsdGNwLzIy
SPA Data Digest: s6eJIKwBGDYY7wAE2mM+Biohcm3zGnOBsIqFWGJtkVk
           HMAC: ny7vYwSRjeKjCIC3rNDKYAdeEgjZ6+9h0qK+ARyMJkQ
 Final SPA Data: /QaLVjNynmbM1wVEMOUyHaNbqfL8G6Z/ooQqnT97wAJfkTcV8I/4pBVohULJ9H9Up/Fabryh0ml+DKYDJAUEqrmwdmo/ZkjTwrt4OReV5SWQmD7y4kjv6eBhTtLPB8BYE47tKwbURqTrbZOggB5RedjOfdirLNlkUny7vYwSRjeKjCIC3rNDKYAdeEgjZ6+9h0qK+ARyMJkQ

Generating SPA packet:
            protocol: udp
         source port: <OS assigned>
    destination port: 62201
             IP/host: 203.0.113.254
send_spa_packet: bytes sent: 204
[root@test-cl ~]#

⑤ Server で有効な SPA パケットを受信したので、firewalltcp/22(ssh) を開きます。

(stanza #1) SPA Packet from IP: 203.0.113.1 received with access source match
Added access rule to FWKNOP_INPUT for 203.0.113.1 -> 0.0.0.0/0 tcp/22, expires at 1682954396

⑥ Client でポートスキャンすると tcp/22(ssh) が開いていることが確認できます。

[root@test-cl ~]# nmap -sS -p 22 203.0.113.254

Starting Nmap 6.40 ( http://nmap.org ) at 2023-05-01 11:15 EDT
Nmap scan report for 203.0.113.254
Host is up (0.00069s latency).
PORT   STATE SERVICE
22/tcp open  ssh
MAC Address: 00:0C:29:09:EE:A8 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.43 seconds
[root@test-cl ~]#

⑦ もたもたしていると10秒間なんてあっという間に過ぎてしまいます。

Removed rule 1 from FWKNOP_INPUT with expire time of 1682954396

⑧ Client でポートスキャンすると tcp/22(ssh) が閉じていることが確認できます。

[root@test-cl ~]# nmap -sS -p 22 203.0.113.254

Starting Nmap 6.40 ( http://nmap.org ) at 2023-05-01 11:15 EDT
Nmap scan report for 203.0.113.254
Host is up (0.00089s latency).
PORT   STATE    SERVICE
22/tcp filtered ssh
MAC Address: 00:0C:29:09:EE:A8 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.45 seconds
[root@test-cl ~]#

⑨ SPAパケットを送信してから直ちにssh接続するようにします。これなら10秒もかかりません。

[root@test-cl ~]# uname -n
test-cl
[root@test-cl ~]# fwknop -n 203.0.113.254;ssh root@203.0.113.254
root@203.0.113.254's password:
Last login: Sun Apr 30 03:28:45 2023 from 203.0.113.1
[root@test-sv ~]#
[root@test-sv ~]# uname -n
test-sv
[root@test-sv ~]# exit
logout
Connection to 203.0.113.254 closed.
[root@test-cl ~]#

これで最も簡単なSPAパケットによるfirewallの動的ポート開放の検証は完了です。

5. SPAパケット

Server でパケットキャプチャを採ることでSPAパケットを確認することができます。

tcpdump -i ens34 -w SPA.pcap

fwknopの場合は、暗号化されたUDPパケットがSPAパケットの正体でした。

ClientからSPAパケットを送信する時にオプションを付加することでSPAパケットの詳細が確認できます。

[root@test-cl ~]# fwknop -n 203.0.113.254 --verbose -R
SPA Field Values:
=================
   Random Value: 3048682005364172
       Username: root
      Timestamp: 1682955684
    FKO Version: 3.0.0
   Message Type: 1 (Access msg)
 Message String: 203.0.113.1,tcp/22
     Nat Access: <NULL>
    Server Auth: <NULL>
 Client Timeout: 0
    Digest Type: 3 (SHA256)
      HMAC Type: 3 (SHA256)
Encryption Type: 1 (Rijndael)
Encryption Mode: 2 (CBC)
   Encoded Data: 3048682005364172:cm9vdA:1682955684:3.0.0:1:MjAzLjAuMTEzLjEsdGNwLzIy
SPA Data Digest: oRyxAfQijFtq8BRSxZ2Cu2fuDbnMV+5VNEcPeOuK2Ws
           HMAC: ZnSicQ3zEKTPupo/W4kKI2UujRLR6TP4BOgd3P8nwDM
 Final SPA Data: /49cTU3M9kHxxrhpSNM/f4vfV7iGMOatTV5Tlr8NpzznE7z5lWZPBiTwR7u4CV+OlBpAQltA6tnNWEDw45OAyoitqVWnlgznpp0KNsO8hn09z5hVenguBuzbFK7XvquzusqOJR7Q/Frr0oyUyDvAjnZAgyDd5yGD0ZnSicQ3zEKTPupo/W4kKI2UujRLR6TP4BOgd3P8nwDM

Generating SPA packet:
            protocol: udp
         source port: <OS assigned>
    destination port: 62201
             IP/host: 203.0.113.254
send_spa_packet: bytes sent: 204
[root@test-cl ~]#

パケットキャプチャと同じ UDP(204 Byte) であることが分かります。

6. 参考

① A Comprehensive Guide to Strong Service Concealment with fwknop(Tutorial) www.cipherdyne.org

② SPA (Single Packet Authorization)解説 cloudsecurityalliance.jp

③ libpcap.so を CentOS にインストール
new-village.hatenablog.com

④ Software-Defined Perimeter (SDP) 仕様書 v2.0
https://www.cloudsecurityalliance.jp/site/wp-content/uploads/2022/05/SDP-Specification-v2_0-030922-J.pdf

SPA(Single Packet Authorization)がどんなものか分かると、Software-Defined Perimeter (SDP) Specification v2.0 の内容が理解しやすくなると思います。

最後までお読みいただき、ありがとうございました!