ipsetコマンドの使い方

最新記事は以下に記載しました。
https://hana-shin.hatenablog.com/entry/2023/08/04/193149

#1 ipsetコマンドとは?
IPアドレスやポート番号等をひとまとめにして管理するツールです。
ひとまとめにしたものをセットと呼びます。
なお、ipsetで作成したセットは、iptablesのsetモジュールで使用します。

#2 環境
VMware Workstation 14 Playerで仮想マシンを作成しました。
作成した仮想マシンのOS版数は以下のとりです。

```console:OS版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[root@server ~]# uname -r
3.10.0-693.el7.x86_64
```


#3 インストール方法

```console:ipsetパッケージのインストール
[root@server ~]# yum install ipset

[root@server ~]# ipset -V
ipset v6.29, protocol version: 6
```


#4 オプション一覧

```
[root@server ~]# ipset help
ipset v6.29

Usage: ipset [options] COMMAND

Commands:
create SETNAME TYPENAME [type-specific-options]
        Create a new set
add SETNAME ENTRY
        Add entry to the named set
del SETNAME ENTRY
        Delete entry from the named set
test SETNAME ENTRY
        Test entry in the named set
destroy [SETNAME]
        Destroy a named set or all sets
list [SETNAME]
        List the entries of a named set or all sets
save [SETNAME]
        Save the named set or all sets to stdout
restore
        Restore a saved state
flush [SETNAME]
        Flush a named set or all sets
rename FROM-SETNAME TO-SETNAME
        Rename two sets
swap FROM-SETNAME TO-SETNAME
        Swap the contect of two existing sets
help [TYPENAME]
        Print help, and settype specific help
version
        Print version information
quit
        Quit interactive mode

Options:
-o plain|save|xml
       Specify output mode for listing sets.
       Default value for "list" command is mode "plain"
       and for "save" command is mode "save".
-s
        Print elements sorted (if supported by the set type).
-q
        Suppress any notice or warning message.
-r
        Try to resolve IP addresses in the output (slow!)
-!
        Ignore errors when creating or adding sets or
        elements that do exist or when deleting elements
        that don't exist.
-n
        When listing, just list setnames from the kernel.

-t
        When listing, list setnames and set headers
        from kernel only.
-f
        Read from the given file instead of standard
        input (restore) or write to given file instead
        of standard output (list/save).

Supported set types:
(以下、略)
```


#5 セットの作成、削除方法

##5.1 セットを作成する方法(nまたはcreate)
名前がtest1、タイプが`hash:ip`のセットを作成します。

```console:セットの作成
[root@server ~]# ipset n test1 hash:ip
```

```console:セットの確認
[root@server ~]# ipset l
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16528
References: 0
Members:
```


##5.2 セットを削除する方法(xまたはdel)

```console:セットの確認
[root@server ~]# ipset l
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16528
References: 0
Members:
```

test1という名前のセットを削除します。

```console:セットの削除
[root@server ~]# ipset x test1
```

セットを確認します。test1が削除されたことがわかります。

```console:セットの確認
[root@server ~]# ipset l
[root@server ~]#
```

##5.3 セットを一括削除する方法(xまたはdel)

2つのセットを作成します。

```console:事前準備(セットの作成)
[root@server ~]# ipset n test1 hash:ip
[root@server ~]# ipset n test2 hash:ip
```

作成したセットを確認します。test1,test2が作成されたことがわかります。

```console:セットの確認
[root@server ~]# ipset l -n
test1
test2
```

2つのセットを一括で削除します。

```console:セットの削除
[root@server ~]# ipset x
```

セットを確認します。test1,test2が削除されたことがわかります。

```console:セットの確認
[root@server ~]# ipset l -n
[root@server ~]#
```

#6 セットの名前を変更する方法(eまたはrename)
名前がtest1、タイプが`hash:ip`のセットを作成します。

```console:事前準備(セットの作成)
[root@server ~]# ipset n test1 hash:ip
[root@server ~]# ipset l -n
test1
```

test1という名前のセットをtest2に変更します。

```console:名前の変更
[root@server ~]# ipset e test1 test2
[root@server ~]# ipset l -n
test2
```

#7 エントリの追加、削除方法
##7.1 エントリを追加する方法(aまたはadd)

名前がtest1、タイプが`hash:ip`のセットを作成します。

```console:セットの作成
[root@server ~]# ipset n test1 hash:ip
```
test1にエントリを2つ追加します。

```console:エントリの追加
[root@server ~]# ipset a test1 1.1.1.1
[root@server ~]# ipset a test1 2.2.2.2
```

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 0
Members:
2.2.2.2
1.1.1.1
```

##7.2 エントリを削除する方法(dまたはdel)

2つのエントリの中から、エントリを1つ削除します。

```console:セットの削除
[root@server ~]# ipset d test1 1.1.1.1
```

1.1.1.1のエントリが削除されたことがわかります。

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 0
Members:
2.2.2.2
```

##7.3 エントリを一括削除する方法(fまたはflush)

