crashRT のブログ

技術とかそれ以外とか

Slack BotをAPIから作ってみた

Slack Botをたくさん作る必要があったのでAPIから作ろうとしてみました。 ここにマニフェストを使ってAPIからBotを作れると書いてあります。 api.slack.com

まとまった情報があまりなかったのでまとめてみます。 pythonのslack_boltを使っています

App configuration token を取得

API からSlackAppを作るにはApp configuration tokenが必要になります。 以下のサイトに行き「Generate Token」を実行すると取得できます。

api.slack.com

Slack Appの作成

app.client.apps_manifest_create を呼び出すとSlackAppを作成できます。

引数は2つ:

  • token:先ほど取得した App configuration token を使う
  • manifest:今はスコープの設定などができないので、必須のものだけ設定しておく

マニフェストはこんな感じでやってみました:

{
    "display_information": {
        "name": "Sample App",
    }
}

Pythonで書くとこんな感じ:

  import os
  from dotenv import load_dotenv
  from slack_bolt import App

  load_dotenv(".env")
  TOKEN = os.getenv('TOKEN')

  app = App(token=TOKEN)

  app_name = "SampleApp"

  # まずアプリを作成
  init_manifest = {
    "display_information": {
        "name": app_name,
    }
  }

  resp = app.client.apps_manifest_create(token=TOKEN, manifest=init_manifest)

  if not resp["ok"]:
      raise Exception(resp)

  app_id = resp["app_id"]
  oauth_url = resp["oauth_authorize_url"]

App configuration tokenは.envファイルから読み出しています。 レスポンスにapp_idoauth_authorize_urlがあるので取り出しておきます。

詳細はapps.manifest.create についてのドキュメントを見てください。 api.slack.com

アプリの設定をする

app.client.apps_manifest_updateマニフェストの更新ができるので、ここで色々設定をします。 マニフェストについては以下のドキュメントが参考になります。 api.slack.com

必要な引数は3つ。

  • token: 同じくApp configuration tokenを使う
  • app_id : App作成時のレスポンスに含まれる app_id を使う
  • manifest : ドキュメントを参考にJSONなどの形で書く

pythonで書くとこんな感じ:

  manifest = {
    "display_information": {
        "name": str(app_name),
    },
    "features": {
      "bot_user": {
          "display_name":"hoge"
      },
    },
    "settings": {
      "socket_mode_enabled": True,
      "event_subscriptions": {
        "bot_events": [
        ]
      },
    },
    "oauth_config": {
      "scopes": {
        "bot": [
          "chat:write",
          "chat:write.public",
        ]
      },
      "redirect_urls": [
        str(oauth_url)
      ]
    }
  }

  resp = app.client.apps_manifest_update(
      token=TOKEN,
      app_id=app_id,
      manifest=manifest,
  )

  if not resp["ok"]:
      raise Exception(resp)

  print("------------------")
  print(app_name + " を作成しました")

APIの詳細については apps.manifest.update についてのドキュメントを見てください。 api.slack.com

トークンの取得など

App-Level Tokens や Bot User OAuth Token などはAPIからは取得できないので、webから管理画面にアクセスして取得するしかないようです。 管理画面のURLは https://api.slack.com/apps/<app_id> となります。

さいごに

SlackAppをたくさん作る必要があるときに使えば多少手間は省けそうな感じでした。 本当はトークンの取得まで自動でしたかったのですが、流石にできないようです。ここは画面ポチポチするしかなさそうですね〜

僕が書いたコードがあるリポジトリのリンクを一応貼っておきます。使い捨てで書いたコードなのであまりきれいではないですが... github.com

参考資料

ICTSC2023 に参加してきました

3/16~17にICTトラブルシューティングコンテスト2023の本戦に参加してきました! 結果は僕が所属するチームKMCは5位でした。チーム全員初参加にしては頑張った方なんじゃないかなと思います。 来年は優勝目指して頑張ります!

icttoracon.net

オフラインでの開催でいろんな人と会えるのはやっぱり良いですね。 オンラインではKMCと仲が良いtraPの人々と初めて会えたり、インターンで知り合った人と再会したり... いろんな方と話せて楽しかったです!

せっかくなので、本戦で僕が解いた問題について感想とかを書いていこうかなと思います。

問題の感想

[vkm] VKM

シェル芸の問題ですね。チームメイトとホテルの部屋で夜な夜な解いてました。 短くするよりもまずは動くものを作らないとな~と思っていたらchatGPTくんが結構良いものを出してくれちゃいました。

cat /dev/urandom | tr -dc 'A-Z' | fold -w 3 | uniq | head -n 20

これを少し修正して動くようにしたら83byteくらいの動くものが手に入ったので、あとは短くするだけでした。 消しても問題ない空白を消したり、'が実は必要なかったり、uniqしてsortしてshufsort -uR に置き換えたり... コマンドのオプションとかを色々調べながら短くしていった結果56byteまで削ることができました。 最終的に完成したワンライナー

tr -dc A-Z</dev/random|fold -w3|sed 99q|sort -uR|sed 20q

です。

以下のサイトが参考になりました。

qiita.com

[vhn] xへ繋がりたい!

名前を変えてしまったあのサービスに接続できるようにし、また、そのサービス名でユーザーを作成する問題でした。 全体的に名前に関する問題だったな~って感じがしました。

接続の部分はチームメイトがしてくれたのですが、ユーザーを作成するとうまく動かなかったのでそこから一緒に見ていきました。 ユーザーXだけ実行可能なプロセス数が0に制限されていたりパスワード認証でのSSHが2箇所で禁止されていたり...Xに対して恨みがあるんかな~とか思いながら直しました。 ulimit とか /etc/security/limits.conf とか知らなかったので勉強になりました。

[jpq] 初心者プログラマーでも make がしたい!

チュートリアル的な問題でした。 出力されたエラーを丁寧に見ていけば解決はできたのですが、ゼロ幅スペースとか ., の違いとか、微妙に気づきにくいものが多いな~という印象でした。

[aka] 秘密鍵ないなった

RSA暗号で遊んだことが何度かあったので解いてみました。 第1問は簡単に素因数分解できたのでただ計算するだけでした。

第2問はPeggyがヒントを話してくれていたのでそれを元に検索すると、 1089桁の素数が見つかったので多分片方はこれだろうと予想できました。 33x33に整列して表示したら各行・列・対角線上の値がそれぞれエマープ数になるようです。 こんなすごい素数があったんですね~

mywindow.blog.fc2.com

あとはこれでNを割って...という流れで、1000桁って64bitとかでは当然扱いきれないので、計算大変そうだな~って感じてました。 が、Pythonは特に何もしなくても上限なく整数が使えるらしいです。Pythonえらい!

ということでPythonで計算したら無事割り切れて、100桁の別の値が出てきました。 その値で検索してみると、10x10で整列するとこの素数も各行・列・対角線上の値がそれぞれエマープ数になるらしいです。 しかもこの100桁の素数もエマープ数らしいです。これまたすごい素数ですね...

www.zeldadungeon.net

ということで無事素因数2つが見つかったので秘密鍵を求めることができました。

...が、素因数を見つける過程を省略して2つの素因数が有名な素数であることをちゃんと記述していなかったため、点数をもらえませんでした... 普通に素因数分解はできない値なので、ちゃんとその過程も書く必要があったようです。来年以降は気をつけたいですね...

[nle] †権限デストロイヤー†

パソコンをロックせずにトイレに行ったらいろんなファイルの権限が000にされてしまっていた、という問題でした。 去年の実験中にパソコンをロックせずに席を離れている人がいて友達と 「chmod 000 / で完全にパソコンロックしちゃいたいね~」みたいな冗談話していたら似た状況に遭遇してしまいました。

チームメイトが chmod を復活させるコマンドを見つけてくれていた後を引き継ぎました。OS初期化しなくても復活させることが出来たんですね~

sudo /lib64/ld-linux-x86-64.so.2 /usr/bin/chmod 755 /usr/bin/chmod

