gokigenmaruのブログ

40から始めるクラウドエンジニア

さくらのクラウドの「SEG」について調べてみた

クラウド環境でセキュリティ設計を考える際、Internetに出さずにデータをオブジェクトストレージに格納することについて考える機会が増えてきました。
最近、さくらのクラウドで「SEG(Service Endpoint Gateway)」というサービスがリリースされたので、SEGについて机上で勉強してみようと思います。

  • SEGとは何か
  • SEGを前提とした設計方針
  • オブジェクトストレージとのセキュリティ関係

あくまで2026年5月時点で勉強し理解した内容となります。

SEG

SEGとは何か

SEG(Service Endpoint Gateway)は、
「クラウド内のリソースから特定のサービスへ安全に接続するためのネットワーク経路を提供する仕組み」
です。
代表的な特徴は以下です。

  • プライベートネットワーク経由でサービスに接続できる
  • インターネットを経由せず通信可能
  • 接続先サービスを限定できる

さくらのクラウドにおいても、SEGはスイッチの拡張機能として提供され、仮想サーバからマネージドサービスへ安全に接続する経路を提供する役割を持っています。
SEGはあくまで「通信経路を制御するだけのコンポーネント」と理解しています。


SEGの設計方針

SEGを使う場合の考え方は以下の通りです。

設計の基本原則

原則1:許可ではなく「経路を固定する」
一般的なセキュリティ設計はどのIPを許可するか、どのユーザを許可するかという「許可ベース」の考え方になると思います。
しかしSEGの場合は「その経路を通らないと目的のサービスに到達できない状態を作る」になると思います。

原則2:閉域化に近づける
SEGを活用する目的は、通信をインターネットに出さない、公開エンドポイントを使わせない、という点にあります。
例えば:
さくらのクラウド内Server → SEG → オブジェクトストレージ
の形にし、直接インターネットからアクセス不可、SEG経由でのみ通信成立。
という状態にするのが基本です。

原則3:アクセス制御は別レイヤーで行う
SEGはアクセス制御を行いません。
したがって

  • IP制限
  • ユーザ制御
  • 認証

などは、アプリケーションやAPI側で実装する必要があります。

SEGとオブジェクトストレージ

オブジェクトストレージの性質

さくらのクラウドのオブジェクトストレージは、

  • Amazon S3互換APIを持つストレージサービス
  • HTTP/HTTPSベースでアクセス

という特徴があります。
つまり、ネットワーク的には基本的に「外部公開されたAPI」と考えるのが適当そうです。

できること / できないこと

できる
  • アクセスキーによる認証
  • ACLによるpublic/private設定
できない
  • 接続元IPによる制限
  • 特定ネットワークのみ許可
  • 特定環境(SEGなど)からのみ許可

SEGを使った構成は以下になります。
Server → SEG → Object Storage

このときのポイント:

  • 自分の環境からのアクセスは制御可能

- SEGを通すことで通信経路を制限できる

しかしストレージ側での制御はできない

  • ストレージは接続元を識別しない
  • 認証(アクセスキー)が合っていれば受け付ける

なぜ完全な制御にならないのか

理由はシンプルです。
さくらのオブジェクトストレージは、「誰がどこから来たか」ではなく、「正しい認証情報か」で判断する構造と考えられるからです。

実際に起こりうる状況
以下の2つの環境があるとします。
A環境(SEGあり)
Server → SEG → Object Storage

B環境(別アカウント)
Server → Internet → Object Storage

このとき、B環境が正しいアクセスキーを持っていれば SEGを使わずにアクセス可能となります。
※Internetからのアクセスを拒否する設定はオブジェクトストレージのACL機能で実装は可能です。

セキュリティ設計としてどう考えるべきか

ここまでを踏まえた結論としてはSEGではセキュリティは成立しないとなります。
SEGは以下を提供します:

  • 経路制御
  • 通信の閉域化(に近い状態)

しかし、アクセス制御は提供しない為、AWSのアクセス制御のような細かい制御は出来ません。

おわりに

あくまでも勉強をした内容となります。間違っていたら指摘をしてくれるととても助かります。
さくらのクラウドは今現在でも開発が進行中で頻繁にアップデートがあるクラウドです。この内容も数か月したら変わっている可能性があると思っています。

まとめ

  • SEGは通信をInternet(PublicIP宛)からPrivate(PrivateIP宛)へ経路を変更する機能
  • 通信の許可・拒否を行うものではない
  • オブジェクトストレージはPublic/Privateの制御は可能
  • セキュリティという意味ではアクセスキーでの制御となる


さくらのクラウドでVyOSを使う

さくらのクラウドでVyOSを使いたい…ですがさくらのクラウドで用意されているアーカイブの中にVyOSはありません。
ということで、さくらのクラウド上でVyOSを使えるようにしていきます。

さくらのクラウドにVyOSをアップロードする

VyOSとは?

オープンソースのネットワークオペレーティングシステムです。主にルーターファイアウォールVPNゲートウェイなどのネットワーク機器として利用されます。
主な特徴
Debian Linuxベース
VyOSはDebianをベースにしており、Linuxの柔軟性と安定性を活かしています。

CLIコマンドラインインターフェース)による設定
Cisco IOSやJuniper JunOSのようなCLIスタイルで設定でき、ネットワークエンジニアにとって馴染みやすいです。

構成のバージョン管理
設定はテキストファイルとして保存され、バージョン管理やバックアップが容易です。

仮想環境・クラウド対応
VMwareKVMHyper-VAWS、Azureなど、さまざまな仮想環境やクラウドに対応しています。

VPN機能が豊富
IPsecOpenVPN、WireGuard、L2TPなど、多様なVPNプロトコルをサポート。

VyOSのダウンロード

まずはVyOSをダウンロードしてきます。
ダウンロードは以下のサイトから。
vyos.io

このサイト内にある「RollingRelease」が無償のVyOSになります。
VyOSは有償版もあり、「RollingRelease」の左隣にある「Buy Now」からいけるようです。

今回は無償版を利用するので「RollingRelease」を選択。
そうするとVyOS rolling releaseのページに遷移するので、そこでAvailable buildsからOSイメージがダウンロードできます。
見てみると、かなり頻繁、1日おきくらいにリリースされているのが見て取れます。
とりあえず最新版をダウンロードすることに。

今回ダウンロードした「2025.08.03-0023-rolling (sig)」は.isoファイルで605MBでした。

ISOイメージのアップロード

続いてダウンロードしたISOイメージをさくらのクラウドにアップロードします。
アップロードする手順はさくらのクラウドのサイトにありますので、こちらを参考にします。
manual.sakura.ad.jp
ちなみにISOイメージを保存するためのディスク領域に料金が発生します。

月額 日額 時間額
5GB 110円 5円 1円
10GB 220円 11円 1円
20GB 440円 22円 2円

今回は605MBのデータなので、一番安い5GBのディスクを使います。

ISOイメージのアップロード先の作成

まずはISOイメージのアップロードするディスクを作成します。
画面左側のツリーから、「ストレージ」→「ISOイメージ」を選択

画面右上の「追加」を選択

ISOイメージ追加の画面で設定をしていきます。
まずはディスクのサイズを選択、今回は5GBです。

名前、説明をそれぞれ入力。

入力が終わったら画面右下の「作成」を選択。

操作確認の画面が出るので、「作成」を選択。

作成が無事出来ると自動で完了画面が出てくるので、この情報をもとにISOイメージをアップロードします。

ISOイメージのアップロード

作成したディスクにVyOSのISOイメージをアップロードします。
自分はWSL2があるので、WSL2を使ってVyOSのイメージを上げます。
※VyOSのISOイメージはダウンロードフォルダに入っている状態です。

WSL2にログインし以下の通り実行

$ curl --ssl --ftp-pasv --user xxxxxxxx:xxxxxxxxxxx --url ftp://sac-is1a-ftp.cloud.sakura.ad.jp/ --upload-file /mnt/c/Users/UserName/Downloads/vyos-2025.08.03-0023-rolling-generic-amd64.iso 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  605M    0     0  100  605M      0  6950k  0:01:29  0:01:29 --:--:-- 4845k

ちなみに余談ですが、ディスク作成するところまではきちんとさくらのクラウドのサイトを読んでいたのですが、ディスク作成後にイメージをアップロードするところから読んでおらず…イメージアップしたのに使えないぞ…となって30分くらい悩んでました(笑)

アップロードが終わったらさくらのクラウドに戻り、ISOイメージを選択。

すると、作成したディスクが出てきます。有効状態が「アップロード」となっているところを確認。まだこれはアップロードを受付中の状態です。

アップロードしたISOイメージを使えるようにするため、作成したディスクをチェックし画面右上の「詳細」を選択。

画面右上の「FTPを完了」を選択。

操作確認画面で「FTPを完了」を選択。

これでアップロードしたISOイメージが使えるようになります。
画面左側のISOイメージを選択すると、先ほど有効状態が「アップロード」となっていたところが「利用可能」に変わっています。

これでVyOSをさくらのクラウド上で使えるようになりました。

VyOSを構築する

サーバを構築する

VyOSのイメージアップロードが終わったので、さっそくアップロードしたイメージでVyOSを構築します。
左側のツリーから、サーバを選択。

画面右上の「追加」を選択。

スペックはvCPU2GB、Memory4GBにします。

ディスクは「ディスクレス(なし)」を選択、そうすると「ISOイメージを使う」という項目が出てきます。ここからアップロードしたISOイメージが選べます。

アップロードしたVyOSを選択。

NICとシンプル監視は今回は特に設定せず。

サーバ情報で名前を入力。

その他オプションはデフォルトのまま、作成数もデフォルトの1のまま「作成」を選択。

操作確認画面で「作成」を選択。

これでVyOSが作成されました。

VyOS初期設定

ディスクの作成とアタッチ

起動してきたVyOSですが、ISOから起動しているので設定変更をしても再起動すると入れた設定が消えてしまいます。
なので、初期設定としてディスクにインストールしてあげる必要があります。

画面左側のツリーから、「ストレージ」→「ディスク」を選択

画面右上の「追加」を選択。

今回はSSDの20GBにしました。ディスクの名前を入れて「作成」を選択。

操作確認画面で「作成」を選択。

これでブランクのディスクが作成できたので、このディスクをサーバにアタッチします。
サーバにディスクをアタッチするには、サーバを一度落とす必要がありますので、まずはシャットダウンを実行。
画面左側のツリーから、「サーバ」を選択。

先ほど作成したサーバを選択し、画面右上の「電源操作」から「シャットダウン」を選択。

シャットダウンの一括処理画面になるので、画面右上の「シャットダウン」を選択。

操作確認画面で「実行」を選択。

これでサーバがシャットダウンされます。
ディスクをアタッチします。
先ほど作成したサーバを選択し、画面右上の「詳細」を選択。

「ディスク」のタブを選択。

「接続」を選択。

「既存ディスクを接続」を選択し、先ほど作成したディスクを選んで「更新」を選択。

これでディスクがアタッチされました。
画面左側のツリーから、サーバを選択。

先ほど作成したサーバを選択し、画面右上の「電源操作」から「起動」を選択。

起動の一括処理画面になるので、画面右上の「起動」を選択。

操作確認画面で「実行」を選択。

これでディスクを接続したサーバが起動してきました。

VyOSのイメージをディスクにインストール

ディスクのアタッチが終わったら、VyOSのイメージをディスクにインストールします。
まずはVyOSにログイン、SSHとかの設定はしていないので今回はコンソールからログインします。
画面左側のツリーから、サーバを選択。

先ほど作成したサーバを選択し、画面右上の「詳細」を選択。

コンソールタブを選択。

これでコンソールログイン出来ます。

ログインします。初期ユーザIDとパスワードはvyos/vyosです。

今使われているイメージとバージョンを確認

show system imageで使われているイメージが出てこず、show versionを見るとBoot viaがliveになっています。
ということで、ディスクにイメージをインストールします。

インストールはinstall imageを実行
実行すると、「This command will install VyOS to your permanent storage. Would you like to continue?」と聞かれます。
これは「このコマンドはVyOSをストレージにインストールしますか?」という感じな内容です。今回はストレージにインストールしますので、Yを選択。

yを入力すると、イメージの名前をどうするか聞かれます。デフォルトのままでいいので、何も入れずにEnterを押します。

vyosユーザのパスワードを入れてくださいと出るので、8文字くらいでパスワードを入力、入力後再度同じメッセージが出るので同じパスワードを入力。

デフォルトでどのコンソールを使うか聞かれるので、デフォルトのkvmを選択。

どのDiskにインストールするか聞かれる。デフォルトの/dev/vdaを選択。

インストールするとサーバ上のすべてのデータが消えるよ?という警告。問題ないのでyを選択。

過去のインストールデータを探した結果、過去インストールしたデータが見つからない。ドライブの空き領域を全部使うか?と聞かれるのでYを選択。

1と2の設定ファイルがboot用に利用できるけど、どっちを使うか聞かれる。特にないのでデフォルトにする。

イメージのインストールに成功、リブートしてくださいと出るので、そのままリブートを実行。
※昔のクセでrebootコマンドのオプションに -- -rを入れたら、そんなコマンドはないと怒られている…。

起動中のGRUBの画面、作成したイメージで起動しているところ。

無事起動完了、ユーザIDはvyos、パスワードはデフォルトではなく先ほど入力したパスワードでログイン。

show system imageを実行、先ほどDiskにインストールしたイメージで起動していることを確認

show versionを実行、Boot viaがliveからinstalled imageに変わっていることを確認

これでVyOSの初期設定は完了です。あとはすきに設定を入れてsaveをしても大丈夫になりました。

AzureでVMからInternet向けの通信を拒否してもなぜか通信できるIPが存在する

結論

内部インフラサービス(168.63.129.16)への名前解決とメタデータ(169.254.169.254)のHTTP通信はInternet向けの通信をさせないようにしても通る
※内部インフラサービス→DNSゾルバ・インスタンスメタデータサービス(IMDS)・AzureLBのヘルスプローブ・Azureゲストエージョント

どういうことかの説明

