/
カテゴリー

ICTSC2021 夏の陣にご参加いただいた学生の皆様、お疲れ様でした。

今回のICTSC2021 夏の陣は前回のICTSC2020の運営と新しいメンバー、それに加えて機材の提供や作問などでご助力いただいたスポンサー様方のおかげでなんとか開催し無事終了することができました 。参加していただいた方々につきましては、ここで培った知識・技術を今後に活かしていただければと思います。

今回出題した問題の問題文、及び問題解説を公開します。
ぜひ今後の研鑽にご利用いただければと思います。

Container

止まらない

dockerをインストールしただけなのに…

k8s

クラウドネイティブは難しい…

Webサイトにアクセスできない

Linux

頑固なindex.html

キャッシュサーバ立てたけど…

Program

Webサーバが立ち上がらない

ンジンエックス

iscsi

iscsi targetにログインできない!

Routing

対向につながらにな。。

パケットが通らない!

なんでだ!?

Security

L or R?

DHCPv6

インターネット契約って大変だ!

アドレスが配布できない・・・

SSH

SSH繋がらなくなった

VPN

テレワーク推進部

Web

サーバ気象予報

何もしてないのに壊れた!

 /
カテゴリー

概要

Markdownのコンテンツをブラウザで閲覧できる社内サイトがある。

UML図も埋め込みが可能であったが、数ヶ月前から図の部分だけが表示されなくなってしまった。

それも、ほぼ同時期に、複数の端末で。

サーバ側は長年変更しておらず、特に心当たりもない。一体なぜ……。

社内サイトの仕様

  • prob16-webserver (192.168.16.200) 単体のWebサーバ構成
  • Webコンテンツは社内から http://192.168.16.200/ で閲覧できる
  • /home/user/contents/ 以下に .md ファイルを設置すると、5分程度でWebコンテンツに反映される
  • 定期的にOS再起動を伴うメンテナンスを行っている

前提条件

  • prob16-desktop (192.168.16.100)の設定/構成変更による解答は認められません
    • 調査のために設定/構成変更を行うのは問題ありませんが、最終的に他の端末からも閲覧できる必要があります

初期状態

  • prob16-desktop (192.168.16.100) 及び 同様の端末(ログイン不可)において、http://192.168.16.200/page01.html や http://192.168.16.200/page02.html をブラウザで閲覧すると、UML図が表示されない。

終了状態

  • prob16-desktop (192.168.16.100) 及び 同様の端末(ログイン不可)において、http://192.168.16.200/page01.html や http://192.168.16.200/page02.html をブラウザで閲覧すると、UML図含めて全体が正常に表示される。
  • prob16-webserver (192.168.16.200) をOS再起動しても正常に表示される

解説

原因と解決方法

10080番ポートがbad-portとなり、各ブラウザのアップデートによりブロックされました。

初期状態ではplantuml-serverが10080番で稼働しているため、何らかの方法でブラウザから見えるポートを変更する必要があります。

解答例

# plantuml-serverを10081番ポートで上げ直す
$ sudo docker run -d --restart=always -p 10081:8080 plantuml/plantuml-server:jetty

# 変換スクリプトにおいて、plantuml-serverの指定ポートを10081番に変更する
$ sed -i 's/192\.168\.16\.200:10080/192.168.16.200:10081/' /home/user/tools/conv.js

# 変換スクリプトを手動実行する (又はcronの次回実行まで待機する)
$ find /home/user/contents/ -name "*.md" | xargs node /home/user/tools/conv.js

別解:

  • 10080番以外で接続できるよう任意のNAPT設定を行う
  • 既存dockerコンテナのNAPT設定を変更する
  • Apache側でリバースプロキシを行う など

※ firewalldで10080番の許可を入れていましたが、docker側でiptablesに追加されるので不要でした……

解決までの道のり

  • ブラウザのエラー等から原因に気付く (10080番ポートがunsafe(bad-port)となってブラウザによりブロックされている)
  • 10080番をLISTENしているサービスを特定して、何らかの方法でポート番号を変更する
  • crontabから変換スクリプトを特定してポート番号の指定を変更する
