2021 年度 OSS リテラシー 3 : セキュリティ対策 (ポート)

開いているポートの確認

開いているポートを確認するには, netstat コマンドや nmap コマンドを用いる. なお, nmap コマンドはクラッキングの前段階として行われることが多いので, 無用の誤解を与えないために localhost 以外のホストに対して実行しないこと.

netstat

netstat コマンドは net-tools パッケージに含まれているので, それをインストールする.

$ sudo apt-get update

$ sudo apt-get install net-tools

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

  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State      
  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 127.0.0.1:3306          0.0.0.0:*               LISTEN     
  tcp6       0      0 :::22                   :::*                    LISTEN     
  tcp6       0      0 :::3000                 :::*                    LISTEN     
  tcp6       0      0 ::1:25                  :::*                    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 は載っていない.

$ less /etc/services

   ...(略)...
   daytime         13/tcp
   daytime         13/udp
   netstat         15/tcp
   qotd            17/tcp          quote
   msp             18/tcp                          # message send protocol
   msp             18/udp
   chargen         19/tcp          ttytst source
   chargen         19/udp          ttytst source
   ftp-data        20/tcp
   ftp             21/tcp
   fsp             21/udp          fspd
   ssh             22/tcp                          # SSH Remote Login Protocol
   telnet          23/tcp
   smtp            25/tcp          mail
   ...(略)...

いちいち /etc/services を確認しなくても,netstat に権限やオプションをつけることでポート番号と対応するサービス やプログラム名を一度に表示することができる. 以下を試してみよ.

$ netstat -tl

  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State      
  tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN     <-- 前は 0.0.0.0:22 
  tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN     <-- 前は 127.0.0.1:25
  tcp        0      0 localhost:mysql         0.0.0.0:*               LISTEN     
  tcp6       0      0 [::]:ssh                [::]:*                  LISTEN     
  tcp6       0      0 [::]:3000               [::]:*                  LISTEN     
  tcp6       0      0 localhost:smtp          [::]:*                  LISTEN     
  tcp6       0      0 [::]:http               [::]:*                  LISTEN     

$ sudo netstat -ntlp

  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      351/sshd            
  tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      743/exim4           
  tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      402/mysqld          
  tcp6       0      0 :::22                   :::*                    LISTEN      351/sshd            
  tcp6       0      0 :::3000                 :::*                    LISTEN      443/grafana-server  
  tcp6       0      0 ::1:25                  :::*                    LISTEN      743/exim4           
  tcp6       0      0 :::80                   :::*                    LISTEN      13459/apache2    


$ sudo netstat -tlp

  Active Internet connections (only servers)
  Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
  tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN      351/sshd            
  tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN      743/exim4           
  tcp        0      0 localhost:mysql         0.0.0.0:*               LISTEN      402/mysqld          
  tcp6       0      0 [::]:ssh                [::]:*                  LISTEN      351/sshd            
  tcp6       0      0 [::]:3000               [::]:*                  LISTEN      443/grafana-server  
  tcp6       0      0 localhost:smtp          [::]:*                  LISTEN      743/exim4           
  tcp6       0      0 [::]:http               [::]:*                  LISTEN      13459/apache2       

なお,"Local Address" (内部アドレス) の部分をみると,接頭詞が 0.0.0.0 のものと,localhost (127.0.0.1) の 2 種類あることがわかる. 0.0.0.0 はホスト内部・外部の両方からアクセス可能なポート,localhost (127.0.0.1) はホスト内からのみアクセス可能なポートである. 外部に不用意に開放されているポートが無いかの確認をしておくことが重要である.なお,ポートの閉め方については後述する.

nmap

次に nmap を使って開いているポートを確認する. まずは nmap のインストールを行う.

$ sudo apt-get update

$ sudo apt-get install nmap

nmap は netstat と異なり, ホスト名もしくは IP アドレスを引数に与えることになる. 自ホストを意味する localhost (もしくは 127.0.0.1) を引数に与えた場合には, 以下のように開いているポートが一覧される. 22, 80, 3000, 3006 が開いていることがわかる. なお,ポート 3000 は grafana であるが,ここでは ppp と示されている.引数を localhost と した場合に表示されるポート番号は,"netstat -lp" コマンドを実行されたときの "Local Address" (内部アドレス) の接頭詞が 0.0.0.0 のものと,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

イーサネットの口 (ens192) に割り当てた IP アドレス (10.176.0.XXX, XXX は自分のに変更すること) を指定することもでき, その場合は以下のようになる. 引数を IP アドレスに した場合に表示されるポート番号は,"netstat -lp" コマンドを実行されたときの "Local Address" (内部アドレス) の接頭詞が 0.0.0.0 のものだけである.

$ nmap  10.176.0.XXX

  PORT     STATE SERVICE
  22/tcp   open  ssh
  80/tcp   open  http
  3000/tcp open  ppp

上記を見比べると, localhost では 3306 が表示されるが 10.176.0.XX では それが表示されていない. これはポート 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 のオンラインテキストにまとめよ. さらに, そのポートがインターネット上の他ホストからアクセス可能か否かもまとめよ.