```console:事前準備(セット、エントリの作成)
[root@server ~]# ipset n test1 hash:ip
[root@server ~]# ipset a test1 1.1.1.1
[root@server ~]# ipset a test1 2.2.2.2
```

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 0
Members:
1.1.1.1
2.2.2.2
```

セットからエントリを全て削除してみます。

```console:エントリの全削除
[root@server ~]# ipset f test1
```

セットに登録されているエントリを確認します。エントリがすべて削除されたことがわかります。

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16528
References: 0
Members:
```

#8 セーブ、リストア方法
セットやエントリの内容をファイルに保存したり、
ファイルに保存したセットやエントリをリストアすることができます。

##8.1 セットの内容をファイルに保存する方法(save)

```console:セーブ
[root@server ~]# ipset n test1 hash:ip
[root@server ~]# ipset a test1 1.1.1.1
[root@server ~]# ipset save > ip_set.txt
[root@server ~]# cat ip_set.txt
create test1 hash:ip family inet hashsize 1024 maxelem 65536
add test1 1.1.1.1
```

##8.2 リストアする方法(restore)

セットが登録されていないことを確認します。

```console:事前準備(セットの確認）
[root@server ~]# ipset l
```

リストアするファイルの内容を確認します。

```console:リストア内容
[root@server ~]# cat ip_set.txt
create test1 hash:ip family inet hashsize 1024 maxelem 65536
add test1 1.1.1.1
```

```console:リストア
[root@server ~]# ipset restore < ip_set.txt
```

```console:セットの確認
[root@server ~]# ipset l
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16544
References: 0
Members:
1.1.1.1
```

#9 タイプの設定方法
##9.1 タイプの書式
タイプの書式を以下に示します。
methodは、list,hash,bitmapの3種類があります。

```console:manより抜粋
TYPENAME := method:datatype[,datatype[,datatype]]
```



##9.2 hash:ip
タイプが`hash:ip`のエントリを作成してみます。

```console:セット、エントリの作成
[root@server ~]# ipset n test1 hash:ip hashsize 1024
[root@server ~]# ipset a test1 1.1.1.1
[root@server ~]# ipset a test1 192.168.10.1
```

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 0
Members:
192.168.10.1
1.1.1.1
```

##9.3 hash:ip,port
タイプが`hash:ip,port`のエントリを作成してみます。


```console:セット、エントリの作成
[root@server ~]# ipset n test1 hash:ip,port
[root@server ~]# ipset a test1 1.1.1.1,tcp:53
```

```console:セットの確認
[root@server ~]# ipset l
Name: test1
Type: hash:ip,port
Revision: 2
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16560
References: 0
Members:
1.1.1.1,tcp:53
```

##9.4 hash:net
タイプが`hash:net`のエントリを作成してみます。

```console:セット、エントリの作成
[root@server ~]# ipset n test1 hash:net
[root@server ~]# ipset a test1 192.168.10.0/24
[root@server ~]# ipset a test1 10.1.0.0/16
```

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:net
Revision: 3
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 16848
References: 0
Members:
192.168.10.0/24
10.1.0.0/16
```

#10 タイムアウトの設定方法(timeout)
エントリにタイムアウトを設定することができます。
ここでは、エントリに10秒のタイムアウトを設定してみます。
10秒経過すると、エントリが削除されることがわかります。

```console:セット、エントリの作成
[root@server ~]# ipset n test1 hash:ip timeout 10
[root@server ~]# ipset a test1 1.1.1.1
```

```console:セットの確認(残り時間4秒)
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 timeout 10
Size in memory: 16592
References: 0
Members:
1.1.1.1 timeout 4 ★
```

```console:セットの確認(残り時間0秒)
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 timeout 10
Size in memory: 16592
References: 0
Members:
1.1.1.1 timeout 0 ★
```

```console:セットの確認(エントリ消滅)
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 timeout 10
Size in memory: 16592
References: 0
Members:
```

#11 カウンタの設定方法(counters)

```console:セット、エントリの作成
[root@server ~]# ipset n test1 hash:ip counters
[root@server ~]# ipset a test1 1.1.1.1
```

```console:セットの確認
[root@server ~]# ipset l test1
Name: test1
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 counters
Size in memory: 16624
References: 0
Members:
1.1.1.1 packets 0 bytes 0
```


#Z 参考情報
[ipset a tool for faster, more efficient firewalling with iptables](https://www.netdevconf.org/1.1/proceedings/slides/kadlecsik-ipset-firewalling-iptables.pdf)
[IP sets(公式ページ)](http://ipset.netfilter.org/index.html)
[Ipset](https://wiki.archlinux.jp/index.php/Ipset)
[ipsetを使ってスマートにiptablesを設定する](http://equj65.net/tech/ipset/)
[IP set features](http://ipset.netfilter.org/features.html)
[firewalld + ipset でアクセス制限](http://www.server-memo.net/centos-settings/firewalld/firewalld_ipset.html)
[fierewalldでipsetを用いる手続きをメモしておいた](https://memorandum.yamasnet.com/archives/Post-18079.html)