Azureで構築した環境で、セキュリティの要件で特定の内部通信以外の通信を拒否する設定を入れることがありましたがなぜか一部IP宛の通信が通り抜ける事態に。
Azureで上記の通りセキュリティ要件があり内部向けの通信以外を拒否するため、以下の設定を入れることとしました

  • 既定の送信アクセスなし & NATゲートウェイの不使用
  • NetworkSecurityGroupの送信規則で通信したい宛先以外はポート、プロトコル、ソース、宛先をすべてAny/*とし全通信の遮断
  • PublicIPをVMアサインしない

NSGについてはこんなイメージです。

上記の設定であれば通信したい宛先(上記だとVNET間通信)以外は全部落とされる&PublicIPがない/NATするものがないのでInternetに出れないと考えていました。

実際には

上記設定を行いましたが、VNET宛以外の一部通信が出来ました。
気づいた理由は、Azureのメタデータにアクセスする通信があり、想定では通信できずに情報を取得できないはずがなぜか情報が取得できていたということがあり、なぜだということで内部でざわつきました。
自分の中ではInternet向けのGWが無いのであればメタデータは取れないと思い込んでいました。

メタデータあての通信

まずは外部に通信が出来ないことを確認するため、yahoo宛にcurlを投げると…

testvm01:~$ curl -v https://www.yahoo.co.jp/
* Host www.yahoo.co.jp:443 was resolved.
* IPv6: (none)
* IPv4: 182.22.28.252
*   Trying 182.22.28.252:443...
* connect to 182.22.28.252 port 443 from 10.0.0.4 port 54144 failed: Connection timed out
* Failed to connect to www.yahoo.co.jp port 443 after 134451 ms: Couldn't connect to server
* Closing connection
curl: (28) Failed to connect to www.yahoo.co.jp port 443 after 134451 ms: Couldn't connect to server

上記の通り、yahooには通信できず。
その設定のままメタデータ(169.254.169.254)あての通信を行うと。

testvm01:~$ curl -v http://169.254.169.254
*   Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET / HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Content-Type: text/xml; charset=utf-8
< Server: Microsoft-IIS/10.0
< Date: Tue, 15 Jul 2025 04:18:04 GMT
< Content-Length: 354
< 
<?xml version="1.0" encoding="utf-8"?>
<Error xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Code>MissingRequiredQueryParameter</Code>
    <Message>A required query parameter was not specified for this request.</Message>
    <Details>'comp' is a required query string variable.</Details>
* Connection #0 to host 169.254.169.254 left intact

通信できました。
ちなみにですが、NSGでVNET間通信用の許可設定を消しても通信できます。

内部インフラサービス(168.63.129.16)あての名前解決

まずは外部に通信が出来ないことを確認するため、yahoo宛にcurlを投げると…

testvm01:~$ curl -v https://www.yahoo.co.jp/
* Host www.yahoo.co.jp:443 was resolved.
* IPv6: (none)
* IPv4: 182.22.28.252
*   Trying 182.22.28.252:443...
* connect to 182.22.28.252 port 443 from 10.0.0.4 port 54144 failed: Connection timed out
* Failed to connect to www.yahoo.co.jp port 443 after 134451 ms: Couldn't connect to server
* Closing connection
curl: (28) Failed to connect to www.yahoo.co.jp port 443 after 134451 ms: Couldn't connect to server

上記の通り、yahooには通信できず。
その設定のまま内部インフラサービス(168.63.129.16)あてに名前解決を行うと…

testvm01:~$ dig @168.63.129.16 www.google.co.jp

; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> @168.63.129.16 www.google.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56056
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1224
; COOKIE: 6907cdda40937255 (echoed)
;; QUESTION SECTION:
;www.google.co.jp.              IN      A

;; ANSWER SECTION:
www.google.co.jp.       253     IN      A       142.250.198.3

;; Query time: 2 msec
;; SERVER: 168.63.129.16#53(168.63.129.16) (UDP)
;; WHEN: Tue Jul 15 04:27:56 UTC 2025
;; MSG SIZE  rcvd: 73

通信できました。
ちなみにですが、こちらもNSGでVNET間通信用の許可設定を消しても通信できます。

なぜ通信できるのか?

恐らくですが、どちらもAzureにとって必要不可欠な通信であり、閉ざされてしまうとAzureがサービスを提供することが難しくなるためかと思われます。

メタデータあて

メタデータは実際にはPublicIPというわけではなく、リンクローカルのアドレスなので厳密にはInternet向けの通信とはなりません。
なのでVNET内で通信は行われますが、NSGで制御できない理由は不明です。
気になったので、NSGで169.254.169.254を明示的に拒否して試してみました。

試してみます。

testvm01:~$ curl -v http://169.254.169.254
*   Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET / HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Content-Type: text/xml; charset=utf-8
< Server: Microsoft-IIS/10.0
< Date: Tue, 15 Jul 2025 04:42:58 GMT
< Content-Length: 354
< 
<?xml version="1.0" encoding="utf-8"?>
<Error xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Code>MissingRequiredQueryParameter</Code>
    <Message>A required query parameter was not specified for this request.</Message>
    <Details>'comp' is a required query string variable.</Details>
* Connection #0 to host 169.254.169.254 left intact

通信できました。明示的にNSGで拒否しても通信できるのか?
気になったのでVNET間用の通信許可を消して再チャレンジ。

testvm01:~$ curl -v http://169.254.169.254
*   Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET / HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Content-Type: text/xml; charset=utf-8
< Server: Microsoft-IIS/10.0
< Date: Tue, 15 Jul 2025 04:46:41 GMT
< Content-Length: 354
< 
<?xml version="1.0" encoding="utf-8"?>
<Error xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Code>MissingRequiredQueryParameter</Code>
    <Message>A required query parameter was not specified for this request.</Message>
    <Details>'comp' is a required query string variable.</Details>
* Connection #0 to host 169.254.169.254 left intact

通信できました。
もしかしたら明示的に設定してもメタデータ宛の通信は拒否できないかもしれません。
※なんか見落としているような気もする…。 ←このブログを書いている時にNSGのサービスタグで「AzurePlatformIMDS」というものがあることに気づきました。

ということでAzurePlatformIMDSの拒否設定を投入。

testvm01:~$ curl -v http://169.254.169.254
*   Trying 169.254.169.254:80...
* connect to 169.254.169.254 port 80 from 10.0.0.4 port 42048 failed: Connection timed out
* Failed to connect to 169.254.169.254 port 80 after 132929 ms: Couldn't connect to server
* Closing connection
curl: (28) Failed to connect to 169.254.169.254 port 80 after 132929 ms: Couldn't connect to server

無事通信が拒否出来ました。

内部インフラサービスあて

IP アドレス 168.63.129.16 は、Azure プラットフォーム リソースへの通信チャネルの使用を容易にするために使用される仮想パブリック IP アドレスです。
Microsoftのサイトより
なので、こちらはPublicIPの位置づけなのでメタデータとは少し異なります。
ですが、こちらもメタデータと同様に通信制御が出来ず、Gatewayがなくても通信が出来ます。なのでNSGで制御できない理由は不明です。
気になったので、NSGで168.63.129.16を明示的に拒否して試してみました。

testvm01:~$ dig @168.63.129.16 www.google.co.jp

; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> @168.63.129.16 www.google.co.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59654
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1224
; COOKIE: 25ae4c332713dc13 (echoed)
;; QUESTION SECTION:
;www.google.co.jp.              IN      A

;; ANSWER SECTION:
www.google.co.jp.       299     IN      A       142.251.222.3

;; Query time: 39 msec
;; SERVER: 168.63.129.16#53(168.63.129.16) (UDP)
;; WHEN: Tue Jul 15 05:00:58 UTC 2025
;; MSG SIZE  rcvd: 73

通信できました。
もしかしたら明示的に設定してもメタデータと同様、内部インフラサービス宛の通信は拒否できない?
気になったので調べてみると、以下のサイトがありました。
learn.microsoft.com
通信拒否のところを要約するとこんか感じです。

  • 168.63.129.16はAzureの内部プラットフォームIPであり、DNS、IMDS、DHCP、Load Balancerのヘルスチェックなどに使用される。
  • NSG(Network Security Group)のルールには影響されない通信がある(特にVM AgentやDNSなど)。
  • DNS通信をNSGで制御したい場合は、AzurePlatformDNS サービスタグを使って明示的に拒否する必要がある。

ということで、NSGで拒否するにはAzurePlatformDNSのサービスタグじゃないとダメみたいですね。
なのでサービスタグで拒否してみました。

testvm01:~$ dig @168.63.129.16 www.google.co.jp
;; communications error to 168.63.129.16#53: timed out
;; communications error to 168.63.129.16#53: timed out
;; communications error to 168.63.129.16#53: timed out

; <<>> DiG 9.18.30-0ubuntu0.24.04.2-Ubuntu <<>> @168.63.129.16 www.google.co.jp
; (1 server found)
;; global options: +cmd
;; no servers could be reached

無事通信が拒否出来ました。

おわりに

Internet向けの通信を拒否してもメタデータと内部インフラサービスあての通信は出来ます。
ただし、メタデータも内部インフラサービスも「明示的に」拒否をすれば通信を出来なくすることは出来ます。
実際にInternet向けの通信を拒否すると言って、この通信が出来ることで問題があるかと言えばないと思います。
ただ、設定をしたエンジニアがこれを知らずにいると後でわかった時に問題になるのがよくあることかなと思います。
通信できるとなった時に、「Azureはメタデータと内部インフラあての通信はInternet向けの通信を拒否しても出来るんですよね」と言えば問題にならないことが多いと思うので、もしこのIP宛の通信が制御出来なくてこのブログに来た人は「こんな場末のブログでこんなこと書いてる人がいました」と言ってください。もしかしたらいい方向に向かうかもしれません。

GoogleCloudでネットワークを作成する

Google CloudのVPC

VPC (Virtual Private Cloud)とは

Google CloudのVirtual Private Cloud(VPC)は、クラウドベースのリソースとサービスに対してスケーラブルで柔軟性に優れたグローバルなネットワーキングを提供するサービスです。VPCは、Compute Engine仮想マシンVMインスタンスGoogle Kubernetes Engine(GKE)クラスタ、サーバーレスワークロードなどにネットワーキング機能を提供します。

VPCネットワークは、Google Cloud内で仮想化されている点を除き、物理ネットワークと同じように考えることができます。VPCネットワークは、データセンター内のリージョン仮想サブネットワーク(サブネット)のリストで構成されるグローバルリソースであり、すべてグローバルな広域ネットワークで接続されています。

VPCネットワークの主な機能には以下が含まれます

ネットワーク接続: Compute Engine VMインスタンス、GKEクラスタ、サーバーレスワークロードなどに向けた接続を提供します。
ファイアウォールルール: 各VPCネットワークには、構成可能な分散仮想ファイアウォールが実装されています。ファイアウォールルールを使用すると、どのパケットをどの宛先に送信できるようにするかを制御できます。
ルート: VMインスタンスVPCネットワークに対して、インスタンスから宛先(ネットワーク内部またはGoogle Cloudの外部)にトラフィックを送信する方法を通知します。
転送ルール: IPアドレスプロトコル、ポートに基づいてVPCネットワーク内のGoogle Cloudリソースにトラフィックを転送します。
インターフェースとIPアドレス: VPCネットワークは、IPアドレスVMネットワークインターフェース用の構成を提供します。
また、VPCネットワークはGoogle Cloud内で互いに論理的に隔離されており、他のGoogle Cloud利用者からは完全に独立したプライベートネットワークとなります。


とCopilot先生がおっしゃっています。

AWS/Azure/GoogleCloudのVPCの違い

AWS/Azureとの大きな違いは2点あると思っています。

  1. GoogleCloudのVPCIPアドレスのCIDRを持ちません
  2. VPCはグローバルサービス(リージョン固定ではない)として利用

AWS/AzureではVPCにCIDRを持たせその範囲内からサブネットに切り出していきますが、GoogleCloudではVPC側でCIDRを持たずサブネット単位でCIDRを持つ形になります。
また、VPCはグローバルのサービスでリージョンはサブネット毎になります。

ということでこんな感じで理解しました。

VPCネットワークを作ってみる

VPCの作成

ということで、VPCを作成してみます。
プロジェクトのトップページからVPCネットワークをクリック

こんなエラーが出るので、続行をクリック

Compute Engine APIを有効にする

どうやらGoogleCloudではAPIをプロジェクトごとに管理しているので、APIはプロジェクトごとに有効にするようです。

すでにdefaultのVPCがありますが、こちらは利用せず、新たにVPCの作成をします。
画面上部のVPCネットワークを作成をクリック

VPCとサブネット、VPC周りの設定を行っていきます。

まずはVPC名と説明などの設定。
MTUはデフォルトの1460のまま。ネットワークプロファイルは作成せずにサブネットは手動で作成したいのでカスタムにし、IPv6は設定しないこととします。

サブネットの作成、東京リージョンにtest-tokyoという名前のサブネットを作っています。
IPv4のみで、10.0.0.0/24、その他はすべてデフォルトのままです。

ファイアウォール ルールはデフォルトのまま。
ファイアウォールルールはAWSでいうセキュリティグループ、Azureでいうネットワークセキュリティグループと理解しています。これを細かく追うとそれだけでブログ1つかけそう。
設定としては、VPC内の通信許可、icmp/ssh/rdpの許可、自身からの送信の許可、Internetからの拒否が入っています。

高度庵設定はデフォルトのままにしました。
今回はCloudRouterは作らないので動的ルーティングは使わない…はず。

作成をクリック
作成したVPCが表示されます。


作成は簡単にできました。
どのクラウドもそうですが、細かい設定をせずにデフォルトで作成するのであれば簡単にできますし、デフォルト通りに作ってあげれば動くようになっているので助かります。

Google Cloudを学ぶ

今までAWS、Azure、さくらのクラウドとやってきましたが、メジャーどころで手を出していなかったGoogle Cloud。最近、お仕事でGoogle Cloudを触る機会が出来ましたのでちょっとずつ学んでいこうと思います。

Google Cloudとは

Google Cloudは、Googleが提供するクラウドコンピューティングサービスです。これにより、企業や個人がインターネットを通じてさまざまなITリソースを利用できるようになります。

主な特徴

高速ネットワーク: Googleが独自に開発した高速で安定したネットワークを提供しています。
ビッグデータとAI: Googleの強みであるビッグデータ分析とAI技術を活用できます。
フルマネージドサービス: サーバーの管理やメンテナンスをGoogleに任せることができるため、運用の手間が省けます。
セキュリティ: 高度なセキュリティ対策が施されており、安心して利用できます。

代表的なサービス

Google Compute Engine (GCE): 仮想サーバーの構築2。
Google Cloud Storage (GCS): データの保管2。
Google Cloud SQL: リレーショナルデータベースサービス2。
Google Cloud AI Platform: AI開発2。

GoogleCloud

Google Cloudは、特にビッグデータとAIに強みがあり、高速なネットワークとフルマネージドサービスが魅力です。
日本市場ではAWSは豊富なサービス、AzureはMS製品との親和性が特徴であり、ともに30%近い利用率になっています。
かたやGoogleCloudは15%くらいですが、一時期に比べれば他の2社に追いついてきていると思います。

ただ、使用率の低さがあるからか勉強をするにはちょっと不便で、この間参考書を買いに秋葉原書泉ブックタワーに行きましたが、AWS/Azureは数十冊と参考書があるなか、GoogleCloudはたったの2冊しかなく…。会社とかですでにバックボーンがあればいいのでしょうが、個人が1から勉強しようと思うとちょっとハードルが高い気がする。

リージョンとゾーン

GoogleCloudもAWSやAzureと同様にリージョンとゾーンというものがあります。
リージョンはデータセンター群を地域で纏めた呼称、日本だと東京・大阪、欧州だとフランクフルトやロンドン・パリなど、北米だとロサンゼルスやバージニア北部などですね。
ゾーンは各リージョン内にあるデータセンターといった感じ。
リージョンの定義は3つ以上のゾーン(物理的なデータセンター)があるものということで、この辺もAWS/Azureと同じようです。

GoogleCloudの組織階層

GoogleCloudは組織を階層の頂点とし、その下にフォルダがあり、フォルダの中でプロジェクトを作成してGoogleCloudのリソースをプロジェクト内に作成する形になります。
フォルダは複数階層を持つことが出来て、Aフォルダの下にBフォルダとCフォルダを作成するみたいな感じで分けることも可能です。

GoogleCloudの検証用プロジェクトの作成

検証用プロジェクト作成

ということで、参考書も買い実際にGoogleCloudのアカウントを作成しました。
まずはProjectを作れということで、テスト用のProjectを作成し、そこでいろいろと試すことにしました。
GoogleCloudにログインし、画面左上のところをクリック

新しいプロジェクトをクリック

プロジェクト名を入れて作成をクリック

プロジェクトを作成したら画面左上のところをクリック

作成したプロジェクトを選択

これでプロジェクトに入りました

ダッシュボードの表示

プロジェクトの作成が出来たら、まずはダッシュボードを見ようと思います。
画面左上の三本線からリソースを選んでもいいのですが、ダッシュボードは全体が見れるので最初はダッシュボードから見ていくのがいいのかなと思います。
トップ画面の真ん中くらいにあるダッシュボードをクリック

ダッシュボードが表示されました。
ここからいろいろといじっていこうと思います。

まとめ

まずは検証が出来る環境を作成しました。
ざっと調べた感じだと、リージョンやゾーンなどはAWSやAzureと同じ考え方のようでした。
プロジェクトというのは、GoogleCloudは組織(会社)単位で1つのアカウントを作成し、その中でフォルダ(例えば部署ごと)を分けてそこにプロジェクトを作成するツリー型になっていて、この辺はAzureなんかと感覚が似ている気がします。※個人の感想です。

AWSでSite to Site VPNを使う

会社で検証で使えるL3 Switchを手に入れたので、かねてからやってみたかったAWSとのVPN接続をやってみようと思います。

Site to Site VPN

Site-to-Site VPN (Virtual Private Network) は、異なる物理的な場所にある複数のネットワークを安全に接続するための技術です。
これにより、異なるオフィスやデータセンター間でデータを安全にやり取りすることができます。

主な特徴

セキュリティ: データは暗号化されて送信されるため、インターネット上での盗聴や改ざんを防ぎます。
コスト効率: 専用回線を使用するよりもコストが低く、インターネットを介して接続できます。
スケーラビリティ: 新しい拠点を追加するのが比較的簡単です。

利用例

企業の拠点間接続: 本社と支社、または異なる国にあるオフィス間の安全な通信。
データセンターの統合: 複数のデータセンターを一つのネットワークとして運用。

AWSでSite to Site VPNを使う

AWSだと、よく構成例として出るのはコストを削減するためにDirectConnectの副系をVPNにするやり方です。
実際に設定をしてみたかったのですが、物理的なL3機器が必要なので今まで手が出せませんでした。
今回は実際に機器を手に入れたのでやってみます。

仮想プライベートゲートウェイの作成

まずは仮想プライベートゲートウェイの作成です。
VPC」→「仮想プライベートゲートウェイ」で画面右上の「仮想プライベートゲートウェイを作成」を選択。
設定自体は2つを設定すればよく、名前(オプション)と自律システム番号(ASN)を入れるだけ。
名前は適当に、ASNはAmazonデフォルトASNにしました。ASNはVPNをはるときに動的にルーティングをやり取りするときにBGPで使われる番号です。
BGP周りは別途ネットワークの勉強が必要ですが、オンプレとは異なる"プライベート"のAS番号を入れる必要があります。

作成後、使いたいVPCにアタッチする必要があるので注意です。

カスタマーゲートウェイの作成

今度はオンプレ側のL3の設定を入れます。
VPC」→「カスタマーゲートウェイ」で画面右上の「カスタマーゲートウェイを作成」を選択。
こちらはオンプレで使っているL3の設定を入れていきます。
名前はAWSで識別するものなので、わかりやすいもの。
BGP ASNは動的にルーティングをやり取りする際に使うBGPのAS番号。今回は静的にルーティングを書くのでBGPは使いません。デフォルトで入っている番号を使います。
IPアドレスVPNをはるオンプレ側のインターフェースに割り当てられているIPアドレス(通常はパブリックのIPになるはず)
バイスAWS上でオンプレ側のL3を識別するための名前なので、わかりやすいもの。

Site-to-Site VPNの作成

VPC」→「Site-to-Site VPN接続」で画面右上の「VPN接続を作成する」を選択。
ターゲットゲートウェイは先ほど作成した仮想プライベートゲートウェイを選択。
カスタマーゲートウェイも先ほど作成したカスタマーゲートウェイを選択。
ルーティングオプションは今回は静的にして、オンプレ側で使っているIPアドレスを入れます。
ローカル IPv4 ネットワーク CIDRとリモート IPv4 ネットワーク CIDRは特に入力はせず。

これで作成をしました。

トンネルの設定を細かくしたい場合はトンネルオプションで設定をしていきます。
トンネルの内部IP(/30)や事前共有キー(Pre shared key)、暗号化のアルゴリズムとかIKEのバージョンとかをオプションで設定できます。

オンプレL3設定

Site-to-Site VPNの作成した後にオンプレ側の設定のダウンロードが出来ます。
VPC」→「Site-to-Site VPN接続」で画面右上の「設定をダウンロードする」を選択。
いろんなベンダーの機器の設定サンプルをダウンロードすることが出来るので、この中から該当するものを選びます。
ちなみに自分はこのリストにはなかったベンダーの機器だったので、一旦Ciscoの設定をダウンロードしてカスタマイズして入れました。

VPNつながる

これで設定は終わりで後は状態が利用可能にあり、トンネルの詳細でステータスがアップしていることを確認すればOKです。
AWS上でEC2を作成、ルートテーブルでオンプレのルーティングを書いてあげてセキュリティグループでオンプレからの接続を許可し、オンプレ側からSSHとかが出来ることを確認出来れば完了です。

終わりに

L3を用意するのがちょっと大変ですがVPN自体は簡単に設定が出来ました。
AWS側がオンプレ機器の設定サンプルを用意してくれているのもあり、ハードルはかなり低くなっていると思います。

ansibleでyamlファイルなどを編集するときにインデントを入れる方法

Ansibleでyamlファイルを編集する際、インデントを入れるのに苦戦しました。
忘れないように書いておきます。

ansible

ファイル編集

ファイル編集ですが、以下ような編集を行いたいと考えました。

編集前

111:
  aaa:
    bbb:
      ccc:
      ddd:

編集後

111:
  aaa:
    eee:
      fff:
      ggg:
    bbb:
      ccc:
      ddd:

上記の通り、eee~gggまでをaaaの次に入れるようにしたいと思いましたが、やってみると意外とうまくいきませんでした。

インデント込みの内容をファイルに反映出来ない

まずは単純に以下の方針でやろうとしました。

  • ansible.builtin.lineinfileのsearch_stringで"aaa:"を検索する
  • 検索にヒットした文字列の後にlineで複数行の文字列をインデント込みで挿入する

実際にはこういった感じです。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |
        aaa:
          eee:
            fff:
            ggg:
実行結果

実行した結果、ファイルは以下の通りになります。

111:
aaa:
  eee:
    fff:
    ggg:
    bbb:
      ccc:
      ddd:

aaa:の前に入れている空白2つが認識されない結果になりました。

調査

ぱっと見、最初の2つのインデントが認識されていないが、次の行からは空白が認識されているので、単純にもう2つ空白を入れればいけるかと思いましたが、結果は失敗でした。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |
          aaa:
            eee:
              fff:
              ggg:

実行結果

111:
aaa:
  eee:
    fff:
    ggg:
    bbb:
      ccc:
      ddd:

つまり、lineで複数行を指定するとき、文字列が始まるところまでの空白は認識してくれない(次の行以降は前の行で先頭から何個空白があったかは無視されるがそれ以降の空白は認識される)ことがわかりました。

ansibleの調査

ansibleでこれが回避できないか調べてみたところ、line:の後ろに数字を指定できることが判明。
line: | n
こんな感じ。
このnの意味ですが、先頭からn文字以降は文字列として認識してくれると理解しています。
なので、

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |4
          aaa:
            eee:
              fff:
              ggg:

とやると、

111:
    aaa:
      eee:
        fff:
        ggg:
    bbb:
      ccc:
      ddd:

こんな感じで編集されます。
これでyamlファイルのインデントが入れられそうです。

希望のインデントを挿入する

yamlでインデントを合わせるために、以下の通りplaybookを編集。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |2
          aaa:
            eee:
              fff:
              ggg:

実行結果

111:
  aaa:
    eee:
      fff:
      ggg:
    bbb:
      ccc:
      ddd:

となりました。