いろんなコマンドも権限が000になっていたので sudo chmod /bin/* をしてしまったのですが、sudoパーミッションは変更してはいけなかったようです。再展開するしかありませんでした... 再展開後は必要なコマンドのみ権限を復活させながら進めていきました。

chmodmemo.txt の権限変えたら終わりかな~と思っていたのですが、流石にそれだけで終わるということはなく... ファイルのフラグが編集されていて変更不可になっていたようでした。 ファイルにフラグがあったんですね...知らなかったです。 lsattr とか chattrとか初めて使いました。

[kog] さよならリモートワーク

予選で今まで知らなかったVyOSが出ていたので本戦まで少し勉強していたのが役に立って良かったです。 無事firewallの設定を変更したら古の暗号方式がどんどん要求されてしまいました。 少し古い機器を使うときなどによく見かけたエラーでした。

.ssh/config の変更が禁止されているものの /etc/ssh/ssh_config は禁止されていなかったので想定解とは違いそうだと薄々思いながらも他の方法を知らなかったのでこの裏ルートで解消していましました。 サーバー側で使用する暗号を決める設定もあったんですね...

最後に

ICTSC2023 本戦で解いた問題について感想のような何かを書いてみました。 途中までしか解けなかった問題もありましたが、どの問題も解いていて楽しかったです! ありがとうございました!

クラシック音楽爆速入門

クラシック音楽聞いていますか? 今回は僕が好きなクラシック音楽を簡単に紹介してみようと思います。

KMC(https://kmc.gr.jp)の春合宿で話した内容を元にしています。

多分聞いたことあるクラシック

まずは、多分どこかで聞いたことがあるクラシックを紹介しようと思います。 多分今後もどこかで聞くと思うので、そのときにあの曲じゃん!って思えると楽しいかもしれません。

ベートーヴェン 交響曲第5番 ハ短調 Op. 67 『運命』

まずはオーケストラの曲から。ベートーヴェンの『運命』です。 第1楽章冒頭の「ジャジャジャジャーン」の部分は有名ですね。 曲名も結構知られているクラシックの一つだと思います。

music.youtube.com

ベートーヴェン 交響曲第9番 ニ短調 Op. 125『合唱』

2曲目もベートーヴェンから、よく「第九」と呼ばれるこの曲です。 日本では年末にいろんなところで演奏されますね。 第4楽章は『歓喜の歌』として音楽の教科書にも載っていて有名だと思います。 とてもかっこいい曲なので是非フルで聞いてみてください。

music.youtube.com

ドヴォルザーク 交響曲第9番 ホ短調 Op. 95, B. 178『新世界より

もう少しオーケストラが続きます。 今度はドヴォルザークの『新世界より』です。 第4楽章の冒頭は聞いたことがあると思います。

music.youtube.com

第2楽章のオーボエのソロ部分ももしかしたら聞いたことがあるかもしれません。 時々帰りの曲として使われていますね。

music.youtube.com

ビゼーカルメン前奏曲

最後に紹介するオーケストラの曲はビゼーの『カルメン前奏曲 です。 『カルメン』というオペラの前奏曲です。

music.youtube.com

ベートーヴェン バガテル第25番 イ短調 WoO59『エリーゼのために

次にピアノ曲を2曲紹介します。 まずは有名な『エリーゼのために』から。 曲名も有名ですよね。知っている方も多いと思います。

music.youtube.com

エステン『人形の夢と目覚め』Op. 202-4

ピアノ曲2曲目はエステンの『人形の夢と目覚め』です。 お風呂が沸いたときの音として聞いたことがある方も多いと思いますが、実はクラシック曲の一部でした。

music.youtube.com

モーツァルト セレナード第13番 ト長調アイネ・クライネ・ナハトムジーク

バイオリンなどの弦楽器の曲も2曲紹介しようと思います。 まずはモーツァルトの『アイネ・クライネ・ナハトムジーク』から。 第1楽章の冒頭は聞いたことがある方も多いんじゃないかなと思います。

music.youtube.com

ヴィヴァルディ ヴァイオリン協奏曲第1番ホ長調 RV 269『春』

ヴィヴァルディの四季の春と呼ばれている曲です。 第1楽章は聞いたことがある方も多いと思います。

music.youtube.com

オッフェンバック『天国と地獄』

最後に、運動会でよく流れている曲を2曲紹介して終わろうと思います。 まずはオッフェンバックの『天国と地獄』です。 競技中によく流れていると思います。 『地獄のオルフェ』というオペラの序曲の一部です。

music.youtube.com

ヘンデル『見よ、勇者は帰る』HMV63

最後に紹介する曲はヘンデルの『見よ、勇者は帰る』です。 表彰式のときは大体この曲が流れていますよね。

music.youtube.com

クラシックの曲名について

いくつか曲を紹介してきましたが、曲名がなんかややこしいなと感じた方もいると思います。 クラシックの曲名について少しだけ解説します

クラシックの曲名はいくつかの部分に分かれています。先ほど紹介したベートーヴェンの『運命』を例に説明します。

gyazo.com

上の画像のように、クラシックの曲名は

  • 形式
  • 番号
  • 曲の主調
  • 作品番号
  • 副題

からなることが多いです。

形式

曲の形式は交響曲とか協奏曲とかのことです。

交響曲

交響曲 (symphony) はクラシックの花形とも言える形式です。 オーケストラによって演奏されます。(オーケストラの楽器の構成は作曲者が自由に決めることができます)

最も代表的な形式なので、交響曲を略して呼ぶ際に「交響曲」の部分が略され、さらに作曲者の名前も略して ベートーヴェン交響曲第5番を「ベト5」、ブラームス交響曲第4番を「ブラ4」のように呼ぶこともあります。

協奏曲

協奏曲 (concerto) はソリストがオーケストラを従えて演奏する形式です。 ソリストが指揮者の横で演奏しながらオーケストラがそれに合わせて演奏します。 ソリストはピアニストやヴァイオリニストであることが多いです。

ソナタ

一人や二人で演奏される曲は器楽曲と呼ばれますが、ソナタはその中で複数の楽章からなるものです。

バレエ音楽・オペラ音楽

クラシック音楽はバレエやオペラでもよく使われています。 序曲・前奏曲などと曲名についている曲は大体バレエやオペラの曲です。

番号

番号は作曲者ごとの、各形式において何番目かを指すものです。 『運命』の例では、『運命』がベートーヴェンの5番目の交響曲であることを指します。

主調

曲の主調はその曲の雰囲気をよく表すものらしく、曲名に入っていることが多いです。

作品番号

作品番号は作曲者ごとの通し番号で、形式に関係なくつけられます。 Op. 67 や 作品67 などと書かれることが多いです。 Op. は「オーパス」と読みます。

Op. とは別に作品を整理した研究者のイニシャルなどに基づく番号もあります。 モーツァルトのケッヘル番号(K)やヴィヴァルディのリュート番号(RV)などがあります。

楽章

交響曲などはいくつかの(ほぼ独立した)曲がいくつか集まって一つの作品を構成することが多く、 その曲一つ一つのことを楽章と呼びます。 交響曲の場合は4楽章からなることが多いです。

楽章毎に速度の指示があり、第4楽章: Allegro などのように書かれることもあります。 速度の指示は「いきいきと、かなり早いテンポで」「歩く速さ、落ち着いた速度で」のように曖昧な表現となっているので、 同じ曲でも指揮者ごとに速度が違うこともあります。

雰囲気別おすすめの曲

おすすめの曲を雰囲気別にまとめてみました。 お気に入りの曲を是非見つけてみてください。 曲名は誤解を生まない程度に略して書いています。

かっこいいクラシック

落ち着くクラシック

元気が出るクラシック

目覚ましにおすすめなクラシック

『驚愕』はコンサートで寝る客を起こすために作られた曲らしいです。

コンサートのすすめ

クラシック音楽に少し興味が出てきたら、是非コンサートへ行ってみてください。 僕が最初コンサートに行く前に不安だったことを解消しつつ、見どころを少し紹介しようと思います。

コンサートの選び方

まずは近くのコンサートホールを調べてみてください。 京都の場合は京都コンサートホール がおすすめです。

各コンサートホールの公演カレンダーを見て、コンサートホールが主催している公演などから知っている曲があるものに行ってみるのがいいんじゃないかなと思います。 コンサートに行く前はYoutubeなどで事前に聞いておいてから行くのがおすすめです。次の展開がだいたい分かるくらいになってるととても楽しめると思います。

コンサートの価格

クラシックコンサートと聞くとなんかとても高そうな印象があるかもしれませんが、実際は結構手頃です。 海外のオーケストラの来日公演とかでない限りはそんなに高くなくて、大体数千円~高くて5,6千円くらいのことが多いと思います。

コンサートの服装

(少なくとも海外のオーケストラの来日公演とかでない限り)特に気にする必要はありません。 スーツを着てる人はあんまりいなくて、好きな服を着ればいいと思います。 ちょっときれいめな普段服くらいで行けば問題ないと思います。

拍手

クラシックのコンサートの拍手は少し独特なので紹介します。

演奏が終わるともちろん拍手が起こりますが、拍手をするのは一曲が全部終わったときのみです。 楽章毎の切れ目で一旦演奏が止まることが多いのですが、ここでは拍手をしないので注意してください。 いつ拍手すればいいのか不安な場合は周りが拍手し始めたらやる、で全く問題ありません。

最後の曲の拍手はとても長いことが多いです。 体感5分以上拍手していることもある気がします。結構疲れます。 オーケストラの場合は指揮者、リサイタルの場合は演奏者が舞台袖に帰ったり戻ってきたりを何回も繰り返します。 オーケストラなら途中でソロをした人の紹介や各パートの紹介などがあります。 長い拍手の後にアンコールがあることもあります。 今までで一番多かったときはピアノリサイタルに行ったときなのですが、アンコールで4曲演奏してもらえました。 少人数の場合は結構アンコールしてもらえる気がします。

さいごに

僕が好きなクラシック音楽の紹介をしてみました。 今回紹介した曲は Youtube Music の再生リストにまとめてあります。よかったら聞いてみてください!

music.youtube.com

クラシック音楽はおそらく思っている以上に身近なところで流れています。 また、クラシック音楽には流行とか新曲とかもなく会話デッキとして結構優秀なのでおすすめです。 是非1曲お気に入りの曲を見つけてみてください!

Ubuntuでマイクラサーバーを立ててみた

友達とのマイクラ用にマイクラサーバーを立てました。 Minecraftのバージョンは1.20.4です。 サーバー構築時の手順を残しておきます。

サーバーを動かすVMの用意

VMの上で動かすことにしました。 以下のような構成にしました。 - OS: Ubuntu 22.04 - CPU: 4コア - メモリ: 2GiB - 一旦様子見で2GBで作成。今後4GiBに増やすかもしれない - ディスク: 256GiB

minecraftサーバーの構築

VMの用意が出来たのでminecraftサーバーを構築していきます。

Java 17のインストール

minecraft サーバーを動かすにはJavaが必要なのでインストールします。 1.20.4の場合はJava17が必要です。

$ sudo apt install openjdk-17-jdk

正しくインストールできたことを確認します

$ java --version
openjdk 17.0.10 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 17.0.10+7-Ubuntu-122.04.1, mixed mode, sharing)

minecraft サーバーのダウンロード

最新版のサーバーは公式サイトから入手できます。

www.minecraft.net

ダウンロードリンクをコピーし、wget でダウンロードします。

 $ wget <コピーしたURL>

サーバー起動のための準備

サーバーファイルの名前が分かりづらいので変更しておきます。

$ mv server.jar minecraft_server_1.20.4.jar

次のコマンドを実行することでサーバーを起動することができます。

$ java -Xmx1024M -Xms1024M -jar minecraft_server_1.20.4.jar nogui 

このコマンドを実行すると、EULAへの同意が求められます。 eula.txt を編集し同意します。 vim に慣れていない場合はnanoなどを使ってください。

$ vim eula.txt
- eura=false
+ eura=true

再び実行するとサーバーが起動します。 ネットワークの設定も必要ですがここでは省略します。 サーバーに接続できることを確認します。

tmux を使って実行する

このままだとシェルからログアウトするとサーバーが止まってしまうので、バックグラウンドで実行されるようにする必要があります。 しかし、サーバーを運用していく上で時々管理者としてコマンドを実行したい場合があるため、好きなときにフォアグラウンドに戻せることが必要です。 そのため、nohup ... & や systemd などは今回は使わず、tmux を使って実行します。

minecraft サーバーを運用する上で必要な tmux の操作を紹介します。 tmux の詳しい使い方は以下のサイトが参考になると思います。

qiita.com

minecraft という名前をつけてセッションを開始

$ tmux new -s minecraft

セッション内でサーバーを起動します。 このセッション内であれば minecraft のコマンドを実行できます。

セッションから離脱

Ctrl-b -> d

セッション一覧の確認

$ tmux ls

minecraft のセッションの再開

$ tmux a -t minecraft

最後に

自宅サーバー上でminecraftのサーバーを構築してみました。

Django+PostgreSQL+nginx+Dockerでwebアプリを作った話

Django, PostgreSQL, nginx, Docker を使ってwebアプリを作ったので、備忘録も兼ねて環境構築周りの話とか残しておきます。

作ったのはこんな感じのサイトで、MVみたいな映像作品を映像作家と紐づけて管理するためのシステムを作りました。

isle4db.crashrt.work

ディレクトリ構成

.
├── .env
├── docker-compose.prod.yml # 本番環境用のcomposeファイル
├── docker-compose.yml      # 開発環境用のcomposeファイル
├── Dockerfile
├── gunicorn.conf
├── README.md
├── requirements.txt
└── src                     # Djangoのソースコード

開発環境、本番環境を共にDockerコンテナで動かしています。 それぞれ構成が異なるため、composeファイルを分けています。 使用するファイルの指定は -f オプションでできるので、 docker compose -f docker-compose.prod.yml up -d のようにすると本番環境が立ち上がります。 docker-compose.yml の場合は指定は必要ありません。

開発環境

開発環境ではDjango用のコンテナとPostgreSQL用のコンテナの2つを起動します。 composeファイルはこんな感じ。

version: "3"
services:
  db:
    image: postgres:16.0
    env_file: .env
    ports:
      - "54320:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - db-data:/var/lib/postgresql/data/
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    env_file: .env
    environment:
      - ENV="dev"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      db:
        condition: service_healthy

volumes:
  db-data:

.envPOSTGRES_USERPOSTGRES_PASSWORを定義しておきます。

注意すべきなのはhealthcheckの部分です。 普通に書くだけだと PostgreSQL が立ち上がる前に Django がDBに接続しようとしてしまうので、ヘルスチェックで立ち上がったことを確認するようにすることが必要です。

また、Djangosettings.py で次のように記述すると、開発環境でのみ DEBUG=True になります。

ENV = os.getenv('ENV')
if ENV == "dev":
    DEBUG=True
else:
    DEBUG=False

composeファイルで環境変数 ENV を設定しているのでそれを読み出し、'dev' の場合はデバッグを有効にしています。 pythonos.getenv() などはstr型を返すので、 DEBUG=True のようにして直接ブール値を設定することはできません。

Dockerfile はこんな感じです。

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code
RUN pip install -r requirements.txt
ADD . /code/
WORKDIR  /code/src
RUN mkdir -p /var/run/gunicorn
RUN python3 manage.py collectstatic --noinput
CMD ["gunicorn", "app.wsgi", "--bind=unix:/var/run/gunicorn/gunicorn.sock"]

CMD に本番環境用のコマンドがありますが、composeファイルで開発サーバー起動のコマンド(python manage.py runserver 0.0.0.0:8000)に上書きされます。

本番環境

本番環境ではDjango用コンテナ、PostgreSQL用konntena、nginx用コンテナの3つを起動します。 composeファイルはこんな感じ。

version: '3'
version: '3'

services:
  db:
    image: postgres:16.0
    container_name: god-movie-collection-db
    env_file: .prod.env
    ports:
      - "54320:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    volumes:
      - db-data:/var/lib/postgresql/data/
    restart: always
  web:
    build: .
    container_name: god-movie-collection-web
    env_file: .env
    volumes:
      - .:/code
      - gunicorn:/var/run/gunicorn
    restart: always
    depends_on:
      db:
        condition: service_healthy
  nginx:
    image: nginx:1.17.7
    container_name: god-movie-collection-nginx
    depends_on:
      - web
    ports:
      - "80:80"
    volumes:
      - ./gunicorn.conf:/etc/nginx/conf.d/default.conf
      - gunicorn:/var/run/gunicorn
    restart: always
volumes:
  db-data:
  gunicorn:
    driver: local

webサーバーとDjangoの間のインターフェースとしてgunicornを使うので requirements.txt に追記します。 僕のはこんな感じです。

Django==5.0
psycopg2==2.9.9
django-bootstrap4==23.2
gunicorn==21.2.0

gunicorn.confにはこのように書きます。

upstream gunicorn-django {
    server unix:///var/run/gunicorn/gunicorn.sock;
}
server {
    listen 80;
    server_name localhost;
    location / {
        try_files $uri @gunicorn;
    }
    location @gunicorn {
        proxy_pass http://gunicorn-django;
    }
}

おまけ

webアプリを外部に公開するのはCloudflare Tunnel を使うと便利だったのでおすすめです。

www.cloudflare.com

最後に

Djangoでwebアプリを開発するときの環境構築について忘れないうちにまとめておこうと思って書いてみました。 少しでも力になれたら嬉しいです。

cisco 891FJ を使ってみた

ヤフオクcisco 891FJを買ったので,設定とか構築したネットワークとかについて雑に残してみる.

構築したネットワーク

今回,画像の図のようなネットワークを構築することにした.

契約している回線がちょっと変わっているがあまり細かいことを考えたくなかったので, プロバイダと接続している部分は普通の家庭用ルーターを置き,その下で色々構築することにした.

自宅サーバーと個人用のものでネットワークを分けたかったため,次のように VLAN を分けることにした.

  • VLAN 100 (192.168.1.0/24) : インターネットと接続する外側の部分.NW機器が所属
  • VLAN 200 (192.168.2.0/24) : 個人用のネットワーク.生活用PCやスマホなどが所属.
  • VLAN 1100 (192.168.11.0/24) : サーバー用ネットワークでDMZ.外部に公開するサーバーのみが所属. ACLでVLAN 200への通信を遮断する.

物理的な配置の関係で内側に置きたいNASがサーバーと同じスイッチに繋がっているので,C891FJとAT-x210の間はtrunk vlanで接続することにした.

また,C891FJをDHCPサーバーにすることもできたので,スマホなどへはDHCPでアドレスを配ることにした.

このような構成で自宅のネットワークを構築することにした.

コンソールケーブルで接続

crashrt.hatenablog.com

の時と同じく,以下のコンソールケーブルを使用して接続した.

https://www.amazon.co.jp/gp/product/B01F05XLDM/

初期設定

まず,ホスト名前やユーザー名,パスワードの設定を行う.

(config)#hostname
(conig)#enable secret
(config)#enable password
(config)#service password-encryption
(config)#username password

アドレスの設定

VLANを定義する.

(config)# vlan 100
(config-vlan)# name public

その後,SVIの設定をした.

(config)# interface vlan 100
(config-if)# ip address 192.168.1.2 255.255.255.0
(config-if)# no shutdown

他のVLANに関しても設定した後の状態は以下のとおりである. VLAN-IDに1100を設定するには vtp mode transparent を実行しVTPモードをトランスペアレントにする必要がある.*1 VTPでVLANの設定を同期できなくなるが,この機能は使わない予定なのでこれで進める.

vlan 100
 name public
!
vlan 200
 name private
!
vlan 1100
 name server
interface Vlan100
 ip address 192.168.1.2 255.255.255.0
!
interface Vlan200
 ip address 192.168.2.1 255.255.255.0
!
interface Vlan1100
 ip address 192.168.11.1 255.255.255.0

また,各ポートにVLANを割り当てた.

アクセスポートの場合

(config-if)# switchport mode access
(config-if)# switchport access vlan 100

トランクポートの場合

(config-if)# switchport mode trunk
(config-if)# switchport trunk encapsulation dot1q
(config-if)#switchport trunk allowed vlan add 100,200,1100

これでC891FJがIPアドレスを持つことができた.

SSH

IPアドレスでC891FJにアクセスできるようになったので,SSHで繋げるように設定する.

まず,VTYの設定を変更してSSHで接続できるようにする.

(config)# line vty 0 4
(config-line)# transport input ssh

SSHしようとすると以下のように表示された.

ssh 192.168.2.1
Unable to negotiate with 192.168.2.1 port 22: no matching key exchange method found. Their offer: diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

ので,.ssh/config のこのC891FJの部分に以下の行を追記すると接続できるようになった.(公開鍵の登録はしていないのでパスワードの入力が必要)

Host m891fj
    User .....
    Hostname 192.168.2.1
    KexAlgorithms +diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

インターネットに接続

インターネットと通信できるようにする.

まず,デフォルトルートを上流側に設定する.

(config)#ip route 0.0.0.0 0.0.0.0 192.168.1.1

その後,DNSの設定をする.

(config)#ip name-server 8.8.8.8

google.com に接続できることを確認.

milkyway#ping google.com
Translating "google.com"...domain server (192.168.1.1) [OK]

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 142.250.206.238, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/7/8 ms

ACLの設定

サーバー用VLANから個人用VLANへの通信を遮断する.

次のようなACLを作成する.

(config)# access-list 100 deny   ip 192.168.11.0 0.0.0.255 192.168.2.0 0.0.0.255

そして,AT-x210と接続しているインタフェースに適用する.

(config-if)# ip access-group 100 in

機器を接続

AT-x210でVLANの設定をし,サーバー等を接続する.

まず,C891FJと接続しているインターフェースをトランクポートに設定.

(config)#vlan database
(config-vlan)#vlan 100,200,1100
(config-vlan)#exit
(config)#interface port1.0.1
(config-if)#switchport mode trunk
(config-if)#switchport trunk allowed vlan add 100,200,1100
(config-if)#exit

サーバーを接続し,接続したポートを対応するアクセスポートに設定.

(config)#int port1.0.2
(config-if)#switchport mode access
(config-if)#switchport access vlan 1100
(config-if)#exit

これでサーバーもインターネットと通信できるようになる...と思ったが,うまくいかなかった. サーバーからC891FJまでは疎通したが,その先へは疎通しなかった.

Buffaloのルーター192.168.2.0/24 192.168.11.0/24 の経路情報を持っていないのが原因だったので,ルーターの設定画面から経路情報を登録した. すると,無事サーバーもインターネットと通信できるようになった.

DHCPの設定

最後に,スマホなどの無線用にDHCPを設定する.

まず,DHCPプールの設定をする. スマホ等は個人用のVLANに所属させるので,ネットワークは192.168.2.0/24とする.

(config)# ip dhcp pool wireless
(dhcp-config)# network 192.168.2.0 255.255.255.0
(dhcp-config)# default-router 192.168.2.1
(dhcp-config)# dns-server 192.168.2.1 192.168.1.1 8.8.8.8
(dhcp-config)# lease 7

サーバー等で使うアドレスを配布されると困るので,除外する.

(config)# ip dhcp excluded-address 192.168.2.128
(config)# ip dhcp excluded-address 192.168.2.0 192.168.2.128
(config)# ip dhcp excluded-address 192.168.2.255

M891FJにAPモードにしたelecomのルーターを接続すると,無事アドレスが配布された.

最後に

ciscoルーターを使って自分の部屋のNW環境を整備してみた. ルーターをあと二つ増やしてOSPFで経路広報とかできたら楽しそうだな~ってちょっと思ってるのでいつかやりたい.

参考サイト

www.n-study.com

www.infraexpert.com

www.infraexpert.com

www.infraexpert.com

www.infraexpert.com

shinmeisha.co.jp

qiita.com

www.infraexpert.com

www.infraexpert.com

*1:この設定を行わずに使うことのできるvlan-idの範囲は2 - 1001らしい.

AT-x210-9GTを使ってみた

ヤフオクAllied TelesisのAT-x210-9GTを買ったので,初期設定とかでやったこととかをメモ.

www.allied-telesis.co.jp

マニュアルはここにあった.

www.allied-telesis.co.jp

コンソールを接続

初期設定のためにコンソールケーブルで接続しないといけない. コンソールターミナルにはTera Termを使った.

https://ttssh2.osdn.jp/index.html.jattssh2.osdn.jp

ターミナルの設定パラメータはマニュアルに従って

  • スピード:9600
  • データ:8 bit
  • パリティ:none
  • ストップビット:1 bit
  • フロー制御:none

にした.

コンソールケーブルを持っていなかったのでAmazonで買うすることにした.

https://www.amazon.co.jp/gp/product/B00JPFOTOY/

を買って試してみたところ,ケーブルが良くなかったらしくてうまく通信できなかった. そこで同じくAT-x210を持っている友達に使っているコンソールケーブルを聞いて

https://www.amazon.co.jp/gp/product/B01F05XLDM/

を買って試してみたところ無事通信できてコンソールが表示された.

初期設定の状態ではユーザー名は manager,パスワードは friend

初期設定

無事ターミナルに接続できたので,最低限の初期設定をしていく. コマンドモードがあるので,コマンドを実行するときはどのモードにするべきかに注意.

  • 非特権EXECモード:プロンプトの末尾が >
    • 情報表示コマンドの一部のみ実行可能
  • 特権EXECモード:プロンプトの末尾が #
    • すべての情報表示コマンドと実行コマンドが実行可能
  • グローバルコンフィグモード:プロンプトの末尾が (config)#
    • システム全体にかかわる設定コマンドを実行するためのモード

他にもあるらしい.ということで早速設定していく.

グローバルコンフィグモードにする

まずこのコマンドで特権EXECモードにする.

>eneble

次に,グローバルコンフィグモードにする.

#configure terminal

ユーザーを作成する

(config)#username hoge privilege 15 password fuga

権限レベル15は一番強い値.今後はこのアカウントを使っていく.

ホスト名の設定

ホスト名を設定する.マニュアルより.

最大64文字。使用可能な文字は半角英数字とハイフン("-")、アンダースコア("_")のみ。半角英数字で始まり、半角英数字で終わる必要がある。

(config)# hostname piyo

実行後プロンプトに設定したホスト名が表示されるようになる.

ネットワークの設定

vlan1にIPアドレスとして例えば192.168.11.10/24を設定する.

(config)#interface vlan1
(config-if)#ip address 192.168.11.10/24

デフォルトゲートウェイも設定する.

(config-if)#exit
(config)#ip route 0.0.0.0/0 192.168.11.1

SSH接続できるようにする

初期設定のままではSSHで接続できないので設定する.

まず,ホスト鍵ペアを作成する. 鍵タイプとしてRSAとDSAが選べる.今回はRSAで作成する.

(config)# crypto key generate hostkey rsa

これでSSHサーバーを起動できるようになったので,起動する.

(config)# service ssh

作成したユーザーにSSH接続を許可.

(config)# ssh server allow-users hoge

公開鍵を登録.

(config)# crypto key pubkey-chain userkey hoge

すると公開鍵を入力するプロンプトが表示されるので,登録したい公開鍵をペーストする.

設定を保存

今までの設定を起動時コンフィグとして設定する.

(config)# write memory

これで使えるLANポートに色々接続して通信できるようになった・

おわりに

とりあえずスイッチとして動いてくれるようになった.misskey インスタンスとかを動かしているサーバーを繋いだらちゃんと接続できるようになっていたので嬉しい. SSH接続できるようにもしたので設定を色々いじりやすくなったはず.コンソールケーブル壊れやすいらしいからあんまり依存したくない....

ファームウェアのアップデートはまだなのでそのうちやりたい.