2019 年度 OSS リテラシー 3 : セキュリティ対策 (ポート)
開いているポートの確認
開いているポートを確認するには, netstat コマンドや nmap コマンドを用いる. なお, nmap コマンドはクラッキングの前段階として行われることが多いので, 無用の誤解を与えないために localhost 以外のホストに対して実行しないこと.
netstat
netstat とても強力かつ有用なツールであり, 多くのオプションが存在する. 詳細は man netstat コマンドを実行するとオンラインマニュアルが表示されるので それを参照して欲しいが, 以下に代表的なものを挙げる.
- -A : 接続状態を表示するアドレスファミリを指定する
- -I : 指定したNICの情報のみ表示する(ex. -Ieth0)
- -a : 全てのアクティブなソケットを表示する
- -c : 1秒ごとに更新しつつ表示する
- -e : 詳細情報を表示する
- -g : IPv4とIPv6のマルチキャストグループメンバーシップ情報を表示する
- -i : 全てのNICの状態テーブルを表示する
- -l : 接続待ち(LISTEN)状態にあるソケットのみ表示する
- -n : ホストやユーザーの名前解決を行わず数字のまま出力する
- -o : ネットワーキングタイマーの情報を出力する
- -p : ソケットが属すプログラムのPIDとプロセス名を表示する
- -r : ルーティングテーブルを表示する
- -s : 各プロトコルの統計情報を表示する
- -t : TCPソケットを表示する
- -u : UDPソケットを表示する
- -v : 詳細な情報を表示する
例えば, netstat -ntlp コマンドを実行するとポート一覧が表示される. 最初の文字列が tcp は IP v4 を意味し, tcp6 は IPv6 を意味する.
$ netstat -ntl 稼働中のインターネット接続 (サーバのみ) Proto 受信-Q 送信-Q 内部アドレス 外部アドレス 状態 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:10050 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:10051 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 :::3000 :::* LISTEN tcp6 0 0 :::10050 :::* LISTEN tcp6 0 0 :::10051 :::* LISTEN tcp6 0 0 :::80 :::* LISTEN
上記の例では, ポート 22, 10050, 10051 が全ての IP アドレス (0.0.0.0) に 対して開いており, ポート 25, 3306 が自ホスト (127.0.0.1) に対してのみ開 かれていることがわかる. なぜか上記の例ではポート 80 と 3000 が IP v6 で のみ開かれているように書かれているが, 実際には IP v4 に対して 80, 3000 ポートは開かれている(プログラムのバグか?)
ここでポート番号とサービス名との対応が問題になるが, 基本的なポートについては /etc/services ファイルにその対応が書かれている. less などのページャーで /etc/services の中身を確認すると良い. なお, /etc/services に書かれているのはあくまで「代表的」なものであり, ポート番号 3000 や 3006 は載っていない.
実際のところ, 権限やオプションをつけることでポート番号と対応するサービス やプログラム名を一度に表示することができる. 試してみよ.
$ netstat -tl 稼働中のインターネット接続 (サーバのみ) Proto 受信-Q 送信-Q 内部アドレス 外部アドレス 状態 tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN tcp 0 0 localhost:smtp 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:zabbix-agent 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:zabbix-trapper 0.0.0.0:* LISTEN tcp 0 0 localhost:mysql 0.0.0.0:* LISTEN tcp6 0 0 [::]:ssh [::]:* LISTEN tcp6 0 0 [::]:3000 [::]:* LISTEN tcp6 0 0 [::]:zabbix-agent [::]:* LISTEN tcp6 0 0 [::]:zabbix-trapper [::]:* LISTEN tcp6 0 0 [::]:http [::]:* LISTEN $ sudo netstat -ntlp 稼働中のインターネット接続 (サーバのみ) Proto 受信-Q 送信-Q 内部アドレス 外部アドレス 状態 PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 574/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1287/exim4 tcp 0 0 0.0.0.0:10050 0.0.0.0:* LISTEN 29848/zabbix_agentd tcp 0 0 0.0.0.0:10051 0.0.0.0:* LISTEN 873/zabbix_server tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 619/mysqld tcp6 0 0 :::22 :::* LISTEN 574/sshd tcp6 0 0 :::3000 :::* LISTEN 910/grafana-server tcp6 0 0 :::10050 :::* LISTEN 29848/zabbix_agentd tcp6 0 0 :::10051 :::* LISTEN 873/zabbix_server tcp6 0 0 :::80 :::* LISTEN 605/apache2
nmap
次に nmap を使って開いているポートを確認する. まずは nmap のインストールを行う.
$ sudo apt-get update $ sudo apt-get install nmap
nmap は netstat と異なり, ホスト名もしくは IP アドレスを引数に与えることになる. 自ホストを意味する localhost (もしくは 127.0.0.1) を引数に与えた場合には,
$ nmap localhost PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp 80/tcp open http 3000/tcp open ppp 3306/tcp open mysql $ nmap -p 1-11000 localhost PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp 80/tcp open http 3000/tcp open ppp 3306/tcp open mysql 10050/tcp open zabbix-agent 10051/tcp open zabbix-trapper
と出力され, イーサネットの口 (ens192) に割り当てた IP アドレス (10.176.0.XXX, XXX は自分のに変更すること) を指定すると,
$ nmap -p 1-11000 10.176.0.XXX PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3000/tcp open ppp 10050/tcp open zabbix-agent 10051/tcp open zabbix-trapper
と出力される. なお, オプションの -p は探索するポート番号の範囲を指定するものである (デフォルトでは, ポート 10050, 10051 が探索範囲に含まれていないので).
上記を見比べると, localhost では 25, 3306 が表示されるが 10.176.0.XX では それらが表示されていない. これはポート 25 (SMTP (メール)) と 3306 (mysql (DB)) には 自ホストからのみアクセスできることを意味する (= ネットワーク経由でのアクセスはできない). 加えて, nmap コマンドの出力は前述の netstat -ntlp の出力と整合的であることがわかる.
ポートを閉じる
/etc/init.c/ 以下のスクリプトを用いてポートを閉める
サービス単位でポートを閉めることができる. /etc/init.d 以下にサービスをスタート/ストップするためのスクリプトが 置かれているので, それを使えば良い.
例えば HTTP (80 ポート) を閉じる場合を考える. まず始めに 80 番ポートの支配しているプログラム名を netstat で調べる. プログラム名が apache2 であることがわかる.
$ sudo netstat -ntlp| grep 80 tcp6 0 0 :::80 :::* LISTEN 605/apache2
次に, /etc/init.d 以下を眺めると, apache2 が存在することがわかる.
$ ls /etc/init.d/ apache-htcacheclean cron hwclock.sh networking screen-cleanup udev zabbix-server apache2 dbus keyboard-setup.sh procps snmpd vmware-tools apparmor exim4 kmod rsync ssh x11-common console-setup.sh grafana-server mysql rsyslog sudo zabbix-agent
通常, プログラム名とスクリプト名は一致するので, 今回は /etc/init.d/apache2 を使えば良い. 結果的に 80 番ポートを閉める (サービスを止める) には以下のようにする.
$ sudo /etc/init.d/apache2 stop [ ok ] Stopping apache2 (via systemctl): apache2.service.
改めて netstat もしくは nmap コマンドを実行すると, 80 番ポートが閉まった (= 80 ポートを使う apache2 が停止した) ことがわかる.
$ nmap 10.176.0.XXX (自分の IP) PORT STATE SERVICE 22/tcp open ssh 3000/tcp open ppp
再びサービスを開始する場合はスクリプトの引数に start を与える.
$ sudo /etc/init.d/apache2 start [ ok ] Starting apache2 (via systemctl): apache2.service.
再び netstat もしくは nmap を使うと 80 ポートが再び開いたことがわかる.
$ nmap 10.176.0.XXX (自分の IP) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3000/tcp open ppp
課題
- 自ホストにおいて開放されているポートとそのポートを使うサービスの一覧を wbt のオンラインテキストにまとめよ. さらに, そのポートがインターネット上の他ホストからアクセス可能か否かもまとめよ.