背景
OS入れ替えました
自宅サーバのOSを入れ替えました。
これまでは再び仕事をする事もあるだろうと思いCentOS 7を使っていたのですが「もういいんじゃないか」という神託に従い、Arch Linuxに入れ替えました。
15年ほど*BSDの世界にいたので、FreeBSDにするか、Gentoo LinuxにするかArch Linuxにするか悩みましたが、USBメモリにOS入れたいとか色々考えて簡単そうなArch Linuxを選択。
ファイアウォールの設定がわからん
Linuxには複数のIPフィルタがあるが、実際にはほとんどがiptablesのフロントエンドとして動作しており、実態はiptablesかnftablesの二種類のみであると記載されています。
nftablesのほうが新しいと書かれており、そちらを使いたく思ったがArch Linuxはインストール時点でiptablesが依存関係により導入されるという事なので楽ちん志向によりiptablesでの設定を採択しました。
設定
目的
ここでは以下を目的として据えます。
- 接続元は日本国内に限定する
- iptablesを用いてファイアウォールを設定する
- NICの変更なども考慮して柔軟性を確保する
ipsetの導入
まずはIPアドレスのグループ化を行うため、ipsetを導入しました。
# pacman -S ipset
# systemctl start ipset
# systemctl enable ipset
ipsetは複数のIPアドレスに名前を使てまとめるためのツールだそうです。
日本国内のIPアドレス一覧はGoogleで検索してここで取得しました。キーボードマクロで以下のようなスクリプトを作成します。
#!/bin/sh
ipset create -exist JPLIST hash:net
ipset add JPLIST 1.0.16.0/20
ipset add JPLIST 1.0.64.0/18
ipset add JPLIST 1.1.64.0/18
ipset add JPLIST 1.5.0.0/16
.
.
.
ipset add JPLIST 223.223.208.0/21
ipset add JPLIST 223.223.224.0/19
ipset add JPLIST 223.252.64.0/19
ipset add JPLIST 223.252.112.0/20
NICデバイス名の固定化
最近のLinuxでは、eth1,eth2というようなデバイス名は使われなくなってきているようで、Arch Linuxでも初期状態ではepなちゃらのような名前が付けられていました。
ただ、私の自宅サーバについているNICは3つともIntel製のチップを使っているため、これでは管理が難しい。
管理を容易にして運用上のミスを防ぐため、デバイス名にわかりやすい名前を付けます。デバイス名の管理はudevで行われるため、以下を編集します1。
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="XX:XX:XX:XX:XX:XX", NAME="in01"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="YY:YY:YY:YY:YY:YY", NAME="in02"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ZZ:ZZ:ZZ:ZZ:ZZ:ZZ", NAME="ex01"
命名規則として、内部ネットワークはin??、外部接続のNICはex??としています。
構想としては、内部ネットワークを通常のネットワーク、ストレージネットワークの二つに分けて運用を行いたいのですが、現状では内部ネットワークは一種類だけなのでin02として運用します。
ここでひとまず再起動させて設定を確認します。
# sync
# sync
# sync
# shutdown -r +1
# logout
再起動後、以下のようになっていれば設定完了です。
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: in01: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
inet 192.168.125.220/24 brd 192.168.125.255 scope global noprefixroute in01
valid_lft forever preferred_lft forever
inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
3: ex01: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether ZZ:ZZ:ZZ:ZZ:ZZ:ZZ brd ff:ff:ff:ff:ff:ff
inet AAA.AAA.AAA.AAA/27 brd AAA.AAA.AAA.255 scope global noprefixroute ex01
valid_lft forever preferred_lft forever
inet6 aaaa::aaaa:aaaa:aaaa:aaaa/64 scope link
valid_lft forever preferred_lft forever
4: in02: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether YY:YY:YY:YY:YY:YY brd ff:ff:ff:ff:ff:ff
inet 192.168.125.53/24 brd 192.168.125.255 scope global noprefixroute in02
valid_lft forever preferred_lft forever
inet6 fe80::6a08:7a98:c26d:79f4/64 scope link
valid_lft forever preferred_lft forever
我が家の内部ネットワーク第3オクテットは7年前に別れた恋人の誕生日(01/25)にちなんで125です。今さらネットワーク全体を工事するのも大変でずっとこれにしてるんですが、別れた恋人の名前がタトゥーになってる気分です。
iptablesを設定する
事前準備が整ったので、iptablesを設定します。
今回はipv6を使う予定はないので、編集する設定ファイルは/etc/iptables/iptables.rules
です。
また、ポリシーとしては以下となります。
- 内部ネットワークは素通り
- 外部ネットワークは原則禁止
- SSHは日本国内からのみ許可
- 外部ネットワークはログを取得
よって、このように設定します。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i in0+ -j ACCEPT
-A INPUT -p icmp -j DROP
# SSH
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -m set --match-set JPLIST src -j ACCEPT
# log
-A INPUT -i ex0+ -j LOG
COMMIT
設定が完了したらiptablesを開始します。
# systemctl start iptables
外部からSSH接続できることも確認して、今日はひとまずここまで。
-
systemd-networkdをネットワークマネージャとして用いるならば
.link
設定ファイルでも同様の設定が可能です。 ↩