カテゴリー
【VPS・Linuxサーバー入門】ip6tablesからのWebARENA IndigoのVPSへIPv6仕様のファイアウォールを設定する
※ 当ページには【広告/PR】を含む場合があります。
2022/12/15

以前の記事で
このインスタンスは格安で使える代償として、
ということで、いまだ主流のIPv4ではこのVPSインスタンスを上手く扱うことができません。
これはファイアウォールの構築を考えるのにも影響があり、IPv4をベースにファイアウォールを記述する
iptables
通常の
iptables
今回は、WebARENA IndigoのLinuxインスタンスにip6tablesで簡単なファイアウォールを作成する手順を考えてみましょう。
WebARENA IndigoのDebianインスタンスにユーザーを追加する
作りたてのDebianインスタンスには、
debain
ただし、このデフォルトユーザーは最初からsudoできるように管理者権限を持っていますが、
このままだと無防備ですので、
debian
デフォルトユーザーだけだと、自分で自分の情報を書き換えできないため、一時的に作業用ユーザー・
tmp
まずは
debian
root
$ whoami
debian
#👇rootユーザーに切り替え
$ sudo su -
~# whoami
root
ではrootから、以下のように
tmp
#👇作業ユーザーの追加
~# useradd -m tmp
#👇作業ユーザーにsudoを行う権限グループに追加
~# gpasswd -a tmp sudo
#👇作業ユーザーのパスワードを追加
~# passwd tmp
#👇SSH公開鍵をdebianのものから借用
~# mkdir /home/tmp/.ssh
~# cp /home/debian/.ssh/authorized_keys /home/tmp/.ssh/
~# chown -R tmp:tmp /home/tmp/.ssh
作業用ユーザーが追加できたので、一旦SSH接続をログアウトして、今度はSSHクライアント側の
~/.ssh/config
tmp
Host tmp
HostName 2001:********
User tmp
Port 22
IdentityFile "~/.ssh/private-key"
SSHで
tmp
root
debian
$ ssh tmp
Linux i-1*********6 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
#...
$ whoami
tmp
$ sudo su -
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for tmp:
#👇rootにログイン
~# whoami
root
ここでは一例として、
debian
hoge
~# usermod -l hoge debian
~# usermod -d /home/hoge -m hoge
~# groupmod -n hoge debian
もともと
debian
~# passwd hoge
New password:
Retype new password:
passwd: password updated successfully
設定したパスワードは忘れずに控えておきましょう。
デフォルトユーザーの設定を変更したら、
tmp
hoge
debain
hoge
$ ssh hoge
Linux i-1*********6 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
#...
$ whoami
hoge
問題なくデフォルトユーザーが
hoge
最後に用済みの
tmp
$ sudo userdel tmp
$ sudo rm -rf /home/tmp
なお、SSHのデフォルトのポート番号もできれば変更することをおすすめします。
ip6tablesでファイアウォールの構築する
デフォルトユーザーも設定し終えたので、ここから早速IPv6ベースのファイアウォールを
ちなみに、IPv6の仕組みはIPv4と比べると格段に複雑で、アドレス値も128bitになるため、一目では理解しにくくなっています。
IPv6の詳細に関しては、以下のサイトでネットワークエンジニアの方が簡潔に説明されていますので、そちらでお勉強されてください。
iptables-persistentでファイアウォールを管理
前回の
$ sudo apt update
$ sudo apt upgrade -y
$ sudo apt install iptables-persistent -y
標準的なファイアウォールを構築する
何をもって標準とするかはVPSでやりたい目的で異なるとは思いますが、ここでは例として
を参考にファイアウォールを作成していきます。
WebARENA VPSのインスタンスの持っているネットワークインターフェースを一度把握してみます。
$ ip address show
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: ens10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff
altname enp0s10
inet6 2001:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
存在しているインターフェースはループバックを除くと、イーサネットインターフェース(ここでは
ens10
このインターフェースで、
2001:...
もう一つの
fe80::...
現在のファイアウォールを眺めてみましょう。
$ sudo ip6tables -vnL --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
当然ながら何もルールが存在していませんので、まっさらな状態からファイアウォールを設定していきます。
もし既存のファイアウォールが存在している場合、一旦まっさらにリセットしておきましょう。
$ sudo netfilter-persistent flush
最初にループバックからの自分自身への接続と、TCP通信で既に確立した接続の通信は基本的に許可します。
$ sudo ip6tables -A INPUT -i lo -j ACCEPT
$ sudo ip6tables -A INPUT -i ens10 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ちなみに
-i
また接続が無効となったパケットは破棄させておきましょう。
$ sudo ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP
ICMPv6周りの設定
ICMPv6にはメッセージタイプが0~255の番号で存在しており、中でも重要なタイプのメッセージが以下のように存在しています。
このメッセージタイプを個別に通過させる・させないを細かく制御することで、よりセキュリティの強化されたファイアウォールが構築できるようになります。
例えばセキュリティ的には甘くなりますが、不特定者からのPING(エコー要求:128)受信を許可したい場合には以下を追加します。
$ sudo ip6tables -A INPUT -p ipv6-icmp \
-m icmp6 --icmpv6-type 128 \
-m conntrack --ctstate NEW \
-j ACCEPT
VPSでリモート間アクセスするのにもっとも関連のあるのが、
NS(Neighbor Solicitation)
NA(Neighbor Advertisement)
これら2つを許可しておかないと、ネットワーク内の他のインターフェースのリンク層アドレス(MACアドレス)情報を交換することができなくなります。
グローバルからの
NS(ICMPv6の135)
NA(ICMPv6の136)
$ sudo ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT
$ sudo ip6tables -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT
これで最低限の接続がIPv6で可能になります。
なおこの設定だと全てパケットを通過させてしまう意味で、以下のルールの略記形式になっています。
$ sudo ip6tables -A INPUT -s ::/0 -d ::/0 -p ipv6-icmp \
-m icmp6 --icmpv6-type 135 -j ACCEPT
$ sudo ip6tables -A INPUT -s ::/0 -d ::/0 -p ipv6-icmp \
-m icmp6 --icmpv6-type 136 -j ACCEPT
送信元(
-s
-d
::/0
#👇リンクローカルアドレスを許可
$ sudo ip6tables -A INPUT -s fe80::/64 -d fe80::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT
$ sudo ip6tables -A INPUT -s fe80::/64 -d fe80::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT
#👇ユニークローカルアドレスを許可
$ sudo ip6tables -A INPUT -s fd00::/64 -d fe80::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT
$ sudo ip6tables -A INPUT -s fd00::/64 -d fe80::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT
#👇グローバルユニキャストを許可
$ sudo ip6tables -A INPUT -s 2001:xxxx:xxxx:xxxx::/64 -d 2001:xxxx:xxxx:xxxx::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT
$ sudo ip6tables -A INPUT -s 2001:xxxx:xxxx:xxxx::/64 -d 2001:xxxx:xxxx:xxxx::/64 -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT
というような感じに使います。
プロトコルごとにユーザー定義チェーンでまとめる
プロトコル別にポートを拡張しやすいように、
TCP
UDP
$ sudo ip6tables -N TCP
$ sudo ip6tables -N UDP
ユーザー定義チェーンは、INPUTチェーンから分岐させる形で該当のプロトコルを検出したら各定義チェーンにジャンプさせるように仕向けます。
$ sudo ip6tables -A INPUT -p tcp --syn \
-m conntrack --ctstate NEW -j TCP
$ sudo ip6tables -A INPUT -p udp \
-m conntrack --ctstate NEW -j UDP
TCP系のサービスは
TCP
例えばここでは、SSH(デフォルトポート22)のリモート接続を許可するために、先程の節で22番から変更したポート番号で新規に確立したSSH通信だけを許可するルールを追加します。
$ sudo ip6tables -A TCP -p tcp -m state --syn \
--state NEW --dport <許可したいポート番号> -j ACCEPT
ここでは紹介しませんが、TCPで他に良く使われるのが、WEBサーバーのHTTP(デフォルトポート80)やHTTPS(デフォルトポート443)などあります。
ここらへんはご自身の目的に応じてTCPルールに追加してみてください。
UDP
DHCPサーバー
DHCPサーバーはVPSインスタンスで利用することはまずなさそうですが、自宅でDHCPサーバーなどを立てる際には、DHCPv6でやり取りするときに使われるウェルノウンポート・546番からのパケットを受信する必要があります。
個人的な経験上、いざDHCPサーバーを構築するときに、「なんでDHCPが有効にならないのだろう...」と色々と悩んで、後々ファイアウォールで弾いていたというオチもあるので、
UDP
$ sudo ip6tables -A UDP -s fe80::/64 -p udp --dport 546 \
-m conntrack --ctstate NEW -j ACCEPT
UDPはTCPと比較してマイナーな利用法が多いかもしれませんが、WebRTC用にSTUN/TURNサーバーのポート番号でフォルトは3478などもこのUDPチェーンに登録できるかもしれません。
$ sudo ip6tables -A UDP -p udp --dport 3478 \
-m conntrack --ctstate NEW -j ACCEPT
ここらへんは臨機応変にルールを追加してみてください。
不明なパケットをREJECTさせる
REJECT
DROP
開発中サービスでサーバー側から弾かれた理由が知りたいときには便利ですが、攻撃者にも何かしら攻撃のヒントを与えてしまうかもしれませんので、いらなければ設定しないほうが良いかもしれません。
#👇TCPターゲット、UDPターゲット以外の場合にエラーパケットを送信&パケット破棄
$ sudo ip6tables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
$ sudo ip6tables -A INPUT -p udp -j REJECT --reject-with icmp6-adm-prohibited
#👇それ以外の不定なプロトコルでエラーパケットを送信&パケット破棄
$ sudo ip6tables -A INPUT -j REJECT --reject-with icmp6-adm-prohibited
デフォルトポリシーの書き換え
最後にINPUT・FORWARD・OUTPUTチェーンの基本ポリシーを設定します。
$ sudo ip6tables -P FORWARD DROP
$ sudo ip6tables -P OUTPUT ACCEPT
$ sudo ip6tables -P INPUT DROP
SSH接続でリモートVPSインスタンスに接続する場合、INPUTターゲットの設定に不備があると、
-P INPUT DROP
もしこのような症状が起こった場合、焦らずに次の項目で解説する内容をよく読んで対処してみてください。
ファイアウォールが正常に設定できたなら、忘れずに現在の設定を以下のコマンドで永続化しておきましょう。
$ sudo netfilter-persistent save
以上でWebARENA IndigoのインスタンスでもIpv6ベースのファイアウォールが設定することが可能になりました。
ファイアウォール設定中にSSH繋がらなくなったときの対処法
フィルターの設定内容・フィルターの設定順序を間違えるとSSH接続できなくなるときがあります。
もしもまだ
netfilter-persistent save
有効な復元ポイントがなかったり、誤って無効なファイアウォールで復元ポイントを作成してしまい後戻りが効かない場合には、WebARENA Indigoのダッシュボードから、
[インスタンス管理] > [インスタンス] > 問題のあるインスタンスを選択 > [コンソールを起動]
ユーザーでログイン出来たらなら、
sudo netfilter-persistent flush

まとめ
今回は、通常のIPv4ベースのiptablesで構築するファイアウォールとは少しことなる視点から、IPv6標準のファイアウォールをip6tablesで構築する方法を簡単に解説してみました。
特にip6tablesの使い方は、ほぼiptablesと変わらないのですが、これを使いこなすにはIPv6の規格をよく理解しておく必要があります。
まずはIPv6のファイアウォールを構築しようとする前に、十分IPv6の仕組みを学習した上で設定してみてください。
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー