2020年6月22日月曜日

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

前回の記事ではiptablesを用いたファイアウォールの設定を紹介した。
今回はufwというツールを用いたファイアウォールの設定方法を紹介する。

そもそもufwとは何かというと、Ubuntu独自のiptablesのフロントエンドツールであり内部的にはiptablesを利用している。

iptablesコマンドを用いた方法では複数のコマンドをターミナル打ち込んだり、systemdによる自動起動の設定を行わなければならないなどの面倒な手続きが多かった。
しかし、ufwを用いればそれらの煩雑な手続きを必要とせずにファイアウォールの設定ができる。

1. ufwが利用可能かどうかを確認する


  $ systemctl status ufw
上記コマンドを入力して下記のような表示が出たらufwの利用が可能な状態である。

サービスが見つからないと出てきたらaptを使ってインストールする。
$ sudo apt install ufw

ufwのサービスが見つかった、またはインストールが完了したら
$ sudo ufw status
のコマンドを実行してufwが機能しているかどうかを確認。
何もいじっていない状態では

状態:非アクティブ

と出てくるはず

2. サーバで提供するサービスの通信を許可

ufwを有効な状態にする。
$ sudo ufw enable
下記コマンドで現在のufw設定を確認できる
$ sudo ufw status verbose
デフォルトで入ってくる通信が遮断されて、出てゆく通信はフリーパス状態。内部での転送は使用不可の状態になっているはず
(上記コマンド実行結果の"Default"で始まる行に書かれている)。

あとはサーバで提供するサービスが使用するポートへの通信を許可してゆけばよい。

sshの場合
$ sudo ufw allow in ssh
上記を実行するとufwのステータスに
22/tcp      on enp3s0           ALLOW IN    Anywere
22/tcp (v6) on enp3s0           ALLOW IN    Anywere
が追加されるはず。
ipv6向けのファイアウォール設定も追加されている。便利。

sshの接続元ネットワークセグメントを制限したい場合は
$ sudo ufw allow in from 192.168.10.0/24 to any port 22/tcp
とすると、192.168.10.~ のセグメントの端末からのsshしか受け付けなくなる。
書式は下記で覚えておけばよい
sudo ufw allow in from [ネットワークセグメント/ネットマスク] to any port [ポート番号/プロトコル]

http(80)等も同様にすればよいだろう。設定が終わったら
$ sudo ufw reload
を実行すると設定が反映される。

3. 出てゆく通信の一部を制限

蛇足かもしれないが内輪でやり取りされるべき通信が外部向けのインターフェイスから出てゆかないようにするための設定も施しておく。
$ sudo ufw deny out on eth0 from any to 10.0.0.0/8
$ sudo ufw deny out on eth0 from any to 176.10.0.0/12
$ sudo ufw deny out on eth0 from any to 127.0.0.0/8
$ sudo ufw deny out on eth0 from any to 192.168.0.0/16
$ sudo ufw deny out from any to fe80::/10
上記の各IPアドレスは内部やローカルセグメント用のIPアドレスであり基本的に外部ネットワークへと出てゆくことがないものである。
入力と違ってinの部分がoutになっているほか、outの後に"on [インターフェイス]"で外部ネットワークに繋がっているインターフェイスを指定している。

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

iptablesの設定はシャットダウンのたびに消えるためiptables-restoreとsystemdを組み合わせる等して再起動時に自動的に再設定されるように工夫しなければならない。
ではufwではどうすればよいかというと
不要
である。便利。

設定方法も煩雑ではないし、特に何もしなくても再起動時の再反映をしてくれるため、ファイアウォールについてはよくわからないけど何もしないよりは安心できるから何か設定しておきたい。という場合はufwを使うようにすることをお勧めする。

ただ、ufwの場合は同じIPアドレスからの新規アクセス試行数に制限を加える(所謂brute force対策)など柔軟(あるいは複雑な)設定を行うのに向いていない。
もっと複雑な設定を施したい場合はiptablesコマンド直打ちで頑張る方がよいだろう。

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。

2020年2月5日水曜日

Ubuntu18.04にGMT6.0.0をビルド&インストール

 UbuntuはじめとするLinux環境にGMTをインストールする最も手っ取り早い方法としてはapt等のパッケージを利用する方法がある。しかし、これで入れたGMTはpsxyやgrdimageといったコマンドを打つ前に"gmt "という枕詞を入れなければならず、しかも海岸線データも一緒にインストールしたはずなのに高解像度の海岸線データを使用しようとしても表示されないなどいくらか使い勝手が悪い。

 そこでGMT5系列を自力でコンパイル&インストールして枕詞の入力が不要で高解像度の海岸線データも何の手間なく描画できるように使用というのが今回の目的。

1. 前準備


まずはGMTのソースファイルの保存、および作業場所を確保する

$ mkdir gmt
$ cd gmt


続いてコンパイルに必要なパッケージをインストールする。ここではお手軽にaptを使用する.

$ sudo apt install cmake netcdf-bin libnetcdf-dev libcurl4-gnutls-dev

すでに自力でインストールしている酔狂な方はこの手順は不要だろう。後でcmakeファイルの設定の時にインストール場所をしっかりと教えてあげよう。
以下はオプション。なくても動作するが、あった方がいろいろな追加機能が使えるはず。使ったことないから知らないが...

$ sudo apt install libfftw3-dev gdal-bin libgdal-dev liblapack-dev

2. 必要なファイルのダウンロード


続いてソースファイルをダウンロードしてくる。必要なのは
 gmt-6.0.0-src, gshhg-gmt-2.3.7, dcw-gmt-1.1.4
の3つ。wgetなりブラウザでダウンロードするなりして入手し、作業ディレクトリ内に放り込む。下記コマンドで解凍しておく。

$ tar zxvf gmt-6.0.0.tar.gz
$ tar zxvf gshhg-gmt-2.3.7.tar.gz
$ tar zxvf dcw-gmt-1.1.4.tar.gz


3.コンフィグ&コンパイル

cmakeファイルの設定
$ cd gmt-6.0.0
$ mkdir build  #ビルド用ディレクトリを作成
$ cd cmake    #cmakeディレクトリ内に設定ファイルが置かれている
$ cp ConfigUserTemplate.cmake ConfigUser.cmake


ConfigUser.cmakeを何か適当な(使い慣れた)テキストエディタで開く。
以下の項目を書き換え

41行目
#set (CMAKE_INSTALL_PREFIX "prefix_path")
⇒set (CMAKE_INSTALL_PREFIX "/usr/local/gmt")
コメントを外して"prefix_path"内を書き換え。GMTをインストールするディレクトリを指定する。

111行目
#set (GSHHG_ROOT "gshhg_path")
⇒set (GSHHG_ROOT "/home/[Userdir]/gmt/gshhg-gmt-2.3.7")
コメントを外して"gshhg_path"内を書き換え。gshhgパッケージがある場所を指定する。(念のためフルパス推奨)

114行目
#set (COPY_GSHHG TRUE)
⇒set (COPY_GSHHG TRUE)
コメントを外す

117行目
#set (DCW_ROOT "dcw-gmt_path")
⇒set (DCW_ROOT "/home/[Userdir]/gmt/dcw-gmt-1.1.4")
コメントを外して"dcw-gmt_path"内を書き換え。dcwパッケージがある場所を指定する。(念のためフルパス推奨)

120行目
#set (COPY_DCW TRUE)
⇒set (COPY_DCW TRUE)
コメントを外す


netcdf等を自力でコンパイルした場合はインストールした場所までのパスを123行目以下の部分に記載して場所を教えてあげる。ここでは詳しい説明は割愛。
保存して終了し、cmakeディレクトリからbuildディレクトリに移動。

$ cd ../build

$ cmake ..
$ make && make check
$ sudo make install


インストールが完了したら.bashrcを編集してPathをとおしてあげる。ホームディレクトリに移動し、.bashrcの末尾に下記を追加

PATH="$PATH:/usr/local/gmt/bin"


4.動作確認


$ psxy

とでも入力してメッセージがずらずらと表示されたらインストール成功。

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

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