メインコンテンツへスキップ
  1. 記事一覧/

ポート開放ができない環境でサーバを外部公開するための個人的ベストプラクティス

·329 文字·2 分
Network サーバー Cloudflare ngrok OS
Bigbell
著者
Bigbell
某メガベンチャーで働いているエンジニアの卵です。
目次

はじめに
#

この記事は DeNA 23 新卒 Advent Calendar 2022 の11日目の記事です。

https://qiita.com/advent-calendar/2022/dena-23-shinsotsu

こんにちは DeNA23 卒内定者の bigbell です。
自分は 大学の研究室でネットワークとサーバの運用・保守を担当しているのですが、ポート開放ができない環境でサーバを外部公開する必要があり、その中で得られた知見があるので、同じ悩みを抱えた人のためにも今回初めて記事を書いてみようと思います。

説明が間違っていることもあるかも知れませんがその点はご容赦ください

経緯とか
#

私の研究室では後輩が 官公庁オークションで手に入れてきたラックマウントサーバ(ラックにマウントするとは言ってない)を使用して、入退室管理システムやファイルサーバ、研究で使用する自作ソフトウェアを動かしています。

最近ではAWSやGCPといったクラウドサービスがあるのに「なぜ今の時代にオンプレ環境?」と突っ込みたい人もいるかも知れませんがこれには理由があります。
実はこの環境に移る前はAWSのEC2上に無料枠でサーバを建てて、研究室内のシステムを動かしていました。

しかし、無料枠の範囲内ではサーバのスペックが足りず、自作のソフトウェアを実行するとまともにSSHすら繋がらなくなってしまう有様でした。
この問題を受けて、当初は幾らかお金が掛かるのには目をつぶって運用しようかという話にもなったのですが、「研究室内でそんなに使われていないシステムを動かすのに金銭的コストを掛けるのもどうなの?」という意見を受けて白紙になりました。
「う〜ん…運用どうしよう」と考えていた所、ちょうど後輩が官公庁オークションで上記のラックマウントサーバを手に入れてきたので、こちらを使用したオンプレ環境に移行したという形です。

直面した問題
#

サーバを手に入れて、よし!これで問題は解決!!と言いたい所でしたが、サーバを外部公開するに当たって別の問題に直面しました。
各研究室には大学側が設置している上流のルータを通してプライベートIPが振られており、基本的に自前で用意したサーバをポート開放して公開することはできないのです。
大学によっては情シスの人に頼めば良い感じにルータを設定してくれて、外部公開できる所もあるかと思いますが私の大学ではそれは厳しそうでした。

上述の問題の解決策として、よくQiitaでは ngrok (エングロック) のサービスをした方法が紹介されています。
このサービスは ngrok のサーバに対してトンネルを貼ることで、外部からの通信を中継してくれるというサービスです。
簡単に言えばリバースプロキシを楽に使えるようにしたようなもので、プライベートIPしか振られていないような環境でもインターネットにさえ繋がっていればサーバを外部に公開することができます。

ちなみに公式では以下のように説明されています

ngrokは、NATやファイアウォールに囲まれたローカルネットワークのサービスを安全なトンネルを介して公衆インターネットに公開します。ローカルウェブサイトの共有、Webhookコンシューマの構築/テストWebhook コンシューマーの構築/テスト、個人サービスのセルフホスティングなどが可能です。

このように非常に便利なサービスですが無料枠で使用する場合は以下の制限があります

  • 独自のドメインを割り当てることができず毎回URLが変わってしまう
  • 帯域幅と転送量にリミットがある

そこで、より低コストで利用できるサービスがないか探した所、 Cloudflare社が提供しているサービスを見つけました。
このサービスを利用すると ngrok の有料プランに該当する機能をコストを掛けずに利用できます!! (※ただし、無料プランでは1回にアップロードできるファイルサイズは100MB以下という制限だけ存在します)

Cloudflare のサービスを使ったサーバの外部公開方法
#

アカウントの作成とCloudflareへのドメインの登録が済んでいることを前提として進めていきます。

1. cloudflared のダウンロード
#

以下のURLを参照して各自の環境に合わせた最新のバイナリファイルを選択してください。
https://github.com/cloudflare/cloudflared/releases/latest/

$ wget https://github.com/cloudflare/cloudflared/releases/download/2022.10.3/cloudflared-linux-amd64
aptyum 等を利用してインストールすることもできますが、自動更新の機能を利用したいので、ここではバイナリファイルを直接ダウンロードしてインストールを行います。

2. バイナリファイルの名前を変更して適切なパスに配置する
#

$ mv cloudflared-linux-amd64 cloudflared
$ sudo cp ./cloudflared /usr/local/bin/

3. 実行権限を与える
#

$ sudo chmod +x /usr/local/bin/cloudflared

4. Cloudflare にログインする
#

以下のコマンドを実行して表示されたURLを任意のブラウザで開く
ページが開いたら紐付けたいドメイン名を選択して 承認ボタン を押す

