2020年6月20日土曜日

ubuntuサーバに最低限やっておくべきセキュリティ対策 ~iptables 編~

LinuxはWindowsに比べてセキュリティリスクが小さいとされる。それでも悪意ある人間(或いはbot)から全く狙われないというわけではない。
むしろ近年は何々Pi等のシングルボードコンピュータが普及し、それらのマシンへ侵入、悪用を図る連中も多くなっているためLinux系OSでもやはり何もセキュリティ対策をしないというのは危険といえるだろう。

Ubuntuに限らず、大抵のLinuxOSにはiptablesがファイアウォールとして標準搭載されているが、その初期設定はネットワークから入ってくるものも出てゆくものも素通り状態のため大変危険だ。

iptablesの初期状態


  $ sudo iptables -L
  Chain INPUT(policy ACCEPT)
  target	prot opt source		destination
  
  Chain FORWARD (policy ACCEPT)
  target	prot opt source		destination
  
  Chain OUTPUT (policy ACCEPT)
  target	prot opt source		destination
すべての通信が何の規制もなく素通りになっている

したがって最低限施しておくべきファイアウォールの設定を自分用のメモ書きも兼ねて記しておく。

1. 一度出てゆくもの以外のすべての通信を遮断


  $ sudo iptables -P INPUT -j DROP
  $ sudo iptables -P FORWARD -j DROP

iptablesはスーパーユーザーでなければ操作できないのでsudoを頭につける。
-Pオプションは各Chain(通信の方向)におけるデフォルトの処理を指定する。
-jオプションの後ろに対象となる通信に対して行う処理を記載する。
ACCEPT(許可)、DROP(遮断)、FORWARD(転送)の3種類の処理を指定することが多い。

2. 必要な通信を受け入れる


  $sudo iptables -A INPUT -i lo -j ACCEPT
  $sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-Aオプションでルールを追加するChainを指定する。
-iオプションは入力のインターフェイス名(eth0、enp3s0等)を指定する。
-mオプションと--stateオプションで通信の種類に応じて処理を指定できる。
この場合、ループバック(lo)と呼ばれる内部からの通信と自端末からの問いかけに対する外部サーバからの応答を受け入れるように設定している。

3. 外部への通信についても一部制限を設ける


  $sudo iptables -A OUTPUT -A OUTPUT -d 10.0.0.0/8 -o eth0 -j DROP
  $sudo iptables -A OUTPUT -d 176.16.0.0/12 -o eth0 -j DROP
  $sudo iptables -A OUTPUT -d 127.0.0.0/8 -o eth0 -j DROP
  $sudo iptables -A OUTPUT -d 192.168.0.0/16 -o eth0 -j DROP
-dオプションで宛先IPアドレスごとの処理を指定できる。
-oオプションは出力のインターフェイス名。
上記で指定しているIPアドレスはローカルホストやローカルネットワークのIPアドレスとして使用されることが多い。
そして、出力インターフェイスには外部への通信で使われるものを指定する。ここではeth0を指定しているが乱暴に言えば壁面のLANポートに繋がっているインターフェイスを指定すればよい。
つまるところ、ここでは内輪でやり取りされるべき通信が外部へ漏れないようにするための設定をしている。

これだけでもブラウザやaptを動かす分には問題ないが、サーバであるからにはsshやhttp等の通信を外部から受け付けられるようにしなければならない。

4. 各種サービスの通信を許可する


  $sudo iptables -A INPUT -p tcp -m tcp -m state --state NEW,RELATED,ESTABLISHED --dport 22 -j ACCEPT
  $sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
  $sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
--dportオプションで通信を許可するサービスが使うポートを指定する。
"--dport ssh" や "--dport http" のように書いてもよい。
ここでは一例としてssh(22)とwebサーバ用のhttp(80)、https(443)の各ポートを開ける設定を施している。
sshに関してはクライアントからのオファーにあたる通信と接続確立後の通信を受け入れるように追加の設定を記述している。
これに関してはそのサーバで何をするかによって開けるポートが変わってくるのでここで書いたものはあくまでも一例ということにして各自で調整してほしい。

5. 起動時に自動的に反映されるようにする

これまではターミナルに直接コマンドを打ち込むことで設定をしてきたが、そのようにするとシャットダウンするたびに設定が消えてしまう。

そのためにはiptables-saveコマンドで現在の設定をファイルに書き出し、systemdを用いて起動時にiptablesの設定が自動で実行されるようにしなければならない。
また、IPv6に接続可能なインターネットサービスに接続している場合はIPv6用のファイアウォール設定が反映されるようにもしなければならない。

iptables-saveコマンドで現状の設定を設定ファイルの形でを出力できる
  $sudo iptables-save > /etc/iptables.roules
/etcディレクトリにiptables.roulesという名前でiptablesの設定をファイルに書き出す。
中身は下記のようになっているはず。

/etc/iptables.roules
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [27:2626]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#以下3行はサーバで提供するサービスによって書き換える
-A INPUT -m tcp -p tcp -m state --state NEW,RELATED,ESTABLISHED --dport 22 -j ACCEPT
-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m tcp -p tcp --dport 443 -j ACCEPT
###
-A OUTPUT -d 10.0.0.0/8 -o eth0 -j DROP
-A OUTPUT -d 176.16.0.0/12 -o eth0 -j DROP
-A OUTPUT -d 127.0.0.0/8 -o eth0 -j DROP
-A OUTPUT -d 192.168.0.0/16 -o eth0 -j DROP
COMMIT
これと同様の設定をIPv6用のファイアウォール(ip6tables)に対して施す。
$sudo cp /etc/iptables.roules /etc/ip6tables.roules
上記コマンドでip6tables用の設定ファイルを作成し、中身を下記のように変更する
/etc/ip6tables.roules

  *filter :INPUT DROP [0:0]
  :FORWARD DROP [0:0]
  :OUTPUT ACCEPT [18:1434]
  -A INPUT -i lo -j ACCEPT
  -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  #以下4行はIPv6のルーティング用に許可する項目
  #詳細は割愛
  -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 133 -j ACCEPT
  -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j ACCEPT
  -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j ACCEPT
  -A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -j ACCEPT
  ###
  #以下3行はサーバで提供するサービスによって書き換える
  -A INPUT -m tcp -p tcp -m  state --state NEW,RELATED,ESTABLISHED --dport 22 -j ACCEPT
  -A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
  -A INPUT -m tcp -p tcp --dport 443 -j ACCEPT
  ###
  COMMIT
続いて/etc/systemd/systemディレクトリ内にiptables_default.serviceファイルを作成し、下記の内容を記述する。
/etc/systemd/iptables_default.service

[Unit]
Description=Restore iptables rules
After=network-online.target
Requires=network-online.target

[Service]
Type=simple
ExecStart=/bin/sh -c '/sbin/iptables-restore < /etc/iptables.rules; /sbin/ip6tables-restore < /etc/ip6tables.rules'
ExecStop=/bin/sh -c '/sbin/iptables -F;/sbin/iptables -X;/sbin/iptables -Z;\
        /sbin/iptables -P INPUT ACCEPT;/sbin/iptables -P FORWARD ACCEPT;\
        /sbin/ip6tables -F;/sbin/ip6tables -X;/sbin/ip6tables -Z;\
        /sbin/ip6tables -P INPUT ACCEPT;/sbin/ip6tables -P FORWARD ACCEPT'
RemainAfterExit=true

[Install]
WantedBy=multi-user.target
起動時に自動的に実行されるように設定する

$sudo systemctl enable iptables_default.service

下記コマンドを実行して
$systemctl status iptables_default.service

enabledと表示されたらOK。

0 件のコメント:

コメントを投稿

Ubuntuサーバに最低限やっておくべきセキュリティ対策 ~ufw編~

前回の記事ではiptablesを用いたファイアウォールの設定を紹介した。 今回はufwというツールを用いたファイアウォールの設定方法を紹介する。 そもそもufwとは何かというと、Ubuntu独自のiptablesのフロントエンドツールであり内部的にはiptablesを利...