[[email protected] ~]$ crontab -l
*/5    * * * * find /home/user/contents/ -name "*.md" | xargs node /home/user/tools/conv.js >/dev/null 2>&1
3-58/5 * * * * find /var/www/html/ -name "*.html" -mmin +10 | xargs rm >/dev/null 2>&1

[[email protected] ~]$ grep -C 3 10080 /home/user/tools/conv.js }).use(require('markdown-it-plantuml'), {     openMarker: '```uml',     closeMarker: '```',     server: 'http://192.168.16.200:10080'   // plantuml-server }).use(require('markdown-it-meta'), { }) 

  • 変換スクリプトを手動で実行する or 次回のcron実行を待つ

想定外の別解

PlantUMLの公式サーバ http://www.plantuml.com/plantuml/svg/ を利用するという解答が3チームありました。

出題意図としては、機密情報等を扱う社内サイトを想定しており、自前のplantuml-serverを用意する構成としておりましたが、
確かに問題文では一切触れておらず、外部疎通性もありましたので、最も手軽な解決方法ではありました。

解決後の姿

 /
カテゴリー

概要

あなたは、「テレワークを行う社員の仕事用ルータをセットアップしておいてほしい。」と雑にタスクを割り当てられました。

作業内容は紙に書かれていました。

要約
サーバにVyOSがはいっています。
このサーバを社員の家に置くので、WireGuard VPNのクライアントの設定をいれてください。
簡単な仕事だと思いますが、よろしくお願いいたします。

前提条件

  • WireGuardクライアント側の鍵は既に作られていて、サーバ側に登録済みである。
  • WireGuardのサーバ側PublicKeyはEwxEvuDmdaKslWndieq1BFsNQgWjtyWKPe+kCDSc+nQ=である。

初期状態

WireGuardの設定が入っていない。

終了状態

  • 以下の構成で構築されていること。
WireGuardサーバ                     WireGuardクライアント
アドレス 192.168.1.2:51820     ⇔   アドレス 192.168.1.1:51820
wg01アドレス 10.0.0.2/31            wg01アドレス 10.0.0.3/31
  • WireGuard Interfaceを通して、10.0.0.2からping応答があること。
  • 設定の永続化が行われていること。

解説

この問題は、WireGuardのクライアントの設定を作り、永続化する構築問でした。

VyOSにおけるWireGuardの設定は、公式のdocumentに詳細に書かれております。

最終的なVyOSの設定は想定解答では以下になります。

interfaces {
    ethernet eth0 {
        address 192.168.1.1/24
        hw-id 9c:a3:ba:24:00:52
    }
    loopback lo {
    }
    wireguard wg0 {
        address 10.0.0.3/31
        peer wgserver {
            address 192.168.1.2
            allowed-ips 10.0.0.2/31
            port 51820
            pubkey ****************
        }
    }
}
protocols {
    static {
        route 0.0.0.0/0 {
            next-hop 192.168.1.254 {
            }
        }
    }
}
service {
    ssh {
    }
}
system {
以下省略

以上で、永続化も行えます。

その他の解答

  1. WireGuardのコマンドを利用した構築
    • wg01.confを作成し、wgコマンドを利用して解答しているチームが多く見られました。
    • この場合、systemdなどで永続化する必要があります。
 /
カテゴリー

概要

AくんはSSHに関する設定をいろいろいじっていたところ、SSHで繋がらなくなってしまった。
どうやらVNCはそのまま繋がるようなので、原因を特定して繋がるようにしてほしい。

前提条件

  • SSHサーバにはVNCで接続できる

初期状態

  • prob51-ssh-clienからprob51-ssh-serverにSSHで接続できない

終了状態

  • クライアントからサーバにSSH接続できる
  • 適切な問題の原因と解決法が回答に記載されている

解説

この問題は3つのトラブルが原因でした。

1. KexAlgorithms の設定

エラーメッセージから鍵交換方式の設定がおかしいことがわかります。

$ ssh 172.16.0.1
Unable to negotiate with 172.16.0.1 port 22: no matching key exchange method found. Their offer: curve25519-sha256,[email protected],ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1

これはクライアントの .ssh/config に設定された鍵交換方法をコメントアウトしたり、Their offer 以下に書かれた方式を設定するなどで解決します。

2. user というユーザ名でログインができない

サーバの /var/log/secure を見ると以下のメッセージが見つかります。

: User user from 172.16.0.2 not allowed because listed in DenyUsers
: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=172.51.0.2  user=user
: Failed password for invalid user user from 172.51.0.2 port 45508 ssh2

/etc/ssh/sshd_config を見ると DenyUsers ディレクティブに user が含まれているので、許可されるよう設定します。

ちなみに、この DenyUsers はトラコン運営が選んだわけではなく、CentOSのデフォルトの設定です。

3. 多重接続の設定

エラーメッセージからSSHの多重化でトラブルが起きていることがわかります。

mux_client_request_session: session request failed: Session open refused by peer
Failed to connect to new control master

sshd_config を見ると MaxSessions0 となっているのでこれを修正します。

ちなみに、この MaxSessions というのは同時にSSH接続が可能な数ではありません。デフォルトは10になっていますが、これは11個目のセッションがはじかれるというわけではないのです。

 /
カテゴリー

概要

新卒社員であるあなたは先輩社員のお手伝いをすることになりました。先輩社員は次のようなネットワークを作りたいと考えているそうです。

  • 無線接続のユーザと同じように、有線接続のユーザも認証するために802.1X認証をしたい
  • routerの上には、RadiusサーバとLDAPサーバが動いている
  • LDAPサーバでユーザを一元管理しているため、RadiusサーバはLDAPサーバに登録されているユーザ情報を基に通信を認可を行いたい

ある程度先輩社員は設定を行ったそうなのですが、通信が上手くできないそうです。助けてあげてください。

先輩のメモ

  • client1, client2には必要な設定ファイルを用意しておいた
  • switchの設定は上手くいっているはずだから気にしなくていい
  • freeradiusのログには有用なことが書いてあるらしい

client1, client2

これらの機器は、802.1X認証をする機器です。/home/user/wpa_supplicant.confに接続に必要な情報が書かれています。以下のコマンドでサプリカントを起動することができます。/dataに起動時に実行されるインターフェース設定などが書かれたファイルが置かれています。

$ wpa_supplicant -B -D wired -i eth1 -c ./wpa_supplicant.conf
  • /data/setup-interfaces.sh: インターフェース設定を行うためのスクリプト
  • /data/teardown-interfaces.sh: インターフェース設定を消すためのスクリプト
  • /data/setup-interfaces.service: インターフェースを起動時に設定するためのsystemdのサービスファイル

switch

この機器は、802.1X認証を受ける機器です。/dataに起動時に実行されるインターフェース設定などが書かれたファイルやオーセンティケーターを起動するためのコマンドなどが書かれています。

client1, client2はwpa_supplicantを利用することで、switchの認証を行うことができます。wpa_supplicantを停止しても3分程度は接続がつながりますが、しばらく待つと認証が切れて切断されます。

  • /data/setup-interfaces.sh: インターフェース設定を行うためのスクリプト
  • /data/teardown-interfaces.sh: インターフェース設定を消すためのスクリプト
  • /data/setup-interfaces.service: インターフェースを起動時に設定するためのsystemdのサービスファイル
  • /data/[email protected]: hostapdが認証を許可した時に8021x_handler.pyを呼ぶためのデーモン用のsystemdのサービスファイル
  • /data/8021x_handler.py: ebtablesを操作し、802.1Xの認証結果をファイアウォールに反映させるスクリプト

router

この機器は、認証用のデーモンが動いている機器です。freeradius, openldapが動作しています。

  • /data/setup-interfaces.sh: インターフェース設定を行うためのスクリプト
  • /data/teardown-interfaces.sh: インターフェース設定を消すためのスクリプト
  • /data/setup-interfaces.service: インターフェースを起動時に設定するためのsystemdのサービスファイル
  • freeradius
    • 認証情報:
      • 172.31.1.253から通信を受けられるように設定されている
      • パスワード: ictsc2021
    • ユーザなどを取得するためにLDAPサーバに問い合わせを行っている
  • openldap
    • 認証情報:
      • admin DN: cn=admin,dc=2021-summer,dc=ictsc,dc=net
      • admin PW: ictsc2021

前提条件

  • client1, client2, switchの設定を変更したり加えたりしてはいけない
    • これらの機器は先輩社員さんがちゃんと設定を行っています
    • 設定変更を加えることなく問題を解くことができます

初期状態

  • client1, client2から172.31.0.254にpingを打っても返ってこない

終了状態

  • client1, client2から172.31.0.254にpingを打つと返ってくる

解説

今回の問題は、LDAPに保存されているパスワードのハッシュアルゴリズムとMS-CHAPv2で利用できるハッシュアルゴリズムが異なっていることによって、認証が行えていないというのが問題でした。

そのため、LDAPにMS-CHAPv2で利用できるような形式でハッシュ化した属性を追加すればOKです。

  1. sambaのobjectClassの定義をロードする(sambaNTPassword属性を利用するため)
sudo apt install samba
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/share/doc/samba/examples/LDAP/samba.ldif
  1. ユーザ用のLDIFファイルをロードする

sambaSIDはsambaSamAccount objectClassを利用するのに必須な属性です。なので、適当に生成する必要があります。sambaSIDは以下のようなスクリプトで生成することができます。

import binascii
import hashlib
import random

def nt_hash(password):
    password = password.encode("UTF-16LE")
    hashed = hashlib.new("MD4", password).digest()
    return binascii.hexlify(hashed).decode().upper()

def generate_samba_sid():
    p1, p2, p3 = [random.randint(0, 4294967295) for _ in range(3)]
    return f"S-1-5-21-{p1}-{p2}-{p3}"

password = input("password: ")
print(nt_hash(password))
print(generate_samba_sid())

スクリプトでSIDとNTハッシュ化されたパスワードを生成したら、ユーザのパスワードを追加するLDIFファイルを作成してロードします。

dn: uid=adam,ou=Users,dc=2021-summer,dc=ictsc,dc=net
changetype: modify
add: objectClass
objectClass: sambaSamAccount
-
add: sambaSID
sambaSID: S-1-5-21-401484083-650785073-894160332
-
add: sambaNTPassword
sambaNTPassword: 1574D4A36AE4DE77D91A42E12B5F30B3
dn: uid=eve,ou=Users,dc=2021-summer,dc=ictsc,dc=net
changetype: modify
add: objectClass
objectClass: sambaSamAccount
-
add: sambaSID
sambaSID: S-1-5-21-883903360-3810299002-3370863084
-
add: sambaNTPassword
sambaNTPassword: 27B0A3ACE19B518DEDADBC9D9EF50BF6
sudo ldapmodify -h localhost -D cn=admin,dc=2021-summer,dc=ictsc,dc=net -W -f ./adam.ldif
sudo ldapmodify -h localhost -D cn=admin,dc=2021-summer,dc=ictsc,dc=net -W -f ./eve.ldif
  1. /etc/freeradius/3.0/mods-enabled/ldapを編集する

追加した属性をfreeradiusの方から利用できるようにするために、/etc/freeradius/3.0/mods-enabled/ldapを編集して、NT-Passwordが格納されている属性のマッピングを追加します。これによって、freeradiusでNTハッシュ化したパスワードを利用することができます。

        #  attribute ref.
        update {
                control:Password-With-Header    += 'userPassword'
                control:NT-Password             := 'sambaNTPassword'
#               reply:Reply-Message             := 'radiusReplyMessage'

部分点

想定解の部分点は、パスワードをロードできた時点で200点、freeradiusの設定をするのを含めて300点になる予定でしたが、想定外解法(平文でパスワードを保存する解法)がほとんどでした。こちらの場合、終了条件に抵触しているわけではないので、こちらの場合でも同様に満点で採点しています。