警告 ※URLを開くときはcloudflareにログインしている状態で開く必要があります。
$ cloudflared tunnel login

5. トンネルを作成する (この時点では設定をするだけでまだコネクションは貼られない)
#

トンネルを作成すると ~/ホームフォルダ/.cloudflared/ 内にトンネルID等の認証ファイルが生成される abcd1234-0000-0000-0000-000000000000.json の形式の名前のjsonファイルです。
$ cloudflared tunnel create <任意のTunnelの名前>

6. トンネルIDとドメイン名を紐づける
#

一つ前の作業で作成されたJSONファイルを確認してトンネルのIDを把握しておく
トンネルIDが分かったら以下のコマンドで トンネルID設定したいドメイン を紐づける

$ cloudflared tunnel route dns <Tunnelのid> <(紐付けたいドメイン名)>

7. 公開するポートと紐づけるドメインの設定
#

cloudflared という名前のディレクトリを作成し、その中に config.yml という名前のファイルを作成する。 config.yml の中身は各自の目的に合わせて下の例のように記述する。

$ sudo mkdir /etc/cloudflared
$ sudo nano /etc/cloudflared/config.yml

config.ymlの内容
#

ここでは SSHVNCサーバ を外部に公開する設定にしています。 他のポートを公開したい場合は各自任意の情報に書き換えてください。

tunnel: トンネルのID
credentials-file: 絶対パス/.cloudflared/作成されたjsonファイルを指定

ingress:
  - hostname: <紐付けたいドメイン名>
    service: ssh://localhost:22
  - hostname: <紐付けたいドメイン名>
    service: tcp://localhost:5900
  - service: http_status:404

8. cloudflaredをサービスとして設定する (自動で起動するようにする)
#

$ sudo cloudflared --config /etc/cloudflared/config.yml service install

9. cloudflaredを起動する
#

$ sudo systemctl start cloudflared
$ sudo systemctl enable cloudflared

10. 正常に起動しているか確認する
#

Active の欄が active (running) になっていればOK

$ sudo systemctl status cloudflared
🟢 cloudflared.service - Cloudflare Tunnel
   Loaded: loaded (/etc/systemd/system/cloudflared.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-10-27 12:29:48 JST; 3 weeks 0 days ago
 Main PID: 2976033 (cloudflared)
    Tasks: 30 (limit: 202791)
   Memory: 64.3M
   CGroup: /system.slice/cloudflared.service
           └─2976033 /usr/local/bin/cloudflared --config /etc/cloudflared/config.yml tunnel run

自動アップデートの設定
#

下記のコマンドで cloudflared.service を開き、ExecStartの行から --no-autoupdate の記述を削除する

$ sudo nano /etc/systemd/system/cloudflared.service
$ sudo systemctl daemon-reload
$ sudo systemctl restart cloudflared

SSH接続できるようにするための設定
#

※クライアント側の設定です! サーバ側のSSHポートを公開して外部からアクセスできるようにしたい場合は、以下の設定も必要になります。 ProxyCommand の行が肝です

Host ssh.example.com
	HostName ssh.example.com
	User hoge
	ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h

VNC接続するときのコマンド
#

$ sudo cloudflared access tcp --hostname vnc.example.com --url localhost:1234

コマンドを実行した後にVNC Viewer等で localhost:1234 に接続すると繋がります

まとめ
#

この記事ではポート開放ができない環境でも、Cloudflareのサービスの利用によってサーバを外部公開する方法を紹介しました。 近年ではAWSやGCPといったクラウドサービスが普及しているため、サーバの外部公開で困ることは少ないかも知れません。 しかし、研究活動の一環での利用となると、コストやその他諸々の事情でそれらの利用が難しい場合も あります。 この問題を解決するための方法として本記事ではCloudflareのサービスについて紹介しました。

なお、記事中ではあまり触れていませんが、Cloudflareのサービスを使い出す前は ngrok のサービスも実際に導入し利用を検討していました。 こちらのサービスはコマンドを1つ叩くだけで指定したポート番号を外部に公開できるため、短期間だけデバックやデモとして公開したい場合には非常に便利なサービスです。 URLが固定じゃなくても問題ない場合にはまずは ngrokを試してみても良いかもしれません。 同様の問題を抱えている人にこの記事が参考になれば幸いです。

明日は@a5chinさんによる「数独・ナンプレを画像から解く AI を作る」という記事が公開されます。 お楽しみに!!

https://qiita.com/advent-calendar/2022/dena-23-shinsotsu

Related

Bibtexの導入
·67 文字·1 分
LaTex VSCode 拡張機能 Bibtex Programing
この記事では、LaTexで参考文献を管理する上で便利なBibtexについて紹介します。
LaTexの環境構築
·173 文字·1 分
LaTex VSCode 拡張機能 Programing
どうもBigbellです。記念すべき1つ目の記事です。理系大学の人だと卒論をLatexで書く人が多いと思いますが、環境作るのって面倒ですよね。そこで、今回はLaTexの(macにおける)環境構築の手順について紹介したいと思います。
工事中
日記