牧場生まれの牛乳

いろんなことしてる牛乳です。

ICTSC2018の運営をやったお話

ICTSC2018とは?

icttoracon.net

今年ずっと運営としてお手伝いしてきた大会です。ネットワーク機器やサーバ機器を用いた環境構築やそのシステム上でのトラブルを解決するコンテストです。今年、僕はインフラ構築チームの中で監視サーバの設定やエージェントの投入・設定などを行っていました。来年はバックボーンネットワークも監視も両方やるつもりで頑張りたい(なお卒論)。卒業できないとまずいですからね。

ちゃんと解説書いてる方はこっちです。

icttoracon.net

やったことについて

f:id:proelbtn:20190303142724p:plain

こんなことしてました。ダッシュボード作るの下手くそですね。来年は完璧にしていきます(後述するが、時間が足りなかった)。バックボーンネットワークの機器にSNMPやsyslogの設定を入れたり、syslogのaggregationやzabbix proxyの設定などを主にしていました。

監視サーバ群が刺さっているネットワークとオンサイトのネットワークはIPSecを張っていたのですが、なぜかオンサイトの一部のサブネットとしか疎通性がなく、クラウドから直接メトリックを取得できなくなってしまいました。なので、開催1週間前くらいにZabbix proxyやLogstashを立ち上げてどうにかするように変更していました(来年はちゃんとする)。

問題について

今回、僕はFTPに関する問題を出しました。

問題文

あなたの後輩が「FTPが動かない」と相談してきました。後輩の頼みを断れないあなたはこの問題を見てみることになりました。 どうやら家の外から認証は出来そうなのですが、ディレクトリ一覧を見ることが出来なさそうです。

手元PCから192.168.7.1で接続し、ディレクトリ一覧を取得できるようにしてください。

トポロジ図

f:id:proelbtn:20190303144316p:plain

禁止行為

  • 以下の設定を変更してはいけない
connect_from_port_20=YES
  • 以下のルールを削除・無効化してはいけない
iptables -A OUTPUT -p tcp --sport 20 -j REJECT

解法について

想定解法はTech-blogに書いているので省略します。ざっくりいうとpasv_address, pasv_min_address, pasv_max_addressの設定をしてiptablesをエイッってすると解けます。

当初僕の中ではこの問題は「iptablesの設定をちゃんと投入できるか?」という部分を問う問題だったのですが、問題文や環境の不備のせいで、ACTIVEモードでも接続できてしまうようになっていました。今どきACTIVEモードで接続できる環境の方が少ないとは思いますけど、それも満点解法としてます(禁止事項にちゃんとACTIVEモード禁止と書いておけばよかった)。一応その解法も想定内だったので。

ですが、2日目の途中にちょっと特殊な解法が来ました。

僕「Extended Passive Mode???」

Passive Modeについて

そもそもFTPにおけるACTIVEとPASVとはどんな違いがあるのでしょうか?まぁ、わざわざ書かなくてもだいたいググればすぐ出てきます。

naoberry.com

データ転送を行う通信路をサーバが能動的(Active)に開きに行くか、クライアントが接続してくれるのを待っている(Passive)のかという違いですね。 このご時世、自分の使っているパソコンにグローバルIPv4が直接振られているマシンとか、FTPのためにゲートウェイにport forwardingの設定を入れるというのも稀なお話ですよね。なのでPASVで接続する方が大抵の場合良い方法になります。

FTPでは以下のような流れで通信を行います。

% telnet localhost 21
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 (vsFTPd 3.0.3)
USER admin
331 Please specify the password.
PASS password
230 Login successful.
PASV
227 Entering Passive Mode (127,0,0,1,185,90).
RETR test.txt
150 Opening BINARY mode data connection for test.txt (14 bytes).
226 Transfer complete.
% telnet localhost 47450
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Hello, World!
Connection closed by foreign host.

データチャネルでUSERコマンドとPASSコマンドを用いて認証をし、PASVコマンドでPassiveモードに移行した後、localhost:47450に接続し、test.txtの中身を受け取っています。FTPサーバがPASVの後に返しているレスポンスには、PASVモードで接続する時にどこに接続すればいいのかを示しています。今回の問題はNAT内にいると、このアドレスがNAT内のアドレスになってしまいグローバルから直接接続できなくなるのが原因でした。

では、Extened Passive Modeとは一体何なのでしょうか?先程と同様の接続をExtended Passive Modeで行ってみましょう。

% telnet localhost 21
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 (vsFTPd 3.0.3)
USER admin
331 Please specify the password.
PASS password
230 Login successful.
EPSV
229 Entering Extended Passive Mode (|||47457|)
RETR test.txt
150 Opening BINARY mode data connection for test.txt (14 bytes).
226 Transfer complete.
% telnet localhost 47457
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Hello, World!
Connection closed by foreign host.

今回は、47457とポート番号がはっきりと記載されてますね。RFC2428のThe EPSV Commandの章を見ると、次のように書かれています。

   The EPSV command requests that a server listen on a data port and
   wait for a connection.  The EPSV command takes an optional argument.
   The response to this command includes only the TCP port number of the
   listening connection.  The format of the response, however, is
   similar to the argument of the EPRT command.  This allows the same
   parsing routines to be used for both commands.  In addition, the
   format leaves a place holder for the network protocol and/or network
   address, which may be needed in the EPSV response in the future.  The
   response code for entering passive mode using an extended address
   MUST be 229.  The interpretation of this code, according to [PR85]
   is:

        2yz Positive Completion
        x2z Connections
        xy9 Extended Passive Mode Entered

   The text returned in response to the EPSV command MUST be:

        <text indicating server is entering extended passive mode> \
            (<d><d><d><tcp-port><d>)

   The portion of the string enclosed in parentheses MUST be the exact
   string needed by the EPRT command to open the data connection, as
   specified above.

   The first two fields contained in the parenthesis MUST be blank.  The
   third field MUST be the string representation of the TCP port number
   on which the server is listening for a data connection.  The network
   protocol used by the data connection will be the same network
   protocol used by the control connection.  In addition, the network
   address used to establish the data connection will be the same
   network address used for the control connection.  An example response
   string follows:

        Entering Extended Passive Mode (|||6446|)

PASVの応答とは異なり、EPSVの応答はポート番号だけを含んでいて、IPアドレスは制御コネクションを張った時と同じ物を用いればよいという事になっています。このようにすることで、複数のグローバルIPアドレスからアクセスされる可能性のあるFTPサーバやNAT以下にあるFTPサーバは幸せになれそうですね。

Extended Passive Modeで接続する場合は、想定解法の内、pasv_addressの設定がいらなくなるというわけですね。

まとめ

ICTSC2018の参加記的なやつですよ。あと、作問とかが雑だったかもしれないというお話です。