こんにちは。
コネヒトのテクノロジー推進部でインフラエンジニアをしている @laugh_k です。
先日リモートワークにおいても、共通の固定IPからのアクセスを実現するために Squidで簡易的なProxyを用意したので、そのときの話をまとめます。
TL;DR
- ビジネスサイドのあるチームで社外のツールを利用しようとしたが、IP制限が必要だった
- IP制限のあるツールはリモートワーク前提の状況と相性が悪い
- VPN サービスの契約も検討したが、人数も限られていたため、Squid を使った簡易的な Proxy サーバをたてて対応した
- 割り切った利用方法であれば、今でもEC2インスタンスはサクッと環境構築できるので便利
きっかけ
元はビジネスチームより「IP制限がある外部サービスを利用したいので簡易的なVPNを用意できないか」とインフラチームに来た相談がきっかけです。
要件を確認していくと「会社として共通の固定IPから外部サービスにアクセスできるようにする」ということを満たせればよさそうでした。そのため、VPNという手段に囚われずに要件に応えた結果 Squid を用いた Proxy サーバを用意することになりました。
なぜSquidを使ったProxyをEC2で用意したか
Squid を使ったProxyの選定
社外から共通の固定IP経由でWebサービスにアクセスする方法は色々ありますが、今回は以下の理由で VPN よりも Proxy を用意したほうが良いだろうと判断しました。
- 今回の件は全社員の話ではなく、ビジネスサイドの特定のチームメンバーが共通の固定IPを利用できればよかった
- 使いたいツールの案件が終了すれば、固定IPの管理自体が不要になる
- 要件の規模に対してVPNの用意は環境を構築する側にとっても、利用する側にとっても少々大げさだと感じた
Proxy の用意に当たっては Squid の利用を決めました。
選定理由としては、特段「Squid でなければいけない理由」はなく、単純に環境準備を担当した筆者自身が Squid を用いた Proxy の運用経験があったことによります。Proxy が実現可能であれば他のツール、ソフトウェアでも問題ないでしょう。
EC2 の選定
当初は Proxy を ECS on Fargate 上につくりサーバレスな状態にすることも考えました。しかし、今回は以下の理由でインスタンス1台とEIPの組み合わせだけでいけるEC2のパターンの方がお手軽感があったためEC2(OS: ubuntu 22.04 LTS)を選定しています。
- 準備にかけられる時間がかなり限られていた
- 必要な案件が終わればProxy自体不要になるので、最終的に環境ごと捨てられる見込みがあった
既にIaC化されているなど、社内に実績があるのであれば ECS on Fargate と NLB, NAT Gateway を組み合わせて環境をつくるものアリだと考えています。
構成
Proxy SwitchcyOmega のようなブラウザ拡張を入れてもらい、IP制限のあるツールの利用にのみProxyサーバを利用してもらう前提で以下のような構成にしました。
- 専用のネットワーク環境(VPC, subnet, EIP など)を用意
- EC2 インスタンスをEIPに関連付けて1台起動
- 最低限の Ansible Playbook を書きつつ、Squid のインストールと設定をする
- Proxy へのアクセス制限は Security Group に任せる形にして、Squid 側では設けない(詳細は後述)
アクセス制限
Proxy は関係者のみが使えるようにアクセス制限をかけています。
理想で言えばアクセス制限はなんらかの認証基盤を介したものにできるとよいのですが、今回の案件限定と割り切り、2022-08-29時点では利用メンバー環境のIPベースのものとしています。
またIPベースのアクセス制限も Security Group のみで行うようにし、Squid の設定では制限を設けていません。これはシンプルな設定にすることだけでなく、設定変更の頻度が多くなりそうな場合に自動化をやりやすくする狙いもあります。
Ansible Playbook
実際に使った Ansible Playbook も紹介します。( inventory は SSH ログイン情報のみなので省略)
ファイル構成は次の通りです。
. |-- inventory.yaml |-- main.yaml `-- templates `-- etc/squid/conf.d/allows.conf.j2
main.yaml
は内容は次の通りで、標準の方法で squid を install して最小限の設定を施すものとしています。
--- - hosts: all become: true tasks: - name: install squid apt: name: squid state: present - name: squid configuration template: src: etc/squid/conf.d/allows.conf.j2 dest: /etc/squid/conf.d/allows.conf owner: root group: root mode: 0644 validate: /usr/sbin/squid -k parse -f %s notify: - restart squid handlers: - name: restart squid service: name: squid state: restarted
templates/etc/squid/conf.d/allows.conf.j2
は次の通りです。
acl accesslist src all http_access allow accesslist # proxy からのアクセスを隠ぺいする forwarded_for off header_access X-Forwarded-For deny all header_access Via deny all header_access Cache-Control deny all # キャッシュをoff no_cache deny all
前述のとおり、アクセス制限は Security Group で行うため、Squid 側には設けていません。
また、内容を見るとわかりますが、結果的には templates ではなく files でよいです。templates となっているのは「後から必要になった場合もすぐに対応できるように」と選んで書き始めたことによります。
適用する際は SSH ログイン情報をそろえて次の通りに実行すればよいです。
$ ansible-playbook -i inventory.yaml main.yaml
その他の準備
Proxy そのももの用意以外に準備したことも紹介します。
使い方のアナウンス
原則としてブラウザ拡張は Proxy SwitchcyOmega を利用してもらう前提とし、利用方法を Notion にまとめました。
その際に、Proxy SwitchOmegaの設定は個別にやってもらうのではなく、あらかじめインポート可能なファイルにしてインポートして使ってもらうようにしています。設定ファイルは Google Drive で共有します。
この対応により、Proxy利用メンバーにはIP制限のあるサービスでのみProxyを経由したアクセスができる環境をつくりました。
利用メンバーの自宅 IP のヒアリングとアクセス許可
前述したとおりProxyにはアクセス制限をかけているので、利用メンバーの許可設定が必要です。
やり方は至ってシンプルで、利用メンバー一人一人に自分のインターネット環境のIPアドレスを確認してもらい、共有してもらいます。そのIPアドレスからのアクセスを Proxy 環境で利用している Security Group で許可をするだけです。
このアクセス制限のやり方だと結局利用メンバーのIPアドレスの管理は発生してしまいますが、社内のみで完結できます。社内での手間は発生しますが、外部サービスに対して個別に問い合わせをするよりはスムーズに管理ができています。
一方で、固定回線ではなくモバイルWifi環境から業務をするメンバーもいるため、それなりに自宅ネットワークのIPアドレス変更が起こるケースが発生しています。このあたりの問題に対しては今のところ人力で対応しているものの、頻度によっては Security Group の許可設定を変更可能にする Slackbot の用意などの手段も検討しています。
用意してみた雑感
リモートワーク状態で、IPアドレス制限のあるサービスを共通のProxy経由で利用する方法を紹介しました。
今回紹介したProxyの用意方法は、正直なところ完璧なシステムというものではありません。サーバーレスな環境で運用負荷を減らしたり、認証基盤を用いたアクセス制限をするなど改善できる点は多くあると認識しています。
一方で、今回の要件「一時的に特定のメンバーがIP制限付きのサービスを利用したい」という問題に、限られた時間と労力で解決するにはちょうど良いボリューム感であったとも感じています。
リモートワークにおいても共通の固定IPが必要になるケースは発生しうると思います。その際、限定的な条件であれば今回紹介したような簡易的な Proxy を用意するだけでも十分に対処できることもあるので、よろしければご参考にしてみてください。